BPF List
 help / color / mirror / Atom feed
* [PATCH bpf-next 0/8] bpf: Expand ksock send-path support
@ 2026-10-20 10:25 Mahe Tardy
  2026-10-20 10:25 ` [PATCH bpf-next 1/8] bpf: improve ksock_kfunc_set LSM recursion filter Mahe Tardy
                   ` (8 more replies)
  0 siblings, 9 replies; 15+ messages in thread
From: Mahe Tardy @ 2026-10-20 10:25 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

This patch series improves the bpf_ksock infrastructure in line with the
work proposed during Prague Plumbers 2026 presentation[^1]:
* refine the LSM verifier filter
* allow bpf_ksock_connect() to be called in the send path
* add bpf_ksock_sendto() kfunc to complement to bpf_ksock_send()

This is useful when using ksock to reply to differents peers while
reusing the same UDP socket and generally works toward the goal of ksock
to support the basic socket operations.

[^1]: https://lpc.events/event/20/contributions/2430/

Mahe Tardy (8):
  bpf: improve ksock_kfunc_set LSM recursion filter
  selftests/bpf: Test allowed bpf_ksock operations at send LSM attach
  bpf: move ksock_connect() out of init kfunc set
  selftests/bpf: Test verifier filter for ksock connect on LSM attach
  selftests/bpf: Test ksock connect/send combinations
  bpf: add bpf_ksock_sendto() kfunc
  selftests/bpf: Test forbidden bpf_ksock_sendto() LSM attach
  selftests/bpf: Test ksock sendto()

 net/core/bpf_ksock.c                          | 129 +++++++++++++-----
 .../testing/selftests/bpf/prog_tests/ksock.c  |  53 +++++--
 .../selftests/bpf/prog_tests/ksock_sendto.c   | 108 +++++++++++++++
 .../selftests/bpf/progs/ksock_common.h        |   2 +
 tools/testing/selftests/bpf/progs/ksock_lsm.c |  32 +++--
 .../selftests/bpf/progs/ksock_lsm_verifier.c  |  98 ++++++++++++-
 .../selftests/bpf/progs/ksock_sendto.c        |  59 ++++++++
 7 files changed, 432 insertions(+), 49 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/ksock_sendto.c
 create mode 100644 tools/testing/selftests/bpf/progs/ksock_sendto.c

--
2.43.0


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

* [PATCH bpf-next 1/8] bpf: improve ksock_kfunc_set LSM recursion filter
  2026-10-20 10:25 [PATCH bpf-next 0/8] bpf: Expand ksock send-path support Mahe Tardy
@ 2026-10-20 10:25 ` Mahe Tardy
  2026-10-20 10:25 ` [PATCH bpf-next 2/8] selftests/bpf: Test allowed bpf_ksock operations at send LSM attach Mahe Tardy
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Mahe Tardy @ 2026-10-20 10:25 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

Improves '7ae4eb14c5f9 ("bpf: Add ksock kfuncs")' verifier filter to
avoid recursion from calling bpf_ksock_send() from the
security_socket_sendmsg() LSM hooks. The filter was unnecessarily
restrictive, this makes sure only bpf_ksock_send() is forbidden and not
the bpf_ksock_acquire() and bpf_ksock_release() kfuncs that are part of
the same set but are safe to be called in that context.

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

diff --git a/net/core/bpf_ksock.c b/net/core/bpf_ksock.c
index 48a2e2327ace..6c508c7a0adc 100644
--- a/net/core/bpf_ksock.c
+++ b/net/core/bpf_ksock.c
@@ -264,6 +264,7 @@ BTF_ID(func, bpf_lsm_socket_sendmsg)
 #else
 BTF_ID_UNUSED
 #endif
+BTF_ID_LIST_SINGLE(bpf_ksock_send_id, func, bpf_ksock_send)
 #endif

 static int bpf_ksock_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id)
@@ -275,9 +276,13 @@ static int bpf_ksock_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id)
 		return 0;

 #ifdef CONFIG_BPF_LSM
-	if (prog->type == BPF_PROG_TYPE_LSM &&
-	    prog->aux->attach_btf_id != bpf_lsm_socket_sendmsg_id[0])
+	if (prog->type == BPF_PROG_TYPE_LSM) {
+		if (prog->aux->attach_btf_id == bpf_lsm_socket_sendmsg_id[0] &&
+		    kfunc_id == bpf_ksock_send_id[0])
+			return -EACCES;
+
 		return 0;
+	}
 #endif

 	return -EACCES;
--
2.43.0


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

* [PATCH bpf-next 2/8] selftests/bpf: Test allowed bpf_ksock operations at send LSM attach
  2026-10-20 10:25 [PATCH bpf-next 0/8] bpf: Expand ksock send-path support Mahe Tardy
  2026-10-20 10:25 ` [PATCH bpf-next 1/8] bpf: improve ksock_kfunc_set LSM recursion filter Mahe Tardy
@ 2026-10-20 10:25 ` Mahe Tardy
  2026-10-20 10:52   ` bot+bpf-ci
  2026-10-20 10:25 ` [PATCH bpf-next 3/8] bpf: move ksock_connect() out of init kfunc set Mahe Tardy
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 15+ messages in thread
From: Mahe Tardy @ 2026-10-20 10:25 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

This test makes sure that bpf_ksock_acquire() and bpf_ksock_release()
can be called from programs attached to ksock_socket_sendmsg().

Signed-off-by: Mahe Tardy <mahe.tardy@gmail.com>
---
 .../selftests/bpf/progs/ksock_lsm_verifier.c  | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c b/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c
index fd2ccfdb5802..740ed370d28f 100644
--- a/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c
+++ b/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c
@@ -12,7 +12,7 @@ char send_data[11] = "dummy data";
 SEC("lsm.s/socket_sendmsg")
 __description("bpf_ksock_send is rejected from socket_sendmsg LSM hook")
 __failure __msg("calling kernel function bpf_ksock_send is not allowed")
