0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <errno.h>
0011 #include <error.h>
0012 #include <fcntl.h>
0013 #include <linux/bpf.h>
0014 #include <linux/filter.h>
0015 #include <linux/unistd.h>
0016 #include <netinet/in.h>
0017 #include <netinet/tcp.h>
0018 #include <stdio.h>
0019 #include <stdlib.h>
0020 #include <string.h>
0021 #include <sys/epoll.h>
0022 #include <sys/types.h>
0023 #include <sys/socket.h>
0024 #include <sys/resource.h>
0025 #include <unistd.h>
0026
0027 #include "../kselftest.h"
0028
0029 struct test_params {
0030 int recv_family;
0031 int send_family;
0032 int protocol;
0033 size_t recv_socks;
0034 uint16_t recv_port;
0035 uint16_t send_port_min;
0036 };
0037
0038 static size_t sockaddr_size(void)
0039 {
0040 return sizeof(struct sockaddr_storage);
0041 }
0042
0043 static struct sockaddr *new_any_sockaddr(int family, uint16_t port)
0044 {
0045 struct sockaddr_storage *addr;
0046 struct sockaddr_in *addr4;
0047 struct sockaddr_in6 *addr6;
0048
0049 addr = malloc(sizeof(struct sockaddr_storage));
0050 memset(addr, 0, sizeof(struct sockaddr_storage));
0051
0052 switch (family) {
0053 case AF_INET:
0054 addr4 = (struct sockaddr_in *)addr;
0055 addr4->sin_family = AF_INET;
0056 addr4->sin_addr.s_addr = htonl(INADDR_ANY);
0057 addr4->sin_port = htons(port);
0058 break;
0059 case AF_INET6:
0060 addr6 = (struct sockaddr_in6 *)addr;
0061 addr6->sin6_family = AF_INET6;
0062 addr6->sin6_addr = in6addr_any;
0063 addr6->sin6_port = htons(port);
0064 break;
0065 default:
0066 error(1, 0, "Unsupported family %d", family);
0067 }
0068 return (struct sockaddr *)addr;
0069 }
0070
0071 static struct sockaddr *new_loopback_sockaddr(int family, uint16_t port)
0072 {
0073 struct sockaddr *addr = new_any_sockaddr(family, port);
0074 struct sockaddr_in *addr4;
0075 struct sockaddr_in6 *addr6;
0076
0077 switch (family) {
0078 case AF_INET:
0079 addr4 = (struct sockaddr_in *)addr;
0080 addr4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
0081 break;
0082 case AF_INET6:
0083 addr6 = (struct sockaddr_in6 *)addr;
0084 addr6->sin6_addr = in6addr_loopback;
0085 break;
0086 default:
0087 error(1, 0, "Unsupported family %d", family);
0088 }
0089 return addr;
0090 }
0091
0092 static void attach_ebpf(int fd, uint16_t mod)
0093 {
0094 static char bpf_log_buf[65536];
0095 static const char bpf_license[] = "GPL";
0096
0097 int bpf_fd;
0098 const struct bpf_insn prog[] = {
0099
0100 { BPF_ALU64 | BPF_MOV | BPF_X, BPF_REG_6, BPF_REG_1, 0, 0 },
0101
0102 { BPF_LD | BPF_ABS | BPF_W, 0, 0, 0, 0 },
0103
0104 { BPF_ALU64 | BPF_MOD | BPF_K, BPF_REG_0, 0, 0, mod },
0105
0106 { BPF_JMP | BPF_EXIT, 0, 0, 0, 0 }
0107 };
0108 union bpf_attr attr;
0109
0110 memset(&attr, 0, sizeof(attr));
0111 attr.prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
0112 attr.insn_cnt = ARRAY_SIZE(prog);
0113 attr.insns = (unsigned long) &prog;
0114 attr.license = (unsigned long) &bpf_license;
0115 attr.log_buf = (unsigned long) &bpf_log_buf;
0116 attr.log_size = sizeof(bpf_log_buf);
0117 attr.log_level = 1;
0118 attr.kern_version = 0;
0119
0120 bpf_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
0121 if (bpf_fd < 0)
0122 error(1, errno, "ebpf error. log:\n%s\n", bpf_log_buf);
0123
0124 if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_EBPF, &bpf_fd,
0125 sizeof(bpf_fd)))
0126 error(1, errno, "failed to set SO_ATTACH_REUSEPORT_EBPF");
0127
0128 close(bpf_fd);
0129 }
0130
0131 static void attach_cbpf(int fd, uint16_t mod)
0132 {
0133 struct sock_filter code[] = {
0134
0135 { BPF_LD | BPF_W | BPF_ABS, 0, 0, 0 },
0136
0137 { BPF_ALU | BPF_MOD, 0, 0, mod },
0138
0139 { BPF_RET | BPF_A, 0, 0, 0 },
0140 };
0141 struct sock_fprog p = {
0142 .len = ARRAY_SIZE(code),
0143 .filter = code,
0144 };
0145
0146 if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &p, sizeof(p)))
0147 error(1, errno, "failed to set SO_ATTACH_REUSEPORT_CBPF");
0148 }
0149
0150 static void build_recv_group(const struct test_params p, int fd[], uint16_t mod,
0151 void (*attach_bpf)(int, uint16_t))
0152 {
0153 struct sockaddr * const addr =
0154 new_any_sockaddr(p.recv_family, p.recv_port);
0155 int i, opt;
0156
0157 for (i = 0; i < p.recv_socks; ++i) {
0158 fd[i] = socket(p.recv_family, p.protocol, 0);
0159 if (fd[i] < 0)
0160 error(1, errno, "failed to create recv %d", i);
0161
0162 opt = 1;
0163 if (setsockopt(fd[i], SOL_SOCKET, SO_REUSEPORT, &opt,
0164 sizeof(opt)))
0165 error(1, errno, "failed to set SO_REUSEPORT on %d", i);
0166
0167 if (i == 0)
0168 attach_bpf(fd[i], mod);
0169
0170 if (bind(fd[i], addr, sockaddr_size()))
0171 error(1, errno, "failed to bind recv socket %d", i);
0172
0173 if (p.protocol == SOCK_STREAM) {
0174 opt = 4;
0175 if (setsockopt(fd[i], SOL_TCP, TCP_FASTOPEN, &opt,
0176 sizeof(opt)))
0177 error(1, errno,
0178 "failed to set TCP_FASTOPEN on %d", i);
0179 if (listen(fd[i], p.recv_socks * 10))
0180 error(1, errno, "failed to listen on socket");
0181 }
0182 }
0183 free(addr);
0184 }
0185
0186 static void send_from(struct test_params p, uint16_t sport, char *buf,
0187 size_t len)
0188 {
0189 struct sockaddr * const saddr = new_any_sockaddr(p.send_family, sport);
0190 struct sockaddr * const daddr =
0191 new_loopback_sockaddr(p.send_family, p.recv_port);
0192 const int fd = socket(p.send_family, p.protocol, 0), one = 1;
0193
0194 if (fd < 0)
0195 error(1, errno, "failed to create send socket");
0196
0197 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
0198 error(1, errno, "failed to set reuseaddr");
0199
0200 if (bind(fd, saddr, sockaddr_size()))
0201 error(1, errno, "failed to bind send socket");
0202
0203 if (sendto(fd, buf, len, MSG_FASTOPEN, daddr, sockaddr_size()) < 0)
0204 error(1, errno, "failed to send message");
0205
0206 close(fd);
0207 free(saddr);
0208 free(daddr);
0209 }
0210
0211 static void test_recv_order(const struct test_params p, int fd[], int mod)
0212 {
0213 char recv_buf[8], send_buf[8];
0214 struct msghdr msg;
0215 struct iovec recv_io = { recv_buf, 8 };
0216 struct epoll_event ev;
0217 int epfd, conn, i, sport, expected;
0218 uint32_t data, ndata;
0219
0220 epfd = epoll_create(1);
0221 if (epfd < 0)
0222 error(1, errno, "failed to create epoll");
0223 for (i = 0; i < p.recv_socks; ++i) {
0224 ev.events = EPOLLIN;
0225 ev.data.fd = fd[i];
0226 if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd[i], &ev))
0227 error(1, errno, "failed to register sock %d epoll", i);
0228 }
0229
0230 memset(&msg, 0, sizeof(msg));
0231 msg.msg_iov = &recv_io;
0232 msg.msg_iovlen = 1;
0233
0234 for (data = 0; data < p.recv_socks * 2; ++data) {
0235 sport = p.send_port_min + data;
0236 ndata = htonl(data);
0237 memcpy(send_buf, &ndata, sizeof(ndata));
0238 send_from(p, sport, send_buf, sizeof(ndata));
0239
0240 i = epoll_wait(epfd, &ev, 1, -1);
0241 if (i < 0)
0242 error(1, errno, "epoll wait failed");
0243
0244 if (p.protocol == SOCK_STREAM) {
0245 conn = accept(ev.data.fd, NULL, NULL);
0246 if (conn < 0)
0247 error(1, errno, "error accepting");
0248 i = recvmsg(conn, &msg, 0);
0249 close(conn);
0250 } else {
0251 i = recvmsg(ev.data.fd, &msg, 0);
0252 }
0253 if (i < 0)
0254 error(1, errno, "recvmsg error");
0255 if (i != sizeof(ndata))
0256 error(1, 0, "expected size %zd got %d",
0257 sizeof(ndata), i);
0258
0259 for (i = 0; i < p.recv_socks; ++i)
0260 if (ev.data.fd == fd[i])
0261 break;
0262 memcpy(&ndata, recv_buf, sizeof(ndata));
0263 fprintf(stderr, "Socket %d: %d\n", i, ntohl(ndata));
0264
0265 expected = (sport % mod);
0266 if (i != expected)
0267 error(1, 0, "expected socket %d", expected);
0268 }
0269 }
0270
0271 static void test_reuseport_ebpf(struct test_params p)
0272 {
0273 int i, fd[p.recv_socks];
0274
0275 fprintf(stderr, "Testing EBPF mod %zd...\n", p.recv_socks);
0276 build_recv_group(p, fd, p.recv_socks, attach_ebpf);
0277 test_recv_order(p, fd, p.recv_socks);
0278
0279 p.send_port_min += p.recv_socks * 2;
0280 fprintf(stderr, "Reprograming, testing mod %zd...\n", p.recv_socks / 2);
0281 attach_ebpf(fd[0], p.recv_socks / 2);
0282 test_recv_order(p, fd, p.recv_socks / 2);
0283
0284 for (i = 0; i < p.recv_socks; ++i)
0285 close(fd[i]);
0286 }
0287
0288 static void test_reuseport_cbpf(struct test_params p)
0289 {
0290 int i, fd[p.recv_socks];
0291
0292 fprintf(stderr, "Testing CBPF mod %zd...\n", p.recv_socks);
0293 build_recv_group(p, fd, p.recv_socks, attach_cbpf);
0294 test_recv_order(p, fd, p.recv_socks);
0295
0296 p.send_port_min += p.recv_socks * 2;
0297 fprintf(stderr, "Reprograming, testing mod %zd...\n", p.recv_socks / 2);
0298 attach_cbpf(fd[0], p.recv_socks / 2);
0299 test_recv_order(p, fd, p.recv_socks / 2);
0300
0301 for (i = 0; i < p.recv_socks; ++i)
0302 close(fd[i]);
0303 }
0304
0305 static void test_extra_filter(const struct test_params p)
0306 {
0307 struct sockaddr * const addr =
0308 new_any_sockaddr(p.recv_family, p.recv_port);
0309 int fd1, fd2, opt;
0310
0311 fprintf(stderr, "Testing too many filters...\n");
0312 fd1 = socket(p.recv_family, p.protocol, 0);
0313 if (fd1 < 0)
0314 error(1, errno, "failed to create socket 1");
0315 fd2 = socket(p.recv_family, p.protocol, 0);
0316 if (fd2 < 0)
0317 error(1, errno, "failed to create socket 2");
0318
0319 opt = 1;
0320 if (setsockopt(fd1, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)))
0321 error(1, errno, "failed to set SO_REUSEPORT on socket 1");
0322 if (setsockopt(fd2, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)))
0323 error(1, errno, "failed to set SO_REUSEPORT on socket 2");
0324
0325 attach_ebpf(fd1, 10);
0326 attach_ebpf(fd2, 10);
0327
0328 if (bind(fd1, addr, sockaddr_size()))
0329 error(1, errno, "failed to bind recv socket 1");
0330
0331 if (!bind(fd2, addr, sockaddr_size()) || errno != EADDRINUSE)
0332 error(1, errno, "bind socket 2 should fail with EADDRINUSE");
0333
0334 free(addr);
0335 }
0336
0337 static void test_filter_no_reuseport(const struct test_params p)
0338 {
0339 struct sockaddr * const addr =
0340 new_any_sockaddr(p.recv_family, p.recv_port);
0341 const char bpf_license[] = "GPL";
0342 struct bpf_insn ecode[] = {
0343 { BPF_ALU64 | BPF_MOV | BPF_K, BPF_REG_0, 0, 0, 10 },
0344 { BPF_JMP | BPF_EXIT, 0, 0, 0, 0 }
0345 };
0346 struct sock_filter ccode[] = {{ BPF_RET | BPF_A, 0, 0, 0 }};
0347 union bpf_attr eprog;
0348 struct sock_fprog cprog;
0349 int fd, bpf_fd;
0350
0351 fprintf(stderr, "Testing filters on non-SO_REUSEPORT socket...\n");
0352
0353 memset(&eprog, 0, sizeof(eprog));
0354 eprog.prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
0355 eprog.insn_cnt = ARRAY_SIZE(ecode);
0356 eprog.insns = (unsigned long) &ecode;
0357 eprog.license = (unsigned long) &bpf_license;
0358 eprog.kern_version = 0;
0359
0360 memset(&cprog, 0, sizeof(cprog));
0361 cprog.len = ARRAY_SIZE(ccode);
0362 cprog.filter = ccode;
0363
0364
0365 bpf_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &eprog, sizeof(eprog));
0366 if (bpf_fd < 0)
0367 error(1, errno, "ebpf error");
0368 fd = socket(p.recv_family, p.protocol, 0);
0369 if (fd < 0)
0370 error(1, errno, "failed to create socket 1");
0371
0372 if (bind(fd, addr, sockaddr_size()))
0373 error(1, errno, "failed to bind recv socket 1");
0374
0375 errno = 0;
0376 if (!setsockopt(fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_EBPF, &bpf_fd,
0377 sizeof(bpf_fd)) || errno != EINVAL)
0378 error(1, errno, "setsockopt should have returned EINVAL");
0379
0380 errno = 0;
0381 if (!setsockopt(fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &cprog,
0382 sizeof(cprog)) || errno != EINVAL)
0383 error(1, errno, "setsockopt should have returned EINVAL");
0384
0385 free(addr);
0386 }
0387
0388 static void test_filter_without_bind(void)
0389 {
0390 int fd1, fd2, opt = 1;
0391
0392 fprintf(stderr, "Testing filter add without bind...\n");
0393 fd1 = socket(AF_INET, SOCK_DGRAM, 0);
0394 if (fd1 < 0)
0395 error(1, errno, "failed to create socket 1");
0396 fd2 = socket(AF_INET, SOCK_DGRAM, 0);
0397 if (fd2 < 0)
0398 error(1, errno, "failed to create socket 2");
0399 if (setsockopt(fd1, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)))
0400 error(1, errno, "failed to set SO_REUSEPORT on socket 1");
0401 if (setsockopt(fd2, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)))
0402 error(1, errno, "failed to set SO_REUSEPORT on socket 2");
0403
0404 attach_ebpf(fd1, 10);
0405 attach_cbpf(fd2, 10);
0406
0407 close(fd1);
0408 close(fd2);
0409 }
0410
0411 void enable_fastopen(void)
0412 {
0413 int fd = open("/proc/sys/net/ipv4/tcp_fastopen", 0);
0414 int rw_mask = 3;
0415 int val, size;
0416 char buf[16];
0417
0418 if (fd < 0)
0419 error(1, errno, "Unable to open tcp_fastopen sysctl");
0420 if (read(fd, buf, sizeof(buf)) <= 0)
0421 error(1, errno, "Unable to read tcp_fastopen sysctl");
0422 val = atoi(buf);
0423 close(fd);
0424
0425 if ((val & rw_mask) != rw_mask) {
0426 fd = open("/proc/sys/net/ipv4/tcp_fastopen", O_RDWR);
0427 if (fd < 0)
0428 error(1, errno,
0429 "Unable to open tcp_fastopen sysctl for writing");
0430 val |= rw_mask;
0431 size = snprintf(buf, 16, "%d", val);
0432 if (write(fd, buf, size) <= 0)
0433 error(1, errno, "Unable to write tcp_fastopen sysctl");
0434 close(fd);
0435 }
0436 }
0437
0438 static struct rlimit rlim_old;
0439
0440 static __attribute__((constructor)) void main_ctor(void)
0441 {
0442 getrlimit(RLIMIT_MEMLOCK, &rlim_old);
0443
0444 if (rlim_old.rlim_cur != RLIM_INFINITY) {
0445 struct rlimit rlim_new;
0446
0447 rlim_new.rlim_cur = rlim_old.rlim_cur + (1UL << 20);
0448 rlim_new.rlim_max = rlim_old.rlim_max + (1UL << 20);
0449 setrlimit(RLIMIT_MEMLOCK, &rlim_new);
0450 }
0451 }
0452
0453 static __attribute__((destructor)) void main_dtor(void)
0454 {
0455 setrlimit(RLIMIT_MEMLOCK, &rlim_old);
0456 }
0457
0458 int main(void)
0459 {
0460 fprintf(stderr, "---- IPv4 UDP ----\n");
0461
0462
0463
0464 test_reuseport_ebpf((struct test_params) {
0465 .recv_family = AF_INET,
0466 .send_family = AF_INET,
0467 .protocol = SOCK_DGRAM,
0468 .recv_socks = 10,
0469 .recv_port = 8000,
0470 .send_port_min = 9000});
0471 test_reuseport_ebpf((struct test_params) {
0472 .recv_family = AF_INET,
0473 .send_family = AF_INET,
0474 .protocol = SOCK_DGRAM,
0475 .recv_socks = 20,
0476 .recv_port = 8000,
0477 .send_port_min = 9000});
0478 test_reuseport_cbpf((struct test_params) {
0479 .recv_family = AF_INET,
0480 .send_family = AF_INET,
0481 .protocol = SOCK_DGRAM,
0482 .recv_socks = 10,
0483 .recv_port = 8001,
0484 .send_port_min = 9020});
0485 test_reuseport_cbpf((struct test_params) {
0486 .recv_family = AF_INET,
0487 .send_family = AF_INET,
0488 .protocol = SOCK_DGRAM,
0489 .recv_socks = 20,
0490 .recv_port = 8001,
0491 .send_port_min = 9020});
0492 test_extra_filter((struct test_params) {
0493 .recv_family = AF_INET,
0494 .protocol = SOCK_DGRAM,
0495 .recv_port = 8002});
0496 test_filter_no_reuseport((struct test_params) {
0497 .recv_family = AF_INET,
0498 .protocol = SOCK_DGRAM,
0499 .recv_port = 8008});
0500
0501 fprintf(stderr, "---- IPv6 UDP ----\n");
0502 test_reuseport_ebpf((struct test_params) {
0503 .recv_family = AF_INET6,
0504 .send_family = AF_INET6,
0505 .protocol = SOCK_DGRAM,
0506 .recv_socks = 10,
0507 .recv_port = 8003,
0508 .send_port_min = 9040});
0509 test_reuseport_ebpf((struct test_params) {
0510 .recv_family = AF_INET6,
0511 .send_family = AF_INET6,
0512 .protocol = SOCK_DGRAM,
0513 .recv_socks = 20,
0514 .recv_port = 8003,
0515 .send_port_min = 9040});
0516 test_reuseport_cbpf((struct test_params) {
0517 .recv_family = AF_INET6,
0518 .send_family = AF_INET6,
0519 .protocol = SOCK_DGRAM,
0520 .recv_socks = 10,
0521 .recv_port = 8004,
0522 .send_port_min = 9060});
0523 test_reuseport_cbpf((struct test_params) {
0524 .recv_family = AF_INET6,
0525 .send_family = AF_INET6,
0526 .protocol = SOCK_DGRAM,
0527 .recv_socks = 20,
0528 .recv_port = 8004,
0529 .send_port_min = 9060});
0530 test_extra_filter((struct test_params) {
0531 .recv_family = AF_INET6,
0532 .protocol = SOCK_DGRAM,
0533 .recv_port = 8005});
0534 test_filter_no_reuseport((struct test_params) {
0535 .recv_family = AF_INET6,
0536 .protocol = SOCK_DGRAM,
0537 .recv_port = 8009});
0538
0539 fprintf(stderr, "---- IPv6 UDP w/ mapped IPv4 ----\n");
0540 test_reuseport_ebpf((struct test_params) {
0541 .recv_family = AF_INET6,
0542 .send_family = AF_INET,
0543 .protocol = SOCK_DGRAM,
0544 .recv_socks = 20,
0545 .recv_port = 8006,
0546 .send_port_min = 9080});
0547 test_reuseport_ebpf((struct test_params) {
0548 .recv_family = AF_INET6,
0549 .send_family = AF_INET,
0550 .protocol = SOCK_DGRAM,
0551 .recv_socks = 10,
0552 .recv_port = 8006,
0553 .send_port_min = 9080});
0554 test_reuseport_cbpf((struct test_params) {
0555 .recv_family = AF_INET6,
0556 .send_family = AF_INET,
0557 .protocol = SOCK_DGRAM,
0558 .recv_socks = 10,
0559 .recv_port = 8007,
0560 .send_port_min = 9100});
0561 test_reuseport_cbpf((struct test_params) {
0562 .recv_family = AF_INET6,
0563 .send_family = AF_INET,
0564 .protocol = SOCK_DGRAM,
0565 .recv_socks = 20,
0566 .recv_port = 8007,
0567 .send_port_min = 9100});
0568
0569
0570 enable_fastopen();
0571 fprintf(stderr, "---- IPv4 TCP ----\n");
0572 test_reuseport_ebpf((struct test_params) {
0573 .recv_family = AF_INET,
0574 .send_family = AF_INET,
0575 .protocol = SOCK_STREAM,
0576 .recv_socks = 10,
0577 .recv_port = 8008,
0578 .send_port_min = 9120});
0579 test_reuseport_cbpf((struct test_params) {
0580 .recv_family = AF_INET,
0581 .send_family = AF_INET,
0582 .protocol = SOCK_STREAM,
0583 .recv_socks = 10,
0584 .recv_port = 8009,
0585 .send_port_min = 9160});
0586 test_extra_filter((struct test_params) {
0587 .recv_family = AF_INET,
0588 .protocol = SOCK_STREAM,
0589 .recv_port = 8010});
0590 test_filter_no_reuseport((struct test_params) {
0591 .recv_family = AF_INET,
0592 .protocol = SOCK_STREAM,
0593 .recv_port = 8011});
0594
0595 fprintf(stderr, "---- IPv6 TCP ----\n");
0596 test_reuseport_ebpf((struct test_params) {
0597 .recv_family = AF_INET6,
0598 .send_family = AF_INET6,
0599 .protocol = SOCK_STREAM,
0600 .recv_socks = 10,
0601 .recv_port = 8012,
0602 .send_port_min = 9200});
0603 test_reuseport_cbpf((struct test_params) {
0604 .recv_family = AF_INET6,
0605 .send_family = AF_INET6,
0606 .protocol = SOCK_STREAM,
0607 .recv_socks = 10,
0608 .recv_port = 8013,
0609 .send_port_min = 9240});
0610 test_extra_filter((struct test_params) {
0611 .recv_family = AF_INET6,
0612 .protocol = SOCK_STREAM,
0613 .recv_port = 8014});
0614 test_filter_no_reuseport((struct test_params) {
0615 .recv_family = AF_INET6,
0616 .protocol = SOCK_STREAM,
0617 .recv_port = 8015});
0618
0619 fprintf(stderr, "---- IPv6 TCP w/ mapped IPv4 ----\n");
0620 test_reuseport_ebpf((struct test_params) {
0621 .recv_family = AF_INET6,
0622 .send_family = AF_INET,
0623 .protocol = SOCK_STREAM,
0624 .recv_socks = 10,
0625 .recv_port = 8016,
0626 .send_port_min = 9320});
0627 test_reuseport_cbpf((struct test_params) {
0628 .recv_family = AF_INET6,
0629 .send_family = AF_INET,
0630 .protocol = SOCK_STREAM,
0631 .recv_socks = 10,
0632 .recv_port = 8017,
0633 .send_port_min = 9360});
0634
0635 test_filter_without_bind();
0636
0637 fprintf(stderr, "SUCCESS\n");
0638 return 0;
0639 }