Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next

Daniel Borkmann says:

====================
pull-request: bpf-next 2024-08-23

We've added 10 non-merge commits during the last 15 day(s) which contain
a total of 10 files changed, 222 insertions(+), 190 deletions(-).

The main changes are:

1) Add TCP_BPF_SOCK_OPS_CB_FLAGS to bpf_*sockopt() to address the case
when long-lived sockets miss a chance to set additional callbacks
if a sockops program was not attached early in their lifetime,
from Alan Maguire.

2) Add a batch of BPF selftest improvements which fix a few bugs and add
missing features to improve the test coverage of sockmap/sockhash,
from Michal Luczaj.

3) Fix a false-positive Smatch-reported off-by-one in tcp_validate_cookie()
which is part of the test_tcp_custom_syncookie BPF selftest,
from Kuniyuki Iwashima.

4) Fix the flow_dissector BPF selftest which had a bug in IP header's
tot_len calculation doing subtraction after htons() instead of inside
htons(), from Asbjørn Sloth Tønnesen.

* tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next:
selftest: bpf: Remove mssind boundary check in test_tcp_custom_syncookie.c.
selftests/bpf: Introduce __attribute__((cleanup)) in create_pair()
selftests/bpf: Exercise SOCK_STREAM unix_inet_redir_to_connected()
selftests/bpf: Honour the sotype of af_unix redir tests
selftests/bpf: Simplify inet_socketpair() and vsock_socketpair_connectible()
selftests/bpf: Socket pair creation, cleanups
selftests/bpf: Support more socket types in create_pair()
selftests/bpf: Avoid subtraction after htons() in ipip tests
selftests/bpf: add sockopt tests for TCP_BPF_SOCK_OPS_CB_FLAGS
bpf/bpf_get,set_sockopt: add option to set TCP-BPF sock ops flags
====================

Link: https://patch.msgid.link/20240823134959.1091-1-daniel@iogearbox.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+222 -190
+2 -1
include/uapi/linux/bpf.h
··· 2851 2851 * **TCP_SYNCNT**, **TCP_USER_TIMEOUT**, **TCP_NOTSENT_LOWAT**, 2852 2852 * **TCP_NODELAY**, **TCP_MAXSEG**, **TCP_WINDOW_CLAMP**, 2853 2853 * **TCP_THIN_LINEAR_TIMEOUTS**, **TCP_BPF_DELACK_MAX**, 2854 - * **TCP_BPF_RTO_MIN**. 2854 + * **TCP_BPF_RTO_MIN**, **TCP_BPF_SOCK_OPS_CB_FLAGS**. 2855 2855 * * **IPPROTO_IP**, which supports *optname* **IP_TOS**. 2856 2856 * * **IPPROTO_IPV6**, which supports the following *optname*\ s: 2857 2857 * **IPV6_TCLASS**, **IPV6_AUTOFLOWLABEL**. ··· 7080 7080 TCP_BPF_SYN = 1005, /* Copy the TCP header */ 7081 7081 TCP_BPF_SYN_IP = 1006, /* Copy the IP[46] and TCP header */ 7082 7082 TCP_BPF_SYN_MAC = 1007, /* Copy the MAC, IP[46], and TCP header */ 7083 + TCP_BPF_SOCK_OPS_CB_FLAGS = 1008, /* Get or Set TCP sock ops flags */ 7083 7084 }; 7084 7085 7085 7086 enum {
+16
net/core/filter.c
··· 5279 5279 return -EINVAL; 5280 5280 inet_csk(sk)->icsk_rto_min = timeout; 5281 5281 break; 5282 + case TCP_BPF_SOCK_OPS_CB_FLAGS: 5283 + if (val & ~(BPF_SOCK_OPS_ALL_CB_FLAGS)) 5284 + return -EINVAL; 5285 + tp->bpf_sock_ops_cb_flags = val; 5286 + break; 5282 5287 default: 5283 5288 return -EINVAL; 5284 5289 } ··· 5372 5367 if (*optlen < 1) 5373 5368 return -EINVAL; 5374 5369 break; 5370 + case TCP_BPF_SOCK_OPS_CB_FLAGS: 5371 + if (*optlen != sizeof(int)) 5372 + return -EINVAL; 5373 + if (getopt) { 5374 + struct tcp_sock *tp = tcp_sk(sk); 5375 + int cb_flags = tp->bpf_sock_ops_cb_flags; 5376 + 5377 + memcpy(optval, &cb_flags, *optlen); 5378 + return 0; 5379 + } 5380 + return bpf_sol_tcp_setsockopt(sk, optname, optval, *optlen); 5375 5381 default: 5376 5382 if (getopt) 5377 5383 return -EINVAL;
+2 -1
tools/include/uapi/linux/bpf.h
··· 2851 2851 * **TCP_SYNCNT**, **TCP_USER_TIMEOUT**, **TCP_NOTSENT_LOWAT**, 2852 2852 * **TCP_NODELAY**, **TCP_MAXSEG**, **TCP_WINDOW_CLAMP**, 2853 2853 * **TCP_THIN_LINEAR_TIMEOUTS**, **TCP_BPF_DELACK_MAX**, 2854 - * **TCP_BPF_RTO_MIN**. 2854 + * **TCP_BPF_RTO_MIN**, **TCP_BPF_SOCK_OPS_CB_FLAGS**. 2855 2855 * * **IPPROTO_IP**, which supports *optname* **IP_TOS**. 2856 2856 * * **IPPROTO_IPV6**, which supports the following *optname*\ s: 2857 2857 * **IPV6_TCLASS**, **IPV6_AUTOFLOWLABEL**. ··· 7080 7080 TCP_BPF_SYN = 1005, /* Copy the TCP header */ 7081 7081 TCP_BPF_SYN_IP = 1006, /* Copy the IP[46] and TCP header */ 7082 7082 TCP_BPF_SYN_MAC = 1007, /* Copy the MAC, IP[46], and TCP header */ 7083 + TCP_BPF_SOCK_OPS_CB_FLAGS = 1008, /* Get or Set TCP sock ops flags */ 7083 7084 }; 7084 7085 7085 7086 enum {
+6 -6
tools/testing/selftests/bpf/prog_tests/flow_dissector.c
··· 378 378 .iph_inner.ihl = 5, 379 379 .iph_inner.protocol = IPPROTO_TCP, 380 380 .iph_inner.tot_len = 381 - __bpf_constant_htons(MAGIC_BYTES) - 382 - sizeof(struct iphdr), 381 + __bpf_constant_htons(MAGIC_BYTES - 382 + sizeof(struct iphdr)), 383 383 .tcp.doff = 5, 384 384 .tcp.source = 80, 385 385 .tcp.dest = 8080, ··· 407 407 .iph_inner.ihl = 5, 408 408 .iph_inner.protocol = IPPROTO_TCP, 409 409 .iph_inner.tot_len = 410 - __bpf_constant_htons(MAGIC_BYTES) - 411 - sizeof(struct iphdr), 410 + __bpf_constant_htons(MAGIC_BYTES - 411 + sizeof(struct iphdr)), 412 412 .tcp.doff = 5, 413 413 .tcp.source = 80, 414 414 .tcp.dest = 8080, ··· 436 436 .iph_inner.ihl = 5, 437 437 .iph_inner.protocol = IPPROTO_TCP, 438 438 .iph_inner.tot_len = 439 - __bpf_constant_htons(MAGIC_BYTES) - 440 - sizeof(struct iphdr), 439 + __bpf_constant_htons(MAGIC_BYTES - 440 + sizeof(struct iphdr)), 441 441 .tcp.doff = 5, 442 442 .tcp.source = 99, 443 443 .tcp.dest = 9090,
+47
tools/testing/selftests/bpf/prog_tests/setget_sockopt.c
··· 154 154 close(sfd); 155 155 } 156 156 157 + static void test_nonstandard_opt(int family) 158 + { 159 + struct setget_sockopt__bss *bss = skel->bss; 160 + struct bpf_link *getsockopt_link = NULL; 161 + int sfd = -1, fd = -1, cfd = -1, flags; 162 + socklen_t flagslen = sizeof(flags); 163 + 164 + memset(bss, 0, sizeof(*bss)); 165 + 166 + sfd = start_server(family, SOCK_STREAM, 167 + family == AF_INET6 ? addr6_str : addr4_str, 0, 0); 168 + if (!ASSERT_GE(sfd, 0, "start_server")) 169 + return; 170 + 171 + fd = connect_to_fd(sfd, 0); 172 + if (!ASSERT_GE(fd, 0, "connect_to_fd_server")) 173 + goto err_out; 174 + 175 + /* cgroup/getsockopt prog will intercept getsockopt() below and 176 + * retrieve the tcp socket bpf_sock_ops_cb_flags value for the 177 + * accept()ed socket; this was set earlier in the passive established 178 + * callback for the accept()ed socket via bpf_setsockopt(). 179 + */ 180 + getsockopt_link = bpf_program__attach_cgroup(skel->progs._getsockopt, cg_fd); 181 + if (!ASSERT_OK_PTR(getsockopt_link, "getsockopt prog")) 182 + goto err_out; 183 + 184 + cfd = accept(sfd, NULL, 0); 185 + if (!ASSERT_GE(cfd, 0, "accept")) 186 + goto err_out; 187 + 188 + if (!ASSERT_OK(getsockopt(cfd, SOL_TCP, TCP_BPF_SOCK_OPS_CB_FLAGS, &flags, &flagslen), 189 + "getsockopt_flags")) 190 + goto err_out; 191 + ASSERT_EQ(flags & BPF_SOCK_OPS_STATE_CB_FLAG, BPF_SOCK_OPS_STATE_CB_FLAG, 192 + "cb_flags_set"); 193 + err_out: 194 + close(sfd); 195 + if (fd != -1) 196 + close(fd); 197 + if (cfd != -1) 198 + close(cfd); 199 + bpf_link__destroy(getsockopt_link); 200 + } 201 + 157 202 void test_setget_sockopt(void) 158 203 { 159 204 cg_fd = test__join_cgroup(CG_NAME); ··· 236 191 test_udp(AF_INET); 237 192 test_ktls(AF_INET6); 238 193 test_ktls(AF_INET); 194 + test_nonstandard_opt(AF_INET); 195 + test_nonstandard_opt(AF_INET6); 239 196 240 197 done: 241 198 setget_sockopt__destroy(skel);
+9 -19
tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
··· 451 451 #define MAX_EVENTS 10 452 452 static void test_sockmap_skb_verdict_shutdown(void) 453 453 { 454 + int n, err, map, verdict, c1 = -1, p1 = -1; 454 455 struct epoll_event ev, events[MAX_EVENTS]; 455 - int n, err, map, verdict, s, c1 = -1, p1 = -1; 456 456 struct test_sockmap_pass_prog *skel; 457 - int epollfd; 458 457 int zero = 0; 458 + int epollfd; 459 459 char b; 460 460 461 461 skel = test_sockmap_pass_prog__open_and_load(); ··· 469 469 if (!ASSERT_OK(err, "bpf_prog_attach")) 470 470 goto out; 471 471 472 - s = socket_loopback(AF_INET, SOCK_STREAM); 473 - if (s < 0) 474 - goto out; 475 - err = create_pair(s, AF_INET, SOCK_STREAM, &c1, &p1); 472 + err = create_pair(AF_INET, SOCK_STREAM, &c1, &p1); 476 473 if (err < 0) 477 474 goto out; 478 475 ··· 503 506 504 507 static void test_sockmap_skb_verdict_fionread(bool pass_prog) 505 508 { 509 + int err, map, verdict, c0 = -1, c1 = -1, p0 = -1, p1 = -1; 506 510 int expected, zero = 0, sent, recvd, avail; 507 - int err, map, verdict, s, c0 = -1, c1 = -1, p0 = -1, p1 = -1; 508 511 struct test_sockmap_pass_prog *pass = NULL; 509 512 struct test_sockmap_drop_prog *drop = NULL; 510 513 char buf[256] = "0123456789"; ··· 531 534 if (!ASSERT_OK(err, "bpf_prog_attach")) 532 535 goto out; 533 536 534 - s = socket_loopback(AF_INET, SOCK_STREAM); 535 - if (!ASSERT_GT(s, -1, "socket_loopback(s)")) 536 - goto out; 537 - err = create_socket_pairs(s, AF_INET, SOCK_STREAM, &c0, &c1, &p0, &p1); 538 - if (!ASSERT_OK(err, "create_socket_pairs(s)")) 537 + err = create_socket_pairs(AF_INET, SOCK_STREAM, &c0, &c1, &p0, &p1); 538 + if (!ASSERT_OK(err, "create_socket_pairs()")) 539 539 goto out; 540 540 541 541 err = bpf_map_update_elem(map, &zero, &c1, BPF_NOEXIST); ··· 564 570 565 571 static void test_sockmap_skb_verdict_peek_helper(int map) 566 572 { 567 - int err, s, c1, p1, zero = 0, sent, recvd, avail; 573 + int err, c1, p1, zero = 0, sent, recvd, avail; 568 574 char snd[256] = "0123456789"; 569 575 char rcv[256] = "0"; 570 576 571 - s = socket_loopback(AF_INET, SOCK_STREAM); 572 - if (!ASSERT_GT(s, -1, "socket_loopback(s)")) 573 - return; 574 - 575 - err = create_pair(s, AF_INET, SOCK_STREAM, &c1, &p1); 576 - if (!ASSERT_OK(err, "create_pairs(s)")) 577 + err = create_pair(AF_INET, SOCK_STREAM, &c1, &p1); 578 + if (!ASSERT_OK(err, "create_pair()")) 577 579 return; 578 580 579 581 err = bpf_map_update_elem(map, &zero, &c1, BPF_NOEXIST);
+101 -48
tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h
··· 3 3 4 4 #include <linux/vm_sockets.h> 5 5 6 + /* include/linux/net.h */ 7 + #define SOCK_TYPE_MASK 0xf 8 + 6 9 #define IO_TIMEOUT_SEC 30 7 10 #define MAX_STRERR_LEN 256 8 11 #define MAX_TEST_NAME 80 ··· 16 13 #endif 17 14 18 15 #define __always_unused __attribute__((__unused__)) 16 + 17 + /* include/linux/cleanup.h */ 18 + #define __get_and_null(p, nullvalue) \ 19 + ({ \ 20 + __auto_type __ptr = &(p); \ 21 + __auto_type __val = *__ptr; \ 22 + *__ptr = nullvalue; \ 23 + __val; \ 24 + }) 25 + 26 + #define take_fd(fd) __get_and_null(fd, -EBADF) 19 27 20 28 #define _FAIL(errnum, fmt...) \ 21 29 ({ \ ··· 193 179 __ret; \ 194 180 }) 195 181 182 + static inline void close_fd(int *fd) 183 + { 184 + if (*fd >= 0) 185 + xclose(*fd); 186 + } 187 + 188 + #define __close_fd __attribute__((cleanup(close_fd))) 189 + 196 190 static inline int poll_connect(int fd, unsigned int timeout_sec) 197 191 { 198 192 struct timeval timeout = { .tv_sec = timeout_sec }; ··· 334 312 return xbpf_map_update_elem(sock_mapfd, &key, &value, BPF_NOEXIST); 335 313 } 336 314 337 - static inline int create_pair(int s, int family, int sotype, int *c, int *p) 338 - { 339 - struct sockaddr_storage addr; 340 - socklen_t len; 341 - int err = 0; 342 - 343 - len = sizeof(addr); 344 - err = xgetsockname(s, sockaddr(&addr), &len); 345 - if (err) 346 - return err; 347 - 348 - *c = xsocket(family, sotype, 0); 349 - if (*c < 0) 350 - return errno; 351 - err = xconnect(*c, sockaddr(&addr), len); 352 - if (err) { 353 - err = errno; 354 - goto close_cli0; 355 - } 356 - 357 - *p = xaccept_nonblock(s, NULL, NULL); 358 - if (*p < 0) { 359 - err = errno; 360 - goto close_cli0; 361 - } 362 - return err; 363 - close_cli0: 364 - close(*c); 365 - return err; 366 - } 367 - 368 - static inline int create_socket_pairs(int s, int family, int sotype, 369 - int *c0, int *c1, int *p0, int *p1) 370 - { 371 - int err; 372 - 373 - err = create_pair(s, family, sotype, c0, p0); 374 - if (err) 375 - return err; 376 - 377 - err = create_pair(s, family, sotype, c1, p1); 378 - if (err) { 379 - close(*c0); 380 - close(*p0); 381 - } 382 - return err; 383 - } 384 - 385 315 static inline int enable_reuseport(int s, int progfd) 386 316 { 387 317 int err, one = 1; ··· 386 412 return socket_loopback_reuseport(family, sotype, -1); 387 413 } 388 414 415 + static inline int create_pair(int family, int sotype, int *p0, int *p1) 416 + { 417 + __close_fd int s, c = -1, p = -1; 418 + struct sockaddr_storage addr; 419 + socklen_t len = sizeof(addr); 420 + int err; 421 + 422 + s = socket_loopback(family, sotype); 423 + if (s < 0) 424 + return s; 425 + 426 + err = xgetsockname(s, sockaddr(&addr), &len); 427 + if (err) 428 + return err; 429 + 430 + c = xsocket(family, sotype, 0); 431 + if (c < 0) 432 + return c; 433 + 434 + err = connect(c, sockaddr(&addr), len); 435 + if (err) { 436 + if (errno != EINPROGRESS) { 437 + FAIL_ERRNO("connect"); 438 + return err; 439 + } 440 + 441 + err = poll_connect(c, IO_TIMEOUT_SEC); 442 + if (err) { 443 + FAIL_ERRNO("poll_connect"); 444 + return err; 445 + } 446 + } 447 + 448 + switch (sotype & SOCK_TYPE_MASK) { 449 + case SOCK_DGRAM: 450 + err = xgetsockname(c, sockaddr(&addr), &len); 451 + if (err) 452 + return err; 453 + 454 + err = xconnect(s, sockaddr(&addr), len); 455 + if (err) 456 + return err; 457 + 458 + *p0 = take_fd(s); 459 + break; 460 + case SOCK_STREAM: 461 + case SOCK_SEQPACKET: 462 + p = xaccept_nonblock(s, NULL, NULL); 463 + if (p < 0) 464 + return p; 465 + 466 + *p0 = take_fd(p); 467 + break; 468 + default: 469 + FAIL("Unsupported socket type %#x", sotype); 470 + return -EOPNOTSUPP; 471 + } 472 + 473 + *p1 = take_fd(c); 474 + return 0; 475 + } 476 + 477 + static inline int create_socket_pairs(int family, int sotype, int *c0, int *c1, 478 + int *p0, int *p1) 479 + { 480 + int err; 481 + 482 + err = create_pair(family, sotype, c0, p0); 483 + if (err) 484 + return err; 485 + 486 + err = create_pair(family, sotype, c1, p1); 487 + if (err) { 488 + close(*c0); 489 + close(*p0); 490 + } 491 + 492 + return err; 493 + } 389 494 390 495 #endif // __SOCKMAP_HELPERS__
+14 -103
tools/testing/selftests/bpf/prog_tests/sockmap_listen.c
··· 677 677 int verd_mapfd, enum redir_mode mode) 678 678 { 679 679 const char *log_prefix = redir_mode_str(mode); 680 - int s, c0, c1, p0, p1; 680 + int c0, c1, p0, p1; 681 681 unsigned int pass; 682 682 int err, n; 683 683 u32 key; ··· 685 685 686 686 zero_verdict_count(verd_mapfd); 687 687 688 - s = socket_loopback(family, sotype | SOCK_NONBLOCK); 689 - if (s < 0) 690 - return; 691 - 692 - err = create_socket_pairs(s, family, sotype, &c0, &c1, &p0, &p1); 688 + err = create_socket_pairs(family, sotype | SOCK_NONBLOCK, &c0, &c1, 689 + &p0, &p1); 693 690 if (err) 694 - goto close_srv; 691 + return; 695 692 696 693 err = add_to_sockmap(sock_mapfd, p0, p1); 697 694 if (err) ··· 719 722 xclose(c1); 720 723 xclose(p0); 721 724 xclose(c0); 722 - close_srv: 723 - xclose(s); 724 725 } 725 726 726 727 static void test_skb_redir_to_connected(struct test_sockmap_listen *skel, ··· 904 909 905 910 static void redir_partial(int family, int sotype, int sock_map, int parser_map) 906 911 { 907 - int s, c0 = -1, c1 = -1, p0 = -1, p1 = -1; 912 + int c0 = -1, c1 = -1, p0 = -1, p1 = -1; 908 913 int err, n, key, value; 909 914 char buf[] = "abc"; 910 915 ··· 914 919 if (err) 915 920 return; 916 921 917 - s = socket_loopback(family, sotype | SOCK_NONBLOCK); 918 - if (s < 0) 919 - goto clean_parser_map; 920 - 921 - err = create_socket_pairs(s, family, sotype, &c0, &c1, &p0, &p1); 922 + err = create_socket_pairs(family, sotype | SOCK_NONBLOCK, &c0, &c1, 923 + &p0, &p1); 922 924 if (err) 923 - goto close_srv; 925 + goto clean_parser_map; 924 926 925 927 err = add_to_sockmap(sock_map, p0, p1); 926 928 if (err) ··· 936 944 xclose(p0); 937 945 xclose(c1); 938 946 xclose(p1); 939 - close_srv: 940 - xclose(s); 941 947 942 948 clean_parser_map: 943 949 key = 0; ··· 1490 1500 /* Returns two connected loopback vsock sockets */ 1491 1501 static int vsock_socketpair_connectible(int sotype, int *v0, int *v1) 1492 1502 { 1493 - struct sockaddr_storage addr; 1494 - socklen_t len = sizeof(addr); 1495 - int s, p, c; 1496 - 1497 - s = socket_loopback(AF_VSOCK, sotype); 1498 - if (s < 0) 1499 - return -1; 1500 - 1501 - c = xsocket(AF_VSOCK, sotype | SOCK_NONBLOCK, 0); 1502 - if (c == -1) 1503 - goto close_srv; 1504 - 1505 - if (getsockname(s, sockaddr(&addr), &len) < 0) 1506 - goto close_cli; 1507 - 1508 - if (connect(c, sockaddr(&addr), len) < 0 && errno != EINPROGRESS) { 1509 - FAIL_ERRNO("connect"); 1510 - goto close_cli; 1511 - } 1512 - 1513 - len = sizeof(addr); 1514 - p = accept_timeout(s, sockaddr(&addr), &len, IO_TIMEOUT_SEC); 1515 - if (p < 0) 1516 - goto close_cli; 1517 - 1518 - if (poll_connect(c, IO_TIMEOUT_SEC) < 0) { 1519 - FAIL_ERRNO("poll_connect"); 1520 - goto close_acc; 1521 - } 1522 - 1523 - *v0 = p; 1524 - *v1 = c; 1525 - 1526 - return 0; 1527 - 1528 - close_acc: 1529 - close(p); 1530 - close_cli: 1531 - close(c); 1532 - close_srv: 1533 - close(s); 1534 - 1535 - return -1; 1503 + return create_pair(AF_VSOCK, sotype | SOCK_NONBLOCK, v0, v1); 1536 1504 } 1537 1505 1538 1506 static void vsock_unix_redir_connectible(int sock_mapfd, int verd_mapfd, ··· 1639 1691 1640 1692 static int inet_socketpair(int family, int type, int *s, int *c) 1641 1693 { 1642 - struct sockaddr_storage addr; 1643 - socklen_t len; 1644 - int p0, c0; 1645 - int err; 1646 - 1647 - p0 = socket_loopback(family, type | SOCK_NONBLOCK); 1648 - if (p0 < 0) 1649 - return p0; 1650 - 1651 - len = sizeof(addr); 1652 - err = xgetsockname(p0, sockaddr(&addr), &len); 1653 - if (err) 1654 - goto close_peer0; 1655 - 1656 - c0 = xsocket(family, type | SOCK_NONBLOCK, 0); 1657 - if (c0 < 0) { 1658 - err = c0; 1659 - goto close_peer0; 1660 - } 1661 - err = xconnect(c0, sockaddr(&addr), len); 1662 - if (err) 1663 - goto close_cli0; 1664 - err = xgetsockname(c0, sockaddr(&addr), &len); 1665 - if (err) 1666 - goto close_cli0; 1667 - err = xconnect(p0, sockaddr(&addr), len); 1668 - if (err) 1669 - goto close_cli0; 1670 - 1671 - *s = p0; 1672 - *c = c0; 1673 - return 0; 1674 - 1675 - close_cli0: 1676 - xclose(c0); 1677 - close_peer0: 1678 - xclose(p0); 1679 - return err; 1694 + return create_pair(family, type | SOCK_NONBLOCK, s, c); 1680 1695 } 1681 1696 1682 1697 static void udp_redir_to_connected(int family, int sock_mapfd, int verd_mapfd, ··· 1706 1795 int sfd[2]; 1707 1796 int err; 1708 1797 1709 - if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0, sfd)) 1798 + if (socketpair(AF_UNIX, type | SOCK_NONBLOCK, 0, sfd)) 1710 1799 return; 1711 1800 c0 = sfd[0], p0 = sfd[1]; 1712 1801 1713 - err = inet_socketpair(family, SOCK_DGRAM, &p1, &c1); 1802 + err = inet_socketpair(family, type, &p1, &c1); 1714 1803 if (err) 1715 1804 goto close; 1716 1805 ··· 1758 1847 int sfd[2]; 1759 1848 int err; 1760 1849 1761 - err = inet_socketpair(family, SOCK_DGRAM, &p0, &c0); 1850 + err = inet_socketpair(family, type, &p0, &c0); 1762 1851 if (err) 1763 1852 return; 1764 1853 ··· 1793 1882 unix_inet_redir_to_connected(family, SOCK_DGRAM, 1794 1883 sock_map, -1, verdict_map, 1795 1884 REDIR_EGRESS, NO_FLAGS); 1796 - unix_inet_redir_to_connected(family, SOCK_DGRAM, 1885 + unix_inet_redir_to_connected(family, SOCK_STREAM, 1797 1886 sock_map, -1, verdict_map, 1798 1887 REDIR_EGRESS, NO_FLAGS); 1799 1888
+23 -3
tools/testing/selftests/bpf/progs/setget_sockopt.c
··· 59 59 { .opt = TCP_THIN_LINEAR_TIMEOUTS, .flip = 1, }, 60 60 { .opt = TCP_USER_TIMEOUT, .new = 123400, .expected = 123400, }, 61 61 { .opt = TCP_NOTSENT_LOWAT, .new = 1314, .expected = 1314, }, 62 + { .opt = TCP_BPF_SOCK_OPS_CB_FLAGS, .new = BPF_SOCK_OPS_ALL_CB_FLAGS, 63 + .expected = BPF_SOCK_OPS_ALL_CB_FLAGS, }, 62 64 { .opt = 0, }, 63 65 }; 64 66 ··· 355 353 return 1; 356 354 } 357 355 356 + SEC("cgroup/getsockopt") 357 + int _getsockopt(struct bpf_sockopt *ctx) 358 + { 359 + struct bpf_sock *sk = ctx->sk; 360 + int *optval = ctx->optval; 361 + struct tcp_sock *tp; 362 + 363 + if (!sk || ctx->level != SOL_TCP || ctx->optname != TCP_BPF_SOCK_OPS_CB_FLAGS) 364 + return 1; 365 + 366 + tp = bpf_core_cast(sk, struct tcp_sock); 367 + if (ctx->optval + sizeof(int) <= ctx->optval_end) { 368 + *optval = tp->bpf_sock_ops_cb_flags; 369 + ctx->retval = 0; 370 + } 371 + return 1; 372 + } 373 + 358 374 SEC("sockops") 359 375 int skops_sockopt(struct bpf_sock_ops *skops) 360 376 { 361 377 struct bpf_sock *bpf_sk = skops->sk; 362 378 struct sock *sk; 379 + int flags; 363 380 364 381 if (!bpf_sk) 365 382 return 1; ··· 405 384 nr_passive += !(bpf_test_sockopt(skops, sk) || 406 385 test_tcp_maxseg(skops, sk) || 407 386 test_tcp_saved_syn(skops, sk)); 408 - bpf_sock_ops_cb_flags_set(skops, 409 - skops->bpf_sock_ops_cb_flags | 410 - BPF_SOCK_OPS_STATE_CB_FLAG); 387 + flags = skops->bpf_sock_ops_cb_flags | BPF_SOCK_OPS_STATE_CB_FLAG; 388 + bpf_setsockopt(skops, SOL_TCP, TCP_BPF_SOCK_OPS_CB_FLAGS, &flags, sizeof(flags)); 411 389 break; 412 390 case BPF_SOCK_OPS_STATE_CB: 413 391 if (skops->args[1] == BPF_TCP_CLOSE_WAIT)
+2 -9
tools/testing/selftests/bpf/progs/test_tcp_custom_syncookie.c
··· 486 486 goto err; 487 487 488 488 mssind = (cookie & (3 << 6)) >> 6; 489 - if (ctx->ipv4) { 490 - if (mssind > ARRAY_SIZE(msstab4)) 491 - goto err; 492 - 489 + if (ctx->ipv4) 493 490 ctx->attrs.mss = msstab4[mssind]; 494 - } else { 495 - if (mssind > ARRAY_SIZE(msstab6)) 496 - goto err; 497 - 491 + else 498 492 ctx->attrs.mss = msstab6[mssind]; 499 - } 500 493 501 494 ctx->attrs.snd_wscale = cookie & BPF_SYNCOOKIE_WSCALE_MASK; 502 495 ctx->attrs.rcv_wscale = ctx->attrs.snd_wscale;