Merge tag 'mailbox-v5.17' of git://git.linaro.org/landing-teams/working/fujitsu/integ...
[linux-2.6-microblaze.git] / tools / testing / selftests / net / reuseport_bpf.c
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 }