Netdev List
 help / color / mirror / Atom feed
* [PATCH bpf-next v2 1/2] bpf: Add bpf_ksock_bind() kfunc
@ 2026-10-26 19:03 Mahe Tardy
  2026-10-26 19:03 ` [PATCH bpf-next v2 2/2] selftests/bpf: Test " Mahe Tardy
  0 siblings, 1 reply; 2+ messages in thread
From: Mahe Tardy @ 2026-10-26 19:03 UTC (permalink / raw)
  To: bpf
  Cc: andrii, ast, daniel, davem, willemb, eddyz87, edumazet,
	john.fastabend, kuba, horms, liamwisehart, martin.lau, pabeni,
	song, netdev, sdf.kernel, yonghong.song, jolsa, kuniyu, memxor,
	emil, almagui, Mahe Tardy

Part of the effort to make ksock have all basic socket operations. This
is for example useful when replying to a peer which expects a message
from a particular source port.

Signed-off-by: Mahe Tardy <mahe.tardy@gmail.com>
---
 net/core/bpf_ksock.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/net/core/bpf_ksock.c b/net/core/bpf_ksock.c
index 37168f43c16c..25111712b944 100644
--- a/net/core/bpf_ksock.c
+++ b/net/core/bpf_ksock.c
@@ -178,6 +178,37 @@ bpf_ksock_create(const struct bpf_ksock_create_opts *opts, u32 opts__sz,
 	return NULL;
 }

+/**
+ * bpf_ksock_bind() - Bind a BPF kernel socket to a local address.
+ * @ks:		The BPF kernel socket context.
+ * @addr:	Pointer to an IPv4 or IPv6 socket address.
+ * @addr__sz:	Size of the address union.
+ *
+ * Binds the socket to the specified local address and port. A port of zero
+ * selects an ephemeral port.
+ *
+ * This function may sleep, so it can only be used in sleepable BPF programs
+ * (SYSCALL).
+ *
+ * Return: 0 on success, negative errno on error.
+ */
+__bpf_kfunc int bpf_ksock_bind(struct bpf_ksock *ks,
+			       const union bpf_ksock_addr *addr, u32 addr__sz)
+{
+	struct sockaddr_storage sa;
+	int addrlen;
+
+	/* Prevent wq kthread context for CAP_NET_BIND_SERVICE check */
+	if (current->flags & PF_KTHREAD)
+		return -EOPNOTSUPP;
+
+	addrlen = bpf_ksock_addr_to_sockaddr(addr, addr__sz, &sa);
+	if (addrlen < 0)
+		return addrlen;
+
+	return __sys_bind_socket(ks->sock, &sa, addrlen);
+}
+
 /**
  * bpf_ksock_connect() - Connect a BPF kernel socket to a remote address.
  * @ks:		The BPF kernel socket context.
@@ -285,6 +316,7 @@ __bpf_kfunc_end_defs();
 BTF_KFUNCS_START(ksock_init_kfunc_btf_ids)
 BTF_ID_FLAGS(func, bpf_ksock_create, KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE)
 BTF_ID_FLAGS(func, bpf_ksock_connect, KF_SLEEPABLE)
+BTF_ID_FLAGS(func, bpf_ksock_bind, KF_SLEEPABLE)
 BTF_KFUNCS_END(ksock_init_kfunc_btf_ids)

 static const struct btf_kfunc_id_set ksock_init_kfunc_set = {
--
2.43.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH bpf-next v2 2/2] selftests/bpf: Test bpf_ksock_bind() kfunc
  2026-10-26 19:03 [PATCH bpf-next v2 1/2] bpf: Add bpf_ksock_bind() kfunc Mahe Tardy
@ 2026-10-26 19:03 ` Mahe Tardy
  0 siblings, 0 replies; 2+ messages in thread
From: Mahe Tardy @ 2026-10-26 19:03 UTC (permalink / raw)
  To: bpf
  Cc: andrii, ast, daniel, davem, willemb, eddyz87, edumazet,
	john.fastabend, kuba, horms, liamwisehart, martin.lau, pabeni,
	song, netdev, sdf.kernel, yonghong.song, jolsa, kuniyu, memxor,
	emil, almagui, Mahe Tardy

Reuse the existing basic ksock test to also bind to a specific source
and verify that the source address was respected when receiving.

Signed-off-by: Mahe Tardy <mahe.tardy@gmail.com>
---
 .../testing/selftests/bpf/prog_tests/ksock.c  | 22 ++++++++++++++-----
 .../selftests/bpf/progs/ksock_common.h        |  2 ++
 tools/testing/selftests/bpf/progs/ksock_lsm.c | 18 +++++++++++----
 3 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/ksock.c b/tools/testing/selftests/bpf/prog_tests/ksock.c
index dd6b167623d9..b319f74bcf3d 100644
--- a/tools/testing/selftests/bpf/prog_tests/ksock.c
+++ b/tools/testing/selftests/bpf/prog_tests/ksock.c
@@ -10,6 +10,7 @@

 #define NS_TEST "ksock_lsm_ns"
 #define RECV_PORT 7777