-int BPF_PROG(ksock_socket_sendmsg, struct socket *sock, struct msghdr *msg,
+int BPF_PROG(socket_sendmsg_ksock_send, struct socket *sock, struct msghdr *msg,
 	     int size, int ret)
 {
 	struct __ksock_ctx_value *v;
@@ -32,4 +32,21 @@ int BPF_PROG(ksock_socket_sendmsg, struct socket *sock, struct msghdr *msg,
 	return ret;
 }

+SEC("lsm.s/socket_sendmsg")
+__description("bpf_ksock operations other than send are allowed from socket_sendmsg LSM hook")
+__success
+int BPF_PROG(socket_sendmsg_ksock_allowed, struct socket *sock,
+	     struct msghdr *msg, int size, int ret)
+{
+	struct bpf_ksock *ks;
+
+	ks = ksock_ctx_get();
+	if (!ks)
+		return ret;
+
+	bpf_ksock_release(ks);
+	return ret;
+}
+
+
 char __license[] SEC("license") = "GPL";
--
2.43.0


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

* [PATCH bpf-next 3/8] bpf: move ksock_connect() out of init kfunc set
  2026-10-20 10:25 [PATCH bpf-next 0/8] bpf: Expand ksock send-path support Mahe Tardy
  2026-10-20 10:25 ` [PATCH bpf-next 1/8] bpf: improve ksock_kfunc_set LSM recursion filter Mahe Tardy
  2026-10-20 10:25 ` [PATCH bpf-next 2/8] selftests/bpf: Test allowed bpf_ksock operations at send LSM attach Mahe Tardy
@ 2026-10-20 10:25 ` Mahe Tardy
  2026-10-20 10:25 ` [PATCH bpf-next 4/8] selftests/bpf: Test verifier filter for ksock connect on LSM attach Mahe Tardy
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Mahe Tardy @ 2026-10-20 10:25 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

This allows to ksock_send() to various destinations by allowing to call
ksock_connect() in the send path instead of initializing it once for all
in the SYSCALL program. It was limiting in cases ksock was used to reply
to specific destinations.

We need to break this potential cycle between the two LSM hooks and BPF
programs calling kfuncs triggering themselves:

socket_sendmsg program
  bpf_ksock_connect()
    connect_socket() -> security_socket_connect()
      socket_connect program
	bpf_ksock_send()
          kernel_sendmsg() -> sock_sendmsg() -> __sock_sendmsg()
            security_socket_sendmsg()
              socket_sendmsg program

Breaking this on one edge is sufficient, so in this commit we prevent
bpf_ksock_connect() to be called from LSM programs attached to the
security_socket_sendmsg() hook.

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

diff --git a/net/core/bpf_ksock.c b/net/core/bpf_ksock.c
index 6c508c7a0adc..87329c4a2f8e 100644
--- a/net/core/bpf_ksock.c
+++ b/net/core/bpf_ksock.c
@@ -144,7 +144,7 @@ bpf_ksock_create(const struct bpf_ksock_create_opts *opts, u32 opts__sz,
  * Connects the socket to the specified remote address and port.
  *
  * This function may sleep while connecting the socket, so it can only be used
- * in sleepable BPF programs (SYSCALL).
+ * in sleepable BPF programs.
  *
  * Return: 0 on success, negative errno on error.
  */
@@ -243,7 +243,6 @@ __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_KFUNCS_END(ksock_init_kfunc_btf_ids)

 static const struct btf_kfunc_id_set ksock_init_kfunc_set = {
@@ -254,6 +253,7 @@ static const struct btf_kfunc_id_set ksock_init_kfunc_set = {
 BTF_KFUNCS_START(ksock_kfunc_btf_ids)
 BTF_ID_FLAGS(func, bpf_ksock_release, KF_RELEASE)
 BTF_ID_FLAGS(func, bpf_ksock_acquire, KF_ACQUIRE | KF_RCU | KF_RET_NULL)
+BTF_ID_FLAGS(func, bpf_ksock_connect, KF_SLEEPABLE)
 BTF_ID_FLAGS(func, bpf_ksock_send, KF_SLEEPABLE)
 BTF_KFUNCS_END(ksock_kfunc_btf_ids)

@@ -265,6 +265,14 @@ BTF_ID(func, bpf_lsm_socket_sendmsg)
 BTF_ID_UNUSED
 #endif
 BTF_ID_LIST_SINGLE(bpf_ksock_send_id, func, bpf_ksock_send)
+
+BTF_ID_LIST(bpf_lsm_socket_connect_id)
+#ifdef CONFIG_SECURITY_NETWORK
+BTF_ID(func, bpf_lsm_socket_connect)
+#else
+BTF_ID_UNUSED
+#endif
+BTF_ID_LIST_SINGLE(bpf_ksock_connect_id, func, bpf_ksock_connect)
 #endif

 static int bpf_ksock_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id)
@@ -278,7 +286,17 @@ static int bpf_ksock_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id)
 #ifdef CONFIG_BPF_LSM
 	if (prog->type == BPF_PROG_TYPE_LSM) {
 		if (prog->aux->attach_btf_id == bpf_lsm_socket_sendmsg_id[0] &&
-		    kfunc_id == bpf_ksock_send_id[0])
+		    (kfunc_id == bpf_ksock_send_id[0] ||
+		    /*
+		     * Break the socket_sendmsg -> bpf_ksock_connect() ->
+		     * socket_connect -> bpf_ksock_send() -> socket_sendmsg'
+		     * cycle. Blocking this edge is enough.
+		     */
+		     kfunc_id == bpf_ksock_connect_id[0]))
+			return -EACCES;
+
+		if (prog->aux->attach_btf_id == bpf_lsm_socket_connect_id[0] &&
+		    kfunc_id == bpf_ksock_connect_id[0])
 			return -EACCES;

 		return 0;
--
2.43.0


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

* [PATCH bpf-next 4/8] selftests/bpf: Test verifier filter for ksock connect on LSM attach
  2026-10-20 10:25 [PATCH bpf-next 0/8] bpf: Expand ksock send-path support Mahe Tardy
                   ` (2 preceding siblings ...)
  2026-10-20 10:25 ` [PATCH bpf-next 3/8] bpf: move ksock_connect() out of init kfunc set Mahe Tardy
@ 2026-10-20 10:25 ` Mahe Tardy
  2026-10-20 10:25 ` [PATCH bpf-next 5/8] selftests/bpf: Test ksock connect/send combinations Mahe Tardy
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Mahe Tardy @ 2026-10-20 10:25 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

Tests that the verifier filter prevents bpf_ksock_connect() to be called
in a LSM program attached to security_socket_connect() as it would
create a direct recursion. Also checks that the other LSM hook unrelated
kfuncs can be called.

Moreover, checks that calling bpf_ksock_connect() is prevented also from
security_socket_sendmsg() as it would allow to create two BPF programs
that would call each other in a cycle through LSMs.

Signed-off-by: Mahe Tardy <mahe.tardy@gmail.com>
---
 .../selftests/bpf/progs/ksock_lsm_verifier.c  | 59 +++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c b/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c
index 740ed370d28f..7b5d118e5750 100644
--- a/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c
+++ b/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c
@@ -48,5 +48,64 @@ int BPF_PROG(socket_sendmsg_ksock_allowed, struct socket *sock,
 	return ret;
 }

+SEC("lsm.s/socket_sendmsg")
+__description("bpf_ksock_connect is rejected from socket_sendmsg LSM hook")
+__failure __msg("calling kernel function bpf_ksock_connect is not allowed")
+int BPF_PROG(socket_sendmsg_ksock_connect, struct socket *sock,
+	     struct msghdr *msg, int size, int ret)
+{
+	struct bpf_ksock *ks;
+	union bpf_ksock_addr addr = {};
+
+	ks = ksock_ctx_get();
+	if (!ks)
+		return ret;
+
+	bpf_ksock_connect(ks, &addr, sizeof(addr));
+	bpf_ksock_release(ks);
+	return ret;
+}
+
+SEC("lsm.s/socket_connect")
+__description("bpf_ksock_connect is rejected from socket_connect LSM hook")
+__failure __msg("calling kernel function bpf_ksock_connect is not allowed")
+int BPF_PROG(socket_connect_ksock_connect, struct socket *sock, struct sockaddr *address,
+	     int addrlen, int ret)
+{
+	struct __ksock_ctx_value *v;
+	union bpf_ksock_addr addr = {};
+	struct bpf_ksock *ks;
+
+	v = ksock_ctx_value_lookup();
+	if (!v)
+		return ret;
+
+	ks = bpf_kptr_xchg(&v->ctx, NULL);
+	if (!ks)
+		return ret;
+
+	bpf_ksock_connect(ks, &addr, sizeof(addr));
+	bpf_ksock_release(ks);
+
+	return ret;
+}
+
+SEC("lsm.s/socket_connect")
+__description("bpf_ksock operations other than connect are allowed from socket_connect LSM hook")
+__success
+int BPF_PROG(socket_connect_ksock_allowed, struct socket *sock,
+	     struct sockaddr *address, int addrlen, int ret)
+{
+	struct bpf_ksock *ks;
+
+	ks = ksock_ctx_get();
+	if (!ks)
+		return ret;
+
+	bpf_ksock_send(ks, send_data, sizeof(send_data));
+	bpf_ksock_release(ks);
+
+	return ret;
+}

 char __license[] SEC("license") = "GPL";
--
2.43.0


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

* [PATCH bpf-next 5/8] selftests/bpf: Test ksock connect/send combinations
  2026-10-20 10:25 [PATCH bpf-next 0/8] bpf: Expand ksock send-path support Mahe Tardy
                   ` (3 preceding siblings ...)
  2026-10-20 10:25 ` [PATCH bpf-next 4/8] selftests/bpf: Test verifier filter for ksock connect on LSM attach Mahe Tardy
@ 2026-10-20 10:25 ` Mahe Tardy
  2026-10-20 10:25 ` [PATCH bpf-next 6/8] bpf: add bpf_ksock_sendto() kfunc Mahe Tardy
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Mahe Tardy @ 2026-10-20 10:25 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

Tests more consistently that calling bpf_ksock_send() from unconnected
ksock socket fails and that bpf_ksock_connect() can be called from the
SYSCALL program creating the socket or from the LSM program also calling
bpf_ksock_send().

Signed-off-by: Mahe Tardy <mahe.tardy@gmail.com>
---
 .../testing/selftests/bpf/prog_tests/ksock.c  | 53 +++++++++++++++----
 tools/testing/selftests/bpf/progs/ksock_lsm.c | 32 ++++++++---
 2 files changed, 68 insertions(+), 17 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/ksock.c b/tools/testing/selftests/bpf/prog_tests/ksock.c
index dd6b167623d9..78677bfffdf3 100644
--- a/tools/testing/selftests/bpf/prog_tests/ksock.c
+++ b/tools/testing/selftests/bpf/prog_tests/ksock.c
@@ -17,6 +17,12 @@ struct ksock_test_env {
 	int rfd;
 };

+struct ksock_test_case {
+	const char *name;
+	bool connect_in_syscall;
+	bool connect_in_lsm;
+};
+
 static bool ksock_test_env_setup(struct ksock_test_env *env)
 {
 	struct sockaddr_in addr = {
@@ -55,16 +61,18 @@ static bool ksock_test_env_setup(struct ksock_test_env *env)
 	return false;
 }

-void test_ksock_lsm(void)
+static void test_ksock_lsm_case(const struct ksock_test_case *test)
 {
 	LIBBPF_OPTS(bpf_test_run_opts, opts);
-	struct ksock_test_env env;
 	struct sockaddr_in trigger_addr = {
 		.sin_family = AF_INET,
 		.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
 	};
+	struct ksock_test_env env;
 	struct ksock_lsm *skel;
 	char recv_data[sizeof(skel->data->send_data)] = {};
+	bool connected = test->connect_in_syscall || test->connect_in_lsm;
+	int expected_send_ret = connected ? (int)sizeof(skel->data->send_data) : -EDESTADDRREQ;
 	ssize_t n;
 	int tfd = -1;
 	int err;
@@ -79,6 +87,8 @@ void test_ksock_lsm(void)
 	/* Step 1: Run the setup SYSCALL prog to create the ksock */
 	skel->bss->ipv4_remote = htonl(INADDR_LOOPBACK);
 	skel->bss->remote_port = RECV_PORT;
+	skel->bss->connect_in_syscall = test->connect_in_syscall;
+	skel->bss->connect_in_lsm = test->connect_in_lsm;
 	err = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.ksock_setup),
 				     &opts);
 	if (!ASSERT_OK(err, "ksock_setup run"))
@@ -103,15 +113,25 @@ void test_ksock_lsm(void)
 	if (!ASSERT_OK(err, "trigger bind"))
 		goto fail;

-	/* Step 3: Verify the LSM hook sent the notification */
-	if (!ASSERT_EQ(skel->data->send_ret, sizeof(skel->data->send_data),
-		       "LSM send bytes"))
+	/* Step 3: Verify the operations and received notification, if any. */
+	if (!ASSERT_EQ(skel->data->connect_ret, connected ? 0 : -1, "connect retval"))
+		goto fail;
+
+	if (!ASSERT_EQ(skel->data->send_ret, expected_send_ret, "LSM send retval"))
+		goto fail;
+
+	n = recvfrom(env.rfd, recv_data, sizeof(recv_data),
+		     connected ? 0 : MSG_DONTWAIT, NULL, NULL);
+	if (!connected) {
+		if (ASSERT_EQ(n, -1, "no datagram"))
+			ASSERT_EQ(errno, EAGAIN, "recvfrom errno");
 		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");
+	if (!ASSERT_EQ(n, sizeof(recv_data), "recvfrom len") ||
+	    !ASSERT_MEMEQ(recv_data, skel->data->send_data, sizeof(recv_data),
+			  "payload match"))
+		goto fail;

 fail:
 	if (tfd >= 0)
@@ -124,6 +144,21 @@ void test_ksock_lsm(void)
 	ksock_lsm__destroy(skel);
 }

+void test_ksock_lsm(void)
+{
+	static const struct ksock_test_case tests[] = {
+		{ .name = "unconnected_send" },
+		{ .name = "syscall_connect_send", .connect_in_syscall = true },
+		{ .name = "lsm_connect_send", .connect_in_lsm = true },
+	};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(tests); i++) {
+		if (test__start_subtest(tests[i].name))
+			test_ksock_lsm_case(&tests[i]);
+	}
+}
+
 void test_ksock_lsm_verifier(void)
 {
 	RUN_TESTS(ksock_lsm_verifier);
diff --git a/tools/testing/selftests/bpf/progs/ksock_lsm.c b/tools/testing/selftests/bpf/progs/ksock_lsm.c
index 9808451098ef..944398ce2852 100644
--- a/tools/testing/selftests/bpf/progs/ksock_lsm.c
+++ b/tools/testing/selftests/bpf/progs/ksock_lsm.c
@@ -13,6 +13,9 @@ char send_data[32] = "hello from bpf ksock";
 __be32 ipv4_remote;
 __u16 remote_port;
 int target_pid;
+bool connect_in_syscall;
+bool connect_in_lsm;
+int connect_ret = -1;
 int send_ret = -1;

 SEC("syscall")
@@ -31,14 +34,15 @@ int ksock_setup(void *ctx)
 	if (!ks)
 		return err;

-	addr.sin.sin_family = AF_INET;
-	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 (connect_in_syscall) {
+		addr.sin.sin_family = AF_INET;
+		addr.sin.sin_port = bpf_htons(remote_port);
+		addr.sin.sin_addr.s_addr = ipv4_remote;
+		connect_ret = bpf_ksock_connect(ks, &addr, sizeof(addr));
+		if (connect_ret) {
+			bpf_ksock_release(ks);
+			return connect_ret;
+		}
 	}

 	err = ksock_ctx_insert(ks);
@@ -51,6 +55,7 @@ SEC("lsm.s/socket_bind")
 int BPF_PROG(ksock_socket_bind, struct socket *sock, struct sockaddr *address,
 	     int addrlen, int ret)
 {
+	union bpf_ksock_addr addr = {};
 	struct bpf_ksock *ks;
 	u32 pid = bpf_get_current_pid_tgid() >> 32;

@@ -63,7 +68,18 @@ int BPF_PROG(ksock_socket_bind, struct socket *sock, struct sockaddr *address,
 		return ret;
 	}

+	addr.sin.sin_family = AF_INET;
+	addr.sin.sin_port = bpf_htons(remote_port);
+	addr.sin.sin_addr.s_addr = ipv4_remote;
+
+	if (connect_in_lsm) {
+		connect_ret = bpf_ksock_connect(ks, &addr, sizeof(addr));
+		if (connect_ret)
+			goto out;
+	}
+
 	send_ret = bpf_ksock_send(ks, send_data, sizeof(send_data));
+out:
 	bpf_ksock_release(ks);

 	return ret;
--
2.43.0


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

* [PATCH bpf-next 6/8] bpf: add bpf_ksock_sendto() kfunc
  2026-10-20 10:25 [PATCH bpf-next 0/8] bpf: Expand ksock send-path support Mahe Tardy
                   ` (4 preceding siblings ...)
  2026-10-20 10:25 ` [PATCH bpf-next 5/8] selftests/bpf: Test ksock connect/send combinations Mahe Tardy
@ 2026-10-20 10:25 ` Mahe Tardy
  2026-10-20 10:25 ` [PATCH bpf-next 7/8] selftests/bpf: Test forbidden bpf_ksock_sendto() LSM attach Mahe Tardy
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Mahe Tardy @ 2026-10-20 10:25 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

The motivation is to plumb more of the socket API into ksock, thus
supporting sendto() in addition to send() which makes a lot of sense in
the context of UDP sockets which are the only type currently supported.
This is useful when ksock is used to reply to specific addresses or send
to multiple addresses.

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

diff --git a/net/core/bpf_ksock.c b/net/core/bpf_ksock.c
index 87329c4a2f8e..dda5aefb101e 100644
--- a/net/core/bpf_ksock.c
+++ b/net/core/bpf_ksock.c
@@ -37,6 +37,49 @@ static void ksock_release_work_fn(struct work_struct *work)
 	kfree(ks);
 }

+static int bpf_ksock_addr_to_sockaddr(const union bpf_ksock_addr *addr,
+				      u32 addr_sz, struct sockaddr_storage *sa)
+{
+	if (!addr || addr_sz != sizeof(*addr))
+		return -EINVAL;
+
+	/* Kfunc memory arguments may be unaligned. */
+	memcpy(sa, addr, sizeof(*addr));
+
+	switch (sa->ss_family) {
+	case AF_INET:
+		return sizeof(struct sockaddr_in);
+	case AF_INET6:
+		return sizeof(struct sockaddr_in6);
+	default:
+		return -EAFNOSUPPORT;
+	}
+}
+
+static int ksock_sendto(struct bpf_ksock *ks, const void *data, u32 data_sz,
+			const union bpf_ksock_addr *addr, u32 addr_sz)
+{
+	struct sockaddr_storage sa;
+	struct msghdr msg = {
+		.msg_flags = MSG_DONTWAIT,
+	};
+	struct kvec iov = {
+		.iov_base = (void *)data,
+		.iov_len = data_sz,
+	};
+	int addrlen;
+
+	if (addr) {
+		addrlen = bpf_ksock_addr_to_sockaddr(addr, addr_sz, &sa);
+		if (addrlen < 0)
+			return addrlen;
+		msg.msg_name = &sa;
+		msg.msg_namelen = addrlen;
+	}
+
+	return kernel_sendmsg(ks->sock, &msg, &iov, 1, data_sz);
+}
+
 __bpf_kfunc_start_defs();

 /**
@@ -155,22 +198,9 @@ __bpf_kfunc int bpf_ksock_connect(struct bpf_ksock *ks,
 	struct sockaddr_storage sa;
 	int addrlen;

-	if (!addr || addr__sz != sizeof(*addr))
-		return -EINVAL;
-
-	/* Kfunc memory arguments may be unaligned. */
-	memcpy(&sa, addr, sizeof(*addr));
-
-	switch (sa.ss_family) {
-	case AF_INET:
-		addrlen = sizeof(struct sockaddr_in);
-		break;
-	case AF_INET6:
-		addrlen = sizeof(struct sockaddr_in6);
-		break;
-	default:
-		return -EAFNOSUPPORT;
-	}
+	addrlen = bpf_ksock_addr_to_sockaddr(addr, addr__sz, &sa);
+	if (addrlen < 0)
+		return addrlen;

 	return connect_socket(ks->sock, &sa, addrlen, 0);
 }
@@ -225,18 +255,29 @@ CFI_NOSEAL(bpf_ksock_release_dtor);
 __bpf_kfunc int bpf_ksock_send(struct bpf_ksock *ks, const void *data,
 			       u32 data__sz)
 {
-	struct msghdr msg = {
-		.msg_flags = MSG_DONTWAIT,
-	};
-	struct kvec iov = {
-		.iov_base = (void *)data,
-		.iov_len = data__sz,
-	};
-	int ret;
-
-	ret = kernel_sendmsg(ks->sock, &msg, &iov, 1, data__sz);
+	return ksock_sendto(ks, data, data__sz, NULL, 0);
+}

-	return ret;
+/**
+ * bpf_ksock_sendto() - Send data through a BPF kernel socket to a remote address.
+ * @ks:		The BPF kernel socket context. Must be an acquired reference.
+ * @data:	Pointer to the data to send.
+ * @data__sz:	Size of the data to send.
+ * @addr__nullable: Pointer to an IPv4 or IPv6 socket address, or NULL to use
+ *		   the connected destination.
+ * @addr__sz:	Size of the address union, ignored when the address is NULL.
+ *
+ * Sends data to the specified address, or to the connected destination when
+ * the address is NULL, best-effort and nonblocking. This may sleep
+ * (kernel_sendmsg), so it can only be called from sleepable BPF programs.
+ *
+ * Return: Number of bytes sent on success, negative errno on error.
+ */
+__bpf_kfunc int bpf_ksock_sendto(struct bpf_ksock *ks, const void *data, u32 data__sz,
+				 const union bpf_ksock_addr *addr__nullable,
+				 u32 addr__sz)
+{
+	return ksock_sendto(ks, data, data__sz, addr__nullable, addr__sz);
 }

 __bpf_kfunc_end_defs();
@@ -255,6 +296,7 @@ BTF_ID_FLAGS(func, bpf_ksock_release, KF_RELEASE)
 BTF_ID_FLAGS(func, bpf_ksock_acquire, KF_ACQUIRE | KF_RCU | KF_RET_NULL)
 BTF_ID_FLAGS(func, bpf_ksock_connect, KF_SLEEPABLE)
 BTF_ID_FLAGS(func, bpf_ksock_send, KF_SLEEPABLE)
+BTF_ID_FLAGS(func, bpf_ksock_sendto, KF_SLEEPABLE)
 BTF_KFUNCS_END(ksock_kfunc_btf_ids)

 #ifdef CONFIG_BPF_LSM
@@ -265,6 +307,7 @@ BTF_ID(func, bpf_lsm_socket_sendmsg)
 BTF_ID_UNUSED
 #endif
 BTF_ID_LIST_SINGLE(bpf_ksock_send_id, func, bpf_ksock_send)
+BTF_ID_LIST_SINGLE(bpf_ksock_sendto_id, func, bpf_ksock_sendto)

 BTF_ID_LIST(bpf_lsm_socket_connect_id)
 #ifdef CONFIG_SECURITY_NETWORK
@@ -287,6 +330,7 @@ static int bpf_ksock_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id)
 	if (prog->type == BPF_PROG_TYPE_LSM) {
 		if (prog->aux->attach_btf_id == bpf_lsm_socket_sendmsg_id[0] &&
 		    (kfunc_id == bpf_ksock_send_id[0] ||
+		     kfunc_id == bpf_ksock_sendto_id[0] ||
 		    /*
 		     * Break the socket_sendmsg -> bpf_ksock_connect() ->
 		     * socket_connect -> bpf_ksock_send() -> socket_sendmsg'
--
2.43.0


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

* [PATCH bpf-next 7/8] selftests/bpf: Test forbidden bpf_ksock_sendto() LSM attach
  2026-10-20 10:25 [PATCH bpf-next 0/8] bpf: Expand ksock send-path support Mahe Tardy
                   ` (5 preceding siblings ...)
  2026-10-20 10:25 ` [PATCH bpf-next 6/8] bpf: add bpf_ksock_sendto() kfunc Mahe Tardy
@ 2026-10-20 10:25 ` Mahe Tardy
  2026-10-20 10:52   ` bot+bpf-ci
  2026-10-20 10:25 ` [PATCH bpf-next 8/8] selftests/bpf: Test ksock sendto() Mahe Tardy
  2026-10-20 15:07 ` [PATCH bpf-next 0/8] bpf: Expand ksock send-path support Alexei Starovoitov
  8 siblings, 1 reply; 15+ messages in thread
From: Mahe Tardy @ 2026-10-20 10:25 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

Similarly to '7b0dfbf5776b ("selftests/bpf: Test forbidden
bpf_ksock_send() LSM attach")', tests that the verifier filter prevents
bpf_ksock_sendto() to be called in a LSM program attached to
security_socket_sendmsg() as it would create a direct recursion.

Signed-off-by: Mahe Tardy <mahe.tardy@gmail.com>
---
 .../selftests/bpf/progs/ksock_lsm_verifier.c  | 22 ++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c b/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c
index 7b5d118e5750..82901c9e78c8 100644
--- a/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c
+++ b/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c
@@ -33,7 +33,26 @@ int BPF_PROG(socket_sendmsg_ksock_send, struct socket *sock, struct msghdr *msg,
 }

 SEC("lsm.s/socket_sendmsg")
-__description("bpf_ksock operations other than send are allowed from socket_sendmsg LSM hook")
+__description("bpf_ksock_sendto is rejected from socket_sendmsg LSM hook")
+__failure __msg("calling kernel function bpf_ksock_sendto is not allowed")
+int BPF_PROG(socket_sendmsg_ksock_sendto, struct socket *sock,
+	     struct msghdr *msg, int size, int ret)
+{
+	struct bpf_ksock *ks;
+
+	ks = ksock_ctx_get();
+	if (!ks)
+		return ret;
+
+	bpf_ksock_sendto(ks, send_data, sizeof(send_data), NULL, 0);
+	bpf_ksock_release(ks);
+
+	return ret;
+}
+
+
+SEC("lsm.s/socket_sendmsg")
+__description("bpf_ksock acquire and release are allowed from socket_sendmsg LSM hook")
 __success
 int BPF_PROG(socket_sendmsg_ksock_allowed, struct socket *sock,
 	     struct msghdr *msg, int size, int ret)
@@ -103,6 +122,7 @@ int BPF_PROG(socket_connect_ksock_allowed, struct socket *sock,
 		return ret;

 	bpf_ksock_send(ks, send_data, sizeof(send_data));
+	bpf_ksock_sendto(ks, send_data, sizeof(send_data), NULL, 0);
 	bpf_ksock_release(ks);

 	return ret;
--
2.43.0


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

* [PATCH bpf-next 8/8] selftests/bpf: Test ksock sendto()
  2026-10-20 10:25 [PATCH bpf-next 0/8] bpf: Expand ksock send-path support Mahe Tardy
                   ` (6 preceding siblings ...)
  2026-10-20 10:25 ` [PATCH bpf-next 7/8] selftests/bpf: Test forbidden bpf_ksock_sendto() LSM attach Mahe Tardy
@ 2026-10-20 10:25 ` Mahe Tardy
  2026-10-20 15:07 ` [PATCH bpf-next 0/8] bpf: Expand ksock send-path support Alexei Starovoitov
  8 siblings, 0 replies; 15+ messages in thread
From: Mahe Tardy @ 2026-10-20 10:25 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

These tests are covering that:
1. sendto() on a unconnected UDP socket works (and that the socket stays
   unconnected, i.e. send() on it fails with -EDESTADDRREQ).
2. sendto() on a connected UDP socket with a NULL address is equivalent
   to send().
3. sendto() on a connected socket with an explicit address doesn't
   change the peer of the socket (send() after sendto() still sends to
   the original connected address).

Signed-off-by: Mahe Tardy <mahe.tardy@gmail.com>
---
 .../selftests/bpf/prog_tests/ksock_sendto.c   | 108 ++++++++++++++++++
 .../selftests/bpf/progs/ksock_common.h        |   2 +
 .../selftests/bpf/progs/ksock_sendto.c        |  59 ++++++++++
 3 files changed, 169 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/ksock_sendto.c
 create mode 100644 tools/testing/selftests/bpf/progs/ksock_sendto.c

diff --git a/tools/testing/selftests/bpf/prog_tests/ksock_sendto.c b/tools/testing/selftests/bpf/prog_tests/ksock_sendto.c
new file mode 100644
index 000000000000..498f0e1be6ee
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/ksock_sendto.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2026 Isovalent */
+
+#include "test_progs.h"
+#include "network_helpers.h"
+#include "ksock_sendto.skel.h"
+
+struct sendto_test_case {
+	const char *name;
+	bool connected;
+	bool use_sendto_addr;
+};
+
+static bool recv_payload(int fd, const void *expected, size_t len)
+{
+	char buf[64];
+	ssize_t n;
+
+	n = recv(fd, buf, sizeof(buf), MSG_TRUNC);
+	if (!ASSERT_EQ(n, len, "recv length"))
+		return false;
+	return ASSERT_MEMEQ(buf, expected, len, "recv payload");
+}
+
+static void test_sendto_case(const struct sendto_test_case *test)
+{
+	LIBBPF_OPTS(bpf_test_run_opts, opts);
+	struct ksock_sendto *skel;
+	int receivers[2] = { -1, -1 };
+	int err, i, port, sendto_fd;
+	char buf[64];
+	ssize_t n;
+
+	skel = ksock_sendto__open_and_load();
+	if (!ASSERT_OK_PTR(skel, "ksock_sendto open and load"))
+		return;
+
+	/* Use separate receivers for the default peer and explicit destination. */
+	for (i = 0; i < ARRAY_SIZE(receivers); i++) {
+		receivers[i] = start_server(AF_INET, SOCK_DGRAM, "127.0.0.1", 0, 1000);
+		if (!ASSERT_OK_FD(receivers[i], "receiver socket"))
+			goto out;
+	}
+
+	port = get_socket_local_port(receivers[0]);
+	if (!ASSERT_GE(port, 0, "connected port"))
+		goto out;
+	skel->bss->connected_port = port;
+	port = get_socket_local_port(receivers[1]);
+	if (!ASSERT_GE(port, 0, "sendto port"))
+		goto out;
+	skel->bss->sendto_port = port;
+	skel->bss->connected = test->connected;
+	skel->bss->use_sendto_addr = test->use_sendto_addr;
+
+	err = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_sendto), &opts);
+	if (!ASSERT_OK(err, "run test_sendto") || !ASSERT_OK(opts.retval, "test_sendto retval"))
+		goto out;
+
+	/* Check sendto() outcome */
+	if (!ASSERT_EQ(skel->data->sendto_ret, sizeof(skel->data->sendto_data), "sendto bytes"))
+		goto out;
+	sendto_fd = receivers[test->use_sendto_addr ? 1 : 0];
+	if (!recv_payload(sendto_fd, skel->data->sendto_data, sizeof(skel->data->sendto_data)))
+		goto out;
+
+	/* Check send() outcome */
+	if (test->connected) {
+		if (!ASSERT_EQ(skel->data->send_ret, sizeof(skel->data->send_data), "send bytes"))
+			goto out;
+		if (!recv_payload(receivers[0], skel->data->send_data,
+				  sizeof(skel->data->send_data)))
+			goto out;
+	} else if (!ASSERT_EQ(skel->data->send_ret, -EDESTADDRREQ,
+			      "send after sendto remains unconnected")) {
+		goto out;
+	}
+
+	/* Catch unexpected deliveries to either destination. */
+	for (i = 0; i < ARRAY_SIZE(receivers); i++) {
+		n = recv(receivers[i], buf, sizeof(buf), MSG_DONTWAIT);
+		if (!ASSERT_EQ(n, -1, "no extra datagram") ||
+		    !ASSERT_EQ(errno, EAGAIN, "recv errno"))
+			goto out;
+	}
+
+out:
+	for (i = 0; i < ARRAY_SIZE(receivers); i++) {
+		if (receivers[i] >= 0)
+			close(receivers[i]);
+	}
+	ksock_sendto__destroy(skel);
+}
+
+void test_ksock_sendto(void)
+{
+	static const struct sendto_test_case tests[] = {
+		{ .name = "unconnected", .use_sendto_addr = true },
+		{ .name = "connected_null_addr", .connected = true },
+		{ .name = "connected_explicit_addr", .connected = true, .use_sendto_addr = true },
+	};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(tests); i++) {
+		if (test__start_subtest(tests[i].name))
+			test_sendto_case(&tests[i]);
+	}
+}
diff --git a/tools/testing/selftests/bpf/progs/ksock_common.h b/tools/testing/selftests/bpf/progs/ksock_common.h
index 01edaeb9fdd4..2a32cff2fbe9 100644
--- a/tools/testing/selftests/bpf/progs/ksock_common.h
+++ b/tools/testing/selftests/bpf/progs/ksock_common.h
@@ -16,6 +16,8 @@ int bpf_ksock_connect(struct bpf_ksock *ks, const union bpf_ksock_addr *addr,
 struct bpf_ksock *bpf_ksock_acquire(struct bpf_ksock *ks) __ksym;
 void bpf_ksock_release(struct bpf_ksock *ks) __ksym;
 int bpf_ksock_send(struct bpf_ksock *ks, const void *data, u32 data__sz) __ksym;
+int bpf_ksock_sendto(struct bpf_ksock *ks, const void *data, u32 data__sz,
+		     const union bpf_ksock_addr *addr__nullable, u32 addr__sz) __ksym;
 void bpf_rcu_read_lock(void) __ksym;
 void bpf_rcu_read_unlock(void) __ksym;

diff --git a/tools/testing/selftests/bpf/progs/ksock_sendto.c b/tools/testing/selftests/bpf/progs/ksock_sendto.c
new file mode 100644
index 000000000000..b6eacf277fcb
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/ksock_sendto.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2026 Isovalent */
+
+#include "vmlinux.h"
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_endian.h>
+#include "bpf_tracing_net.h"
+#include "ksock_common.h"
+
+char sendto_data[] = "hello from bpf sendto";
+char send_data[] = "hello from bpf send";
+
+__be16 connected_port;
+__be16 sendto_port;
+bool connected;
+bool use_sendto_addr;
+int sendto_ret = -1;
+int send_ret = -1;
+
+SEC("syscall")
+int test_sendto(void *ctx)
+{
+	struct bpf_ksock_create_opts opts = {
+		.family = AF_INET,
+		.type = SOCK_DGRAM,
+		.protocol = IPPROTO_UDP,
+	};
+	union bpf_ksock_addr addr = {};
+	struct bpf_ksock *ks;
+	int err = 0;
+
+	ks = bpf_ksock_create(&opts, sizeof(opts), &err);
+	if (!ks)
+		return err;
+
+	addr.sin.sin_family = AF_INET;
+	addr.sin.sin_addr.s_addr = bpf_htonl(0x7f000001);
+	if (connected) {
+		addr.sin.sin_port = connected_port;
+		err = bpf_ksock_connect(ks, &addr, sizeof(addr));
+		if (err)
+			goto out;
+	}
+
+	addr.sin.sin_port = sendto_port;
+	if (use_sendto_addr)
+		sendto_ret = bpf_ksock_sendto(ks, sendto_data, sizeof(sendto_data),
+					      &addr, sizeof(addr));
+	else
+		sendto_ret = bpf_ksock_sendto(ks, sendto_data, sizeof(sendto_data), NULL, 0);
+
+	/* sendto() must neither connect the socket nor change its default peer. */
+	send_ret = bpf_ksock_send(ks, send_data, sizeof(send_data));
+out:
+	bpf_ksock_release(ks);
+	return err;
+}
+
+char __license[] SEC("license") = "GPL";
--
2.43.0


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

* Re: [PATCH bpf-next 2/8] selftests/bpf: Test allowed bpf_ksock operations at send LSM attach
  2026-10-20 10:25 ` [PATCH bpf-next 2/8] selftests/bpf: Test allowed bpf_ksock operations at send LSM attach Mahe Tardy
@ 2026-10-20 10:52   ` bot+bpf-ci
  2026-10-20 11:06     ` Mahe Tardy
  0 siblings, 1 reply; 15+ messages in thread
From: bot+bpf-ci @ 2026-10-20 10:52 UTC (permalink / raw)
  To: mahe.tardy, 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, ast, andrii, daniel, martin.lau,
	eddyz87, yonghong.song, mason, ihor.solodrai

[-- Attachment #1: Type: text/plain, Size: 1489 bytes --]

> selftests/bpf: Test allowed bpf_ksock operations at send LSM attach

TL;DR: Commit message only: it names ksock_socket_sendmsg(), which isn't a
real function or hook and is renamed by this patch. Suggest naming the
socket_sendmsg LSM hook and mentioning the rename.

>     selftests/bpf: Test allowed bpf_ksock operations at send LSM attach
>
>     This test makes sure that bpf_ksock_acquire() and bpf_ksock_release()
>     can be called from programs attached to ksock_socket_sendmsg().
>
>     Signed-off-by: Mahe Tardy <mahe.tardy@gmail.com>

This isn't a bug, but is ksock_socket_sendmsg() the right name to use here?

There is no kernel function or LSM hook with that name.  It was the name of
the existing BPF program in ksock_lsm_verifier.c, and this same patch
renames that program:

-int BPF_PROG(ksock_socket_sendmsg, struct socket *sock, struct msghdr *msg,
+int BPF_PROG(socket_sendmsg_ksock_send, struct socket *sock, struct msghdr *msg,

so after the patch is applied the identifier in the changelog refers to
nothing.  The attach point is the socket_sendmsg LSM hook
(SEC("lsm.s/socket_sendmsg"), i.e. security_socket_sendmsg()).

Could the changelog name that hook instead, and also mention that the
existing program is renamed?


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/39408886865

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

* Re: [PATCH bpf-next 7/8] selftests/bpf: Test forbidden bpf_ksock_sendto() LSM attach
  2026-10-20 10:25 ` [PATCH bpf-next 7/8] selftests/bpf: Test forbidden bpf_ksock_sendto() LSM attach Mahe Tardy
@ 2026-10-20 10:52   ` bot+bpf-ci
  2026-10-20 11:08     ` Mahe Tardy
  0 siblings, 1 reply; 15+ messages in thread
From: bot+bpf-ci @ 2026-10-20 10:52 UTC (permalink / raw)
  To: mahe.tardy, 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, ast, andrii, daniel, martin.lau,
	eddyz87, yonghong.song, mason, ihor.solodrai

[-- Attachment #1: Type: text/plain, Size: 3566 bytes --]

> selftests/bpf: Test forbidden bpf_ksock_sendto() LSM attach

TL;DR:
- Selftest calls bpf_ksock_sendto() without a prototype until a later patch,
  so the test may not build or run here (bisectability)
- Double blank line nit

> diff --git a/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c b/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c
> --- a/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c
> +++ b/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c
> @@ -33,7 +33,26 @@ int BPF_PROG(socket_sendmsg_ksock_send, struct socket *sock, struct msghdr *msg,
>  }
>
>  SEC("lsm.s/socket_sendmsg")
> -__description("bpf_ksock operations other than send are allowed from socket_sendmsg LSM hook")
> +__description("bpf_ksock_sendto is rejected from socket_sendmsg LSM hook")
> +__failure __msg("calling kernel function bpf_ksock_sendto is not allowed")
> +int BPF_PROG(socket_sendmsg_ksock_sendto, struct socket *sock,
> +	     struct msghdr *msg, int size, int ret)
> +{
> +	struct bpf_ksock *ks;
> +
> +	ks = ksock_ctx_get();
> +	if (!ks)
> +		return ret;
> +
> +	bpf_ksock_sendto(ks, send_data, sizeof(send_data), NULL, 0);

Is there a BPF-side prototype for bpf_ksock_sendto() at this point in the
series?

ksock_common.h declares bpf_ksock_create(), bpf_ksock_connect(),
bpf_ksock_acquire(), bpf_ksock_release() and bpf_ksock_send() with __ksym,
and this patch only touches progs/ksock_lsm_verifier.c, so nothing declares
bpf_ksock_sendto().  vmlinux.h carries types only, not function prototypes.

With a recent clang this should be a call to an undeclared function, which
is an error.  With an older clang the call would be emitted as an undefined
external symbol without __ksym/BTF information, and libbpf would fail to
open or load the object.

Either way ksock_lsm_verifier.bpf.o, and therefore RUN_TESTS(ksock_lsm_verifier)
in prog_tests/ksock.c, would not build or run at this commit, which breaks
bisectability.

The declaration is only added by the later patch "selftests/bpf: Test ksock
sendto()" (65327a57ba55), which adds this to ksock_common.h:

  int bpf_ksock_sendto(struct bpf_ksock *ks, const void *data, u32 data__sz,
                       const union bpf_ksock_addr *addr__nullable,
                       u32 addr__sz) __ksym;

Could that declaration move into this patch, or this patch be reordered after
that one?

> +	bpf_ksock_release(ks);
> +
> +	return ret;
> +}
> +
> +

This isn't a bug, but there are two consecutive blank lines here after
socket_sendmsg_ksock_sendto(), while the other programs in this file are
separated by a single blank line (checkpatch --strict reports "Please don't
use multiple blank lines").  Could one of them be dropped?

> +SEC("lsm.s/socket_sendmsg")
> +__description("bpf_ksock acquire and release are allowed from socket_sendmsg LSM hook")
>  __success
>  int BPF_PROG(socket_sendmsg_ksock_allowed, struct socket *sock,
>  	     struct msghdr *msg, int size, int ret)

[ ... ]

> @@ -103,6 +122,7 @@ int BPF_PROG(socket_connect_ksock_allowed, struct socket *sock,
>  		return ret;
>
>  	bpf_ksock_send(ks, send_data, sizeof(send_data));
> +	bpf_ksock_sendto(ks, send_data, sizeof(send_data), NULL, 0);

This call to bpf_ksock_sendto() has the same missing-prototype problem
described above.

>  	bpf_ksock_release(ks);
>
>  	return ret;


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/39408886865

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

* Re: [PATCH bpf-next 2/8] selftests/bpf: Test allowed bpf_ksock operations at send LSM attach
  2026-10-20 10:52   ` bot+bpf-ci
@ 2026-10-20 11:06     ` Mahe Tardy
  0 siblings, 0 replies; 15+ messages in thread
From: Mahe Tardy @ 2026-10-20 11:06 UTC (permalink / raw)
  To: bot+bpf-ci
  Cc: bpf, 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, martin.lau, mason, ihor.solodrai

On Tue, Oct 20, 2026 at 10:52:15AM +0000, bot+bpf-ci@kernel.org wrote:
> > selftests/bpf: Test allowed bpf_ksock operations at send LSM attach
> 
> TL;DR: Commit message only: it names ksock_socket_sendmsg(), which isn't a
> real function or hook and is renamed by this patch. Suggest naming the
> socket_sendmsg LSM hook and mentioning the rename.
> 
> >     selftests/bpf: Test allowed bpf_ksock operations at send LSM attach
> >
> >     This test makes sure that bpf_ksock_acquire() and bpf_ksock_release()
> >     can be called from programs attached to ksock_socket_sendmsg().
> >
> >     Signed-off-by: Mahe Tardy <mahe.tardy@gmail.com>
> 
> This isn't a bug, but is ksock_socket_sendmsg() the right name to use here?
> 
> There is no kernel function or LSM hook with that name.  It was the name of
> the existing BPF program in ksock_lsm_verifier.c, and this same patch
> renames that program:
> 
> -int BPF_PROG(ksock_socket_sendmsg, struct socket *sock, struct msghdr *msg,
> +int BPF_PROG(socket_sendmsg_ksock_send, struct socket *sock, struct msghdr *msg,
> 
> so after the patch is applied the identifier in the changelog refers to
> nothing.  The attach point is the socket_sendmsg LSM hook
> (SEC("lsm.s/socket_sendmsg"), i.e. security_socket_sendmsg()).
> 
> Could the changelog name that hook instead, and also mention that the
> existing program is renamed?

Yeah I made that typo in another patch and spotted it before sending but
missed it here, some confusion between the security hook on sendmsg and
the ksock kfunc.

Will fix it in next version.

> 
> 
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
> 
> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/39408886865


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

* Re: [PATCH bpf-next 7/8] selftests/bpf: Test forbidden bpf_ksock_sendto() LSM attach
  2026-10-20 10:52   ` bot+bpf-ci
@ 2026-10-20 11:08     ` Mahe Tardy
  0 siblings, 0 replies; 15+ messages in thread
From: Mahe Tardy @ 2026-10-20 11:08 UTC (permalink / raw)
  To: bot+bpf-ci
  Cc: bpf, 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, martin.lau, mason, ihor.solodrai

On Tue, Oct 20, 2026 at 10:52:16AM +0000, bot+bpf-ci@kernel.org wrote:
> > selftests/bpf: Test forbidden bpf_ksock_sendto() LSM attach
> 
> TL;DR:
> - Selftest calls bpf_ksock_sendto() without a prototype until a later patch,
>   so the test may not build or run here (bisectability)
> - Double blank line nit
> 
> > diff --git a/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c b/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c
> > --- a/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c
> > +++ b/tools/testing/selftests/bpf/progs/ksock_lsm_verifier.c
> > @@ -33,7 +33,26 @@ int BPF_PROG(socket_sendmsg_ksock_send, struct socket *sock, struct msghdr *msg,
> >  }
> >
> >  SEC("lsm.s/socket_sendmsg")
> > -__description("bpf_ksock operations other than send are allowed from socket_sendmsg LSM hook")
> > +__description("bpf_ksock_sendto is rejected from socket_sendmsg LSM hook")
> > +__failure __msg("calling kernel function bpf_ksock_sendto is not allowed")
> > +int BPF_PROG(socket_sendmsg_ksock_sendto, struct socket *sock,
> > +	     struct msghdr *msg, int size, int ret)
> > +{
> > +	struct bpf_ksock *ks;
> > +
> > +	ks = ksock_ctx_get();
> > +	if (!ks)
> > +		return ret;
> > +
> > +	bpf_ksock_sendto(ks, send_data, sizeof(send_data), NULL, 0);
> 
> Is there a BPF-side prototype for bpf_ksock_sendto() at this point in the
> series?
> 
> ksock_common.h declares bpf_ksock_create(), bpf_ksock_connect(),
> bpf_ksock_acquire(), bpf_ksock_release() and bpf_ksock_send() with __ksym,
> and this patch only touches progs/ksock_lsm_verifier.c, so nothing declares
> bpf_ksock_sendto().  vmlinux.h carries types only, not function prototypes.
> 
> With a recent clang this should be a call to an undeclared function, which
> is an error.  With an older clang the call would be emitted as an undefined
> external symbol without __ksym/BTF information, and libbpf would fail to
> open or load the object.
> 
> Either way ksock_lsm_verifier.bpf.o, and therefore RUN_TESTS(ksock_lsm_verifier)
> in prog_tests/ksock.c, would not build or run at this commit, which breaks
> bisectability.
> 
> The declaration is only added by the later patch "selftests/bpf: Test ksock
> sendto()" (65327a57ba55), which adds this to ksock_common.h:
> 
>   int bpf_ksock_sendto(struct bpf_ksock *ks, const void *data, u32 data__sz,
>                        const union bpf_ksock_addr *addr__nullable,
>                        u32 addr__sz) __ksym;
> 
> Could that declaration move into this patch, or this patch be reordered after
> that one?

Yeah I re-ordered the last two patches last minute and forgot about
this.

> 
> > +	bpf_ksock_release(ks);
> > +
> > +	return ret;
> > +}
> > +
> > +
> 
> This isn't a bug, but there are two consecutive blank lines here after
> socket_sendmsg_ksock_sendto(), while the other programs in this file are
> separated by a single blank line (checkpatch --strict reports "Please don't
> use multiple blank lines").  Could one of them be dropped?

sure.

> 
> > +SEC("lsm.s/socket_sendmsg")
> > +__description("bpf_ksock acquire and release are allowed from socket_sendmsg LSM hook")
> >  __success
> >  int BPF_PROG(socket_sendmsg_ksock_allowed, struct socket *sock,
> >  	     struct msghdr *msg, int size, int ret)
> 
> [ ... ]
> 
> > @@ -103,6 +122,7 @@ int BPF_PROG(socket_connect_ksock_allowed, struct socket *sock,
> >  		return ret;
> >
> >  	bpf_ksock_send(ks, send_data, sizeof(send_data));
> > +	bpf_ksock_sendto(ks, send_data, sizeof(send_data), NULL, 0);
> 
> This call to bpf_ksock_sendto() has the same missing-prototype problem
> described above.
> 
> >  	bpf_ksock_release(ks);
> >
> >  	return ret;
> 
> 
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
> 
> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/39408886865


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

* Re: [PATCH bpf-next 0/8] bpf: Expand ksock send-path support
  2026-10-20 10:25 [PATCH bpf-next 0/8] bpf: Expand ksock send-path support Mahe Tardy
                   ` (7 preceding siblings ...)
  2026-10-20 10:25 ` [PATCH bpf-next 8/8] selftests/bpf: Test ksock sendto() Mahe Tardy
@ 2026-10-20 15:07 ` Alexei Starovoitov
  2026-10-20 15:47   ` Mahe Tardy
  8 siblings, 1 reply; 15+ messages in thread
From: Alexei Starovoitov @ 2026-10-20 15:07 UTC (permalink / raw)
  To: Mahe Tardy, bpf
  Cc: andrii, daniel, davem, willemb, eddyz87, edumazet, john.fastabend,
	kuba, horms, liamwisehart, martin.lau, pabeni, song, netdev,
	sdf.kernel, yonghong.song, jolsa, kuniyu, memxor, emil, almagui

On Tue, Oct 20, 2026 at 03:25 AM Mahe Tardy <mahe.tardy@gmail.com> wrote:
> * allow bpf_ksock_connect() to be called in the send path
> * add bpf_ksock_sendto() kfunc to complement to bpf_ksock_send()
>
> This is useful when using ksock to reply to differents peers while
> reusing the same UDP socket and generally works toward the goal of ksock
> to support the basic socket operations.

can we drop connect from LSM progs and patches 1-5 altogether ?
bpf_ksock_sendto() alone replies to different peers on one socket.

connect + send from LSM progs can't do that reliably. The socket is
shared through the kptr and sleepable progs run concurrently. Between
bpf_ksock_connect(A) and bpf_ksock_send() on one CPU, another CPU does
bpf_ksock_connect(B) and the datagram for A goes to B.

Without connect there, acquire/release in socket_sendmsg has no user:
nothing can be done with that reference. bpf_ksock_sendto() is in
ksock_kfunc_btf_ids, so the current filter rejects it in socket_sendmsg
already. Then no need for bpf_ksock_send_id, bpf_ksock_sendto_id,
bpf_ksock_connect_id, bpf_lsm_socket_connect_id and the cycle comment.

Selftests are left out below. Patch 8 stays as is, patch 7 stays
without the socket_connect hunk.

Something like this (compile tested only):

diff --git a/net/core/bpf_ksock.c b/net/core/bpf_ksock.c
index 48a2e23..48757dc 100644
--- a/net/core/bpf_ksock.c
+++ b/net/core/bpf_ksock.c
@@ -37,6 +37,25 @@ static void ksock_release_work_fn(struct work_struct *work)
 	kfree(ks);
 }

+static int bpf_ksock_addr_to_sockaddr(const union bpf_ksock_addr *addr,
+				      u32 addr_sz, struct sockaddr_storage *sa)
+{
+	if (!addr || addr_sz != sizeof(*addr))
+		return -EINVAL;
+
+	/* Kfunc memory arguments may be unaligned. */
+	memcpy(sa, addr, sizeof(*addr));
+
+	switch (sa->ss_family) {
+	case AF_INET:
+		return sizeof(struct sockaddr_in);
+	case AF_INET6:
+		return sizeof(struct sockaddr_in6);
+	default:
+		return -EAFNOSUPPORT;
+	}
+}
+
 __bpf_kfunc_start_defs();

 /**
@@ -155,22 +174,9 @@ __bpf_kfunc int bpf_ksock_connect(struct bpf_ksock *ks,
 	struct sockaddr_storage sa;
 	int addrlen;

-	if (!addr || addr__sz != sizeof(*addr))
-		return -EINVAL;
-
-	/* Kfunc memory arguments may be unaligned. */
-	memcpy(&sa, addr, sizeof(*addr));
-
-	switch (sa.ss_family) {
-	case AF_INET:
-		addrlen = sizeof(struct sockaddr_in);
-		break;
-	case AF_INET6:
-		addrlen = sizeof(struct sockaddr_in6);
-		break;
-	default:
-		return -EAFNOSUPPORT;
-	}
+	addrlen = bpf_ksock_addr_to_sockaddr(addr, addr__sz, &sa);
+	if (addrlen < 0)
+		return addrlen;

 	return connect_socket(ks->sock, &sa, addrlen, 0);
 }
@@ -212,19 +218,25 @@ __bpf_kfunc void bpf_ksock_release_dtor(void *ks)
 CFI_NOSEAL(bpf_ksock_release_dtor);

 /**
- * bpf_ksock_send() - Send data through a BPF kernel socket.
+ * bpf_ksock_sendto() - Send data through a BPF kernel socket to a remote address.
  * @ks:		The BPF kernel socket context. Must be an acquired reference.
  * @data:	Pointer to the data to send.
  * @data__sz:	Size of the data to send.
+ * @addr__nullable: Pointer to an IPv4 or IPv6 socket address, or NULL to use
+ *		   the connected destination.
+ * @addr__sz:	Size of the address union, ignored when the address is NULL.
  *
- * Sends data on a connected socket, best-effort and nonblocking. This may sleep
+ * Sends data to the specified address, or to the connected destination when
+ * the address is NULL, best-effort and nonblocking. This may sleep
  * (kernel_sendmsg), so it can only be called from sleepable BPF programs.
  *
  * Return: Number of bytes sent on success, negative errno on error.
  */
-__bpf_kfunc int bpf_ksock_send(struct bpf_ksock *ks, const void *data,
-			       u32 data__sz)
+__bpf_kfunc int bpf_ksock_sendto(struct bpf_ksock *ks, const void *data, u32 data__sz,
+				 const union bpf_ksock_addr *addr__nullable,
+				 u32 addr__sz)
 {
+	struct sockaddr_storage sa;
 	struct msghdr msg = {
 		.msg_flags = MSG_DONTWAIT,
 	};
@@ -232,11 +244,34 @@ __bpf_kfunc int bpf_ksock_send(struct bpf_ksock *ks, const void *data,
 		.iov_base = (void *)data,
 		.iov_len = data__sz,
 	};
-	int ret;
+	int addrlen;

-	ret = kernel_sendmsg(ks->sock, &msg, &iov, 1, data__sz);
+	if (addr__nullable) {
+		addrlen = bpf_ksock_addr_to_sockaddr(addr__nullable, addr__sz, &sa);
+		if (addrlen < 0)
+			return addrlen;
+		msg.msg_name = &sa;
+		msg.msg_namelen = addrlen;
+	}

-	return ret;
+	return kernel_sendmsg(ks->sock, &msg, &iov, 1, data__sz);
+}
+
+/**
+ * bpf_ksock_send() - Send data through a BPF kernel socket.
+ * @ks:		The BPF kernel socket context. Must be an acquired reference.
+ * @data:	Pointer to the data to send.
+ * @data__sz:	Size of the data to send.
+ *
+ * Sends data on a connected socket, best-effort and nonblocking. This may sleep
+ * (kernel_sendmsg), so it can only be called from sleepable BPF programs.
+ *
+ * Return: Number of bytes sent on success, negative errno on error.
+ */
+__bpf_kfunc int bpf_ksock_send(struct bpf_ksock *ks, const void *data,
+			       u32 data__sz)
+{
+	return bpf_ksock_sendto(ks, data, data__sz, NULL, 0);
 }

 __bpf_kfunc_end_defs();
@@ -255,6 +290,7 @@ BTF_KFUNCS_START(ksock_kfunc_btf_ids)
 BTF_ID_FLAGS(func, bpf_ksock_release, KF_RELEASE)
 BTF_ID_FLAGS(func, bpf_ksock_acquire, KF_ACQUIRE | KF_RCU | KF_RET_NULL)
 BTF_ID_FLAGS(func, bpf_ksock_send, KF_SLEEPABLE)
+BTF_ID_FLAGS(func, bpf_ksock_sendto, KF_SLEEPABLE)
 BTF_KFUNCS_END(ksock_kfunc_btf_ids)

 #ifdef CONFIG_BPF_LSM

pw-bot: cr

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

* Re: [PATCH bpf-next 0/8] bpf: Expand ksock send-path support
  2026-10-20 15:07 ` [PATCH bpf-next 0/8] bpf: Expand ksock send-path support Alexei Starovoitov
@ 2026-10-20 15:47   ` Mahe Tardy
  0 siblings, 0 replies; 15+ messages in thread
From: Mahe Tardy @ 2026-10-20 15:47 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: bpf, andrii, daniel, davem, willemb, eddyz87, edumazet,
	john.fastabend, kuba, horms, liamwisehart, martin.lau, pabeni,
	song, netdev, sdf.kernel, yonghong.song, jolsa, kuniyu, memxor,
	emil, almagui

On Tue, Oct 20, 2026 at 03:07:31PM +0000, Alexei Starovoitov wrote:
> On Tue, Oct 20, 2026 at 03:25 AM Mahe Tardy <mahe.tardy@gmail.com> wrote:
> > * allow bpf_ksock_connect() to be called in the send path
> > * add bpf_ksock_sendto() kfunc to complement to bpf_ksock_send()
> >
> > This is useful when using ksock to reply to differents peers while
> > reusing the same UDP socket and generally works toward the goal of ksock
> > to support the basic socket operations.
> 
> can we drop connect from LSM progs and patches 1-5 altogether ?
> bpf_ksock_sendto() alone replies to different peers on one socket.
> 
> connect + send from LSM progs can't do that reliably. The socket is
> shared through the kptr and sleepable progs run concurrently. Between
> bpf_ksock_connect(A) and bpf_ksock_send() on one CPU, another CPU does
> bpf_ksock_connect(B) and the datagram for A goes to B.
> 
> Without connect there, acquire/release in socket_sendmsg has no user:
> nothing can be done with that reference. bpf_ksock_sendto() is in
> ksock_kfunc_btf_ids, so the current filter rejects it in socket_sendmsg
> already. Then no need for bpf_ksock_send_id, bpf_ksock_sendto_id,
> bpf_ksock_connect_id, bpf_lsm_socket_connect_id and the cycle comment.
> 
> Selftests are left out below. Patch 8 stays as is, patch 7 stays
> without the socket_connect hunk.
> 

Okay, agree it's simpler! Let me send this as v2.

[...]

> 
> pw-bot: cr

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

end of thread, other threads:[~2026-10-20 15:47 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-20 10:25 [PATCH bpf-next 0/8] bpf: Expand ksock send-path support Mahe Tardy
2026-10-20 10:25 ` [PATCH bpf-next 1/8] bpf: improve ksock_kfunc_set LSM recursion filter Mahe Tardy
2026-10-20 10:25 ` [PATCH bpf-next 2/8] selftests/bpf: Test allowed bpf_ksock operations at send LSM attach Mahe Tardy
2026-10-20 10:52   ` bot+bpf-ci
2026-10-20 11:06     ` Mahe Tardy
2026-10-20 10:25 ` [PATCH bpf-next 3/8] bpf: move ksock_connect() out of init kfunc set Mahe Tardy
2026-10-20 10:25 ` [PATCH bpf-next 4/8] selftests/bpf: Test verifier filter for ksock connect on LSM attach Mahe Tardy
2026-10-20 10:25 ` [PATCH bpf-next 5/8] selftests/bpf: Test ksock connect/send combinations Mahe Tardy
2026-10-20 10:25 ` [PATCH bpf-next 6/8] bpf: add bpf_ksock_sendto() kfunc Mahe Tardy
2026-10-20 10:25 ` [PATCH bpf-next 7/8] selftests/bpf: Test forbidden bpf_ksock_sendto() LSM attach Mahe Tardy
2026-10-20 10:52   ` bot+bpf-ci
2026-10-20 11:08     ` Mahe Tardy
2026-10-20 10:25 ` [PATCH bpf-next 8/8] selftests/bpf: Test ksock sendto() Mahe Tardy
2026-10-20 15:07 ` [PATCH bpf-next 0/8] bpf: Expand ksock send-path support Alexei Starovoitov
2026-10-20 15:47   ` Mahe Tardy

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