* [PATCH mptcp-next v3 0/7] mptcp: add bpf_setsockopt support
@ 2026-07-27 2:28 Gang Yan
2026-07-27 2:28 ` [PATCH mptcp-next v3 1/7] mptcp: drop unused @max arg of __mptcp_setsockopt_set_val Gang Yan
` (8 more replies)
0 siblings, 9 replies; 13+ messages in thread
From: Gang Yan @ 2026-07-27 2:28 UTC (permalink / raw)
To: mptcp; +Cc: Gang Yan
From: Gang Yan <yangang@kylinos.cn>
Hi, Matt, Geliang, Paolo
Patch 3-4 have been reviewed by Paolo before, and ready for merge
[1][2].
Changelog:
v3:
- Patch 2 keeps the mptcp_setsockopt_all_sf as Geliang suggested.
v2:
- Patches 1 and 2 are new in this series; they address TCP_MAXSEG
handling in the bpf_setsockopt() path.
- Patch 4 adds an early return to fix msk->sk_rcvlowat being
unexpectedly modified, an issue seen in v1.
- Patch 5 makes the hook safe for the non-tcp master socket: it guards
bpf_sock_ops_cb_flags_set() with sk_is_tcp() to prevent out-of-bounds
heap reads/writes through tcp_sk(sk)->bpf_sock_ops_cb_flags, and does
not set is_locked_tcp_sock for the msk (unlike tcp_call_bpf()). That
flag authorizes the verifier's direct tcp_sock-offset field accesses;
since the msk is not a tcp_sock, leaving it at the default 0 is safe.
v1:
Link: https://patchwork.kernel.org/project/mptcp/cover/20260713095735.1222033-1-gang.yan@linux.dev/
[1] https://patchwork.kernel.org/project/mptcp/patch/20260522-sockopt_lock-v5-2-108629a46e98@kylinos.cn/
[2] https://patchwork.kernel.org/project/mptcp/patch/20260522-sockopt_lock-v5-4-108629a46e98@kylinos.cn/
Gang Yan (7):
mptcp: drop unused @max arg of __mptcp_setsockopt_set_val
mptcp: take TCP_MAXSEG handling into __mptcp_setsockopt_set_val
mptcp: use sockopt_lock/release_sock in sockopt
mptcp: reject sockopt requiring ssks' lock in BPF context
mptcp: enable bpf_setsockopt on the master socket
mptcp: add TCP_CONNECT_CB sock_ops hook
selftests: bpf: verify mptcp bpf_setsockopt from TCP_CONNECT_CB
include/net/mptcp.h | 9 ++
net/core/filter.c | 10 ++
net/ipv4/tcp.c | 1 +
net/mptcp/protocol.c | 6 +
net/mptcp/protocol.h | 29 ++++
net/mptcp/sockopt.c | 127 +++++++++++-------
.../testing/selftests/bpf/prog_tests/mptcp.c | 61 +++++++++
.../selftests/bpf/progs/mptcp_setsockopt.c | 32 +++++
8 files changed, 223 insertions(+), 52 deletions(-)
create mode 100644 tools/testing/selftests/bpf/progs/mptcp_setsockopt.c
--
2.43.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH mptcp-next v3 1/7] mptcp: drop unused @max arg of __mptcp_setsockopt_set_val
2026-07-27 2:28 [PATCH mptcp-next v3 0/7] mptcp: add bpf_setsockopt support Gang Yan
@ 2026-07-27 2:28 ` Gang Yan
2026-07-27 6:37 ` Geliang Tang
2026-07-27 2:28 ` [PATCH mptcp-next v3 2/7] mptcp: take TCP_MAXSEG handling into __mptcp_setsockopt_set_val Gang Yan
` (7 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: Gang Yan @ 2026-07-27 2:28 UTC (permalink / raw)
To: mptcp; +Cc: Gang Yan
From: Gang Yan <yangang@kylinos.cn>
The @max argument is never read in the function body. Remove it and the
MAX_TCP_KEEP* values passed by the TCP_KEEPIDLE/INTVL/KEEPCNT callers.
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
net/mptcp/sockopt.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index fcf6feb2a9eb..9c4faa0d82ef 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -632,7 +632,7 @@ static int mptcp_setsockopt_sol_tcp_congestion(struct mptcp_sock *msk, sockptr_t
return ret;
}
-static int __mptcp_setsockopt_set_val(struct mptcp_sock *msk, int max,
+static int __mptcp_setsockopt_set_val(struct mptcp_sock *msk,
int (*set_val)(struct sock *, int),
int *msk_val, int val)
{
@@ -876,18 +876,15 @@ static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
ret = __mptcp_setsockopt_sol_tcp_nodelay(msk, val);
break;
case TCP_KEEPIDLE:
- ret = __mptcp_setsockopt_set_val(msk, MAX_TCP_KEEPIDLE,
- &tcp_sock_set_keepidle_locked,
+ ret = __mptcp_setsockopt_set_val(msk, &tcp_sock_set_keepidle_locked,
&msk->keepalive_idle, val);
break;
case TCP_KEEPINTVL:
- ret = __mptcp_setsockopt_set_val(msk, MAX_TCP_KEEPINTVL,
- &tcp_sock_set_keepintvl,
+ ret = __mptcp_setsockopt_set_val(msk, &tcp_sock_set_keepintvl,
&msk->keepalive_intvl, val);
break;
case TCP_KEEPCNT:
- ret = __mptcp_setsockopt_set_val(msk, MAX_TCP_KEEPCNT,
- &tcp_sock_set_keepcnt,
+ ret = __mptcp_setsockopt_set_val(msk, &tcp_sock_set_keepcnt,
&msk->keepalive_cnt,
val);
break;
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH mptcp-next v3 2/7] mptcp: take TCP_MAXSEG handling into __mptcp_setsockopt_set_val
2026-07-27 2:28 [PATCH mptcp-next v3 0/7] mptcp: add bpf_setsockopt support Gang Yan
2026-07-27 2:28 ` [PATCH mptcp-next v3 1/7] mptcp: drop unused @max arg of __mptcp_setsockopt_set_val Gang Yan
@ 2026-07-27 2:28 ` Gang Yan
2026-07-27 6:39 ` Geliang Tang
2026-07-27 2:28 ` [PATCH mptcp-next v3 3/7] mptcp: use sockopt_lock/release_sock in sockopt Gang Yan
` (6 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: Gang Yan @ 2026-07-27 2:28 UTC (permalink / raw)
To: mptcp; +Cc: Gang Yan
From: Gang Yan <yangang@kylinos.cn>
mptcp_setsockopt_all_sf is only used in 'TCP_MAXSEG', and it can be
replaced with __mptcp_setsockopt_set_val.
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
net/ipv4/tcp.c | 1 +
net/mptcp/sockopt.c | 5 ++---
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index b427f924608c..5915d0e62f43 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3830,6 +3830,7 @@ int tcp_sock_set_maxseg(struct sock *sk, int val)
WRITE_ONCE(tcp_sk(sk)->rx_opt.user_mss, val);
return 0;
}
+EXPORT_SYMBOL(tcp_sock_set_maxseg);
/*
* Socket option code for TCP.
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index 9c4faa0d82ef..a7d4135757e7 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -889,9 +889,8 @@ static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
val);
break;
case TCP_MAXSEG:
- msk->maxseg = val;
- ret = mptcp_setsockopt_all_sf(msk, SOL_TCP, optname, optval,
- optlen);
+ ret = __mptcp_setsockopt_set_val(msk, &tcp_sock_set_maxseg,
+ &msk->maxseg, val);
break;
default:
ret = -ENOPROTOOPT;
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH mptcp-next v3 3/7] mptcp: use sockopt_lock/release_sock in sockopt
2026-07-27 2:28 [PATCH mptcp-next v3 0/7] mptcp: add bpf_setsockopt support Gang Yan
2026-07-27 2:28 ` [PATCH mptcp-next v3 1/7] mptcp: drop unused @max arg of __mptcp_setsockopt_set_val Gang Yan
2026-07-27 2:28 ` [PATCH mptcp-next v3 2/7] mptcp: take TCP_MAXSEG handling into __mptcp_setsockopt_set_val Gang Yan
@ 2026-07-27 2:28 ` Gang Yan
2026-07-27 2:28 ` [PATCH mptcp-next v3 4/7] mptcp: reject sockopt requiring ssks' lock in BPF context Gang Yan
` (5 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Gang Yan @ 2026-07-27 2:28 UTC (permalink / raw)
To: mptcp; +Cc: Gang Yan
From: Gang Yan <yangang@kylinos.cn>
TCP and the core socket layer use sockopt_lock_sock() /
sockopt_release_sock() in their setsockopt and getsockopt handlers.
Switch the MPTCP socket (msk) level lock_sock()/release_sock()
calls to use the BPF-aware wrappers, making the MPTCP sockopt
codepaths consistent with the rest of the networking stack.
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
net/mptcp/sockopt.c | 84 ++++++++++++++++++++++-----------------------
1 file changed, 42 insertions(+), 42 deletions(-)
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index a7d4135757e7..f00d85809c52 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -78,7 +78,7 @@ static void mptcp_sol_socket_sync_intval(struct mptcp_sock *msk, int optname, in
struct mptcp_subflow_context *subflow;
struct sock *sk = (struct sock *)msk;
- lock_sock(sk);
+ sockopt_lock_sock(sk);
sockopt_seq_inc(msk);
mptcp_for_each_subflow(msk, subflow) {
@@ -123,7 +123,7 @@ static void mptcp_sol_socket_sync_intval(struct mptcp_sock *msk, int optname, in
unlock_sock_fast(ssk, slow);
}
- release_sock(sk);
+ sockopt_release_sock(sk);
}
static int mptcp_sol_socket_intval(struct mptcp_sock *msk, int optname, int val)
@@ -162,7 +162,7 @@ static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optnam
if (ret)
return ret;
- lock_sock(sk);
+ sockopt_lock_sock(sk);
mptcp_for_each_subflow(msk, subflow) {
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
@@ -171,7 +171,7 @@ static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optnam
release_sock(ssk);
}
- release_sock(sk);
+ sockopt_release_sock(sk);
return 0;
}
@@ -237,7 +237,7 @@ static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk,
if (ret)
return ret;
- lock_sock(sk);
+ sockopt_lock_sock(sk);
mptcp_for_each_subflow(msk, subflow) {
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
@@ -251,7 +251,7 @@ static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk,
ret = err;
}
- release_sock(sk);
+ sockopt_release_sock(sk);
return ret;
}
@@ -276,7 +276,7 @@ static int mptcp_setsockopt_sol_socket_linger(struct mptcp_sock *msk, sockptr_t
if (ret)
return ret;
- lock_sock(sk);
+ sockopt_lock_sock(sk);
sockopt_seq_inc(msk);
mptcp_for_each_subflow(msk, subflow) {
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
@@ -293,7 +293,7 @@ static int mptcp_setsockopt_sol_socket_linger(struct mptcp_sock *msk, sockptr_t
unlock_sock_fast(ssk, slow);
}
- release_sock(sk);
+ sockopt_release_sock(sk);
return 0;
}
@@ -309,10 +309,10 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
case SO_REUSEADDR:
case SO_BINDTODEVICE:
case SO_BINDTOIFINDEX:
- lock_sock(sk);
+ sockopt_lock_sock(sk);
ssk = __mptcp_nmpc_sk(msk);
if (IS_ERR(ssk)) {
- release_sock(sk);
+ sockopt_release_sock(sk);
return PTR_ERR(ssk);
}
@@ -327,7 +327,7 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
else if (optname == SO_BINDTOIFINDEX)
sk->sk_bound_dev_if = ssk->sk_bound_dev_if;
}
- release_sock(sk);
+ sockopt_release_sock(sk);
return ret;
case SO_KEEPALIVE:
case SO_PRIORITY:
@@ -405,16 +405,16 @@ static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
case IPV6_V6ONLY:
case IPV6_TRANSPARENT:
case IPV6_FREEBIND:
- lock_sock(sk);
+ sockopt_lock_sock(sk);
ssk = __mptcp_nmpc_sk(msk);
if (IS_ERR(ssk)) {
- release_sock(sk);
+ sockopt_release_sock(sk);
return PTR_ERR(ssk);
}
ret = tcp_setsockopt(ssk, SOL_IPV6, optname, optval, optlen);
if (ret != 0) {
- release_sock(sk);
+ sockopt_release_sock(sk);
return ret;
}
@@ -434,7 +434,7 @@ static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
break;
}
- release_sock(sk);
+ sockopt_release_sock(sk);
break;
}
@@ -611,7 +611,7 @@ static int mptcp_setsockopt_sol_tcp_congestion(struct mptcp_sock *msk, sockptr_t
cap_net_admin = ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN);
ret = 0;
- lock_sock(sk);
+ sockopt_lock_sock(sk);
sockopt_seq_inc(msk);
mptcp_for_each_subflow(msk, subflow) {
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
@@ -628,7 +628,7 @@ static int mptcp_setsockopt_sol_tcp_congestion(struct mptcp_sock *msk, sockptr_t
if (ret == 0)
strscpy(msk->ca_name, name, sizeof(msk->ca_name));
- release_sock(sk);
+ sockopt_release_sock(sk);
return ret;
}
@@ -707,11 +707,11 @@ static int mptcp_setsockopt_sol_ip_set(struct mptcp_sock *msk, int optname,
if (err != 0)
return err;
- lock_sock(sk);
+ sockopt_lock_sock(sk);
ssk = __mptcp_nmpc_sk(msk);
if (IS_ERR(ssk)) {
- release_sock(sk);
+ sockopt_release_sock(sk);
return PTR_ERR(ssk);
}
@@ -732,13 +732,13 @@ static int mptcp_setsockopt_sol_ip_set(struct mptcp_sock *msk, int optname,
READ_ONCE(inet_sk(sk)->local_port_range));
break;
default:
- release_sock(sk);
+ sockopt_release_sock(sk);
WARN_ON_ONCE(1);
return -EOPNOTSUPP;
}
sockopt_seq_inc(msk);
- release_sock(sk);
+ sockopt_release_sock(sk);
return 0;
}
@@ -754,7 +754,7 @@ static int mptcp_setsockopt_v4_set_tos(struct mptcp_sock *msk, int optname,
if (err != 0)
return err;
- lock_sock(sk);
+ sockopt_lock_sock(sk);
sockopt_seq_inc(msk);
val = READ_ONCE(inet_sk(sk)->tos);
mptcp_for_each_subflow(msk, subflow) {
@@ -765,7 +765,7 @@ static int mptcp_setsockopt_v4_set_tos(struct mptcp_sock *msk, int optname,
__ip_sock_set_tos(ssk, val);
unlock_sock_fast(ssk, slow);
}
- release_sock(sk);
+ sockopt_release_sock(sk);
return 0;
}
@@ -794,7 +794,7 @@ static int mptcp_setsockopt_first_sf_only(struct mptcp_sock *msk, int level, int
int ret;
/* Limit to first subflow, before the connection establishment */
- lock_sock(sk);
+ sockopt_lock_sock(sk);
ssk = __mptcp_nmpc_sk(msk);
if (IS_ERR(ssk)) {
ret = PTR_ERR(ssk);
@@ -804,7 +804,7 @@ static int mptcp_setsockopt_first_sf_only(struct mptcp_sock *msk, int level, int
ret = tcp_setsockopt(ssk, level, optname, optval, optlen);
unlock:
- release_sock(sk);
+ sockopt_release_sock(sk);
return ret;
}
@@ -857,7 +857,7 @@ static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
if (ret)
return ret;
- lock_sock(sk);
+ sockopt_lock_sock(sk);
switch (optname) {
case TCP_INQ:
if (val < 0 || val > 1)
@@ -896,7 +896,7 @@ static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
ret = -ENOPROTOOPT;
}
- release_sock(sk);
+ sockopt_release_sock(sk);
return ret;
}
@@ -920,9 +920,9 @@ int mptcp_setsockopt(struct sock *sk, int level, int optname,
* is in TCP fallback, when TCP socket options are passed through
* to the one remaining subflow.
*/
- lock_sock(sk);
+ sockopt_lock_sock(sk);
ssk = __mptcp_tcp_fallback(msk);
- release_sock(sk);
+ sockopt_release_sock(sk);
if (ssk)
return tcp_setsockopt(ssk, level, optname, optval, optlen);
@@ -945,7 +945,7 @@ static int mptcp_getsockopt_first_sf_only(struct mptcp_sock *msk, int level, int
struct sock *ssk;
int ret;
- lock_sock(sk);
+ sockopt_lock_sock(sk);
ssk = msk->first;
if (ssk)
goto get;
@@ -960,7 +960,7 @@ static int mptcp_getsockopt_first_sf_only(struct mptcp_sock *msk, int level, int
ret = tcp_getsockopt(ssk, level, optname, optval, optlen);
out:
- release_sock(sk);
+ sockopt_release_sock(sk);
return ret;
}
@@ -1131,7 +1131,7 @@ static int mptcp_getsockopt_tcpinfo(struct mptcp_sock *msk, char __user *optval,
infoptr = optval + sfd.size_subflow_data;
- lock_sock(sk);
+ sockopt_lock_sock(sk);
mptcp_for_each_subflow(msk, subflow) {
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
@@ -1144,7 +1144,7 @@ static int mptcp_getsockopt_tcpinfo(struct mptcp_sock *msk, char __user *optval,
tcp_get_info(ssk, &info);
if (copy_to_user(infoptr, &info, sfd.size_user)) {
- release_sock(sk);
+ sockopt_release_sock(sk);
return -EFAULT;
}
@@ -1154,7 +1154,7 @@ static int mptcp_getsockopt_tcpinfo(struct mptcp_sock *msk, char __user *optval,
}
}
- release_sock(sk);
+ sockopt_release_sock(sk);
sfd.num_subflows = sfcount;
@@ -1223,7 +1223,7 @@ static int mptcp_getsockopt_subflow_addrs(struct mptcp_sock *msk, char __user *o
addrptr = optval + sfd.size_subflow_data;
- lock_sock(sk);
+ sockopt_lock_sock(sk);
mptcp_for_each_subflow(msk, subflow) {
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
@@ -1236,7 +1236,7 @@ static int mptcp_getsockopt_subflow_addrs(struct mptcp_sock *msk, char __user *o
mptcp_get_sub_addrs(ssk, &a);
if (copy_to_user(addrptr, &a, sfd.size_user)) {
- release_sock(sk);
+ sockopt_release_sock(sk);
return -EFAULT;
}
@@ -1246,7 +1246,7 @@ static int mptcp_getsockopt_subflow_addrs(struct mptcp_sock *msk, char __user *o
}
}
- release_sock(sk);
+ sockopt_release_sock(sk);
sfd.num_subflows = sfcount;
@@ -1332,7 +1332,7 @@ static int mptcp_getsockopt_full_info(struct mptcp_sock *msk, char __user *optva
sizeof(struct mptcp_subflow_info));
tcpinfoptr = u64_to_user_ptr(mfi.tcp_info);
- lock_sock(sk);
+ sockopt_lock_sock(sk);
mptcp_for_each_subflow(msk, subflow) {
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
struct mptcp_subflow_info sfinfo;
@@ -1362,7 +1362,7 @@ static int mptcp_getsockopt_full_info(struct mptcp_sock *msk, char __user *optva
tcpinfoptr += mfi.size_tcpinfo_user;
sfinfoptr += mfi.size_sfinfo_user;
}
- release_sock(sk);
+ sockopt_release_sock(sk);
mfi.num_subflows = sfcount;
if (mptcp_put_full_info(&mfi, optval, copylen, optlen))
@@ -1371,7 +1371,7 @@ static int mptcp_getsockopt_full_info(struct mptcp_sock *msk, char __user *optva
return 0;
fail_release:
- release_sock(sk);
+ sockopt_release_sock(sk);
return -EFAULT;
}
@@ -1526,9 +1526,9 @@ int mptcp_getsockopt(struct sock *sk, int level, int optname,
* is in TCP fallback, when socket options are passed through
* to the one remaining subflow.
*/
- lock_sock(sk);
+ sockopt_lock_sock(sk);
ssk = __mptcp_tcp_fallback(msk);
- release_sock(sk);
+ sockopt_release_sock(sk);
if (ssk)
return tcp_getsockopt(ssk, level, optname, optval, option);
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH mptcp-next v3 4/7] mptcp: reject sockopt requiring ssks' lock in BPF context
2026-07-27 2:28 [PATCH mptcp-next v3 0/7] mptcp: add bpf_setsockopt support Gang Yan
` (2 preceding siblings ...)
2026-07-27 2:28 ` [PATCH mptcp-next v3 3/7] mptcp: use sockopt_lock/release_sock in sockopt Gang Yan
@ 2026-07-27 2:28 ` Gang Yan
2026-07-27 2:28 ` [PATCH mptcp-next v3 5/7] mptcp: enable bpf_setsockopt on the master socket Gang Yan
` (4 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Gang Yan @ 2026-07-27 2:28 UTC (permalink / raw)
To: mptcp; +Cc: Gang Yan
From: Gang Yan <yangang@kylinos.cn>
Several MPTCP setsockopt handlers need to acquire the subflow lock
via lock_sock(ssk) to propagate settings to each subflow. This lock
can sleep and is therefore not usable in BPF context where sleeping
is forbidden.
The short-term solution is to make any sockopt operation that requires
subflow-level lock fail with -EOPNOTSUPP when called from BPF context.
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
net/mptcp/sockopt.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index f00d85809c52..a26758a82150 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -185,6 +185,9 @@ static int mptcp_setsockopt_sol_socket_int(struct mptcp_sock *msk, int optname,
if (ret)
return ret;
+ if (has_current_bpf_ctx())
+ return -EOPNOTSUPP;
+
switch (optname) {
case SO_KEEPALIVE:
case SO_DEBUG:
@@ -218,6 +221,9 @@ static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk,
struct so_timestamping timestamping;
int ret;
+ if (has_current_bpf_ctx())
+ return -EOPNOTSUPP;
+
if (optlen == sizeof(timestamping)) {
if (copy_from_sockptr(×tamping, optval,
sizeof(timestamping)))
@@ -265,6 +271,9 @@ static int mptcp_setsockopt_sol_socket_linger(struct mptcp_sock *msk, sockptr_t
sockptr_t kopt;
int ret;
+ if (has_current_bpf_ctx())
+ return -EOPNOTSUPP;
+
if (optlen < sizeof(ling))
return -EINVAL;
@@ -598,6 +607,9 @@ static int mptcp_setsockopt_sol_tcp_congestion(struct mptcp_sock *msk, sockptr_t
bool cap_net_admin;
int ret;
+ if (has_current_bpf_ctx())
+ return -EOPNOTSUPP;
+
if (optlen < 1)
return -EINVAL;
@@ -639,6 +651,9 @@ static int __mptcp_setsockopt_set_val(struct mptcp_sock *msk,
struct mptcp_subflow_context *subflow;
int err = 0;
+ if (has_current_bpf_ctx())
+ return -EOPNOTSUPP;
+
mptcp_for_each_subflow(msk, subflow) {
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
int ret;
@@ -662,6 +677,9 @@ static int __mptcp_setsockopt_sol_tcp_cork(struct mptcp_sock *msk, int val)
struct mptcp_subflow_context *subflow;
struct sock *sk = (struct sock *)msk;
+ if (has_current_bpf_ctx())
+ return -EOPNOTSUPP;
+
sockopt_seq_inc(msk);
msk->cork = !!val;
mptcp_for_each_subflow(msk, subflow) {
@@ -682,6 +700,9 @@ static int __mptcp_setsockopt_sol_tcp_nodelay(struct mptcp_sock *msk, int val)
struct mptcp_subflow_context *subflow;
struct sock *sk = (struct sock *)msk;
+ if (has_current_bpf_ctx())
+ return -EOPNOTSUPP;
+
sockopt_seq_inc(msk);
msk->nodelay = !!val;
mptcp_for_each_subflow(msk, subflow) {
@@ -749,6 +770,9 @@ static int mptcp_setsockopt_v4_set_tos(struct mptcp_sock *msk, int optname,
struct sock *sk = (struct sock *)msk;
int err, val;
+ if (has_current_bpf_ctx())
+ return -EOPNOTSUPP;
+
err = ip_setsockopt(sk, SOL_IP, optname, optval, optlen);
if (err != 0)
@@ -1632,6 +1656,9 @@ int mptcp_set_rcvlowat(struct sock *sk, int val)
if (sk->sk_protocol == IPPROTO_TCP)
return -EINVAL;
+ if (has_current_bpf_ctx())
+ return -EOPNOTSUPP;
+
if (sk->sk_userlocks & SOCK_RCVBUF_LOCK)
cap = sk->sk_rcvbuf >> 1;
else
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH mptcp-next v3 5/7] mptcp: enable bpf_setsockopt on the master socket
2026-07-27 2:28 [PATCH mptcp-next v3 0/7] mptcp: add bpf_setsockopt support Gang Yan
` (3 preceding siblings ...)
2026-07-27 2:28 ` [PATCH mptcp-next v3 4/7] mptcp: reject sockopt requiring ssks' lock in BPF context Gang Yan
@ 2026-07-27 2:28 ` Gang Yan
2026-07-27 2:28 ` [PATCH mptcp-next v3 6/7] mptcp: add TCP_CONNECT_CB sock_ops hook Gang Yan
` (3 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Gang Yan @ 2026-07-27 2:28 UTC (permalink / raw)
To: mptcp; +Cc: Gang Yan
From: Gang Yan <yangang@kylinos.cn>
bpf_setsockopt() currently cannot be used on mptcp master sockets:
__bpf_setsockopt() dispatches by level to the protocol-agnostic
sol_*_sockopt() helpers, which either reject the msk
(sk_protocol == IPPROTO_MPTCP) and the ssk (sk_is_tcp() is false)
or bypass mptcp's own dispatch (e.g. SOL_IP going straight to
do_ip_setsockopt()).
This patch routes any level to mptcp_setsockopt(), which already
handles all levels.
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
include/net/mptcp.h | 9 +++++++++
net/core/filter.c | 7 +++++++
2 files changed, 16 insertions(+)
diff --git a/include/net/mptcp.h b/include/net/mptcp.h
index 333bde2a0b76..fcce2b7e9ef9 100644
--- a/include/net/mptcp.h
+++ b/include/net/mptcp.h
@@ -237,6 +237,9 @@ static inline __be32 mptcp_reset_option(const struct sk_buff *skb)
}
void mptcp_active_detect_blackhole(struct sock *sk, bool expired);
+
+int mptcp_setsockopt(struct sock *sk, int level, int optname,
+ sockptr_t optval, unsigned int optlen);
#else
static inline void mptcp_init(void)
@@ -314,6 +317,12 @@ static inline struct request_sock *mptcp_subflow_reqsk_alloc(const struct reques
static inline __be32 mptcp_reset_option(const struct sk_buff *skb) { return htonl(0u); }
static inline void mptcp_active_detect_blackhole(struct sock *sk, bool expired) { }
+
+static inline int mptcp_setsockopt(struct sock *sk, int level, int optname,
+ sockptr_t optval, unsigned int optlen)
+{
+ return -EINVAL;
+}
#endif /* CONFIG_MPTCP */
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
diff --git a/net/core/filter.c b/net/core/filter.c
index b446aa8be5c3..18e650bf7393 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -5683,6 +5683,13 @@ static int __bpf_setsockopt(struct sock *sk, int level, int optname,
if (!sk_fullsock(sk))
return -EINVAL;
+ /* Route any bpf_setsockopt on the mptcp socket to mptcp_setsockopt,
+ * which handles all levels.
+ */
+ if (IS_ENABLED(CONFIG_MPTCP) && sk->sk_protocol == IPPROTO_MPTCP)
+ return mptcp_setsockopt(sk, level, optname,
+ KERNEL_SOCKPTR(optval), optlen);
+
if (level == SOL_SOCKET)
return sol_socket_sockopt(sk, optname, optval, &optlen, false);
else if (IS_ENABLED(CONFIG_INET) && level == SOL_IP)
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH mptcp-next v3 6/7] mptcp: add TCP_CONNECT_CB sock_ops hook
2026-07-27 2:28 [PATCH mptcp-next v3 0/7] mptcp: add bpf_setsockopt support Gang Yan
` (4 preceding siblings ...)
2026-07-27 2:28 ` [PATCH mptcp-next v3 5/7] mptcp: enable bpf_setsockopt on the master socket Gang Yan
@ 2026-07-27 2:28 ` Gang Yan
2026-07-27 2:28 ` [PATCH mptcp-next v3 7/7] selftests: bpf: verify mptcp bpf_setsockopt from TCP_CONNECT_CB Gang Yan
` (2 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Gang Yan @ 2026-07-27 2:28 UTC (permalink / raw)
To: mptcp; +Cc: Gang Yan
From: Gang Yan <yangang@kylinos.cn>
This patch adds a helper named 'mptcp_call_bpf' like tcp_call_bpf.
Invoke the new helper from mptcp_connect() with
BPF_SOCK_OPS_TCP_CONNECT_CB, placed after the subflow lock is acquired
and before tcp_connect(). At this point the msk lock is held by
__inet_stream_connect(), mirroring the placement of TCP_CONNECT_CB in
tcp_v4_connect()/tcp_v6_connect().
'bpf_sock_ops_cb_flags_set' can be called via msk, so using sk_is_tcp()
to avoid this issue.
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
net/core/filter.c | 3 +++
net/mptcp/protocol.c | 6 ++++++
net/mptcp/protocol.h | 29 +++++++++++++++++++++++++++++
3 files changed, 38 insertions(+)
diff --git a/net/core/filter.c b/net/core/filter.c
index 18e650bf7393..2f9778181279 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -6097,6 +6097,9 @@ BPF_CALL_2(bpf_sock_ops_cb_flags_set, struct bpf_sock_ops_kern *, bpf_sock,
if (!IS_ENABLED(CONFIG_INET) || !sk_fullsock(sk))
return -EINVAL;
+ if (!sk_is_tcp(sk))
+ return -EOPNOTSUPP;
+
tcp_sk(sk)->bpf_sock_ops_cb_flags = val;
return argval & (~BPF_SOCK_OPS_ALL_CB_FLAGS);
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index ffcf5a1788f6..837bb76e5c2d 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -4149,6 +4149,12 @@ static int mptcp_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
if (!msk->fastopening)
lock_sock(ssk);
+ /* Notify cgroup BPF on the msk before initiating the subflow connect.
+ * Mirrors BPF_SOCK_OPS_TCP_CONNECT_CB; msk lock is held by the
+ * caller (__inet_stream_connect) and ssk is held before.
+ */
+ mptcp_call_bpf(sk, BPF_SOCK_OPS_TCP_CONNECT_CB, 0, NULL);
+
/* the following mirrors closely a very small chunk of code from
* __inet_stream_connect()
*/
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index da40c6f3705f..e862310b2f81 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1374,4 +1374,33 @@ mptcp_token_join_cookie_init_state(struct mptcp_subflow_request_sock *subflow_re
static inline void mptcp_join_cookie_init(void) {}
#endif
+#ifdef CONFIG_BPF_JIT
+static inline int mptcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args)
+{
+ struct bpf_sock_ops_kern sock_ops;
+ int ret;
+
+ memset(&sock_ops, 0, offsetof(struct bpf_sock_ops_kern, temp));
+
+ if (sk_fullsock(sk)) {
+ sock_ops.is_fullsock = 1;
+ sock_owned_by_me(sk);
+ }
+
+ sock_ops.sk = sk;
+ sock_ops.op = op;
+
+ if (nargs > 0)
+ memcpy(sock_ops.args, args, nargs * sizeof(*args));
+
+ ret = BPF_CGROUP_RUN_PROG_SOCK_OPS(&sock_ops);
+ return ret == 0 ? sock_ops.reply : -1;
+}
+#else
+static inline int mptcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args)
+{
+ return -1;
+}
+#endif
+
#endif /* __MPTCP_PROTOCOL_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH mptcp-next v3 7/7] selftests: bpf: verify mptcp bpf_setsockopt from TCP_CONNECT_CB
2026-07-27 2:28 [PATCH mptcp-next v3 0/7] mptcp: add bpf_setsockopt support Gang Yan
` (5 preceding siblings ...)
2026-07-27 2:28 ` [PATCH mptcp-next v3 6/7] mptcp: add TCP_CONNECT_CB sock_ops hook Gang Yan
@ 2026-07-27 2:28 ` Gang Yan
2026-07-27 3:12 ` [PATCH mptcp-next v3 0/7] mptcp: add bpf_setsockopt support MPTCP CI
2026-07-27 6:04 ` Geliang Tang
8 siblings, 0 replies; 13+ messages in thread
From: Gang Yan @ 2026-07-27 2:28 UTC (permalink / raw)
To: mptcp; +Cc: Gang Yan
From: Gang Yan <yangang@kylinos.cn>
Add a BPF sockops program attached to BPF_CGROUP_SOCK_OPS that fires
on BPF_SOCK_OPS_TCP_CONNECT_CB and exercises bpf_setsockopt() on the
mptcp master socket (msk).
Two scenarios are covered by the new "setsockopt" subtest:
- TCP_INQ must succeed and the value (1) must be observable from
userspace via getsockopt() on the mptcp socket.
- TCP_CONGESTION needs the subflow lock and is therefore rejected
in bpf context with -EOPNOTSUPP.
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
.../testing/selftests/bpf/prog_tests/mptcp.c | 61 +++++++++++++++++++
.../selftests/bpf/progs/mptcp_setsockopt.c | 32 ++++++++++
2 files changed, 93 insertions(+)
create mode 100644 tools/testing/selftests/bpf/progs/mptcp_setsockopt.c
diff --git a/tools/testing/selftests/bpf/prog_tests/mptcp.c b/tools/testing/selftests/bpf/prog_tests/mptcp.c
index 7f48fd9e94e1..ad59f8fcbb68 100644
--- a/tools/testing/selftests/bpf/prog_tests/mptcp.c
+++ b/tools/testing/selftests/bpf/prog_tests/mptcp.c
@@ -18,6 +18,7 @@
#include "mptcp_bpf_rr.skel.h"
#include "mptcp_bpf_red.skel.h"
#include "mptcp_bpf_burst.skel.h"
+#include "mptcp_setsockopt.skel.h"
#define NS_TEST "mptcp_ns"
#define ADDR_1 "10.0.1.1"
@@ -813,6 +814,64 @@ static void test_burst(void)
mptcp_bpf_burst__destroy(skel);
}
+static void test_setsockopt(void)
+{
+ struct mptcp_setsockopt *skel;
+ struct netns_obj *netns;
+ int cgroup_fd, server_fd, client_fd;
+ int err;
+ int inq;
+ socklen_t len;
+
+ cgroup_fd = test__join_cgroup("/mptcp_setsockopt");
+ if (!ASSERT_OK_FD(cgroup_fd, "join_cgroup"))
+ return;
+
+ skel = mptcp_setsockopt__open_and_load();
+ if (!ASSERT_OK_PTR(skel, "skel_open_load"))
+ goto close_cgroup;
+
+ skel->links.mptcp_connect_cb =
+ bpf_program__attach_cgroup(skel->progs.mptcp_connect_cb,
+ cgroup_fd);
+ if (!ASSERT_OK_PTR(skel->links.mptcp_connect_cb, "attach connect_cb"))
+ goto skel_destroy;
+
+ netns = netns_new(NS_TEST, true);
+ if (!ASSERT_OK_PTR(netns, "netns_new"))
+ goto skel_destroy;
+
+ server_fd = start_mptcp_server(AF_INET, NULL, 0, 0);
+ if (!ASSERT_OK_FD(server_fd, "start_mptcp_server"))
+ goto close_netns;
+
+ client_fd = connect_to_fd(server_fd, 0);
+ if (!ASSERT_OK_FD(client_fd, "connect_to_fd"))
+ goto close_server;
+
+ /* TCP_INQ should be set successfullly */
+ ASSERT_EQ(skel->bss->connect_cb_inq_ret, 0, "connect_cb TCP_INQ ret");
+
+ len = sizeof(inq);
+ err = getsockopt(client_fd, SOL_TCP, TCP_INQ, &inq, &len);
+ if (ASSERT_OK(err, "getsockopt TCP_INQ"))
+ ASSERT_EQ(inq, 1, "TCP_INQ value");
+
+ /* TCP_CONGESTION should be -EOPNOTSUPP */
+ ASSERT_EQ(skel->bss->connect_cb_cc_ret, -EOPNOTSUPP,
+ "connect_cb TCP_CONGESTION ret");
+
+ close(client_fd);
+close_server:
+ close(server_fd);
+close_netns:
+ netns_free(netns);
+skel_destroy:
+ mptcp_setsockopt__destroy(skel);
+close_cgroup:
+ close(cgroup_fd);
+}
+
void test_mptcp(void)
{
if (test__start_subtest("base"))
@@ -835,4 +894,6 @@ void test_mptcp(void)
test_red();
if (test__start_subtest("burst"))
test_burst();
+ if (test__start_subtest("setsockopt"))
+ test_setsockopt();
}
diff --git a/tools/testing/selftests/bpf/progs/mptcp_setsockopt.c b/tools/testing/selftests/bpf/progs/mptcp_setsockopt.c
new file mode 100644
index 000000000000..f54b77ea6c5f
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/mptcp_setsockopt.c
@@ -0,0 +1,32 @@
+#include "bpf_tracing_net.h"
+#include "mptcp_bpf.h"
+
+#ifndef TCP_INQ
+#define TCP_INQ 36
+#endif
+
+int connect_cb_inq_ret;
+int connect_cb_cc_ret;
+
+char cc_reno[TCP_CA_NAME_MAX] = "reno";
+
+SEC("sockops")
+int mptcp_connect_cb(struct bpf_sock_ops *skops)
+{
+ struct bpf_sock *sk = skops->sk;
+ int one = 1;
+
+ if (skops->op != BPF_SOCK_OPS_TCP_CONNECT_CB)
+ return 1;
+
+ if (!sk || sk->protocol != IPPROTO_MPTCP)
+ return 1;
+
+ connect_cb_inq_ret =
+ bpf_setsockopt(skops, SOL_TCP, TCP_INQ, &one, sizeof(one));
+ connect_cb_cc_ret =
+ bpf_setsockopt(skops, SOL_TCP, TCP_CONGESTION,
+ cc_reno, sizeof(cc_reno));
+
+ return 1;
+}
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH mptcp-next v3 0/7] mptcp: add bpf_setsockopt support
2026-07-27 2:28 [PATCH mptcp-next v3 0/7] mptcp: add bpf_setsockopt support Gang Yan
` (6 preceding siblings ...)
2026-07-27 2:28 ` [PATCH mptcp-next v3 7/7] selftests: bpf: verify mptcp bpf_setsockopt from TCP_CONNECT_CB Gang Yan
@ 2026-07-27 3:12 ` MPTCP CI
2026-07-27 6:04 ` Geliang Tang
8 siblings, 0 replies; 13+ messages in thread
From: MPTCP CI @ 2026-07-27 3:12 UTC (permalink / raw)
To: Gang Yan; +Cc: mptcp
Hi Gang,
Thank you for your modifications, that's great!
Our CI did some validations and here is its report:
- KVM Validation: normal (except selftest_mptcp_join): Script error! ❓
- KVM Validation: normal (only selftest_mptcp_join): Script error! ❓
- KVM Validation: debug (except selftest_mptcp_join): Script error! ❓
- KVM Validation: debug (only selftest_mptcp_join): Script error! ❓
- KVM Validation: btf-normal (only bpftest_all): Script error! ❓
- KVM Validation: btf-debug (only bpftest_all): Script error! ❓
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/30233020793
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/acb09ec8b8b1
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1134827
If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:
$ cd [kernel source code]
$ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
--pull always mptcp/mptcp-upstream-virtme-docker:latest \
auto-normal
For more details:
https://github.com/multipath-tcp/mptcp-upstream-virtme-docker
Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)
Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH mptcp-next v3 0/7] mptcp: add bpf_setsockopt support
2026-07-27 2:28 [PATCH mptcp-next v3 0/7] mptcp: add bpf_setsockopt support Gang Yan
` (7 preceding siblings ...)
2026-07-27 3:12 ` [PATCH mptcp-next v3 0/7] mptcp: add bpf_setsockopt support MPTCP CI
@ 2026-07-27 6:04 ` Geliang Tang
2026-07-27 6:20 ` gang.yan
8 siblings, 1 reply; 13+ messages in thread
From: Geliang Tang @ 2026-07-27 6:04 UTC (permalink / raw)
To: Gang Yan, mptcp; +Cc: Gang Yan
Hi Gang,
On Mon, 2026-07-27 at 10:28 +0800, Gang Yan wrote:
> From: Gang Yan <yangang@kylinos.cn>
>
> Hi, Matt, Geliang, Paolo
>
> Patch 3-4 have been reviewed by Paolo before, and ready for merge
> [1][2].
Do not put unrelated code into a single series. This series is for
adding bpf_setsockopt support; other patches do not belong here.
>
> Changelog:
> v3:
> - Patch 2 keeps the mptcp_setsockopt_all_sf as Geliang suggested.
I recommend that you hold off on sending this patch for now: "Let's
wait until IPV6_TCLASS is merged before posting this patch." Rather
than keeping an unused mptcp_setsockopt_all_sf.
Do not send code that has not passed compilation to the mailing list.
> v2:
> - Patches 1 and 2 are new in this series; they address TCP_MAXSEG
> handling in the bpf_setsockopt() path.
> - Patch 4 adds an early return to fix msk->sk_rcvlowat being
> unexpectedly modified, an issue seen in v1.
> - Patch 5 makes the hook safe for the non-tcp master socket: it
> guards
> bpf_sock_ops_cb_flags_set() with sk_is_tcp() to prevent out-of-
> bounds
> heap reads/writes through tcp_sk(sk)->bpf_sock_ops_cb_flags, and
> does
> not set is_locked_tcp_sock for the msk (unlike tcp_call_bpf()).
> That
> flag authorizes the verifier's direct tcp_sock-offset field
> accesses;
> since the msk is not a tcp_sock, leaving it at the default 0 is
> safe.
>
> v1:
> Link:
> https://patchwork.kernel.org/project/mptcp/cover/20260713095735.1222033-1-gang.yan@linux.dev/
>
> [1]
> https://patchwork.kernel.org/project/mptcp/patch/20260522-sockopt_lock-v5-2-108629a46e98@kylinos.cn/
> [2]
> https://patchwork.kernel.org/project/mptcp/patch/20260522-sockopt_lock-v5-4-108629a46e98@kylinos.cn/
>
> Gang Yan (7):
> mptcp: drop unused @max arg of __mptcp_setsockopt_set_val
> mptcp: take TCP_MAXSEG handling into __mptcp_setsockopt_set_val
> mptcp: use sockopt_lock/release_sock in sockopt
> mptcp: reject sockopt requiring ssks' lock in BPF context
> mptcp: enable bpf_setsockopt on the master socket
> mptcp: add TCP_CONNECT_CB sock_ops hook
> selftests: bpf: verify mptcp bpf_setsockopt from TCP_CONNECT_CB
>
> include/net/mptcp.h | 9 ++
> net/core/filter.c | 10 ++
> net/ipv4/tcp.c | 1 +
> net/mptcp/protocol.c | 6 +
> net/mptcp/protocol.h | 29 ++++
> net/mptcp/sockopt.c | 127 +++++++++++-----
> --
> .../testing/selftests/bpf/prog_tests/mptcp.c | 61 +++++++++
> .../selftests/bpf/progs/mptcp_setsockopt.c | 32 +++++
> 8 files changed, 223 insertions(+), 52 deletions(-)
> create mode 100644
> tools/testing/selftests/bpf/progs/mptcp_setsockopt.c
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH mptcp-next v3 0/7] mptcp: add bpf_setsockopt support
2026-07-27 6:04 ` Geliang Tang
@ 2026-07-27 6:20 ` gang.yan
0 siblings, 0 replies; 13+ messages in thread
From: gang.yan @ 2026-07-27 6:20 UTC (permalink / raw)
To: Geliang Tang, mptcp; +Cc: Gang Yan
July 27, 2026 at 2:04 PM, "Geliang Tang" <geliang@kernel.org mailto:geliang@kernel.org?to=%22Geliang%20Tang%22%20%3Cgeliang%40kernel.org%3E > wrote:
>
> Hi Gang,
>
> On Mon, 2026-07-27 at 10:28 +0800, Gang Yan wrote:
>
> >
> > From: Gang Yan <yangang@kylinos.cn>
> >
> > Hi, Matt, Geliang, Paolo
> >
> > Patch 3-4 have been reviewed by Paolo before, and ready for merge
> > [1][2].
> >
> Do not put unrelated code into a single series. This series is for
> adding bpf_setsockopt support; other patches do not belong here.
>
> >
> > Changelog:
> > v3:
> > - Patch 2 keeps the mptcp_setsockopt_all_sf as Geliang suggested.
> >
> I recommend that you hold off on sending this patch for now: "Let's
> wait until IPV6_TCLASS is merged before posting this patch." Rather
> than keeping an unused mptcp_setsockopt_all_sf.
>
> Do not send code that has not passed compilation to the mailing list.
>
Hi Geliang
I sincerely apologize for the noise. I'll drop this patch and wait for the IPV6_TCLASS merge.
Thanks
Gang
> >
> > v2:
> > - Patches 1 and 2 are new in this series; they address TCP_MAXSEG
> > handling in the bpf_setsockopt() path.
> > - Patch 4 adds an early return to fix msk->sk_rcvlowat being
> > unexpectedly modified, an issue seen in v1.
> > - Patch 5 makes the hook safe for the non-tcp master socket: it
> > guards
> > bpf_sock_ops_cb_flags_set() with sk_is_tcp() to prevent out-of-
> > bounds
> > heap reads/writes through tcp_sk(sk)->bpf_sock_ops_cb_flags, and
> > does
> > not set is_locked_tcp_sock for the msk (unlike tcp_call_bpf()).
> > That
> > flag authorizes the verifier's direct tcp_sock-offset field
> > accesses;
> > since the msk is not a tcp_sock, leaving it at the default 0 is
> > safe.
> >
> > v1:
> > Link:
> > https://patchwork.kernel.org/project/mptcp/cover/20260713095735.1222033-1-gang.yan@linux.dev/
> >
> > [1]
> > https://patchwork.kernel.org/project/mptcp/patch/20260522-sockopt_lock-v5-2-108629a46e98@kylinos.cn/
> > [2]
> > https://patchwork.kernel.org/project/mptcp/patch/20260522-sockopt_lock-v5-4-108629a46e98@kylinos.cn/
> >
> > Gang Yan (7):
> > mptcp: drop unused @max arg of __mptcp_setsockopt_set_val
> > mptcp: take TCP_MAXSEG handling into __mptcp_setsockopt_set_val
> > mptcp: use sockopt_lock/release_sock in sockopt
> > mptcp: reject sockopt requiring ssks' lock in BPF context
> > mptcp: enable bpf_setsockopt on the master socket
> > mptcp: add TCP_CONNECT_CB sock_ops hook
> > selftests: bpf: verify mptcp bpf_setsockopt from TCP_CONNECT_CB
> >
> > include/net/mptcp.h | 9 ++
> > net/core/filter.c | 10 ++
> > net/ipv4/tcp.c | 1 +
> > net/mptcp/protocol.c | 6 +
> > net/mptcp/protocol.h | 29 ++++
> > net/mptcp/sockopt.c | 127 +++++++++++-----
> > --
> > .../testing/selftests/bpf/prog_tests/mptcp.c | 61 +++++++++
> > .../selftests/bpf/progs/mptcp_setsockopt.c | 32 +++++
> > 8 files changed, 223 insertions(+), 52 deletions(-)
> > create mode 100644
> > tools/testing/selftests/bpf/progs/mptcp_setsockopt.c
> >
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH mptcp-next v3 1/7] mptcp: drop unused @max arg of __mptcp_setsockopt_set_val
2026-07-27 2:28 ` [PATCH mptcp-next v3 1/7] mptcp: drop unused @max arg of __mptcp_setsockopt_set_val Gang Yan
@ 2026-07-27 6:37 ` Geliang Tang
0 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2026-07-27 6:37 UTC (permalink / raw)
To: Gang Yan, mptcp; +Cc: Gang Yan
On Mon, 2026-07-27 at 10:28 +0800, Gang Yan wrote:
> From: Gang Yan <yangang@kylinos.cn>
>
> The @max argument is never read in the function body. Remove it and
> the
> MAX_TCP_KEEP* values passed by the TCP_KEEPIDLE/INTVL/KEEPCNT
> callers.
No, we shouldn't drop this "max" argument. Instead, we need to add some
code to check the "val" argument against the "max" argument in
__mptcp_setsockopt_set_val(), something like:
if (val < 1 || val > max)
return -EINVAL;
>
> Signed-off-by: Gang Yan <yangang@kylinos.cn>
> ---
> net/mptcp/sockopt.c | 11 ++++-------
> 1 file changed, 4 insertions(+), 7 deletions(-)
>
> diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
> index fcf6feb2a9eb..9c4faa0d82ef 100644
> --- a/net/mptcp/sockopt.c
> +++ b/net/mptcp/sockopt.c
> @@ -632,7 +632,7 @@ static int
> mptcp_setsockopt_sol_tcp_congestion(struct mptcp_sock *msk, sockptr_t
> return ret;
> }
>
> -static int __mptcp_setsockopt_set_val(struct mptcp_sock *msk, int
> max,
> +static int __mptcp_setsockopt_set_val(struct mptcp_sock *msk,
> int (*set_val)(struct sock *,
> int),
> int *msk_val, int val)
> {
> @@ -876,18 +876,15 @@ static int mptcp_setsockopt_sol_tcp(struct
> mptcp_sock *msk, int optname,
> ret = __mptcp_setsockopt_sol_tcp_nodelay(msk, val);
> break;
> case TCP_KEEPIDLE:
> - ret = __mptcp_setsockopt_set_val(msk,
> MAX_TCP_KEEPIDLE,
> -
> &tcp_sock_set_keepidle_locked,
> + ret = __mptcp_setsockopt_set_val(msk,
> &tcp_sock_set_keepidle_locked,
> &msk-
> >keepalive_idle, val);
> break;
> case TCP_KEEPINTVL:
> - ret = __mptcp_setsockopt_set_val(msk,
> MAX_TCP_KEEPINTVL,
> -
> &tcp_sock_set_keepintvl,
> + ret = __mptcp_setsockopt_set_val(msk,
> &tcp_sock_set_keepintvl,
> &msk-
> >keepalive_intvl, val);
> break;
> case TCP_KEEPCNT:
> - ret = __mptcp_setsockopt_set_val(msk,
> MAX_TCP_KEEPCNT,
> -
> &tcp_sock_set_keepcnt,
> + ret = __mptcp_setsockopt_set_val(msk,
> &tcp_sock_set_keepcnt,
> &msk-
> >keepalive_cnt,
> val);
> break;
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH mptcp-next v3 2/7] mptcp: take TCP_MAXSEG handling into __mptcp_setsockopt_set_val
2026-07-27 2:28 ` [PATCH mptcp-next v3 2/7] mptcp: take TCP_MAXSEG handling into __mptcp_setsockopt_set_val Gang Yan
@ 2026-07-27 6:39 ` Geliang Tang
0 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2026-07-27 6:39 UTC (permalink / raw)
To: Gang Yan, mptcp; +Cc: Gang Yan
On Mon, 2026-07-27 at 10:28 +0800, Gang Yan wrote:
> From: Gang Yan <yangang@kylinos.cn>
>
> mptcp_setsockopt_all_sf is only used in 'TCP_MAXSEG', and it can be
> replaced with __mptcp_setsockopt_set_val.
>
> Signed-off-by: Gang Yan <yangang@kylinos.cn>
> ---
> net/ipv4/tcp.c | 1 +
> net/mptcp/sockopt.c | 5 ++---
> 2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index b427f924608c..5915d0e62f43 100644
> --- a/net/ipv4/tcp.c
> +++ b/net/ipv4/tcp.c
> @@ -3830,6 +3830,7 @@ int tcp_sock_set_maxseg(struct sock *sk, int
> val)
> WRITE_ONCE(tcp_sk(sk)->rx_opt.user_mss, val);
> return 0;
> }
> +EXPORT_SYMBOL(tcp_sock_set_maxseg);
>
> /*
> * Socket option code for TCP.
> diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
> index 9c4faa0d82ef..a7d4135757e7 100644
> --- a/net/mptcp/sockopt.c
> +++ b/net/mptcp/sockopt.c
> @@ -889,9 +889,8 @@ static int mptcp_setsockopt_sol_tcp(struct
> mptcp_sock *msk, int optname,
> val);
> break;
> case TCP_MAXSEG:
> - msk->maxseg = val;
> - ret = mptcp_setsockopt_all_sf(msk, SOL_TCP, optname,
> optval,
> - optlen);
> + ret = __mptcp_setsockopt_set_val(msk,
> &tcp_sock_set_maxseg,
> + &msk->maxseg, val);
So, here you do need to pass in MAX_TCP_MAXSEG, and you need to
consider what would be a reasonable value to define it as.
> break;
> default:
> ret = -ENOPROTOOPT;
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-07-27 6:39 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-27 2:28 [PATCH mptcp-next v3 0/7] mptcp: add bpf_setsockopt support Gang Yan
2026-07-27 2:28 ` [PATCH mptcp-next v3 1/7] mptcp: drop unused @max arg of __mptcp_setsockopt_set_val Gang Yan
2026-07-27 6:37 ` Geliang Tang
2026-07-27 2:28 ` [PATCH mptcp-next v3 2/7] mptcp: take TCP_MAXSEG handling into __mptcp_setsockopt_set_val Gang Yan
2026-07-27 6:39 ` Geliang Tang
2026-07-27 2:28 ` [PATCH mptcp-next v3 3/7] mptcp: use sockopt_lock/release_sock in sockopt Gang Yan
2026-07-27 2:28 ` [PATCH mptcp-next v3 4/7] mptcp: reject sockopt requiring ssks' lock in BPF context Gang Yan
2026-07-27 2:28 ` [PATCH mptcp-next v3 5/7] mptcp: enable bpf_setsockopt on the master socket Gang Yan
2026-07-27 2:28 ` [PATCH mptcp-next v3 6/7] mptcp: add TCP_CONNECT_CB sock_ops hook Gang Yan
2026-07-27 2:28 ` [PATCH mptcp-next v3 7/7] selftests: bpf: verify mptcp bpf_setsockopt from TCP_CONNECT_CB Gang Yan
2026-07-27 3:12 ` [PATCH mptcp-next v3 0/7] mptcp: add bpf_setsockopt support MPTCP CI
2026-07-27 6:04 ` Geliang Tang
2026-07-27 6:20 ` gang.yan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox