* [RFC mptcp-next v9 00/10] MPTCP KTLS support
@ 2026-03-13 1:42 Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 01/10] tls: introduce struct tls_prot_ops Geliang Tang
` (10 more replies)
0 siblings, 11 replies; 15+ messages in thread
From: Geliang Tang @ 2026-03-13 1:42 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
v9:
- add a new patch to "add MPTCP SKB offset check in strp queue walk",
thanks to Gang Yan for the fix.
- add a new patch to "avoid deadlocks in read_sock path", replacing the
"in_softirq()" check used in v8.
- update the selftests.
v8:
- do not hold tls_prot_ops_lock in tls_init(); otherwise, a deadlock
occurs.
- change return value of mptcp_stream_is_readable() as 'bool' to fix the
"expected restricted __poll_t" warning reported by CI.
- fixed other CI checkpatch warnings regarding excessively long lines.
- Link: https://patchwork.kernel.org/project/mptcp/cover/cover.1768294706.git.tanggeliang@kylinos.cn/
v7:
- Passing an MPTCP socket to tcp_sock_rate_check_app_limited() causes a
crash. In v7, an MPTCP version of check_app_limited() is implemented,
which calls tcp_sock_rate_check_app_limited() for each subflow.
- Register tls_tcp_ops and tls_mptcp_ops in tls_register() rather than in
tls_init().
- Set ctx->ops in tls_init() instead of in do_tls_setsockopt_conf().
- Keep tls_device.c unchanged. MPTCP TLS_HW mode has not been implemented
yet, so EOPNOTSUPP is returned in this case.
- Also add TCP TLS tests in mptcp_join.sh.
- Link: https://patchwork.kernel.org/project/mptcp/cover/cover.1768284047.git.tanggeliang@kylinos.cn/
v6:
- register each ops as Matt suggested.
- drop sk_is_msk().
- add tcp_sock_get_ulp/tcp_sock_set_ulp helpers.
- set another ULP in sock_test_tcpulp as Matt suggested.
- add tls tests using multiple subflows in mptcp_join.sh.
- Link: https://patchwork.kernel.org/project/mptcp/cover/cover.1767518836.git.tanggeliang@kylinos.cn/
v5:
- As suggested by Mat and Matt, this set introduces struct tls_prot_ops
for TLS.
- Includes Gang Yan's patches to add MPTCP support to the TLS selftests.
- Link: https://patchwork.kernel.org/project/mptcp/cover/cover.1766372799.git.tanggeliang@kylinos.cn/
v4:
- split "tls: add MPTCP protocol support" into smaller, more
focused patches.
- a new mptcp_inq helper has been implemented instead of directly
using mptcp_inq_hint to fix the issue mentioned in [1].
- add sk_is_msk helper.
- the 'expect' parameter will no longer be added to sock_test_tcpulp.
Instead, SOCK_TEST_TCPULP items causing the tests failure will be
directly removed.
- remove the "TCP KTLS" tests, keeping only the MPTCP-related ones.
- Link: https://patchwork.kernel.org/project/mptcp/cover/cover.1765505775.git.tanggeliang@kylinos.cn/
[1]
https://patchwork.kernel.org/project/mptcp/patch/ce74452f4c095a1761ef493b767b4bd9f9c14359.1764333805.git.tanggeliang@kylinos.cn/
v3:
- mptcp_read_sock() and mptcp_poll() are not exported, as mptcp_sockopt
test does not use read_sock/poll interfaces. They will be exported when
new tests are added in the future.
- call mptcp_inq_hint in tls_device_rx_resync_new_rec(),
tls_device_core_ctrl_rx_resync() and tls_read_flush_backlog() too.
- update selftests.
- Link: https://patchwork.kernel.org/project/mptcp/cover/cover.1763800601.git.tanggeliang@kylinos.cn/
v2:
- fix disconnect.
- update selftests.
This series adds KTLS support for MPTCP. Since the ULP of msk is not being
used, ULP KTLS can be directly configured onto msk without affecting its
communication.
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/480
Gang Yan (2):
tls: add MPTCP SKB offset check in strp queue walk
mptcp: update mptcp_check_readable
Geliang Tang (8):
tls: introduce struct tls_prot_ops
tls: add ops in tls_context
mptcp: avoid deadlocks in read_sock path
mptcp: implement tls_mptcp_ops
mptcp: update ULP getsockopt
mptcp: enable TLS setsockopt
selftests: mptcp: connect: set smc instead of tls
selftests: mptcp: connect: add TLS tests
include/linux/tcp.h | 2 +
include/net/mptcp.h | 2 +
include/net/tcp.h | 1 +
include/net/tls.h | 20 +++
net/ipv4/tcp.c | 87 +++++++-----
net/mptcp/protocol.c | 131 +++++++++++++++---
net/mptcp/protocol.h | 1 +
net/mptcp/sockopt.c | 37 ++++-
net/tls/tls_main.c | 107 +++++++++++++-
net/tls/tls_strp.c | 31 +++--
net/tls/tls_sw.c | 7 +-
tools/testing/selftests/net/mptcp/config | 1 +
.../selftests/net/mptcp/mptcp_connect.c | 49 ++++++-
.../selftests/net/mptcp/mptcp_connect.sh | 33 +++++
14 files changed, 438 insertions(+), 71 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [RFC mptcp-next v9 01/10] tls: introduce struct tls_prot_ops
2026-03-13 1:42 [RFC mptcp-next v9 00/10] MPTCP KTLS support Geliang Tang
@ 2026-03-13 1:42 ` Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 02/10] tls: add ops in tls_context Geliang Tang
` (9 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Geliang Tang @ 2026-03-13 1:42 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Gang Yan
From: Geliang Tang <tanggeliang@kylinos.cn>
To extend MPTCP support based on TCP TLS, a tls_prot_ops structure has
been introduced for TLS, encapsulating TCP-specific helpers within this
structure.
Add registering, validating and finding functions for this structure to
add, validate and find a tls_prot_ops on the global list tls_prot_ops_list.
Register TCP-specific structure tls_tcp_ops in tls_init().
Co-developed-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
include/net/tls.h | 19 ++++++++++
net/tls/tls_main.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 107 insertions(+)
diff --git a/include/net/tls.h b/include/net/tls.h
index ebd2550280ae..40001110bccb 100644
--- a/include/net/tls.h
+++ b/include/net/tls.h
@@ -220,6 +220,25 @@ struct tls_prot_info {
u16 tail_size;
};
+struct tls_prot_ops {
+ int protocol;
+ struct module *owner;
+ struct list_head list;
+
+ int (*inq)(struct sock *sk);
+ int (*sendmsg_locked)(struct sock *sk, struct msghdr *msg, size_t size);
+ struct sk_buff *(*recv_skb)(struct sock *sk, u32 *off);
+ int (*read_sock)(struct sock *sk, read_descriptor_t *desc,
+ sk_read_actor_t recv_actor);
+ void (*read_done)(struct sock *sk, size_t len);
+ u32 (*get_skb_off)(struct sk_buff *skb);
+ u32 (*get_skb_seq)(struct sk_buff *skb);
+ __poll_t (*poll)(struct file *file, struct socket *sock,
+ struct poll_table_struct *wait);
+ bool (*epollin_ready)(const struct sock *sk);
+ void (*check_app_limited)(struct sock *sk);
+};
+
struct tls_context {
/* read-only cache line */
struct tls_prot_info prot_info;
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
index fd39acf41a61..b123e35a153d 100644
--- a/net/tls/tls_main.c
+++ b/net/tls/tls_main.c
@@ -128,6 +128,24 @@ static struct proto_ops tls_proto_ops[TLS_NUM_PROTS][TLS_NUM_CONFIG][TLS_NUM_CON
static void build_protos(struct proto prot[TLS_NUM_CONFIG][TLS_NUM_CONFIG],
const struct proto *base);
+static DEFINE_SPINLOCK(tls_prot_ops_lock);
+static LIST_HEAD(tls_prot_ops_list);
+
+/* Must be called with rcu read lock held */
+static struct tls_prot_ops *tls_prot_ops_find(int protocol)
+{
+ struct tls_prot_ops *ops, *ret = NULL;
+
+ list_for_each_entry_rcu(ops, &tls_prot_ops_list, list) {
+ if (ops->protocol == protocol) {
+ ret = ops;
+ break;
+ }
+ }
+
+ return ret;
+}
+
void update_sk_prot(struct sock *sk, struct tls_context *ctx)
{
int ip_ver = sk->sk_family == AF_INET6 ? TLSV6 : TLSV4;
@@ -1236,6 +1254,74 @@ static struct tcp_ulp_ops tcp_tls_ulp_ops __read_mostly = {
.get_info_size = tls_get_info_size,
};
+static int tls_validate_prot_ops(const struct tls_prot_ops *ops)
+{
+ if (!ops->inq || !ops->sendmsg_locked ||
+ !ops->recv_skb || !ops->read_sock || !ops->read_done ||
+ !ops->get_skb_off || !ops->get_skb_seq ||
+ !ops->poll || !ops->epollin_ready ||
+ !ops->check_app_limited) {
+ pr_err("%d does not implement required ops\n", ops->protocol);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int tls_register_prot_ops(struct tls_prot_ops *ops)
+{
+ int ret;
+
+ ret = tls_validate_prot_ops(ops);
+ if (ret)
+ return ret;
+
+ spin_lock(&tls_prot_ops_lock);
+ if (tls_prot_ops_find(ops->protocol)) {
+ spin_unlock(&tls_prot_ops_lock);
+ return -EEXIST;
+ }
+ list_add_tail_rcu(&ops->list, &tls_prot_ops_list);
+ spin_unlock(&tls_prot_ops_lock);
+
+ pr_debug("tls_prot_ops %d registered\n", ops->protocol);
+ return 0;
+}
+
+static struct sk_buff *tls_tcp_recv_skb(struct sock *sk, u32 *off)
+{
+ return tcp_recv_skb(sk, tcp_sk(sk)->copied_seq, off);
+}
+
+static u32 tls_tcp_get_skb_off(struct sk_buff *skb)
+{
+ return 0;
+}
+
+static u32 tls_tcp_get_skb_seq(struct sk_buff *skb)
+{
+ return TCP_SKB_CB(skb)->seq;
+}
+
+static bool tls_tcp_epollin_ready(const struct sock *sk)
+{
+ return tcp_epollin_ready(sk, INT_MAX);
+}
+
+static struct tls_prot_ops tls_tcp_ops = {
+ .protocol = IPPROTO_TCP,
+ .inq = tcp_inq,
+ .sendmsg_locked = tcp_sendmsg_locked,
+ .recv_skb = tls_tcp_recv_skb,
+ .read_sock = tcp_read_sock,
+ .read_done = tcp_read_done,
+ .get_skb_off = tls_tcp_get_skb_off,
+ .get_skb_seq = tls_tcp_get_skb_seq,
+ .poll = tcp_poll,
+ .epollin_ready = tls_tcp_epollin_ready,
+ .check_app_limited = tcp_rate_check_app_limited,
+};
+
static int __init tls_register(void)
{
int err;
@@ -1254,6 +1340,8 @@ static int __init tls_register(void)
tcp_register_ulp(&tcp_tls_ulp_ops);
+ tls_register_prot_ops(&tls_tcp_ops);
+
return 0;
err_strp:
tls_strp_dev_exit();
--
2.53.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [RFC mptcp-next v9 02/10] tls: add ops in tls_context
2026-03-13 1:42 [RFC mptcp-next v9 00/10] MPTCP KTLS support Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 01/10] tls: introduce struct tls_prot_ops Geliang Tang
@ 2026-03-13 1:42 ` Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 03/10] tls: add MPTCP SKB offset check in strp queue walk Geliang Tang
` (8 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Geliang Tang @ 2026-03-13 1:42 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Gang Yan
From: Geliang Tang <tanggeliang@kylinos.cn>
A pointer to struct tls_prot_ops, named 'ops', has been added to struct
tls_context. The places originally calling TLS-specific helpers have now
been modified to indirectly invoke them via 'ops' pointer in tls_context.
In do_tls_setsockopt_conf(), ctx->ops is assigned either 'tls_mptcp_ops'
or 'tls_tcp_ops' based on the socket protocol.
Co-developed-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
include/net/tls.h | 1 +
net/tls/tls_main.c | 13 +++++++++----
net/tls/tls_strp.c | 29 +++++++++++++++++++----------
net/tls/tls_sw.c | 7 +++++--
4 files changed, 34 insertions(+), 16 deletions(-)
diff --git a/include/net/tls.h b/include/net/tls.h
index 40001110bccb..3c67c45f13be 100644
--- a/include/net/tls.h
+++ b/include/net/tls.h
@@ -277,6 +277,7 @@ struct tls_context {
struct sock *sk;
void (*sk_destruct)(struct sock *sk);
+ const struct tls_prot_ops *ops;
union tls_crypto_context crypto_send;
union tls_crypto_context crypto_recv;
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
index b123e35a153d..7c537b7fbabb 100644
--- a/net/tls/tls_main.c
+++ b/net/tls/tls_main.c
@@ -206,13 +206,13 @@ int tls_push_sg(struct sock *sk,
ctx->splicing_pages = true;
while (1) {
/* is sending application-limited? */
- tcp_rate_check_app_limited(sk);
+ ctx->ops->check_app_limited(sk);
p = sg_page(sg);
retry:
bvec_set_page(&bvec, p, size, offset);
iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, size);
- ret = tcp_sendmsg_locked(sk, &msg, size);
+ ret = ctx->ops->sendmsg_locked(sk, &msg, size);
if (ret != size) {
if (ret > 0) {
@@ -427,14 +427,14 @@ static __poll_t tls_sk_poll(struct file *file, struct socket *sock,
u8 shutdown;
int state;
- mask = tcp_poll(file, sock, wait);
+ tls_ctx = tls_get_ctx(sk);
+ mask = tls_ctx->ops->poll(file, sock, wait);
state = inet_sk_state_load(sk);
shutdown = READ_ONCE(sk->sk_shutdown);
if (unlikely(state != TCP_ESTABLISHED || shutdown & RCV_SHUTDOWN))
return mask;
- tls_ctx = tls_get_ctx(sk);
ctx = tls_sw_ctx_rx(tls_ctx);
psock = sk_psock_get(sk);
@@ -1094,6 +1094,11 @@ static int tls_init(struct sock *sk)
ctx->tx_conf = TLS_BASE;
ctx->rx_conf = TLS_BASE;
ctx->tx_max_payload_len = TLS_MAX_PAYLOAD_SIZE;
+ ctx->ops = tls_prot_ops_find(sk->sk_protocol);
+ if (!ctx->ops) {
+ rc = -EINVAL;
+ goto out;
+ }
update_sk_prot(sk, ctx);
out:
write_unlock_bh(&sk->sk_callback_lock);
diff --git a/net/tls/tls_strp.c b/net/tls/tls_strp.c
index 98e12f0ff57e..ef1a8659ee18 100644
--- a/net/tls/tls_strp.c
+++ b/net/tls/tls_strp.c
@@ -120,6 +120,7 @@ struct sk_buff *tls_strp_msg_detach(struct tls_sw_context_rx *ctx)
int tls_strp_msg_cow(struct tls_sw_context_rx *ctx)
{
struct tls_strparser *strp = &ctx->strp;
+ struct tls_context *tls_ctx;
struct sk_buff *skb;
if (strp->copy_mode)
@@ -132,7 +133,8 @@ int tls_strp_msg_cow(struct tls_sw_context_rx *ctx)
tls_strp_anchor_free(strp);
strp->anchor = skb;
- tcp_read_done(strp->sk, strp->stm.full_len);
+ tls_ctx = tls_get_ctx(strp->sk);
+ tls_ctx->ops->read_done(strp->sk, strp->stm.full_len);
strp->copy_mode = 1;
return 0;
@@ -376,6 +378,7 @@ static int tls_strp_copyin(read_descriptor_t *desc, struct sk_buff *in_skb,
static int tls_strp_read_copyin(struct tls_strparser *strp)
{
+ struct tls_context *ctx = tls_get_ctx(strp->sk);
read_descriptor_t desc;
desc.arg.data = strp;
@@ -383,13 +386,14 @@ static int tls_strp_read_copyin(struct tls_strparser *strp)
desc.count = 1; /* give more than one skb per call */
/* sk should be locked here, so okay to do read_sock */
- tcp_read_sock(strp->sk, &desc, tls_strp_copyin);
+ ctx->ops->read_sock(strp->sk, &desc, tls_strp_copyin);
return desc.error;
}
static int tls_strp_read_copy(struct tls_strparser *strp, bool qshort)
{
+ struct tls_context *ctx = tls_get_ctx(strp->sk);
struct skb_shared_info *shinfo;
struct page *page;
int need_spc, len;
@@ -398,7 +402,7 @@ static int tls_strp_read_copy(struct tls_strparser *strp, bool qshort)
* to read the data out. Otherwise the connection will stall.
* Without pressure threshold of INT_MAX will never be ready.
*/
- if (likely(qshort && !tcp_epollin_ready(strp->sk, INT_MAX)))
+ if (likely(qshort && !ctx->ops->epollin_ready(strp->sk)))
return 0;
shinfo = skb_shinfo(strp->anchor);
@@ -434,12 +438,13 @@ static int tls_strp_read_copy(struct tls_strparser *strp, bool qshort)
static bool tls_strp_check_queue_ok(struct tls_strparser *strp)
{
unsigned int len = strp->stm.offset + strp->stm.full_len;
+ struct tls_context *ctx = tls_get_ctx(strp->sk);
struct sk_buff *first, *skb;
u32 seq;
first = skb_shinfo(strp->anchor)->frag_list;
skb = first;
- seq = TCP_SKB_CB(first)->seq;
+ seq = ctx->ops->get_skb_seq(first);
/* Make sure there's no duplicate data in the queue,
* and the decrypted status matches.
@@ -449,7 +454,7 @@ static bool tls_strp_check_queue_ok(struct tls_strparser *strp)
len -= skb->len;
skb = skb->next;
- if (TCP_SKB_CB(skb)->seq != seq)
+ if (ctx->ops->get_skb_seq(skb) != seq)
return false;
if (skb_cmp_decrypted(first, skb))
return false;
@@ -460,11 +465,11 @@ static bool tls_strp_check_queue_ok(struct tls_strparser *strp)
static void tls_strp_load_anchor_with_queue(struct tls_strparser *strp, int len)
{
- struct tcp_sock *tp = tcp_sk(strp->sk);
+ struct tls_context *ctx = tls_get_ctx(strp->sk);
struct sk_buff *first;
u32 offset;
- first = tcp_recv_skb(strp->sk, tp->copied_seq, &offset);
+ first = ctx->ops->recv_skb(strp->sk, &offset);
if (WARN_ON_ONCE(!first))
return;
@@ -483,6 +488,7 @@ static void tls_strp_load_anchor_with_queue(struct tls_strparser *strp, int len)
bool tls_strp_msg_load(struct tls_strparser *strp, bool force_refresh)
{
+ struct tls_context *ctx = tls_get_ctx(strp->sk);
struct strp_msg *rxm;
struct tls_msg *tlm;
@@ -490,7 +496,7 @@ bool tls_strp_msg_load(struct tls_strparser *strp, bool force_refresh)
DEBUG_NET_WARN_ON_ONCE(!strp->stm.full_len);
if (!strp->copy_mode && force_refresh) {
- if (unlikely(tcp_inq(strp->sk) < strp->stm.full_len)) {
+ if (unlikely(ctx->ops->inq(strp->sk) < strp->stm.full_len)) {
WRITE_ONCE(strp->msg_ready, 0);
memset(&strp->stm, 0, sizeof(strp->stm));
return false;
@@ -511,9 +517,10 @@ bool tls_strp_msg_load(struct tls_strparser *strp, bool force_refresh)
/* Called with lock held on lower socket */
static int tls_strp_read_sock(struct tls_strparser *strp)
{
+ struct tls_context *ctx = tls_get_ctx(strp->sk);
int sz, inq;
- inq = tcp_inq(strp->sk);
+ inq = ctx->ops->inq(strp->sk);
if (inq < 1)
return 0;
@@ -583,10 +590,12 @@ static void tls_strp_work(struct work_struct *w)
void tls_strp_msg_done(struct tls_strparser *strp)
{
+ struct tls_context *ctx = tls_get_ctx(strp->sk);
+
WARN_ON(!strp->stm.full_len);
if (likely(!strp->copy_mode))
- tcp_read_done(strp->sk, strp->stm.full_len);
+ ctx->ops->read_done(strp->sk, strp->stm.full_len);
else
tls_strp_flush_anchor_copy(strp);
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index a656ce235758..b6959ebcded8 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -1952,13 +1952,14 @@ tls_read_flush_backlog(struct sock *sk, struct tls_prot_info *prot,
size_t len_left, size_t decrypted, ssize_t done,
size_t *flushed_at)
{
+ struct tls_context *tls_ctx = tls_get_ctx(sk);
size_t max_rec;
if (len_left <= decrypted)
return false;
max_rec = prot->overhead_size - prot->tail_size + TLS_MAX_PAYLOAD_SIZE;
- if (done - *flushed_at < SZ_128K && tcp_inq(sk) > max_rec)
+ if (done - *flushed_at < SZ_128K && tls_ctx->ops->inq(sk) > max_rec)
return false;
*flushed_at = done;
@@ -2445,6 +2446,7 @@ int tls_rx_msg_size(struct tls_strparser *strp, struct sk_buff *skb)
size_t cipher_overhead;
size_t data_len = 0;
int ret;
+ u32 seq;
/* Verify that we have a full TLS header, or wait for more data */
if (strp->stm.offset + prot->prepend_size > skb->len)
@@ -2487,8 +2489,9 @@ int tls_rx_msg_size(struct tls_strparser *strp, struct sk_buff *skb)
goto read_failure;
}
+ seq = tls_ctx->ops->get_skb_seq(skb);
tls_device_rx_resync_new_rec(strp->sk, data_len + TLS_HEADER_SIZE,
- TCP_SKB_CB(skb)->seq + strp->stm.offset);
+ seq + strp->stm.offset);
return data_len + TLS_HEADER_SIZE;
read_failure:
--
2.53.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [RFC mptcp-next v9 03/10] tls: add MPTCP SKB offset check in strp queue walk
2026-03-13 1:42 [RFC mptcp-next v9 00/10] MPTCP KTLS support Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 01/10] tls: introduce struct tls_prot_ops Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 02/10] tls: add ops in tls_context Geliang Tang
@ 2026-03-13 1:42 ` Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 04/10] mptcp: update mptcp_check_readable Geliang Tang
` (7 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Geliang Tang @ 2026-03-13 1:42 UTC (permalink / raw)
To: mptcp; +Cc: Gang Yan, Geliang Tang
From: Gang Yan <yangang@kylinos.cn>
In MPTCP scenarios, subflow SKBs may have non-zero offsets due to
out-of-order packet handling or partial data delivery. When walking
the TLS strp queue to verify sequence numbers and decryption status,
we must also validate each SKB's offset using get_skb_off() to ensure
the queue state is consistent. This check is specific to MPTCP; TCP
does not require offset validation as its SKBs always start at offset 0.
If any SKB reports an invalid offset, return false to indicate the
queue is not in a consistent state and trigger a resynchronization.
Co-developed-by: Geliang Tang <geliang@kernel.org>
Signed-off-by: Geliang Tang <geliang@kernel.org>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
net/tls/tls_strp.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/tls/tls_strp.c b/net/tls/tls_strp.c
index ef1a8659ee18..4cf0dfbd7fb4 100644
--- a/net/tls/tls_strp.c
+++ b/net/tls/tls_strp.c
@@ -454,6 +454,8 @@ static bool tls_strp_check_queue_ok(struct tls_strparser *strp)
len -= skb->len;
skb = skb->next;
+ if (ctx->ops->get_skb_off(skb))
+ return false;
if (ctx->ops->get_skb_seq(skb) != seq)
return false;
if (skb_cmp_decrypted(first, skb))
--
2.53.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [RFC mptcp-next v9 04/10] mptcp: update mptcp_check_readable
2026-03-13 1:42 [RFC mptcp-next v9 00/10] MPTCP KTLS support Geliang Tang
` (2 preceding siblings ...)
2026-03-13 1:42 ` [RFC mptcp-next v9 03/10] tls: add MPTCP SKB offset check in strp queue walk Geliang Tang
@ 2026-03-13 1:42 ` Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 05/10] mptcp: avoid deadlocks in read_sock path Geliang Tang
` (6 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Geliang Tang @ 2026-03-13 1:42 UTC (permalink / raw)
To: mptcp; +Cc: Gang Yan, Geliang Tang
From: Gang Yan <yangang@kylinos.cn>
This patch makes mptcp_check_readable() aligned with TCP, and renames it to
mptcp_stream_is_readable(). It will be used in the case of KTLS, because
'prot' will be modified, tls_sw_sock_is_readable() is expected to be called
from prot->sock_is_readable().
Co-developed-by: Geliang Tang <geliang@kernel.org>
Signed-off-by: Geliang Tang <geliang@kernel.org>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
net/mptcp/protocol.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index b5676b37f8f4..c0109338648a 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3242,9 +3242,11 @@ void __mptcp_unaccepted_force_close(struct sock *sk)
__mptcp_destroy_sock(sk);
}
-static __poll_t mptcp_check_readable(struct sock *sk)
+static bool mptcp_stream_is_readable(struct sock *sk)
{
- return mptcp_epollin_ready(sk) ? EPOLLIN | EPOLLRDNORM : 0;
+ if (mptcp_epollin_ready(sk))
+ return true;
+ return sk_is_readable(sk);
}
static void mptcp_check_listen_stop(struct sock *sk)
@@ -4306,7 +4308,8 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock,
mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP;
if (state != TCP_SYN_SENT && state != TCP_SYN_RECV) {
- mask |= mptcp_check_readable(sk);
+ if (mptcp_stream_is_readable(sk))
+ mask |= EPOLLIN | EPOLLRDNORM;
if (shutdown & SEND_SHUTDOWN)
mask |= EPOLLOUT | EPOLLWRNORM;
else
--
2.53.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [RFC mptcp-next v9 05/10] mptcp: avoid deadlocks in read_sock path
2026-03-13 1:42 [RFC mptcp-next v9 00/10] MPTCP KTLS support Geliang Tang
` (3 preceding siblings ...)
2026-03-13 1:42 ` [RFC mptcp-next v9 04/10] mptcp: update mptcp_check_readable Geliang Tang
@ 2026-03-13 1:42 ` Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 06/10] mptcp: implement tls_mptcp_ops Geliang Tang
` (5 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Geliang Tang @ 2026-03-13 1:42 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Gang Yan
From: Geliang Tang <tanggeliang@kylinos.cn>
When invoking mptcp_read_sock() from a softirq context (e.g., through
the TLS read_sock interface), calling lock_sock_fast() in
mptcp_rcv_space_adjust() or mptcp_cleanup_rbuf() can lead to deadlocks,
since the socket lock may already be held.
Replace lock_sock_fast() with spin_trylock_bh() in these functions to
make the locking attempt non-blocking. If the lock cannot be acquired,
skip the operation to avoid deadlock.
Also introduce mptcp_data_trylock() and use it in mptcp_move_skbs() to
make the data locking non-blocking in the read_sock path.
Co-developed-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
net/mptcp/protocol.c | 16 ++++++++--------
net/mptcp/protocol.h | 1 +
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index c0109338648a..fdfe6145f6da 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -557,12 +557,11 @@ static void mptcp_send_ack(struct mptcp_sock *msk)
static void mptcp_subflow_cleanup_rbuf(struct sock *ssk, int copied)
{
- bool slow;
-
- slow = lock_sock_fast(ssk);
+ if (!spin_trylock_bh(&ssk->sk_lock.slock))
+ return;
if (tcp_can_send_ack(ssk))
tcp_cleanup_rbuf(ssk, copied);
- unlock_sock_fast(ssk, slow);
+ spin_unlock_bh(&ssk->sk_lock.slock);
}
static bool mptcp_subflow_could_cleanup(const struct sock *ssk, bool rx_empty)
@@ -2152,14 +2151,14 @@ static void mptcp_rcv_space_adjust(struct mptcp_sock *msk, int copied)
*/
mptcp_for_each_subflow(msk, subflow) {
struct sock *ssk;
- bool slow;
ssk = mptcp_subflow_tcp_sock(subflow);
- slow = lock_sock_fast(ssk);
+ if (!spin_trylock_bh(&ssk->sk_lock.slock))
+ continue;
/* subflows can be added before tcp_init_transfer() */
if (tcp_sk(ssk)->rcvq_space.space)
tcp_rcvbuf_grow(ssk, copied);
- unlock_sock_fast(ssk, slow);
+ spin_unlock_bh(&ssk->sk_lock.slock);
}
}
@@ -2232,7 +2231,8 @@ static bool mptcp_move_skbs(struct sock *sk)
bool enqueued = false;
u32 moved;
- mptcp_data_lock(sk);
+ if (!mptcp_data_trylock(sk))
+ return false;
while (mptcp_can_spool_backlog(sk, &skbs)) {
mptcp_data_unlock(sk);
enqueued |= __mptcp_move_skbs(sk, &skbs, &moved);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index f5d4d7d030f2..3146e26687b4 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -378,6 +378,7 @@ struct mptcp_sock {
};
#define mptcp_data_lock(sk) spin_lock_bh(&(sk)->sk_lock.slock)
+#define mptcp_data_trylock(sk) spin_trylock_bh(&(sk)->sk_lock.slock)
#define mptcp_data_unlock(sk) spin_unlock_bh(&(sk)->sk_lock.slock)
#define mptcp_for_each_subflow(__msk, __subflow) \
--
2.53.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [RFC mptcp-next v9 06/10] mptcp: implement tls_mptcp_ops
2026-03-13 1:42 [RFC mptcp-next v9 00/10] MPTCP KTLS support Geliang Tang
` (4 preceding siblings ...)
2026-03-13 1:42 ` [RFC mptcp-next v9 05/10] mptcp: avoid deadlocks in read_sock path Geliang Tang
@ 2026-03-13 1:42 ` Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 07/10] mptcp: update ULP getsockopt Geliang Tang
` (4 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Geliang Tang @ 2026-03-13 1:42 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Gang Yan
From: Geliang Tang <tanggeliang@kylinos.cn>
This patch implements the MPTCP-specific struct tls_prot_ops, named
'tls_mptcp_ops'.
Note that there is a slight difference between mptcp_inq() and
mptcp_inq_hint(), it does not return 1 when the socket is closed or
shut down; instead, it returns 0. Otherwise, it would break the
condition "inq < 1" in tls_strp_read_sock().
Passing an MPTCP socket to tcp_sock_rate_check_app_limited() can
trigger a crash. Here, an MPTCP version of check_app_limited() is
implemented, which calls tcp_sock_rate_check_app_limited() for each
subflow.
MPTCP TLS_HW mode is not yet implemented, returning EOPNOTSUPP here.
Co-developed-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
include/net/mptcp.h | 2 +
include/net/tcp.h | 1 +
net/ipv4/tcp.c | 9 +++-
net/mptcp/protocol.c | 106 ++++++++++++++++++++++++++++++++++++++++---
net/tls/tls_main.c | 6 +++
5 files changed, 116 insertions(+), 8 deletions(-)
diff --git a/include/net/mptcp.h b/include/net/mptcp.h
index 4cf59e83c1c5..02564eceeb7e 100644
--- a/include/net/mptcp.h
+++ b/include/net/mptcp.h
@@ -132,6 +132,8 @@ struct mptcp_pm_ops {
void (*release)(struct mptcp_sock *msk);
} ____cacheline_aligned_in_smp;
+extern struct tls_prot_ops tls_mptcp_ops;
+
#ifdef CONFIG_MPTCP
void mptcp_init(void);
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 9f0aee9e5d76..071a25e77c03 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -837,6 +837,7 @@ static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize)
/* tcp.c */
void tcp_get_info(struct sock *, struct tcp_info *);
+void tcp_sock_rate_check_app_limited(struct tcp_sock *tp);
void tcp_rate_check_app_limited(struct sock *sk);
/* Read 'sendfile()'-style from a TCP socket */
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index fe23550d5c51..400f84f193a3 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1110,9 +1110,9 @@ int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, int *copied,
}
/* If a gap is detected between sends, mark the socket application-limited. */
-void tcp_rate_check_app_limited(struct sock *sk)
+void tcp_sock_rate_check_app_limited(struct tcp_sock *tp)
{
- struct tcp_sock *tp = tcp_sk(sk);
+ struct sock *sk = (struct sock *)tp;
if (/* We have less than one packet to send. */
tp->write_seq - tp->snd_nxt < tp->mss_cache &&
@@ -1125,6 +1125,11 @@ void tcp_rate_check_app_limited(struct sock *sk)
tp->app_limited =
(tp->delivered + tcp_packets_in_flight(tp)) ? : 1;
}
+
+void tcp_rate_check_app_limited(struct sock *sk)
+{
+ tcp_sock_rate_check_app_limited(tcp_sk(sk));
+}
EXPORT_SYMBOL_GPL(tcp_rate_check_app_limited);
int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index fdfe6145f6da..f6351b663a01 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -24,11 +24,12 @@
#include <net/mptcp.h>
#include <net/hotdata.h>
#include <net/xfrm.h>
+#include <net/tls.h>
#include <asm/ioctls.h>
#include "protocol.h"
#include "mib.h"
-static unsigned int mptcp_inq_hint(const struct sock *sk);
+static unsigned int mptcp_inq_hint(struct sock *sk);
#define CREATE_TRACE_POINTS
#include <trace/events/mptcp.h>
@@ -1885,7 +1886,7 @@ static void mptcp_rps_record_subflows(const struct mptcp_sock *msk)
}
}
-static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+static int mptcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t len)
{
struct mptcp_sock *msk = mptcp_sk(sk);
struct page_frag *pfrag;
@@ -1896,8 +1897,6 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
/* silently ignore everything else */
msg->msg_flags &= MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | MSG_FASTOPEN;
- lock_sock(sk);
-
mptcp_rps_record_subflows(msk);
if (unlikely(inet_test_bit(DEFER_CONNECT, sk) ||
@@ -2005,7 +2004,6 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
__mptcp_push_pending(sk, msg->msg_flags);
out:
- release_sock(sk);
return copied;
do_error:
@@ -2016,6 +2014,17 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
goto out;
}
+static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+{
+ int ret;
+
+ lock_sock(sk);
+ ret = mptcp_sendmsg_locked(sk, msg, len);
+ release_sock(sk);
+
+ return ret;
+}
+
static void mptcp_rcv_space_adjust(struct mptcp_sock *msk, int copied);
static void mptcp_eat_recv_skb(struct sock *sk, struct sk_buff *skb)
@@ -2244,7 +2253,7 @@ static bool mptcp_move_skbs(struct sock *sk)
return enqueued;
}
-static unsigned int mptcp_inq_hint(const struct sock *sk)
+static int mptcp_inq(struct sock *sk)
{
const struct mptcp_sock *msk = mptcp_sk(sk);
const struct sk_buff *skb;
@@ -2259,6 +2268,16 @@ static unsigned int mptcp_inq_hint(const struct sock *sk)
return (unsigned int)hint_val;
}
+ return 0;
+}
+
+static unsigned int mptcp_inq_hint(struct sock *sk)
+{
+ unsigned int inq = mptcp_inq(sk);
+
+ if (inq)
+ return inq;
+
if (sk->sk_state == TCP_CLOSE || (sk->sk_shutdown & RCV_SHUTDOWN))
return 1;
@@ -4684,3 +4703,78 @@ int __init mptcp_proto_v6_init(void)
return err;
}
#endif
+
+static void mptcp_read_done(struct sock *sk, size_t len)
+{
+ struct mptcp_sock *msk = mptcp_sk(sk);
+ struct sk_buff *skb;
+ size_t left;
+ u32 offset;
+
+ msk_owned_by_me(msk);
+
+ if (sk->sk_state == TCP_LISTEN)
+ return;
+
+ left = len;
+ while (left && (skb = mptcp_recv_skb(sk, &offset)) != NULL) {
+ int used;
+
+ used = min_t(size_t, skb->len - offset, left);
+ msk->bytes_consumed += used;
+ MPTCP_SKB_CB(skb)->offset += used;
+ MPTCP_SKB_CB(skb)->map_seq += used;
+ left -= used;
+
+ if (skb->len > offset + used)
+ break;
+
+ mptcp_eat_recv_skb(sk, skb);
+ }
+
+ mptcp_rcv_space_adjust(msk, len - left);
+
+ /* Clean up data we have read: This will do ACK frames. */
+ if (left != len)
+ mptcp_cleanup_rbuf(msk, len - left);
+}
+
+static u32 mptcp_get_skb_off(struct sk_buff *skb)
+{
+ return MPTCP_SKB_CB(skb)->offset;
+}
+
+static u32 mptcp_get_skb_seq(struct sk_buff *skb)
+{
+ return MPTCP_SKB_CB(skb)->map_seq;
+}
+
+static void mptcp_check_app_limited(struct sock *sk)
+{
+ struct mptcp_sock *msk = mptcp_sk(sk);
+ struct mptcp_subflow_context *subflow;
+
+ mptcp_for_each_subflow(msk, subflow) {
+ struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+ bool slow;
+
+ slow = lock_sock_fast(ssk);
+ tcp_sock_rate_check_app_limited(tcp_sk(ssk));
+ unlock_sock_fast(ssk, slow);
+ }
+}
+
+struct tls_prot_ops tls_mptcp_ops = {
+ .protocol = IPPROTO_MPTCP,
+ .inq = mptcp_inq,
+ .sendmsg_locked = mptcp_sendmsg_locked,
+ .recv_skb = mptcp_recv_skb,
+ .read_sock = mptcp_read_sock,
+ .read_done = mptcp_read_done,
+ .get_skb_off = mptcp_get_skb_off,
+ .get_skb_seq = mptcp_get_skb_seq,
+ .poll = mptcp_poll,
+ .epollin_ready = mptcp_epollin_ready,
+ .check_app_limited = mptcp_check_app_limited,
+};
+EXPORT_SYMBOL(tls_mptcp_ops);
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
index 7c537b7fbabb..79c7f2efcda8 100644
--- a/net/tls/tls_main.c
+++ b/net/tls/tls_main.c
@@ -772,6 +772,9 @@ static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
tls_sw_strparser_arm(sk, ctx);
}
+ if (conf == TLS_HW && sk->sk_protocol == IPPROTO_MPTCP)
+ return -EOPNOTSUPP;
+
if (tx)
ctx->tx_conf = conf;
else
@@ -1346,6 +1349,9 @@ static int __init tls_register(void)
tcp_register_ulp(&tcp_tls_ulp_ops);
tls_register_prot_ops(&tls_tcp_ops);
+#ifdef CONFIG_MPTCP
+ tls_register_prot_ops(&tls_mptcp_ops);
+#endif
return 0;
err_strp:
--
2.53.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [RFC mptcp-next v9 07/10] mptcp: update ULP getsockopt
2026-03-13 1:42 [RFC mptcp-next v9 00/10] MPTCP KTLS support Geliang Tang
` (5 preceding siblings ...)
2026-03-13 1:42 ` [RFC mptcp-next v9 06/10] mptcp: implement tls_mptcp_ops Geliang Tang
@ 2026-03-13 1:42 ` Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 08/10] mptcp: enable TLS setsockopt Geliang Tang
` (3 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Geliang Tang @ 2026-03-13 1:42 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Gang Yan
From: Geliang Tang <tanggeliang@kylinos.cn>
This patch extracts TCP_ULP getsockopt operation into a tcp_sock_get_ulp()
helper so that it can also be used in MPTCP.
TCP_ULP was obtained by calling mptcp_getsockopt_first_sf_only() to get
ULP of the first subflow. Now that the mechanism has changed, a new helper
mptcp_getsockopt_tcp_ulp() is added to get ULP of msk.
Co-developed-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
include/linux/tcp.h | 1 +
net/ipv4/tcp.c | 36 ++++++++++++++++++++++--------------
net/mptcp/sockopt.c | 12 ++++++++++++
3 files changed, 35 insertions(+), 14 deletions(-)
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index c44cf9ae8d16..2e673f7b10ef 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -643,6 +643,7 @@ void tcp_sock_set_quickack(struct sock *sk, int val);
int tcp_sock_set_syncnt(struct sock *sk, int val);
int tcp_sock_set_user_timeout(struct sock *sk, int val);
int tcp_sock_set_maxseg(struct sock *sk, int val);
+int tcp_sock_get_ulp(struct sock *sk, sockptr_t optval, sockptr_t optlen);
static inline bool dst_tcp_usec_ts(const struct dst_entry *dst)
{
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 400f84f193a3..63b576eebae6 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -4494,6 +4494,27 @@ struct sk_buff *tcp_get_timestamping_opt_stats(const struct sock *sk,
return stats;
}
+int tcp_sock_get_ulp(struct sock *sk, sockptr_t optval, sockptr_t optlen)
+{
+ struct inet_connection_sock *icsk = inet_csk(sk);
+ int len;
+
+ if (copy_from_sockptr(&len, optlen, sizeof(int)))
+ return -EFAULT;
+ len = min_t(unsigned int, len, TCP_ULP_NAME_MAX);
+ if (!icsk->icsk_ulp_ops) {
+ len = 0;
+ if (copy_to_sockptr(optlen, &len, sizeof(int)))
+ return -EFAULT;
+ return 0;
+ }
+ if (copy_to_sockptr(optlen, &len, sizeof(int)))
+ return -EFAULT;
+ if (copy_to_sockptr(optval, icsk->icsk_ulp_ops->name, len))
+ return -EFAULT;
+ return 0;
+}
+
int do_tcp_getsockopt(struct sock *sk, int level,
int optname, sockptr_t optval, sockptr_t optlen)
{
@@ -4603,20 +4624,7 @@ int do_tcp_getsockopt(struct sock *sk, int level,
return 0;
case TCP_ULP:
- if (copy_from_sockptr(&len, optlen, sizeof(int)))
- return -EFAULT;
- len = min_t(unsigned int, len, TCP_ULP_NAME_MAX);
- if (!icsk->icsk_ulp_ops) {
- len = 0;
- if (copy_to_sockptr(optlen, &len, sizeof(int)))
- return -EFAULT;
- return 0;
- }
- if (copy_to_sockptr(optlen, &len, sizeof(int)))
- return -EFAULT;
- if (copy_to_sockptr(optval, icsk->icsk_ulp_ops->name, len))
- return -EFAULT;
- return 0;
+ return tcp_sock_get_ulp(sk, optval, optlen);
case TCP_FASTOPEN_KEY: {
u64 key[TCP_FASTOPEN_KEY_BUF_LENGTH / sizeof(u64)];
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index de90a2897d2d..a6230f7910fd 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -1393,6 +1393,17 @@ static int mptcp_put_int_option(struct mptcp_sock *msk, char __user *optval,
return 0;
}
+static int mptcp_getsockopt_tcp_ulp(struct sock *sk, char __user *optval,
+ int __user *optlen)
+{
+ int ret;
+
+ lock_sock(sk);
+ ret = tcp_sock_get_ulp(sk, USER_SOCKPTR(optval), USER_SOCKPTR(optlen));
+ release_sock(sk);
+ return ret;
+}
+
static int mptcp_getsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
char __user *optval, int __user *optlen)
{
@@ -1400,6 +1411,7 @@ static int mptcp_getsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
switch (optname) {
case TCP_ULP:
+ return mptcp_getsockopt_tcp_ulp(sk, optval, optlen);
case TCP_CONGESTION:
case TCP_INFO:
case TCP_CC_INFO:
--
2.53.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [RFC mptcp-next v9 08/10] mptcp: enable TLS setsockopt
2026-03-13 1:42 [RFC mptcp-next v9 00/10] MPTCP KTLS support Geliang Tang
` (6 preceding siblings ...)
2026-03-13 1:42 ` [RFC mptcp-next v9 07/10] mptcp: update ULP getsockopt Geliang Tang
@ 2026-03-13 1:42 ` Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 09/10] selftests: mptcp: connect: set smc instead of tls Geliang Tang
` (2 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Geliang Tang @ 2026-03-13 1:42 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Gang Yan
From: Geliang Tang <tanggeliang@kylinos.cn>
This patch extracts TCP_ULP setsockopt operation into a tcp_sock_set_ulp()
helper so that it can also be used in MPTCP.
Add MPTCP TLS setsockopt support in mptcp_setsockopt_sol_tcp(). It allows
setting the TCP_ULP option to 'tls' exclusively, and enables configuration
of the TLS_TX and TLS_RX options at the SOL_TLS level.
This option cannot be set when the socket is in CLOSE or LISTEN state.
Co-developed-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
include/linux/tcp.h | 1 +
net/ipv4/tcp.c | 42 ++++++++++++++++++++++++------------------
net/mptcp/sockopt.c | 25 ++++++++++++++++++++++++-
3 files changed, 49 insertions(+), 19 deletions(-)
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 2e673f7b10ef..79bf6356b98f 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -644,6 +644,7 @@ int tcp_sock_set_syncnt(struct sock *sk, int val);
int tcp_sock_set_user_timeout(struct sock *sk, int val);
int tcp_sock_set_maxseg(struct sock *sk, int val);
int tcp_sock_get_ulp(struct sock *sk, sockptr_t optval, sockptr_t optlen);
+int tcp_sock_set_ulp(struct sock *sk, sockptr_t optval, unsigned int optlen);
static inline bool dst_tcp_usec_ts(const struct dst_entry *dst)
{
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 63b576eebae6..6cfb2e3faf73 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3857,6 +3857,28 @@ int tcp_sock_set_maxseg(struct sock *sk, int val)
return 0;
}
+int tcp_sock_set_ulp(struct sock *sk, sockptr_t optval, unsigned int optlen)
+{
+ char name[TCP_ULP_NAME_MAX];
+ int err = 0;
+ size_t len;
+ int val;
+
+ if (optlen < 1)
+ return -EINVAL;
+
+ len = min_t(long, TCP_ULP_NAME_MAX - 1, optlen);
+ val = strncpy_from_sockptr(name, optval, len);
+ if (val < 0)
+ return -EFAULT;
+ name[val] = 0;
+
+ sockopt_lock_sock(sk);
+ err = tcp_set_ulp(sk, name);
+ sockopt_release_sock(sk);
+ return err;
+}
+
/*
* Socket option code for TCP.
*/
@@ -3890,24 +3912,8 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname,
sockopt_release_sock(sk);
return err;
}
- case TCP_ULP: {
- char name[TCP_ULP_NAME_MAX];
-
- if (optlen < 1)
- return -EINVAL;
-
- val = strncpy_from_sockptr(name, optval,
- min_t(long, TCP_ULP_NAME_MAX - 1,
- optlen));
- if (val < 0)
- return -EFAULT;
- name[val] = 0;
-
- sockopt_lock_sock(sk);
- err = tcp_set_ulp(sk, name);
- sockopt_release_sock(sk);
- return err;
- }
+ case TCP_ULP:
+ return tcp_sock_set_ulp(sk, optval, optlen);
case TCP_FASTOPEN_KEY: {
__u8 key[TCP_FASTOPEN_KEY_BUF_LENGTH];
__u8 *backup_key = NULL;
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index a6230f7910fd..aafc627b3da9 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -12,6 +12,7 @@
#include <net/protocol.h>
#include <net/tcp.h>
#include <net/mptcp.h>
+#include <net/tls.h>
#include "protocol.h"
#define MIN_INFO_OPTLEN_SIZE 16
@@ -567,6 +568,7 @@ static bool mptcp_supported_sockopt(int level, int optname)
case TCP_FASTOPEN_CONNECT:
case TCP_FASTOPEN_KEY:
case TCP_FASTOPEN_NO_COOKIE:
+ case TCP_ULP:
return true;
}
@@ -576,6 +578,13 @@ static bool mptcp_supported_sockopt(int level, int optname)
* TCP_REPAIR_WINDOW are not supported, better avoid this mess
*/
}
+ if (level == SOL_TLS) {
+ switch (optname) {
+ case TLS_TX:
+ case TLS_RX:
+ return true;
+ }
+ }
return false;
}
@@ -815,6 +824,20 @@ static int mptcp_setsockopt_all_sf(struct mptcp_sock *msk, int level,
return ret;
}
+static int mptcp_setsockopt_tcp_ulp(struct sock *sk, sockptr_t optval,
+ unsigned int optlen)
+{
+ char ulp[4] = "";
+
+ if (copy_from_user(ulp, optval.user, 4))
+ return -EFAULT;
+ if (strcmp(ulp, "tls\0"))
+ return -EOPNOTSUPP;
+ if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))
+ return -ENOTCONN;
+ return tcp_sock_set_ulp(sk, optval, optlen);
+}
+
static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
sockptr_t optval, unsigned int optlen)
{
@@ -823,7 +846,7 @@ static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
switch (optname) {
case TCP_ULP:
- return -EOPNOTSUPP;
+ return mptcp_setsockopt_tcp_ulp(sk, optval, optlen);
case TCP_CONGESTION:
return mptcp_setsockopt_sol_tcp_congestion(msk, optval, optlen);
case TCP_DEFER_ACCEPT:
--
2.53.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [RFC mptcp-next v9 09/10] selftests: mptcp: connect: set smc instead of tls
2026-03-13 1:42 [RFC mptcp-next v9 00/10] MPTCP KTLS support Geliang Tang
` (7 preceding siblings ...)
2026-03-13 1:42 ` [RFC mptcp-next v9 08/10] mptcp: enable TLS setsockopt Geliang Tang
@ 2026-03-13 1:42 ` Geliang Tang
2026-03-13 6:26 ` Dust Li
2026-03-13 1:42 ` [RFC mptcp-next v9 10/10] selftests: mptcp: connect: add TLS tests Geliang Tang
2026-03-13 4:27 ` [RFC mptcp-next v9 00/10] MPTCP KTLS support MPTCP CI
10 siblings, 1 reply; 15+ messages in thread
From: Geliang Tang @ 2026-03-13 1:42 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Dust Li, Gang Yan
From: Geliang Tang <tanggeliang@kylinos.cn>
With KTLS being implemented, "tls" should no longer be used in
sock_test_tcpulp(), it breaks mptcp_connect.sh tests. Another ULP
name, "smc", is set instead in this patch.
Cc: Dust Li <dust.li@linux.alibaba.com>
Co-developed-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
tools/testing/selftests/net/mptcp/config | 1 +
tools/testing/selftests/net/mptcp/mptcp_connect.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/net/mptcp/config b/tools/testing/selftests/net/mptcp/config
index 59051ee2a986..18bd29ac5b24 100644
--- a/tools/testing/selftests/net/mptcp/config
+++ b/tools/testing/selftests/net/mptcp/config
@@ -34,3 +34,4 @@ CONFIG_NFT_SOCKET=m
CONFIG_NFT_TPROXY=m
CONFIG_SYN_COOKIES=y
CONFIG_VETH=y
+CONFIG_TLS=y
diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c
index cbe573c4ab3a..64c8a4bfe749 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_connect.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c
@@ -289,7 +289,7 @@ static void sock_test_tcpulp(int sock, int proto, unsigned int line)
if (ret == 0)
X("setsockopt");
} else if (proto == IPPROTO_MPTCP) {
- ret = do_ulp_so(sock, "tls");
+ ret = do_ulp_so(sock, "smc");
if (ret != -1)
X("setsockopt");
}
--
2.53.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [RFC mptcp-next v9 10/10] selftests: mptcp: connect: add TLS tests
2026-03-13 1:42 [RFC mptcp-next v9 00/10] MPTCP KTLS support Geliang Tang
` (8 preceding siblings ...)
2026-03-13 1:42 ` [RFC mptcp-next v9 09/10] selftests: mptcp: connect: set smc instead of tls Geliang Tang
@ 2026-03-13 1:42 ` Geliang Tang
2026-03-13 4:27 ` [RFC mptcp-next v9 00/10] MPTCP KTLS support MPTCP CI
10 siblings, 0 replies; 15+ messages in thread
From: Geliang Tang @ 2026-03-13 1:42 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Gang Yan
From: Geliang Tang <tanggeliang@kylinos.cn>
This patch adds MPTCP TLS tests for mptcp_connect.c/mptcp_connect.sh.
A new TLS type has been added to cfg_sockopt_types, enabled via the
parameter "-o TLS". do_setsockopt_tls() has been implemented to set
TLS parameters for both the server and client.
After adding TLS configuration, sock_test_tcpulp() needs to be updated
as getsockopt ULP may now return not only "mptcp" but also "tls".
These tests report "read: Resource temporarily unavailable" errors
occasionally, which is fixed by adding handling for EAGAIN in
copyfd_io_poll().
Co-developed-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
.../selftests/net/mptcp/mptcp_connect.c | 47 ++++++++++++++++++-
.../selftests/net/mptcp/mptcp_connect.sh | 33 +++++++++++++
2 files changed, 78 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c
index 64c8a4bfe749..0b4428215236 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_connect.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c
@@ -34,6 +34,7 @@
#include <linux/time_types.h>
#include <linux/sockios.h>
#include <linux/compiler.h>
+#include <linux/tls.h>
extern int optind;
@@ -89,6 +90,7 @@ struct cfg_cmsg_types {
struct cfg_sockopt_types {
unsigned int transparent:1;
unsigned int mptfo:1;
+ unsigned int tls:1;
};
struct tcp_inq_state {
@@ -272,6 +274,35 @@ static int do_ulp_so(int sock, const char *name)
return setsockopt(sock, IPPROTO_TCP, TCP_ULP, name, strlen(name));
}
+static void do_setsockopt_tls(int fd)
+{
+ struct tls12_crypto_info_aes_gcm_128 tls_tx = {
+ .info = {
+ .version = TLS_1_2_VERSION,
+ .cipher_type = TLS_CIPHER_AES_GCM_128,
+ },
+ };
+ struct tls12_crypto_info_aes_gcm_128 tls_rx = {
+ .info = {
+ .version = TLS_1_2_VERSION,
+ .cipher_type = TLS_CIPHER_AES_GCM_128,
+ },
+ };
+ int err;
+
+ err = do_ulp_so(fd, "tls");
+ if (err)
+ xerror("setsockopt TCP_ULP");
+
+ err = setsockopt(fd, SOL_TLS, TLS_TX, (void *)&tls_tx, sizeof(tls_tx));
+ if (err)
+ xerror("setsockopt TLS_TX");
+
+ err = setsockopt(fd, SOL_TLS, TLS_RX, (void *)&tls_rx, sizeof(tls_rx));
+ if (err)
+ xerror("setsockopt TLS_RX");
+}
+
#define X(m) xerror("%s:%u: %s: failed for proto %d at line %u", __FILE__, __LINE__, (m), proto, line)
static void sock_test_tcpulp(int sock, int proto, unsigned int line)
{
@@ -283,7 +314,7 @@ static void sock_test_tcpulp(int sock, int proto, unsigned int line)
X("getsockopt");
if (buflen > 0) {
- if (strcmp(buf, "mptcp") != 0)
+ if (strcmp(buf, "mptcp") != 0 && strcmp(buf, "tls") != 0)
xerror("unexpected ULP '%s' for proto %d at line %u", buf, proto, line);
ret = do_ulp_so(sock, "tls");
if (ret == 0)
@@ -422,8 +453,11 @@ static int sock_connect_mptcp(const char * const remoteaddr,
}
freeaddrinfo(addr);
- if (sock != -1)
+ if (sock != -1) {
SOCK_TEST_TCPULP(sock, proto);
+ if (cfg_sockopt_types.tls)
+ do_setsockopt_tls(sock);
+ }
return sock;
}
@@ -684,6 +718,8 @@ static int copyfd_io_poll(int infd, int peerfd, int outfd,
/* Else, still have data to transmit */
} else if (len < 0) {
+ if (errno == EAGAIN)
+ continue;
if (cfg_rcv_trunc)
return 0;
perror("read");
@@ -1212,6 +1248,8 @@ int main_loop_s(int listensock)
}
SOCK_TEST_TCPULP(remotesock, 0);
+ if (cfg_sockopt_types.tls)
+ do_setsockopt_tls(remotesock);
memset(&winfo, 0, sizeof(winfo));
err = copyfd_io(fd, remotesock, 1, true, &winfo);
@@ -1312,6 +1350,11 @@ static void parse_setsock_options(const char *name)
return;
}
+ if (strncmp(name, "TLS", len) == 0) {
+ cfg_sockopt_types.tls = 1;
+ return;
+ }
+
fprintf(stderr, "Unrecognized setsockopt option %s\n", name);
exit(1);
}
diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.sh b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
index a6447f7a31fe..ef8d6ee22b00 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
@@ -815,6 +815,36 @@ run_tests_disconnect()
connect_per_transfer=1
}
+run_tests_tls()
+{
+ TEST_GROUP="TLS"
+ local lret=0
+
+ if ! mptcp_lib_kallsyms_has "mptcp_read_done"; then
+ mptcp_lib_pr_skip "TLS not supported by the kernel"
+ mptcp_lib_result_skip "${TEST_GROUP}"
+ return
+ fi
+
+ mptcp_lib_pr_info "with TLS start"
+
+ do_transfer "$ns1" "$ns2" MPTCP MPTCP "10.0.1.1" "0.0.0.0" "-o TLS"
+ lret=$?
+ if [ $lret -ne 0 ]; then
+ ret=$lret
+ return 1
+ fi
+
+ do_transfer "$ns1" "$ns2" MPTCP MPTCP "dead:beef:1::1" "::" "-o TLS"
+ lret=$?
+ if [ $lret -ne 0 ]; then
+ ret=$lret
+ return 1
+ fi
+
+ mptcp_lib_pr_info "with TLS end"
+}
+
display_time()
{
time_end=$(date +%s)
@@ -959,6 +989,9 @@ log_if_error "Tests with tproxy have failed"
run_tests_disconnect
log_if_error "Tests of the full disconnection have failed"
+run_tests_tls
+log_if_error "Tests with TLS have failed"
+
display_time
mptcp_lib_result_print_all_tap
exit ${final_ret}
--
2.53.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [RFC mptcp-next v9 00/10] MPTCP KTLS support
2026-03-13 1:42 [RFC mptcp-next v9 00/10] MPTCP KTLS support Geliang Tang
` (9 preceding siblings ...)
2026-03-13 1:42 ` [RFC mptcp-next v9 10/10] selftests: mptcp: connect: add TLS tests Geliang Tang
@ 2026-03-13 4:27 ` MPTCP CI
2026-03-13 8:07 ` Geliang Tang
10 siblings, 1 reply; 15+ messages in thread
From: MPTCP CI @ 2026-03-13 4:27 UTC (permalink / raw)
To: Geliang Tang; +Cc: mptcp
Hi Geliang,
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): Unstable: 1 failed test(s): selftest_mptcp_connect_splice 🔴
- KVM Validation: normal (only selftest_mptcp_join): Success! ✅
- KVM Validation: debug (except selftest_mptcp_join): Unstable: 4 failed test(s): packetdrill_dss packetdrill_mp_capable selftest_diag selftest_mptcp_connect_splice 🔴
- KVM Validation: debug (only selftest_mptcp_join): Success! ✅
- KVM Validation: btf-normal (only bpftest_all): Success! ✅
- KVM Validation: btf-debug (only bpftest_all): Success! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/23032875328
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/6363c87fa2fa
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1066012
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] 15+ messages in thread
* Re: [RFC mptcp-next v9 09/10] selftests: mptcp: connect: set smc instead of tls
2026-03-13 1:42 ` [RFC mptcp-next v9 09/10] selftests: mptcp: connect: set smc instead of tls Geliang Tang
@ 2026-03-13 6:26 ` Dust Li
2026-03-13 8:04 ` Geliang Tang
0 siblings, 1 reply; 15+ messages in thread
From: Dust Li @ 2026-03-13 6:26 UTC (permalink / raw)
To: Geliang Tang, mptcp; +Cc: Geliang Tang, Gang Yan
On 2026-03-13 09:42:51, Geliang Tang wrote:
>From: Geliang Tang <tanggeliang@kylinos.cn>
Hi Geliang,
Thanks for the effort !
But it's a pitty that SMC ULP support was removed in
df31a6b0a305(Revert "net/smc: Introduce TCP ULP support") due to
it violates some VFS assuptions :(
Best regards,
Dust
>
>With KTLS being implemented, "tls" should no longer be used in
>sock_test_tcpulp(), it breaks mptcp_connect.sh tests. Another ULP
>name, "smc", is set instead in this patch.
>
>Cc: Dust Li <dust.li@linux.alibaba.com>
>Co-developed-by: Gang Yan <yangang@kylinos.cn>
>Signed-off-by: Gang Yan <yangang@kylinos.cn>
>Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
>---
> tools/testing/selftests/net/mptcp/config | 1 +
> tools/testing/selftests/net/mptcp/mptcp_connect.c | 2 +-
> 2 files changed, 2 insertions(+), 1 deletion(-)
>
>diff --git a/tools/testing/selftests/net/mptcp/config b/tools/testing/selftests/net/mptcp/config
>index 59051ee2a986..18bd29ac5b24 100644
>--- a/tools/testing/selftests/net/mptcp/config
>+++ b/tools/testing/selftests/net/mptcp/config
>@@ -34,3 +34,4 @@ CONFIG_NFT_SOCKET=m
> CONFIG_NFT_TPROXY=m
> CONFIG_SYN_COOKIES=y
> CONFIG_VETH=y
>+CONFIG_TLS=y
>diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c
>index cbe573c4ab3a..64c8a4bfe749 100644
>--- a/tools/testing/selftests/net/mptcp/mptcp_connect.c
>+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c
>@@ -289,7 +289,7 @@ static void sock_test_tcpulp(int sock, int proto, unsigned int line)
> if (ret == 0)
> X("setsockopt");
> } else if (proto == IPPROTO_MPTCP) {
>- ret = do_ulp_so(sock, "tls");
>+ ret = do_ulp_so(sock, "smc");
> if (ret != -1)
> X("setsockopt");
> }
>--
>2.53.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC mptcp-next v9 09/10] selftests: mptcp: connect: set smc instead of tls
2026-03-13 6:26 ` Dust Li
@ 2026-03-13 8:04 ` Geliang Tang
0 siblings, 0 replies; 15+ messages in thread
From: Geliang Tang @ 2026-03-13 8:04 UTC (permalink / raw)
To: dust.li, mptcp; +Cc: Geliang Tang, Gang Yan
Hi Dust,
On Fri, 2026-03-13 at 14:26 +0800, Dust Li wrote:
> On 2026-03-13 09:42:51, Geliang Tang wrote:
> > From: Geliang Tang <tanggeliang@kylinos.cn>
>
> Hi Geliang,
>
> Thanks for the effort !
> But it's a pitty that SMC ULP support was removed in
> df31a6b0a305(Revert "net/smc: Introduce TCP ULP support") due to
> it violates some VFS assuptions :(
Thanks for the reminder. I will consider using another ULP instead.
-Geliang
>
> Best regards,
> Dust
>
> >
> > With KTLS being implemented, "tls" should no longer be used in
> > sock_test_tcpulp(), it breaks mptcp_connect.sh tests. Another ULP
> > name, "smc", is set instead in this patch.
> >
> > Cc: Dust Li <dust.li@linux.alibaba.com>
> > Co-developed-by: Gang Yan <yangang@kylinos.cn>
> > Signed-off-by: Gang Yan <yangang@kylinos.cn>
> > Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> > ---
> > tools/testing/selftests/net/mptcp/config | 1 +
> > tools/testing/selftests/net/mptcp/mptcp_connect.c | 2 +-
> > 2 files changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/tools/testing/selftests/net/mptcp/config
> > b/tools/testing/selftests/net/mptcp/config
> > index 59051ee2a986..18bd29ac5b24 100644
> > --- a/tools/testing/selftests/net/mptcp/config
> > +++ b/tools/testing/selftests/net/mptcp/config
> > @@ -34,3 +34,4 @@ CONFIG_NFT_SOCKET=m
> > CONFIG_NFT_TPROXY=m
> > CONFIG_SYN_COOKIES=y
> > CONFIG_VETH=y
> > +CONFIG_TLS=y
> > diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c
> > b/tools/testing/selftests/net/mptcp/mptcp_connect.c
> > index cbe573c4ab3a..64c8a4bfe749 100644
> > --- a/tools/testing/selftests/net/mptcp/mptcp_connect.c
> > +++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c
> > @@ -289,7 +289,7 @@ static void sock_test_tcpulp(int sock, int
> > proto, unsigned int line)
> > if (ret == 0)
> > X("setsockopt");
> > } else if (proto == IPPROTO_MPTCP) {
> > - ret = do_ulp_so(sock, "tls");
> > + ret = do_ulp_so(sock, "smc");
> > if (ret != -1)
> > X("setsockopt");
> > }
> > --
> > 2.53.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC mptcp-next v9 00/10] MPTCP KTLS support
2026-03-13 4:27 ` [RFC mptcp-next v9 00/10] MPTCP KTLS support MPTCP CI
@ 2026-03-13 8:07 ` Geliang Tang
0 siblings, 0 replies; 15+ messages in thread
From: Geliang Tang @ 2026-03-13 8:07 UTC (permalink / raw)
To: mptcp, Geliang Tang
On Fri, 2026-03-13 at 04:27 +0000, MPTCP CI wrote:
> Hi Geliang,
>
> 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): Unstable: 1
> failed test(s): selftest_mptcp_connect_splice 🔴
> - KVM Validation: normal (only selftest_mptcp_join): Success! ✅
> - KVM Validation: debug (except selftest_mptcp_join): Unstable: 4
> failed test(s): packetdrill_dss packetdrill_mp_capable selftest_diag
> selftest_mptcp_connect_splice 🔴
Patch 10 broke the mptcp_connect_splice.sh test. I will find a way to
fix it.
Thanks,
-Geliang
> - KVM Validation: debug (only selftest_mptcp_join): Success! ✅
> - KVM Validation: btf-normal (only bpftest_all): Success! ✅
> - KVM Validation: btf-debug (only bpftest_all): Success! ✅
> - Task:
> https://github.com/multipath-tcp/mptcp_net-next/actions/runs/23032875328
>
> Initiator: Patchew Applier
> Commits:
> https://github.com/multipath-tcp/mptcp_net-next/commits/6363c87fa2fa
> Patchwork:
> https://patchwork.kernel.org/project/mptcp/list/?series=1066012
>
>
> 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] 15+ messages in thread
end of thread, other threads:[~2026-03-13 8:07 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-13 1:42 [RFC mptcp-next v9 00/10] MPTCP KTLS support Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 01/10] tls: introduce struct tls_prot_ops Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 02/10] tls: add ops in tls_context Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 03/10] tls: add MPTCP SKB offset check in strp queue walk Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 04/10] mptcp: update mptcp_check_readable Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 05/10] mptcp: avoid deadlocks in read_sock path Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 06/10] mptcp: implement tls_mptcp_ops Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 07/10] mptcp: update ULP getsockopt Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 08/10] mptcp: enable TLS setsockopt Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 09/10] selftests: mptcp: connect: set smc instead of tls Geliang Tang
2026-03-13 6:26 ` Dust Li
2026-03-13 8:04 ` Geliang Tang
2026-03-13 1:42 ` [RFC mptcp-next v9 10/10] selftests: mptcp: connect: add TLS tests Geliang Tang
2026-03-13 4:27 ` [RFC mptcp-next v9 00/10] MPTCP KTLS support MPTCP CI
2026-03-13 8:07 ` Geliang Tang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox