Commit e540e3bc authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
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: default avatarJakub Kicinski <kuba@kernel.org>
parents b2ede25b af8a066f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -2851,7 +2851,7 @@ union bpf_attr {
 * 		  **TCP_SYNCNT**, **TCP_USER_TIMEOUT**, **TCP_NOTSENT_LOWAT**,
 * 		  **TCP_NODELAY**, **TCP_MAXSEG**, **TCP_WINDOW_CLAMP**,
 * 		  **TCP_THIN_LINEAR_TIMEOUTS**, **TCP_BPF_DELACK_MAX**,
 * 		  **TCP_BPF_RTO_MIN**.
 *		  **TCP_BPF_RTO_MIN**, **TCP_BPF_SOCK_OPS_CB_FLAGS**.
 * 		* **IPPROTO_IP**, which supports *optname* **IP_TOS**.
 * 		* **IPPROTO_IPV6**, which supports the following *optname*\ s:
 * 		  **IPV6_TCLASS**, **IPV6_AUTOFLOWLABEL**.
@@ -7080,6 +7080,7 @@ enum {
	TCP_BPF_SYN		= 1005, /* Copy the TCP header */
	TCP_BPF_SYN_IP		= 1006, /* Copy the IP[46] and TCP header */
	TCP_BPF_SYN_MAC         = 1007, /* Copy the MAC, IP[46], and TCP header */
	TCP_BPF_SOCK_OPS_CB_FLAGS = 1008, /* Get or Set TCP sock ops flags */
};

enum {
+16 −0
Original line number Diff line number Diff line
@@ -5279,6 +5279,11 @@ static int bpf_sol_tcp_setsockopt(struct sock *sk, int optname,
			return -EINVAL;
		inet_csk(sk)->icsk_rto_min = timeout;
		break;
	case TCP_BPF_SOCK_OPS_CB_FLAGS:
		if (val & ~(BPF_SOCK_OPS_ALL_CB_FLAGS))
			return -EINVAL;
		tp->bpf_sock_ops_cb_flags = val;
		break;
	default:
		return -EINVAL;
	}
@@ -5367,6 +5372,17 @@ static int sol_tcp_sockopt(struct sock *sk, int optname,
		if (*optlen < 1)
			return -EINVAL;
		break;
	case TCP_BPF_SOCK_OPS_CB_FLAGS:
		if (*optlen != sizeof(int))
			return -EINVAL;
		if (getopt) {
			struct tcp_sock *tp = tcp_sk(sk);
			int cb_flags = tp->bpf_sock_ops_cb_flags;

			memcpy(optval, &cb_flags, *optlen);
			return 0;
		}
		return bpf_sol_tcp_setsockopt(sk, optname, optval, *optlen);
	default:
		if (getopt)
			return -EINVAL;
+2 −1
Original line number Diff line number Diff line
@@ -2851,7 +2851,7 @@ union bpf_attr {
 * 		  **TCP_SYNCNT**, **TCP_USER_TIMEOUT**, **TCP_NOTSENT_LOWAT**,
 * 		  **TCP_NODELAY**, **TCP_MAXSEG**, **TCP_WINDOW_CLAMP**,
 * 		  **TCP_THIN_LINEAR_TIMEOUTS**, **TCP_BPF_DELACK_MAX**,
 * 		  **TCP_BPF_RTO_MIN**.
 *		  **TCP_BPF_RTO_MIN**, **TCP_BPF_SOCK_OPS_CB_FLAGS**.
 * 		* **IPPROTO_IP**, which supports *optname* **IP_TOS**.
 * 		* **IPPROTO_IPV6**, which supports the following *optname*\ s:
 * 		  **IPV6_TCLASS**, **IPV6_AUTOFLOWLABEL**.
@@ -7080,6 +7080,7 @@ enum {
	TCP_BPF_SYN		= 1005, /* Copy the TCP header */
	TCP_BPF_SYN_IP		= 1006, /* Copy the IP[46] and TCP header */
	TCP_BPF_SYN_MAC         = 1007, /* Copy the MAC, IP[46], and TCP header */
	TCP_BPF_SOCK_OPS_CB_FLAGS = 1008, /* Get or Set TCP sock ops flags */
};

enum {
+6 −6
Original line number Diff line number Diff line
@@ -378,8 +378,8 @@ struct test tests[] = {
			.iph_inner.ihl = 5,
			.iph_inner.protocol = IPPROTO_TCP,
			.iph_inner.tot_len =
				__bpf_constant_htons(MAGIC_BYTES) -
				sizeof(struct iphdr),
				__bpf_constant_htons(MAGIC_BYTES -
				sizeof(struct iphdr)),
			.tcp.doff = 5,
			.tcp.source = 80,
			.tcp.dest = 8080,
@@ -407,8 +407,8 @@ struct test tests[] = {
			.iph_inner.ihl = 5,
			.iph_inner.protocol = IPPROTO_TCP,
			.iph_inner.tot_len =
				__bpf_constant_htons(MAGIC_BYTES) -
				sizeof(struct iphdr),
				__bpf_constant_htons(MAGIC_BYTES -
				sizeof(struct iphdr)),
			.tcp.doff = 5,
			.tcp.source = 80,
			.tcp.dest = 8080,
@@ -436,8 +436,8 @@ struct test tests[] = {
			.iph_inner.ihl = 5,
			.iph_inner.protocol = IPPROTO_TCP,
			.iph_inner.tot_len =
				__bpf_constant_htons(MAGIC_BYTES) -
				sizeof(struct iphdr),
				__bpf_constant_htons(MAGIC_BYTES -
				sizeof(struct iphdr)),
			.tcp.doff = 5,
			.tcp.source = 99,
			.tcp.dest = 9090,
+47 −0
Original line number Diff line number Diff line
@@ -154,6 +154,51 @@ static void test_ktls(int family)
	close(sfd);
}

static void test_nonstandard_opt(int family)
{
	struct setget_sockopt__bss *bss = skel->bss;
	struct bpf_link *getsockopt_link = NULL;
	int sfd = -1, fd = -1, cfd = -1, flags;
	socklen_t flagslen = sizeof(flags);

	memset(bss, 0, sizeof(*bss));

	sfd = start_server(family, SOCK_STREAM,
			   family == AF_INET6 ? addr6_str : addr4_str, 0, 0);
	if (!ASSERT_GE(sfd, 0, "start_server"))
		return;

	fd = connect_to_fd(sfd, 0);
	if (!ASSERT_GE(fd, 0, "connect_to_fd_server"))
		goto err_out;

	/* cgroup/getsockopt prog will intercept getsockopt() below and
	 * retrieve the tcp socket bpf_sock_ops_cb_flags value for the
	 * accept()ed socket; this was set earlier in the passive established
	 * callback for the accept()ed socket via bpf_setsockopt().
	 */
	getsockopt_link = bpf_program__attach_cgroup(skel->progs._getsockopt, cg_fd);
	if (!ASSERT_OK_PTR(getsockopt_link, "getsockopt prog"))
		goto err_out;

	cfd = accept(sfd, NULL, 0);
	if (!ASSERT_GE(cfd, 0, "accept"))
		goto err_out;

	if (!ASSERT_OK(getsockopt(cfd, SOL_TCP, TCP_BPF_SOCK_OPS_CB_FLAGS, &flags, &flagslen),
		       "getsockopt_flags"))
		goto err_out;
	ASSERT_EQ(flags & BPF_SOCK_OPS_STATE_CB_FLAG, BPF_SOCK_OPS_STATE_CB_FLAG,
		  "cb_flags_set");
err_out:
	close(sfd);
	if (fd != -1)
		close(fd);
	if (cfd != -1)
		close(cfd);
	bpf_link__destroy(getsockopt_link);
}

void test_setget_sockopt(void)
{
	cg_fd = test__join_cgroup(CG_NAME);
@@ -191,6 +236,8 @@ void test_setget_sockopt(void)
	test_udp(AF_INET);
	test_ktls(AF_INET6);
	test_ktls(AF_INET);
	test_nonstandard_opt(AF_INET);
	test_nonstandard_opt(AF_INET6);

done:
	setget_sockopt__destroy(skel);
Loading