~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/net/reuseport_bpf.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Test functionality of BPF filters for SO_REUSEPORT.  The tests below will use
  3  * a BPF program (both classic and extended) to read the first word from an
  4  * incoming packet (expected to be in network byte-order), calculate a modulus
  5  * of that number, and then dispatch the packet to the Nth socket using the
  6  * result.  These tests are run for each supported address family and protocol.
  7  * Additionally, a few edge cases in the implementation are tested.
  8  */
  9 
 10 #include <errno.h>
 11 #include <error.h>
 12 #include <fcntl.h>
 13 #include <linux/bpf.h>
 14 #include <linux/filter.h>
 15 #include <linux/unistd.h>
 16 #include <netinet/in.h>
 17 #include <netinet/tcp.h>
 18 #include <stdio.h>
 19 #include <stdlib.h>
 20 #include <string.h>
 21 #include <sys/epoll.h>
 22 #include <sys/types.h>
 23 #include <sys/socket.h>
 24 #include <sys/resource.h>
 25 #include <unistd.h>
 26 
 27 #include "../kselftest.h"
 28 
 29 struct test_params {
 30         int recv_family;
 31         int send_family;
 32         int protocol;
 33         size_t recv_socks;
 34         uint16_t recv_port;
 35         uint16_t send_port_min;
 36 };
 37 
 38 static size_t sockaddr_size(void)
 39 {
 40         return sizeof(struct sockaddr_storage);
 41 }
 42 
 43 static struct sockaddr *new_any_sockaddr(int family, uint16_t port)
 44 {
 45         struct sockaddr_storage *addr;
 46         struct sockaddr_in *addr4;
 47         struct sockaddr_in6 *addr6;
 48 
 49         addr = malloc(sizeof(struct sockaddr_storage));
 50         memset(addr, 0, sizeof(struct sockaddr_storage));
 51 
 52         switch (family) {
 53         case AF_INET:
 54                 addr4 = (struct sockaddr_in *)addr;
 55                 addr4->sin_family = AF_INET;
 56                 addr4->sin_addr.s_addr = htonl(INADDR_ANY);
 57                 addr4->sin_port = htons(port);
 58                 break;
 59         case AF_INET6:
 60                 addr6 = (struct sockaddr_in6 *)addr;
 61                 addr6->sin6_family = AF_INET6;
 62                 addr6->sin6_addr = in6addr_any;
 63                 addr6->sin6_port = htons(port);
 64                 break;
 65         default:
 66                 error(1, 0, "Unsupported family %d", family);
 67         }
 68         return (struct sockaddr *)addr;
 69 }
 70 
 71 static struct sockaddr *new_loopback_sockaddr(int family, uint16_t port)
 72 {
 73         struct sockaddr *addr = new_any_sockaddr(family, port);
 74         struct sockaddr_in *addr4;
 75         struct sockaddr_in6 *addr6;
 76 
 77         switch (family) {
 78         case AF_INET:
 79                 addr4 = (struct sockaddr_in *)addr;
 80                 addr4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
 81                 break;
 82         case AF_INET6:
 83                 addr6 = (struct sockaddr_in6 *)addr;
 84                 addr6->sin6_addr = in6addr_loopback;
 85                 break;
 86         default:
 87                 error(1, 0, "Unsupported family %d", family);
 88         }
 89         return addr;
 90 }
 91 
 92 static void attach_ebpf(int fd, uint16_t mod)
 93 {
 94         static char bpf_log_buf[65536];
 95         static const char bpf_license[] = "GPL";
 96 
 97         int bpf_fd;
 98         const struct bpf_insn prog[] = {
 99                 /* BPF_MOV64_REG(BPF_REG_6, BPF_REG_1) */
100                 { BPF_ALU64 | BPF_MOV | BPF_X, BPF_REG_6, BPF_REG_1, 0, 0 },
101                 /* BPF_LD_ABS(BPF_W, 0) R0 = (uint32_t)skb[0] */
102                 { BPF_LD | BPF_ABS | BPF_W, 0, 0, 0, 0 },
103                 /* BPF_ALU64_IMM(BPF_MOD, BPF_REG_0, mod) */
104                 { BPF_ALU64 | BPF_MOD | BPF_K, BPF_REG_0, 0, 0, mod },
105                 /* BPF_EXIT_INSN() */
106                 { BPF_JMP | BPF_EXIT, 0, 0, 0, 0 }
107         };
108         union bpf_attr attr;
109 
110         memset(&attr, 0, sizeof(attr));
111         attr.prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
112         attr.insn_cnt = ARRAY_SIZE(prog);
113         attr.insns = (unsigned long) &prog;
114         attr.license = (unsigned long) &bpf_license;
115         attr.log_buf = (unsigned long) &bpf_log_buf;
116         attr.log_size = sizeof(bpf_log_buf);
117         attr.log_level = 1;
118         attr.kern_version = 0;
119 
120         bpf_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
121         if (bpf_fd < 0)
122                 error(1, errno, "ebpf error. log:\n%s\n", bpf_log_buf);
123 
124         if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_EBPF, &bpf_fd,
125                         sizeof(bpf_fd)))
126                 error(1, errno, "failed to set SO_ATTACH_REUSEPORT_EBPF");
127 
128         close(bpf_fd);
129 }
130 
131 static void attach_cbpf(int fd, uint16_t mod)
132 {
133         struct sock_filter code[] = {
134                 /* A = (uint32_t)skb[0] */
135                 { BPF_LD  | BPF_W | BPF_ABS, 0, 0, 0 },
136                 /* A = A % mod */
137                 { BPF_ALU | BPF_MOD, 0, 0, mod },
138                 /* return A */
139                 { BPF_RET | BPF_A, 0, 0, 0 },
140         };
141         struct sock_fprog p = {
142                 .len = ARRAY_SIZE(code),
143                 .filter = code,
144         };
145 
146         if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &p, sizeof(p)))
147                 error(1, errno, "failed to set SO_ATTACH_REUSEPORT_CBPF");
148 }
149 
150 static void build_recv_group(const struct test_params p, int fd[], uint16_t mod,
151                              void (*attach_bpf)(int, uint16_t))
152 {
153         struct sockaddr * const addr =
154                 new_any_sockaddr(p.recv_family, p.recv_port);
155         int i, opt;
156 
157         for (i = 0; i < p.recv_socks; ++i) {
158                 fd[i] = socket(p.recv_family, p.protocol, 0);
159                 if (fd[i] < 0)
160                         error(1, errno, "failed to create recv %d", i);
161 
162                 opt = 1;
163                 if (setsockopt(fd[i], SOL_SOCKET, SO_REUSEPORT, &opt,
164                                sizeof(opt)))
165                         error(1, errno, "failed to set SO_REUSEPORT on %d", i);
166 
167                 if (i == 0)
168                         attach_bpf(fd[i], mod);
169 
170                 if (bind(fd[i], addr, sockaddr_size()))
171                         error(1, errno, "failed to bind recv socket %d", i);
172 
173                 if (p.protocol == SOCK_STREAM) {
174                         opt = 4;
175                         if (setsockopt(fd[i], SOL_TCP, TCP_FASTOPEN, &opt,
176                                        sizeof(opt)))
177                                 error(1, errno,
178                                       "failed to set TCP_FASTOPEN on %d", i);
179                         if (listen(fd[i], p.recv_socks * 10))
180                                 error(1, errno, "failed to listen on socket");
181                 }
182         }
183         free(addr);
184 }
185 
186 static void send_from(struct test_params p, uint16_t sport, char *buf,
187                       size_t len)
188 {
189         struct sockaddr * const saddr = new_any_sockaddr(p.send_family, sport);
190         struct sockaddr * const daddr =
191                 new_loopback_sockaddr(p.send_family, p.recv_port);
192         const int fd = socket(p.send_family, p.protocol, 0), one = 1;
193 
194         if (fd < 0)
195                 error(1, errno, "failed to create send socket");
196 
197         if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
198                 error(1, errno, "failed to set reuseaddr");
199 
200         if (bind(fd, saddr, sockaddr_size()))
201                 error(1, errno, "failed to bind send socket");
202 
203         if (sendto(fd, buf, len, MSG_FASTOPEN, daddr, sockaddr_size()) < 0)
204                 error(1, errno, "failed to send message");
205 
206         close(fd);
207         free(saddr);
208         free(daddr);
209 }
210 
211 static void test_recv_order(const struct test_params p, int fd[], int mod)
212 {
213         char recv_buf[8], send_buf[8];
214         struct msghdr msg;
215         struct iovec recv_io = { recv_buf, 8 };
216         struct epoll_event ev;
217         int epfd, conn, i, sport, expected;
218         uint32_t data, ndata;
219 
220         epfd = epoll_create(1);
221         if (epfd < 0)
222                 error(1, errno, "failed to create epoll");
223         for (i = 0; i < p.recv_socks; ++i) {
224                 ev.events = EPOLLIN;
225                 ev.data.fd = fd[i];
226                 if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd[i], &ev))
227                         error(1, errno, "failed to register sock %d epoll", i);
228         }
229 
230         memset(&msg, 0, sizeof(msg));
231         msg.msg_iov = &recv_io;
232         msg.msg_iovlen = 1;
233 
234         for (data = 0; data < p.recv_socks * 2; ++data) {
235                 sport = p.send_port_min + data;
236                 ndata = htonl(data);
237                 memcpy(send_buf, &ndata, sizeof(ndata));
238                 send_from(p, sport, send_buf, sizeof(ndata));
239 
240                 i = epoll_wait(epfd, &ev, 1, -1);
241                 if (i < 0)
242                         error(1, errno, "epoll wait failed");
243 
244                 if (p.protocol == SOCK_STREAM) {
245                         conn = accept(ev.data.fd, NULL, NULL);
246                         if (conn < 0)
247                                 error(1, errno, "error accepting");
248                         i = recvmsg(conn, &msg, 0);
249                         close(conn);
250                 } else {
251                         i = recvmsg(ev.data.fd, &msg, 0);
252                 }
253                 if (i < 0)
254                         error(1, errno, "recvmsg error");
255                 if (i != sizeof(ndata))
256                         error(1, 0, "expected size %zd got %d",
257                               sizeof(ndata), i);
258 
259                 for (i = 0; i < p.recv_socks; ++i)
260                         if (ev.data.fd == fd[i])
261                                 break;
262                 memcpy(&ndata, recv_buf, sizeof(ndata));
263                 fprintf(stderr, "Socket %d: %d\n", i, ntohl(ndata));
264 
265                 expected = (sport % mod);
266                 if (i != expected)
267                         error(1, 0, "expected socket %d", expected);
268         }
269 }
270 
271 static void test_reuseport_ebpf(struct test_params p)
272 {
273         int i, fd[p.recv_socks];
274 
275         fprintf(stderr, "Testing EBPF mod %zd...\n", p.recv_socks);
276         build_recv_group(p, fd, p.recv_socks, attach_ebpf);
277         test_recv_order(p, fd, p.recv_socks);
278 
279         p.send_port_min += p.recv_socks * 2;
280         fprintf(stderr, "Reprograming, testing mod %zd...\n", p.recv_socks / 2);
281         attach_ebpf(fd[0], p.recv_socks / 2);
282         test_recv_order(p, fd, p.recv_socks / 2);
283 
284         for (i = 0; i < p.recv_socks; ++i)
285                 close(fd[i]);
286 }
287 
288 static void test_reuseport_cbpf(struct test_params p)
289 {
290         int i, fd[p.recv_socks];
291 
292         fprintf(stderr, "Testing CBPF mod %zd...\n", p.recv_socks);
293         build_recv_group(p, fd, p.recv_socks, attach_cbpf);
294         test_recv_order(p, fd, p.recv_socks);
295 
296         p.send_port_min += p.recv_socks * 2;
297         fprintf(stderr, "Reprograming, testing mod %zd...\n", p.recv_socks / 2);
298         attach_cbpf(fd[0], p.recv_socks / 2);
299         test_recv_order(p, fd, p.recv_socks / 2);
300 
301         for (i = 0; i < p.recv_socks; ++i)
302                 close(fd[i]);
303 }
304 
305 static void test_extra_filter(const struct test_params p)
306 {
307         struct sockaddr * const addr =
308                 new_any_sockaddr(p.recv_family, p.recv_port);
309         int fd1, fd2, opt;
310 
311         fprintf(stderr, "Testing too many filters...\n");
312         fd1 = socket(p.recv_family, p.protocol, 0);
313         if (fd1 < 0)
314                 error(1, errno, "failed to create socket 1");
315         fd2 = socket(p.recv_family, p.protocol, 0);
316         if (fd2 < 0)
317                 error(1, errno, "failed to create socket 2");
318 
319         opt = 1;
320         if (setsockopt(fd1, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)))
321                 error(1, errno, "failed to set SO_REUSEPORT on socket 1");
322         if (setsockopt(fd2, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)))
323                 error(1, errno, "failed to set SO_REUSEPORT on socket 2");
324 
325         attach_ebpf(fd1, 10);
326         attach_ebpf(fd2, 10);
327 
328         if (bind(fd1, addr, sockaddr_size()))
329                 error(1, errno, "failed to bind recv socket 1");
330 
331         if (!bind(fd2, addr, sockaddr_size()) || errno != EADDRINUSE)
332                 error(1, errno, "bind socket 2 should fail with EADDRINUSE");
333 
334         free(addr);
335 }
336 
337 static void test_filter_no_reuseport(const struct test_params p)
338 {
339         struct sockaddr * const addr =
340                 new_any_sockaddr(p.recv_family, p.recv_port);
341         const char bpf_license[] = "GPL";
342         struct bpf_insn ecode[] = {
343                 { BPF_ALU64 | BPF_MOV | BPF_K, BPF_REG_0, 0, 0, 10 },
344                 { BPF_JMP | BPF_EXIT, 0, 0, 0, 0 }
345         };
346         struct sock_filter ccode[] = {{ BPF_RET | BPF_A, 0, 0, 0 }};
347         union bpf_attr eprog;
348         struct sock_fprog cprog;
349         int fd, bpf_fd;
350 
351         fprintf(stderr, "Testing filters on non-SO_REUSEPORT socket...\n");
352 
353         memset(&eprog, 0, sizeof(eprog));
354         eprog.prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
355         eprog.insn_cnt = ARRAY_SIZE(ecode);
356         eprog.insns = (unsigned long) &ecode;
357         eprog.license = (unsigned long) &bpf_license;
358         eprog.kern_version = 0;
359 
360         memset(&cprog, 0, sizeof(cprog));
361         cprog.len = ARRAY_SIZE(ccode);
362         cprog.filter = ccode;
363 
364 
365         bpf_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &eprog, sizeof(eprog));
366         if (bpf_fd < 0)
367                 error(1, errno, "ebpf error");
368         fd = socket(p.recv_family, p.protocol, 0);
369         if (fd < 0)
370                 error(1, errno, "failed to create socket 1");
371 
372         if (bind(fd, addr, sockaddr_size()))
373                 error(1, errno, "failed to bind recv socket 1");
374 
375         errno = 0;
376         if (!setsockopt(fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_EBPF, &bpf_fd,
377                         sizeof(bpf_fd)) || errno != EINVAL)
378                 error(1, errno, "setsockopt should have returned EINVAL");
379 
380         errno = 0;
381         if (!setsockopt(fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &cprog,
382                        sizeof(cprog)) || errno != EINVAL)
383                 error(1, errno, "setsockopt should have returned EINVAL");
384 
385         free(addr);
386 }
387 
388 static void test_filter_without_bind(void)
389 {
390         int fd1, fd2, opt = 1;
391 
392         fprintf(stderr, "Testing filter add without bind...\n");
393         fd1 = socket(AF_INET, SOCK_DGRAM, 0);
394         if (fd1 < 0)
395                 error(1, errno, "failed to create socket 1");
396         fd2 = socket(AF_INET, SOCK_DGRAM, 0);
397         if (fd2 < 0)
398                 error(1, errno, "failed to create socket 2");
399         if (setsockopt(fd1, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)))
400                 error(1, errno, "failed to set SO_REUSEPORT on socket 1");
401         if (setsockopt(fd2, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)))
402                 error(1, errno, "failed to set SO_REUSEPORT on socket 2");
403 
404         attach_ebpf(fd1, 10);
405         attach_cbpf(fd2, 10);
406 
407         close(fd1);
408         close(fd2);
409 }
410 
411 void enable_fastopen(void)
412 {
413         int fd = open("/proc/sys/net/ipv4/tcp_fastopen", 0);
414         int rw_mask = 3;  /* bit 1: client side; bit-2 server side */
415         int val, size;
416         char buf[16];
417 
418         if (fd < 0)
419                 error(1, errno, "Unable to open tcp_fastopen sysctl");
420         if (read(fd, buf, sizeof(buf)) <= 0)
421                 error(1, errno, "Unable to read tcp_fastopen sysctl");
422         val = atoi(buf);
423         close(fd);
424 
425         if ((val & rw_mask) != rw_mask) {
426                 fd = open("/proc/sys/net/ipv4/tcp_fastopen", O_RDWR);
427                 if (fd < 0)
428                         error(1, errno,
429                               "Unable to open tcp_fastopen sysctl for writing");
430                 val |= rw_mask;
431                 size = snprintf(buf, 16, "%d", val);
432                 if (write(fd, buf, size) <= 0)
433                         error(1, errno, "Unable to write tcp_fastopen sysctl");
434                 close(fd);
435         }
436 }
437 
438 static struct rlimit rlim_old;
439 
440 static  __attribute__((constructor)) void main_ctor(void)
441 {
442         getrlimit(RLIMIT_MEMLOCK, &rlim_old);
443 
444         if (rlim_old.rlim_cur != RLIM_INFINITY) {
445                 struct rlimit rlim_new;
446 
447                 rlim_new.rlim_cur = rlim_old.rlim_cur + (1UL << 20);
448                 rlim_new.rlim_max = rlim_old.rlim_max + (1UL << 20);
449                 setrlimit(RLIMIT_MEMLOCK, &rlim_new);
450         }
451 }
452 
453 static __attribute__((destructor)) void main_dtor(void)
454 {
455         setrlimit(RLIMIT_MEMLOCK, &rlim_old);
456 }
457 
458 int main(void)
459 {
460         fprintf(stderr, "---- IPv4 UDP ----\n");
461         /* NOTE: UDP socket lookups traverse a different code path when there
462          * are > 10 sockets in a group.  Run the bpf test through both paths.
463          */
464         test_reuseport_ebpf((struct test_params) {
465                 .recv_family = AF_INET,
466                 .send_family = AF_INET,
467                 .protocol = SOCK_DGRAM,
468                 .recv_socks = 10,
469                 .recv_port = 8000,
470                 .send_port_min = 9000});
471         test_reuseport_ebpf((struct test_params) {
472                 .recv_family = AF_INET,
473                 .send_family = AF_INET,
474                 .protocol = SOCK_DGRAM,
475                 .recv_socks = 20,
476                 .recv_port = 8000,
477                 .send_port_min = 9000});
478         test_reuseport_cbpf((struct test_params) {
479                 .recv_family = AF_INET,
480                 .send_family = AF_INET,
481                 .protocol = SOCK_DGRAM,
482                 .recv_socks = 10,
483                 .recv_port = 8001,
484                 .send_port_min = 9020});
485         test_reuseport_cbpf((struct test_params) {
486                 .recv_family = AF_INET,
487                 .send_family = AF_INET,
488                 .protocol = SOCK_DGRAM,
489                 .recv_socks = 20,
490                 .recv_port = 8001,
491                 .send_port_min = 9020});
492         test_extra_filter((struct test_params) {
493                 .recv_family = AF_INET,
494                 .protocol = SOCK_DGRAM,
495                 .recv_port = 8002});
496         test_filter_no_reuseport((struct test_params) {
497                 .recv_family = AF_INET,
498                 .protocol = SOCK_DGRAM,
499                 .recv_port = 8008});
500 
501         fprintf(stderr, "---- IPv6 UDP ----\n");
502         test_reuseport_ebpf((struct test_params) {
503                 .recv_family = AF_INET6,
504                 .send_family = AF_INET6,
505                 .protocol = SOCK_DGRAM,
506                 .recv_socks = 10,
507                 .recv_port = 8003,
508                 .send_port_min = 9040});
509         test_reuseport_ebpf((struct test_params) {
510                 .recv_family = AF_INET6,
511                 .send_family = AF_INET6,
512                 .protocol = SOCK_DGRAM,
513                 .recv_socks = 20,
514                 .recv_port = 8003,
515                 .send_port_min = 9040});
516         test_reuseport_cbpf((struct test_params) {
517                 .recv_family = AF_INET6,
518                 .send_family = AF_INET6,
519                 .protocol = SOCK_DGRAM,
520                 .recv_socks = 10,
521                 .recv_port = 8004,
522                 .send_port_min = 9060});
523         test_reuseport_cbpf((struct test_params) {
524                 .recv_family = AF_INET6,
525                 .send_family = AF_INET6,
526                 .protocol = SOCK_DGRAM,
527                 .recv_socks = 20,
528                 .recv_port = 8004,
529                 .send_port_min = 9060});
530         test_extra_filter((struct test_params) {
531                 .recv_family = AF_INET6,
532                 .protocol = SOCK_DGRAM,
533                 .recv_port = 8005});
534         test_filter_no_reuseport((struct test_params) {
535                 .recv_family = AF_INET6,
536                 .protocol = SOCK_DGRAM,
537                 .recv_port = 8009});
538 
539         fprintf(stderr, "---- IPv6 UDP w/ mapped IPv4 ----\n");
540         test_reuseport_ebpf((struct test_params) {
541                 .recv_family = AF_INET6,
542                 .send_family = AF_INET,
543                 .protocol = SOCK_DGRAM,
544                 .recv_socks = 20,
545                 .recv_port = 8006,
546                 .send_port_min = 9080});
547         test_reuseport_ebpf((struct test_params) {
548                 .recv_family = AF_INET6,
549                 .send_family = AF_INET,
550                 .protocol = SOCK_DGRAM,
551                 .recv_socks = 10,
552                 .recv_port = 8006,
553                 .send_port_min = 9080});
554         test_reuseport_cbpf((struct test_params) {
555                 .recv_family = AF_INET6,
556                 .send_family = AF_INET,
557                 .protocol = SOCK_DGRAM,
558                 .recv_socks = 10,
559                 .recv_port = 8007,
560                 .send_port_min = 9100});
561         test_reuseport_cbpf((struct test_params) {
562                 .recv_family = AF_INET6,
563                 .send_family = AF_INET,
564                 .protocol = SOCK_DGRAM,
565                 .recv_socks = 20,
566                 .recv_port = 8007,
567                 .send_port_min = 9100});
568 
569         /* TCP fastopen is required for the TCP tests */
570         enable_fastopen();
571         fprintf(stderr, "---- IPv4 TCP ----\n");
572         test_reuseport_ebpf((struct test_params) {
573                 .recv_family = AF_INET,
574                 .send_family = AF_INET,
575                 .protocol = SOCK_STREAM,
576                 .recv_socks = 10,
577                 .recv_port = 8008,
578                 .send_port_min = 9120});
579         test_reuseport_cbpf((struct test_params) {
580                 .recv_family = AF_INET,
581                 .send_family = AF_INET,
582                 .protocol = SOCK_STREAM,
583                 .recv_socks = 10,
584                 .recv_port = 8009,
585                 .send_port_min = 9160});
586         test_extra_filter((struct test_params) {
587                 .recv_family = AF_INET,
588                 .protocol = SOCK_STREAM,
589                 .recv_port = 8010});
590         test_filter_no_reuseport((struct test_params) {
591                 .recv_family = AF_INET,
592                 .protocol = SOCK_STREAM,
593                 .recv_port = 8011});
594 
595         fprintf(stderr, "---- IPv6 TCP ----\n");
596         test_reuseport_ebpf((struct test_params) {
597                 .recv_family = AF_INET6,
598                 .send_family = AF_INET6,
599                 .protocol = SOCK_STREAM,
600                 .recv_socks = 10,
601                 .recv_port = 8012,
602                 .send_port_min = 9200});
603         test_reuseport_cbpf((struct test_params) {
604                 .recv_family = AF_INET6,
605                 .send_family = AF_INET6,
606                 .protocol = SOCK_STREAM,
607                 .recv_socks = 10,
608                 .recv_port = 8013,
609                 .send_port_min = 9240});
610         test_extra_filter((struct test_params) {
611                 .recv_family = AF_INET6,
612                 .protocol = SOCK_STREAM,
613                 .recv_port = 8014});
614         test_filter_no_reuseport((struct test_params) {
615                 .recv_family = AF_INET6,
616                 .protocol = SOCK_STREAM,
617                 .recv_port = 8015});
618 
619         fprintf(stderr, "---- IPv6 TCP w/ mapped IPv4 ----\n");
620         test_reuseport_ebpf((struct test_params) {
621                 .recv_family = AF_INET6,
622                 .send_family = AF_INET,
623                 .protocol = SOCK_STREAM,
624                 .recv_socks = 10,
625                 .recv_port = 8016,
626                 .send_port_min = 9320});
627         test_reuseport_cbpf((struct test_params) {
628                 .recv_family = AF_INET6,
629                 .send_family = AF_INET,
630                 .protocol = SOCK_STREAM,
631                 .recv_socks = 10,
632                 .recv_port = 8017,
633                 .send_port_min = 9360});
634 
635         test_filter_without_bind();
636 
637         fprintf(stderr, "SUCCESS\n");
638         return 0;
639 }
640 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php