+#define LOCAL_KSOCK_PORT 6666
 #define RECV_TIMEOUT_SEC 5

 struct ksock_test_env {
@@ -63,6 +64,8 @@ void test_ksock_lsm(void)
 		.sin_family = AF_INET,
 		.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
 	};
+	struct sockaddr_in src_addr;
+	socklen_t src_addrlen = sizeof(src_addr);
 	struct ksock_lsm *skel;
 	char recv_data[sizeof(skel->data->send_data)] = {};
 	ssize_t n;
@@ -76,9 +79,10 @@ void test_ksock_lsm(void)
 	if (!ksock_test_env_setup(&env))
 		goto fail;

-	/* Step 1: Run the setup SYSCALL prog to create the ksock */
+	/* Step 1: Create, bind, and connect the ksock from the SYSCALL prog. */
 	skel->bss->ipv4_remote = htonl(INADDR_LOOPBACK);
 	skel->bss->remote_port = RECV_PORT;
+	skel->bss->local_port = LOCAL_KSOCK_PORT;
 	err = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.ksock_setup),
 				     &opts);
 	if (!ASSERT_OK(err, "ksock_setup run"))
@@ -108,10 +112,18 @@ void test_ksock_lsm(void)
 		       "LSM send bytes"))
 		goto fail;

-	n = recvfrom(env.rfd, recv_data, sizeof(recv_data), 0, NULL, NULL);
-	if (ASSERT_EQ(n, sizeof(recv_data), "recvfrom len"))
-		ASSERT_MEMEQ(recv_data, skel->data->send_data, sizeof(recv_data),
-			     "payload match");
+	n = recvfrom(env.rfd, recv_data, sizeof(recv_data), MSG_TRUNC,
+		     (struct sockaddr *)&src_addr, &src_addrlen);
+	if (!ASSERT_EQ(n, sizeof(recv_data), "recvfrom len"))
+		goto fail;
+	if (!ASSERT_EQ(ntohs(src_addr.sin_port), LOCAL_KSOCK_PORT,
+		       "source address port"))
+		goto fail;
+	if (!ASSERT_EQ(ntohl(src_addr.sin_addr.s_addr), INADDR_LOOPBACK + 1,
+		       "source address ip"))
+		goto fail;
+	ASSERT_MEMEQ(recv_data, skel->data->send_data, sizeof(recv_data),
+		     "payload match");

 fail:
 	if (tfd >= 0)
diff --git a/tools/testing/selftests/bpf/progs/ksock_common.h b/tools/testing/selftests/bpf/progs/ksock_common.h
index 2a32cff2fbe9..87321f4ba4f5 100644
--- a/tools/testing/selftests/bpf/progs/ksock_common.h
+++ b/tools/testing/selftests/bpf/progs/ksock_common.h
@@ -11,6 +11,8 @@

 struct bpf_ksock *bpf_ksock_create(const struct bpf_ksock_create_opts *opts,
 				   u32 opts__sz, int *err__uninit) __ksym;
+int bpf_ksock_bind(struct bpf_ksock *ks, const union bpf_ksock_addr *addr,
+		   u32 addr__sz) __ksym;
 int bpf_ksock_connect(struct bpf_ksock *ks, const union bpf_ksock_addr *addr,
 		      u32 addr__sz) __ksym;
 struct bpf_ksock *bpf_ksock_acquire(struct bpf_ksock *ks) __ksym;
diff --git a/tools/testing/selftests/bpf/progs/ksock_lsm.c b/tools/testing/selftests/bpf/progs/ksock_lsm.c
index 9808451098ef..28da777eea6c 100644
--- a/tools/testing/selftests/bpf/progs/ksock_lsm.c
+++ b/tools/testing/selftests/bpf/progs/ksock_lsm.c
@@ -10,6 +10,7 @@

 char send_data[32] = "hello from bpf ksock";

+__u16 local_port;
 __be32 ipv4_remote;
 __u16 remote_port;
 int target_pid;
@@ -32,19 +33,28 @@ int ksock_setup(void *ctx)
 		return err;

 	addr.sin.sin_family = AF_INET;
+	addr.sin.sin_port = bpf_htons(local_port);
+	addr.sin.sin_addr.s_addr = bpf_htonl(0x7f000002); /* 127.0.0.2 */
+
+	err = bpf_ksock_bind(ks, &addr, sizeof(addr));
+	if (err)
+		goto err_release;
+
 	addr.sin.sin_port = bpf_htons(remote_port);
 	addr.sin.sin_addr.s_addr = ipv4_remote;

 	err = bpf_ksock_connect(ks, &addr, sizeof(addr));
-	if (err) {
-		bpf_ksock_release(ks);
-		return err;
-	}
+	if (err)
+		goto err_release;

 	err = ksock_ctx_insert(ks);
 	if (err && err != -EEXIST)
 		return err;
 	return 0;
+
+err_release:
+	bpf_ksock_release(ks);
+	return err;
 }

 SEC("lsm.s/socket_bind")
--
2.43.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-10-26 19:03 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-26 19:03 [PATCH bpf-next v2 1/2] bpf: Add bpf_ksock_bind() kfunc Mahe Tardy
2026-10-26 19:03 ` [PATCH bpf-next v2 2/2] selftests/bpf: Test " Mahe Tardy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox