History

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next

Pull networking updates from David Miller: "Highlights: 1) Support more Realtek wireless chips, from Jes Sorenson. 2) New BPF types for per-cpu hash and arrap maps, from Alexei Starovoitov. 3) Make several TCP sysctls per-namespace, from Nikolay Borisov. 4) Allow the use of SO_REUSEPORT in order to do per-thread processing of incoming TCP/UDP connections. The muxing can be done using a BPF program which hashes the incoming packet. From Craig Gallek. 5) Add a multiplexer for TCP streams, to provide a messaged based interface. BPF programs can be used to determine the message boundaries. From Tom Herbert. 6) Add 802.1AE MACSEC support, from Sabrina Dubroca. 7) Avoid factorial complexity when taking down an inetdev interface with lots of configured addresses. We were doing things like traversing the entire address less for each address removed, and flushing the entire netfilter conntrack table for every address as well. 8) Add and use SKB bulk free infrastructure, from Jesper Brouer. 9) Allow offloading u32 classifiers to hardware, and implement for ixgbe, from John Fastabend. 10) Allow configuring IRQ coalescing parameters on a per-queue basis, from Kan Liang. 11) Extend ethtool so that larger link mode masks can be supported. From David Decotigny. 12) Introduce devlink, which can be used to configure port link types (ethernet vs Infiniband, etc.), port splitting, and switch device level attributes as a whole. From Jiri Pirko. 13) Hardware offload support for flower classifiers, from Amir Vadai. 14) Add "Local Checksum Offload". Basically, for a tunneled packet the checksum of the outer header is 'constant' (because with the checksum field filled into the inner protocol header, the payload of the outer frame checksums to 'zero'), and we can take advantage of that in various ways. From Edward Cree" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1548 commits) bonding: fix bond_get_stats() net: bcmgenet: fix dma api length mismatch net/mlx4_core: Fix backward compatibility on VFs phy: mdio-thunder: Fix some Kconfig typos lan78xx: add ndo_get_stats64 lan78xx: handle statistics counter rollover RDS: TCP: Remove unused constant RDS: TCP: Add sysctl tunables for sndbuf/rcvbuf on rds-tcp socket net: smc911x: convert pxa dma to dmaengine team: remove duplicate set of flag IFF_MULTICAST bonding: remove duplicate set of flag IFF_MULTICAST net: fix a comment typo ethernet: micrel: fix some error codes ip_tunnels, bpf: define IP_TUNNEL_OPTS_MAX and use it bpf, dst: add and use dst_tclassid helper bpf: make skb->tc_classid also readable net: mvneta: bm: clarify dependencies cls_bpf: reset class and reuse major in da ldmvsw: Checkpatch sunvnet.c and sunvnet_common.c ldmvsw: Add ldmvsw.c driver code ...

Linus Torvalds committed 10 years ago

Commit 1200b682 parents 6b5f04b fe309371281 files · +79030 −34010Browse files

Showing the changes to tools/testing (6 of 1281 files). Show all

Unified · Split

6 files
  1. tools/testing/selftests/lib/Makefile +1 −1
  2. tools/testing/selftests/lib/bitmap.sh +10 −0
  3. tools/testing/selftests/net/.gitignore +1 −0
  4. tools/testing/selftests/net/Makefile +1 −1
  5. tools/testing/selftests/net/reuseport_bpf.c +110 −7
  6. tools/testing/selftests/net/reuseport_bpf_cpu.c +258 −0
tools/testing/selftests/lib/Makefile+1−1
@@ -3,6 +3,6 @@ · 2 unmodified lines
33 # No binaries, but make sure arg-less "make" doesn't trigger "run_tests"
44 all:
55
6−TEST_PROGS := printf.sh
6+TEST_PROGS := printf.sh bitmap.sh
77
88 include ../lib.mk
tools/testing/selftests/lib/bitmap.sh+10−0
@@ -0,0 +1,10 @@
1+#!/bin/sh
2+# Runs bitmap infrastructure tests using test_bitmap kernel module
3+
4+if /sbin/modprobe -q test_bitmap; then
5+ /sbin/modprobe -q -r test_bitmap
6+ echo "bitmap: ok"
7+else
8+ echo "bitmap: [FAIL]"
9+ exit 1
10+fi
tools/testing/selftests/net/.gitignore+1−0
@@ -2,3 +2,4 @@ socket · 1 unmodified line
22 psock_fanout
33 psock_tpacket
44 reuseport_bpf
5+reuseport_bpf_cpu
tools/testing/selftests/net/Makefile+1−1
@@ -4,7 +4,7 @@ CFLAGS = -Wall -O2 -g · 3 unmodified lines
44
55 CFLAGS += -I../../../../usr/include/
66
7−NET_PROGS = socket psock_fanout psock_tpacket reuseport_bpf
7+NET_PROGS = socket psock_fanout psock_tpacket reuseport_bpf reuseport_bpf_cpu
88
99 all: $(NET_PROGS)
1010 %: %.c
tools/testing/selftests/net/reuseport_bpf.c+110−7
@@ -9,10 +9,12 @@ · 8 unmodified lines
99
1010 #include <errno.h>
1111 #include <error.h>
12+#include <fcntl.h>
1213 #include <linux/bpf.h>
1314 #include <linux/filter.h>
1415 #include <linux/unistd.h>
1516 #include <netinet/in.h>
17+#include <netinet/tcp.h>
1618 #include <stdio.h>
1719 #include <stdlib.h>
1820 #include <string.h>
@@ -169,9 +171,15 @@ static void build_recv_group(const struct test_params p, int fd[], uint16_t mod, · 150 unmodified lines
169171 if (bind(fd[i], addr, sockaddr_size()))
170172 error(1, errno, "failed to bind recv socket %d", i);
171173
172− if (p.protocol == SOCK_STREAM)
174+ if (p.protocol == SOCK_STREAM) {
175+ opt = 4;
176+ if (setsockopt(fd[i], SOL_TCP, TCP_FASTOPEN, &opt,
177+ sizeof(opt)))
178+ error(1, errno,
179+ "failed to set TCP_FASTOPEN on %d", i);
173180 if (listen(fd[i], p.recv_socks * 10))
174181 error(1, errno, "failed to listen on socket");
182+ }
175183 }
176184 free(addr);
177185 }
@@ -189,10 +197,8 @@ static void send_from(struct test_params p, uint16_t sport, char *buf, · 11 unmodified lines
189197
190198 if (bind(fd, saddr, sockaddr_size()))
191199 error(1, errno, "failed to bind send socket");
192− if (connect(fd, daddr, sockaddr_size()))
193− error(1, errno, "failed to connect");
194200
195− if (send(fd, buf, len, 0) < 0)
201+ if (sendto(fd, buf, len, MSG_FASTOPEN, daddr, sockaddr_size()) < 0)
196202 error(1, errno, "failed to send message");
197203
198204 close(fd);
@@ -260,7 +266,7 @@ static void test_recv_order(const struct test_params p, int fd[], int mod) · 61 unmodified lines
260266 }
261267 }
262268
263−static void test_reuseport_ebpf(const struct test_params p)
269+static void test_reuseport_ebpf(struct test_params p)
264270 {
265271 int i, fd[p.recv_socks];
266272
@@ -268,6 +274,7 @@ static void test_reuseport_ebpf(const struct test_params p) · 1 unmodified line
268274 build_recv_group(p, fd, p.recv_socks, attach_ebpf);
269275 test_recv_order(p, fd, p.recv_socks);
270276
277+ p.send_port_min += p.recv_socks * 2;
271278 fprintf(stderr, "Reprograming, testing mod %zd...\n", p.recv_socks / 2);
272279 attach_ebpf(fd[0], p.recv_socks / 2);
273280 test_recv_order(p, fd, p.recv_socks / 2);
@@ -276,7 +283,7 @@ static void test_reuseport_ebpf(const struct test_params p) · 2 unmodified lines
276283 close(fd[i]);
277284 }
278285
279−static void test_reuseport_cbpf(const struct test_params p)
286+static void test_reuseport_cbpf(struct test_params p)
280287 {
281288 int i, fd[p.recv_socks];
282289
@@ -284,6 +291,7 @@ static void test_reuseport_cbpf(const struct test_params p) · 1 unmodified line
284291 build_recv_group(p, fd, p.recv_socks, attach_cbpf);
285292 test_recv_order(p, fd, p.recv_socks);
286293
294+ p.send_port_min += p.recv_socks * 2;
287295 fprintf(stderr, "Reprograming, testing mod %zd...\n", p.recv_socks / 2);
288296 attach_cbpf(fd[0], p.recv_socks / 2);
289297 test_recv_order(p, fd, p.recv_socks / 2);
@@ -377,7 +385,7 @@ static void test_filter_no_reuseport(const struct test_params p) · 87 unmodified lines
377385
378386 static void test_filter_without_bind(void)
379387 {
380− int fd1, fd2;
388+ int fd1, fd2, opt = 1;
381389
382390 fprintf(stderr, "Testing filter add without bind...\n");
383391 fd1 = socket(AF_INET, SOCK_DGRAM, 0);
@@ -386,6 +394,10 @@ static void test_filter_without_bind(void) · 2 unmodified lines
386394 fd2 = socket(AF_INET, SOCK_DGRAM, 0);
387395 if (fd2 < 0)
388396 error(1, errno, "failed to create socket 2");
397+ if (setsockopt(fd1, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)))
398+ error(1, errno, "failed to set SO_REUSEPORT on socket 1");
399+ if (setsockopt(fd2, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)))
400+ error(1, errno, "failed to set SO_REUSEPORT on socket 2");
389401
390402 attach_ebpf(fd1, 10);
391403 attach_cbpf(fd2, 10);
@@ -394,6 +406,32 @@ static void test_filter_without_bind(void) · 2 unmodified lines
394406 close(fd2);
395407 }
396408
409+void enable_fastopen(void)
410+{
411+ int fd = open("/proc/sys/net/ipv4/tcp_fastopen", 0);
412+ int rw_mask = 3; /* bit 1: client side; bit-2 server side */
413+ int val, size;
414+ char buf[16];
415+
416+ if (fd < 0)
417+ error(1, errno, "Unable to open tcp_fastopen sysctl");
418+ if (read(fd, buf, sizeof(buf)) <= 0)
419+ error(1, errno, "Unable to read tcp_fastopen sysctl");
420+ val = atoi(buf);
421+ close(fd);
422+
423+ if ((val & rw_mask) != rw_mask) {
424+ fd = open("/proc/sys/net/ipv4/tcp_fastopen", O_RDWR);
425+ if (fd < 0)
426+ error(1, errno,
427+ "Unable to open tcp_fastopen sysctl for writing");
428+ val |= rw_mask;
429+ size = snprintf(buf, 16, "%d", val);
430+ if (write(fd, buf, size) <= 0)
431+ error(1, errno, "Unable to write tcp_fastopen sysctl");
432+ close(fd);
433+ }
434+}
397435
398436 int main(void)
399437 {
@@ -506,6 +544,71 @@ int main(void) · 106 unmodified lines
506544 .recv_port = 8007,
507545 .send_port_min = 9100});
508546
547+ /* TCP fastopen is required for the TCP tests */
548+ enable_fastopen();
549+ fprintf(stderr, "---- IPv4 TCP ----\n");
550+ test_reuseport_ebpf((struct test_params) {
551+ .recv_family = AF_INET,
552+ .send_family = AF_INET,
553+ .protocol = SOCK_STREAM,
554+ .recv_socks = 10,
555+ .recv_port = 8008,
556+ .send_port_min = 9120});
557+ test_reuseport_cbpf((struct test_params) {
558+ .recv_family = AF_INET,
559+ .send_family = AF_INET,
560+ .protocol = SOCK_STREAM,
561+ .recv_socks = 10,
562+ .recv_port = 8009,
563+ .send_port_min = 9160});
564+ test_extra_filter((struct test_params) {
565+ .recv_family = AF_INET,
566+ .protocol = SOCK_STREAM,
567+ .recv_port = 8010});
568+ test_filter_no_reuseport((struct test_params) {
569+ .recv_family = AF_INET,
570+ .protocol = SOCK_STREAM,
571+ .recv_port = 8011});
572+
573+ fprintf(stderr, "---- IPv6 TCP ----\n");
574+ test_reuseport_ebpf((struct test_params) {
575+ .recv_family = AF_INET6,
576+ .send_family = AF_INET6,
577+ .protocol = SOCK_STREAM,
578+ .recv_socks = 10,
579+ .recv_port = 8012,
580+ .send_port_min = 9200});
581+ test_reuseport_cbpf((struct test_params) {
582+ .recv_family = AF_INET6,
583+ .send_family = AF_INET6,
584+ .protocol = SOCK_STREAM,
585+ .recv_socks = 10,
586+ .recv_port = 8013,
587+ .send_port_min = 9240});
588+ test_extra_filter((struct test_params) {
589+ .recv_family = AF_INET6,
590+ .protocol = SOCK_STREAM,
591+ .recv_port = 8014});
592+ test_filter_no_reuseport((struct test_params) {
593+ .recv_family = AF_INET6,
594+ .protocol = SOCK_STREAM,
595+ .recv_port = 8015});
596+
597+ fprintf(stderr, "---- IPv6 TCP w/ mapped IPv4 ----\n");
598+ test_reuseport_ebpf((struct test_params) {
599+ .recv_family = AF_INET6,
600+ .send_family = AF_INET,
601+ .protocol = SOCK_STREAM,
602+ .recv_socks = 10,
603+ .recv_port = 8016,
604+ .send_port_min = 9320});
605+ test_reuseport_cbpf((struct test_params) {
606+ .recv_family = AF_INET6,
607+ .send_family = AF_INET,
608+ .protocol = SOCK_STREAM,
609+ .recv_socks = 10,
610+ .recv_port = 8017,
611+ .send_port_min = 9360});
509612
510613 test_filter_without_bind();
511614
tools/testing/selftests/net/reuseport_bpf_cpu.c+258−0
@@ -0,0 +1,258 @@
1+/*
2+ * Test functionality of BPF filters with SO_REUSEPORT. This program creates
3+ * an SO_REUSEPORT receiver group containing one socket per CPU core. It then
4+ * creates a BPF program that will select a socket from this group based
5+ * on the core id that receives the packet. The sending code artificially
6+ * moves itself to run on different core ids and sends one message from
7+ * each core. Since these packets are delivered over loopback, they should
8+ * arrive on the same core that sent them. The receiving code then ensures
9+ * that the packet was received on the socket for the corresponding core id.
10+ * This entire process is done for several different core id permutations
11+ * and for each IPv4/IPv6 and TCP/UDP combination.
12+ */
13+
14+#define _GNU_SOURCE
15+
16+#include <arpa/inet.h>
17+#include <errno.h>
18+#include <error.h>
19+#include <linux/filter.h>
20+#include <linux/in.h>
21+#include <linux/unistd.h>
22+#include <sched.h>
23+#include <stdio.h>
24+#include <stdlib.h>
25+#include <string.h>
26+#include <sys/epoll.h>
27+#include <sys/types.h>
28+#include <sys/socket.h>
29+#include <unistd.h>
30+
31+static const int PORT = 8888;
32+
33+static void build_rcv_group(int *rcv_fd, size_t len, int family, int proto)
34+{
35+ struct sockaddr_storage addr;
36+ struct sockaddr_in *addr4;
37+ struct sockaddr_in6 *addr6;
38+ size_t i;
39+ int opt;
40+
41+ switch (family) {
42+ case AF_INET:
43+ addr4 = (struct sockaddr_in *)&addr;
44+ addr4->sin_family = AF_INET;
45+ addr4->sin_addr.s_addr = htonl(INADDR_ANY);
46+ addr4->sin_port = htons(PORT);
47+ break;
48+ case AF_INET6:
49+ addr6 = (struct sockaddr_in6 *)&addr;
50+ addr6->sin6_family = AF_INET6;
51+ addr6->sin6_addr = in6addr_any;
52+ addr6->sin6_port = htons(PORT);
53+ break;
54+ default:
55+ error(1, 0, "Unsupported family %d", family);
56+ }
57+
58+ for (i = 0; i < len; ++i) {
59+ rcv_fd[i] = socket(family, proto, 0);
60+ if (rcv_fd[i] < 0)
61+ error(1, errno, "failed to create receive socket");
62+
63+ opt = 1;
64+ if (setsockopt(rcv_fd[i], SOL_SOCKET, SO_REUSEPORT, &opt,
65+ sizeof(opt)))
66+ error(1, errno, "failed to set SO_REUSEPORT");
67+
68+ if (bind(rcv_fd[i], (struct sockaddr *)&addr, sizeof(addr)))
69+ error(1, errno, "failed to bind receive socket");
70+
71+ if (proto == SOCK_STREAM && listen(rcv_fd[i], len * 10))
72+ error(1, errno, "failed to listen on receive port");
73+ }
74+}
75+
76+static void attach_bpf(int fd)
77+{
78+ struct sock_filter code[] = {
79+ /* A = raw_smp_processor_id() */
80+ { BPF_LD | BPF_W | BPF_ABS, 0, 0, SKF_AD_OFF + SKF_AD_CPU },
81+ /* return A */
82+ { BPF_RET | BPF_A, 0, 0, 0 },
83+ };
84+ struct sock_fprog p = {
85+ .len = 2,
86+ .filter = code,
87+ };
88+
89+ if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &p, sizeof(p)))
90+ error(1, errno, "failed to set SO_ATTACH_REUSEPORT_CBPF");
91+}
92+
93+static void send_from_cpu(int cpu_id, int family, int proto)
94+{
95+ struct sockaddr_storage saddr, daddr;
96+ struct sockaddr_in *saddr4, *daddr4;
97+ struct sockaddr_in6 *saddr6, *daddr6;
98+ cpu_set_t cpu_set;
99+ int fd;
100+
101+ switch (family) {
102+ case AF_INET:
103+ saddr4 = (struct sockaddr_in *)&saddr;
104+ saddr4->sin_family = AF_INET;
105+ saddr4->sin_addr.s_addr = htonl(INADDR_ANY);
106+ saddr4->sin_port = 0;
107+
108+ daddr4 = (struct sockaddr_in *)&daddr;
109+ daddr4->sin_family = AF_INET;
110+ daddr4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
111+ daddr4->sin_port = htons(PORT);
112+ break;
113+ case AF_INET6:
114+ saddr6 = (struct sockaddr_in6 *)&saddr;
115+ saddr6->sin6_family = AF_INET6;
116+ saddr6->sin6_addr = in6addr_any;
117+ saddr6->sin6_port = 0;
118+
119+ daddr6 = (struct sockaddr_in6 *)&daddr;
120+ daddr6->sin6_family = AF_INET6;
121+ daddr6->sin6_addr = in6addr_loopback;
122+ daddr6->sin6_port = htons(PORT);
123+ break;
124+ default:
125+ error(1, 0, "Unsupported family %d", family);
126+ }
127+
128+ memset(&cpu_set, 0, sizeof(cpu_set));
129+ CPU_SET(cpu_id, &cpu_set);
130+ if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0)
131+ error(1, errno, "failed to pin to cpu");
132+
133+ fd = socket(family, proto, 0);
134+ if (fd < 0)
135+ error(1, errno, "failed to create send socket");
136+
137+ if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)))
138+ error(1, errno, "failed to bind send socket");
139+
140+ if (connect(fd, (struct sockaddr *)&daddr, sizeof(daddr)))
141+ error(1, errno, "failed to connect send socket");
142+
143+ if (send(fd, "a", 1, 0) < 0)
144+ error(1, errno, "failed to send message");
145+
146+ close(fd);
147+}
148+
149+static
150+void receive_on_cpu(int *rcv_fd, int len, int epfd, int cpu_id, int proto)
151+{
152+ struct epoll_event ev;
153+ int i, fd;
154+ char buf[8];
155+
156+ i = epoll_wait(epfd, &ev, 1, -1);
157+ if (i < 0)
158+ error(1, errno, "epoll_wait failed");
159+
160+ if (proto == SOCK_STREAM) {
161+ fd = accept(ev.data.fd, NULL, NULL);
162+ if (fd < 0)
163+ error(1, errno, "failed to accept");
164+ i = recv(fd, buf, sizeof(buf), 0);
165+ close(fd);
166+ } else {
167+ i = recv(ev.data.fd, buf, sizeof(buf), 0);
168+ }
169+
170+ if (i < 0)
171+ error(1, errno, "failed to recv");
172+
173+ for (i = 0; i < len; ++i)
174+ if (ev.data.fd == rcv_fd[i])
175+ break;
176+ if (i == len)
177+ error(1, 0, "failed to find socket");
178+ fprintf(stderr, "send cpu %d, receive socket %d\n", cpu_id, i);
179+ if (cpu_id != i)
180+ error(1, 0, "cpu id/receive socket mismatch");
181+}
182+
183+static void test(int *rcv_fd, int len, int family, int proto)
184+{
185+ struct epoll_event ev;
186+ int epfd, cpu;
187+
188+ build_rcv_group(rcv_fd, len, family, proto);
189+ attach_bpf(rcv_fd[0]);
190+
191+ epfd = epoll_create(1);
192+ if (epfd < 0)
193+ error(1, errno, "failed to create epoll");
194+ for (cpu = 0; cpu < len; ++cpu) {
195+ ev.events = EPOLLIN;
196+ ev.data.fd = rcv_fd[cpu];
197+ if (epoll_ctl(epfd, EPOLL_CTL_ADD, rcv_fd[cpu], &ev))
198+ error(1, errno, "failed to register sock epoll");
199+ }
200+
201+ /* Forward iterate */
202+ for (cpu = 0; cpu < len; ++cpu) {
203+ send_from_cpu(cpu, family, proto);
204+ receive_on_cpu(rcv_fd, len, epfd, cpu, proto);
205+ }
206+
207+ /* Reverse iterate */
208+ for (cpu = len - 1; cpu >= 0; --cpu) {
209+ send_from_cpu(cpu, family, proto);
210+ receive_on_cpu(rcv_fd, len, epfd, cpu, proto);
211+ }
212+
213+ /* Even cores */
214+ for (cpu = 0; cpu < len; cpu += 2) {
215+ send_from_cpu(cpu, family, proto);
216+ receive_on_cpu(rcv_fd, len, epfd, cpu, proto);
217+ }
218+
219+ /* Odd cores */
220+ for (cpu = 1; cpu < len; cpu += 2) {
221+ send_from_cpu(cpu, family, proto);
222+ receive_on_cpu(rcv_fd, len, epfd, cpu, proto);
223+ }
224+
225+ close(epfd);
226+ for (cpu = 0; cpu < len; ++cpu)
227+ close(rcv_fd[cpu]);
228+}
229+
230+int main(void)
231+{
232+ int *rcv_fd, cpus;
233+
234+ cpus = sysconf(_SC_NPROCESSORS_ONLN);
235+ if (cpus <= 0)
236+ error(1, errno, "failed counting cpus");
237+
238+ rcv_fd = calloc(cpus, sizeof(int));
239+ if (!rcv_fd)
240+ error(1, 0, "failed to allocate array");
241+
242+ fprintf(stderr, "---- IPv4 UDP ----\n");
243+ test(rcv_fd, cpus, AF_INET, SOCK_DGRAM);
244+
245+ fprintf(stderr, "---- IPv6 UDP ----\n");
246+ test(rcv_fd, cpus, AF_INET6, SOCK_DGRAM);
247+
248+ fprintf(stderr, "---- IPv4 TCP ----\n");
249+ test(rcv_fd, cpus, AF_INET, SOCK_STREAM);
250+
251+ fprintf(stderr, "---- IPv6 TCP ----\n");
252+ test(rcv_fd, cpus, AF_INET6, SOCK_STREAM);
253+
254+ free(rcv_fd);
255+
256+ fprintf(stderr, "SUCCESS\n");
257+ return 0;
258+}