From nobody Sun Mar 22 08:25:58 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6B5D22F532F for ; Fri, 13 Mar 2026 01:43:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366194; cv=none; b=hTK3Jw6EE59McRmCTKWdc1aXcGYq1L53W4n85vJPVrnw18iAdQIjs19rzLyB2pGMvcAvLnmOsku7pUvUUQbrW3cxgvSmHppzVtrhV/o7d8KXE8ZicV9Gel5+HFNyCbZ2j7imKTun5OYonN7/vO4LLCBMxoDaQvijPPo3ueAn/p4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366194; c=relaxed/simple; bh=NLLRueB9vNDOV5XD1EDm2D9tHXxCHElffXgzqG/7IX0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Pv3gKE/1dbZ4fqEkeMzymmUXLLdkADNzKv9LKa3I4Y9uU/H1do8xLK3daprA0NOjnV7J4aR0f0ddki8ao/VPauoFXeoY76HPoCKxdSwFdb0/gRlg1ibJl2XZHM9SpUE3zyOCLHVnPsjgizeAIx6ZXsHlCVggzR0D1I0q25aFcSI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rQWzKiyA; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rQWzKiyA" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 04E2BC2BC87; Fri, 13 Mar 2026 01:43:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773366194; bh=NLLRueB9vNDOV5XD1EDm2D9tHXxCHElffXgzqG/7IX0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rQWzKiyAuVOLvmDC5W1DakUCv6tJgGLOREjWx9Fe/9WqQKc5dJwwQIJG2yZ085LTz BPxV82HVN75YVQr/Hrl7vjqLBXJ7/kWrwEijdiyG01oT6V+4Q3BR7F24G7Ktuaw8O5 9I/UnJqgPpqxsRsMJ2zvvxqEYQamNPpDyJ0YVrpyck8bIo0FmsPRD1nVgm04UbTeem b6dlCLbcIeNt9uUcHOmC3HLHN/vazStROkFjqOdCivKK41a2culP2aEeJAO5HvHzNN xjiMrc2l6lMQ5FvdaKQI7iWCln1xsgmM9VHdf8gcRiJJsXCZYSAZIHNFAxIY08gWe8 w4FDYJ5WFEQVw== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang , Gang Yan Subject: [RFC mptcp-next v9 01/10] tls: introduce struct tls_prot_ops Date: Fri, 13 Mar 2026 09:42:43 +0800 Message-ID: <2ebc54f2517c713f2969fe1b7b21f3e2517291ca.1773365606.git.tanggeliang@kylinos.cn> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Geliang Tang 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 Signed-off-by: Gang Yan Signed-off-by: Geliang Tang --- 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; }; =20 +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][T= LS_NUM_CONFIG][TLS_NUM_CON static void build_protos(struct proto prot[TLS_NUM_CONFIG][TLS_NUM_CONFIG], const struct proto *base); =20 +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 =3D NULL; + + list_for_each_entry_rcu(ops, &tls_prot_ops_list, list) { + if (ops->protocol =3D=3D protocol) { + ret =3D ops; + break; + } + } + + return ret; +} + void update_sk_prot(struct sock *sk, struct tls_context *ctx) { int ip_ver =3D sk->sk_family =3D=3D AF_INET6 ? TLSV6 : TLSV4; @@ -1236,6 +1254,74 @@ static struct tcp_ulp_ops tcp_tls_ulp_ops __read_mos= tly =3D { .get_info_size =3D tls_get_info_size, }; =20 +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 =3D 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 =3D { + .protocol =3D IPPROTO_TCP, + .inq =3D tcp_inq, + .sendmsg_locked =3D tcp_sendmsg_locked, + .recv_skb =3D tls_tcp_recv_skb, + .read_sock =3D tcp_read_sock, + .read_done =3D tcp_read_done, + .get_skb_off =3D tls_tcp_get_skb_off, + .get_skb_seq =3D tls_tcp_get_skb_seq, + .poll =3D tcp_poll, + .epollin_ready =3D tls_tcp_epollin_ready, + .check_app_limited =3D tcp_rate_check_app_limited, +}; + static int __init tls_register(void) { int err; @@ -1254,6 +1340,8 @@ static int __init tls_register(void) =20 tcp_register_ulp(&tcp_tls_ulp_ops); =20 + tls_register_prot_ops(&tls_tcp_ops); + return 0; err_strp: tls_strp_dev_exit(); --=20 2.53.0 From nobody Sun Mar 22 08:25:58 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CBB9D2F532F for ; Fri, 13 Mar 2026 01:43:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366196; cv=none; b=WHY7PpZgQNYdifQ1uftmaH5CSjBFAIpthBqT4i4r7uvoSOAbP8TfhixaNUCnnYm9j07nH+le+bQVd0w9yWiqicgstP+BC+1/8A1nOjg5go5JsHrbyRxwSNGb4uwxP5LMxYXobbWKl1KGkTF02IBUyqETePibAgYITpeU2GZ898g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366196; c=relaxed/simple; bh=zAYDPMPnok7tw+ZvabSai8PKvEU/h+e81Uy4zxAWfx0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OCJi7T3WrC8j9zbextwIaoWecpxodflprZPMlCmQs2sszKNI/m5DIDONfyYTPkZmNgnzDtmGNTgNtTQfvi0jSKdvLPFWieCtAh8dGz5FxZAV/BqcVYv58HksxXcOGX3mab2pShmqyJabgaawI+9gNVcV3lbbGfVUU/HiTINZF0k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=t265G3yq; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="t265G3yq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EBB6BC4CEF7; Fri, 13 Mar 2026 01:43:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773366196; bh=zAYDPMPnok7tw+ZvabSai8PKvEU/h+e81Uy4zxAWfx0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=t265G3yqCW285blnegtS+mLCkI7TU31TB0PCmRlvoAEGs9tD3XZaOrLJO+feQgwl6 sko/OSwS/+C0WunnxmhYB+ZQDWsBiY5mKoeWxdwnFVN4nEB0kWfOZQdKuVcUYwFOTW Pwle8xFVJmFTGgvb6g9EOamjywSlAQiVqY0M+iCD7yrasUObv3MpgnH9X+54VaRdHo yxk8pwUuzvjVF+kEbbfGfS/1MSij11S1SHe4LPC5DS3zmVM1YwPCAcXrtBf3z7Tt4I lx+lU4mlXK/gwKh/q0QWfvH+6NI5D2yj+ZAfF4ZRHzeOB3VnF+mxYij9tw+FJaj7Mr np2WGxjJxpX2A== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang , Gang Yan Subject: [RFC mptcp-next v9 02/10] tls: add ops in tls_context Date: Fri, 13 Mar 2026 09:42:44 +0800 Message-ID: <87f4c506dc41b911e90687940b420bee1ca9b00c.1773365606.git.tanggeliang@kylinos.cn> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Geliang Tang 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 Signed-off-by: Gang Yan Signed-off-by: Geliang Tang --- 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; =20 void (*sk_destruct)(struct sock *sk); + const struct tls_prot_ops *ops; =20 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 =3D true; while (1) { /* is sending application-limited? */ - tcp_rate_check_app_limited(sk); + ctx->ops->check_app_limited(sk); p =3D sg_page(sg); retry: bvec_set_page(&bvec, p, size, offset); iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, size); =20 - ret =3D tcp_sendmsg_locked(sk, &msg, size); + ret =3D ctx->ops->sendmsg_locked(sk, &msg, size); =20 if (ret !=3D size) { if (ret > 0) { @@ -427,14 +427,14 @@ static __poll_t tls_sk_poll(struct file *file, struct= socket *sock, u8 shutdown; int state; =20 - mask =3D tcp_poll(file, sock, wait); + tls_ctx =3D tls_get_ctx(sk); + mask =3D tls_ctx->ops->poll(file, sock, wait); =20 state =3D inet_sk_state_load(sk); shutdown =3D READ_ONCE(sk->sk_shutdown); if (unlikely(state !=3D TCP_ESTABLISHED || shutdown & RCV_SHUTDOWN)) return mask; =20 - tls_ctx =3D tls_get_ctx(sk); ctx =3D tls_sw_ctx_rx(tls_ctx); psock =3D sk_psock_get(sk); =20 @@ -1094,6 +1094,11 @@ static int tls_init(struct sock *sk) ctx->tx_conf =3D TLS_BASE; ctx->rx_conf =3D TLS_BASE; ctx->tx_max_payload_len =3D TLS_MAX_PAYLOAD_SIZE; + ctx->ops =3D tls_prot_ops_find(sk->sk_protocol); + if (!ctx->ops) { + rc =3D -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_conte= xt_rx *ctx) int tls_strp_msg_cow(struct tls_sw_context_rx *ctx) { struct tls_strparser *strp =3D &ctx->strp; + struct tls_context *tls_ctx; struct sk_buff *skb; =20 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 =3D skb; =20 - tcp_read_done(strp->sk, strp->stm.full_len); + tls_ctx =3D tls_get_ctx(strp->sk); + tls_ctx->ops->read_done(strp->sk, strp->stm.full_len); strp->copy_mode =3D 1; =20 return 0; @@ -376,6 +378,7 @@ static int tls_strp_copyin(read_descriptor_t *desc, str= uct sk_buff *in_skb, =20 static int tls_strp_read_copyin(struct tls_strparser *strp) { + struct tls_context *ctx =3D tls_get_ctx(strp->sk); read_descriptor_t desc; =20 desc.arg.data =3D strp; @@ -383,13 +386,14 @@ static int tls_strp_read_copyin(struct tls_strparser = *strp) desc.count =3D 1; /* give more than one skb per call */ =20 /* 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); =20 return desc.error; } =20 static int tls_strp_read_copy(struct tls_strparser *strp, bool qshort) { + struct tls_context *ctx =3D 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 *str= p, 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; =20 shinfo =3D skb_shinfo(strp->anchor); @@ -434,12 +438,13 @@ static int tls_strp_read_copy(struct tls_strparser *s= trp, bool qshort) static bool tls_strp_check_queue_ok(struct tls_strparser *strp) { unsigned int len =3D strp->stm.offset + strp->stm.full_len; + struct tls_context *ctx =3D tls_get_ctx(strp->sk); struct sk_buff *first, *skb; u32 seq; =20 first =3D skb_shinfo(strp->anchor)->frag_list; skb =3D first; - seq =3D TCP_SKB_CB(first)->seq; + seq =3D ctx->ops->get_skb_seq(first); =20 /* 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_strparse= r *strp) len -=3D skb->len; skb =3D skb->next; =20 - if (TCP_SKB_CB(skb)->seq !=3D seq) + if (ctx->ops->get_skb_seq(skb) !=3D seq) return false; if (skb_cmp_decrypted(first, skb)) return false; @@ -460,11 +465,11 @@ static bool tls_strp_check_queue_ok(struct tls_strpar= ser *strp) =20 static void tls_strp_load_anchor_with_queue(struct tls_strparser *strp, in= t len) { - struct tcp_sock *tp =3D tcp_sk(strp->sk); + struct tls_context *ctx =3D tls_get_ctx(strp->sk); struct sk_buff *first; u32 offset; =20 - first =3D tcp_recv_skb(strp->sk, tp->copied_seq, &offset); + first =3D ctx->ops->recv_skb(strp->sk, &offset); if (WARN_ON_ONCE(!first)) return; =20 @@ -483,6 +488,7 @@ static void tls_strp_load_anchor_with_queue(struct tls_= strparser *strp, int len) =20 bool tls_strp_msg_load(struct tls_strparser *strp, bool force_refresh) { + struct tls_context *ctx =3D tls_get_ctx(strp->sk); struct strp_msg *rxm; struct tls_msg *tlm; =20 @@ -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); =20 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, boo= l force_refresh) /* Called with lock held on lower socket */ static int tls_strp_read_sock(struct tls_strparser *strp) { + struct tls_context *ctx =3D tls_get_ctx(strp->sk); int sz, inq; =20 - inq =3D tcp_inq(strp->sk); + inq =3D ctx->ops->inq(strp->sk); if (inq < 1) return 0; =20 @@ -583,10 +590,12 @@ static void tls_strp_work(struct work_struct *w) =20 void tls_strp_msg_done(struct tls_strparser *strp) { + struct tls_context *ctx =3D tls_get_ctx(strp->sk); + WARN_ON(!strp->stm.full_len); =20 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); =20 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 =3D tls_get_ctx(sk); size_t max_rec; =20 if (len_left <=3D decrypted) return false; =20 max_rec =3D 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; =20 *flushed_at =3D done; @@ -2445,6 +2446,7 @@ int tls_rx_msg_size(struct tls_strparser *strp, struc= t sk_buff *skb) size_t cipher_overhead; size_t data_len =3D 0; int ret; + u32 seq; =20 /* 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, struc= t sk_buff *skb) goto read_failure; } =20 + seq =3D 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; =20 read_failure: --=20 2.53.0 From nobody Sun Mar 22 08:25:58 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 014452F532F for ; Fri, 13 Mar 2026 01:43:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366199; cv=none; b=DQkkLLYsreIWFFOsjkSvXIeuyNobSiVB/EZH/kQuSHAVBM6WEvwXVb9BdYtb2lS6oMJW5VUCkU9GMgF12JE54607OspGpOhcVMhaupSin7GeAHkUxk6Y/bLtoWf1FbsdG7Qe3jOpuiI/qIT3OLnb/4rxiDAf7XovYt+pTM2doXI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366199; c=relaxed/simple; bh=LQS6YIivyys9LFu5gqANdXMKolQ/xn5G+bxq7MVZnVg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Oc2cKxdvA+WgZWyz4teH7YRFoC9y1/mMts819RTw9jN2AE8bUYmQZFMo3bwIpPdiL/abSa22ia78YZT+oYuQHCDl8h79Upq/c0gOUwEULCK1+6TSmR8T5yd0NuqlcUgikoNhywF1fAco4frH93IfL/Ce5FCF05qVUuOydO1xKJM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=S+HUpVj5; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="S+HUpVj5" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1BFF9C116C6; Fri, 13 Mar 2026 01:43:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773366198; bh=LQS6YIivyys9LFu5gqANdXMKolQ/xn5G+bxq7MVZnVg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=S+HUpVj5uQ5CJJVxcsYWYBa2f6yZtZqFU0hO7T8l5i+VkgxGMAgpnRPdoa8KsoD9N /qvy+YkIHO36vYccq4fKjf4jRKEoIN7TrAj1ck4Agms0uo6tfOuzsUOi/mWIJe/ym8 Io5C2vc+nqU3GbpQUmxgQtzIBNRgN3VewbL4/G+HoKSz1FUVgTOsnIEal1sX1D3Ydh 4zi2KXY08Ks9AJwmgHCuZwZEjsE19DZcF+hfRDXc6TMJYKh3UGqVvkR08mqKQrzOZP RkWSkWE+d+12sHhzU5s3rxYS/kvIqHuEqfyJwVqfQJY6HjAsAOvV16RIFdI53maTtw n6ppYGHU9cpog== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Gang Yan , Geliang Tang Subject: [RFC mptcp-next v9 03/10] tls: add MPTCP SKB offset check in strp queue walk Date: Fri, 13 Mar 2026 09:42:45 +0800 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Gang Yan 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 Signed-off-by: Geliang Tang Signed-off-by: Gang Yan --- 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_strparse= r *strp) len -=3D skb->len; skb =3D skb->next; =20 + if (ctx->ops->get_skb_off(skb)) + return false; if (ctx->ops->get_skb_seq(skb) !=3D seq) return false; if (skb_cmp_decrypted(first, skb)) --=20 2.53.0 From nobody Sun Mar 22 08:25:58 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1FE43275B18 for ; Fri, 13 Mar 2026 01:43:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366201; cv=none; b=NTrU4DrNJ9AgZ8a47EXdGcVIY6WX+80zNWRrNTaOGp4eMNPvOvnY1fpTgi9eIyipJAl3CslfBM8j9gOvCFnfv4sxD2OQasItRrZ6TGgEjX0tltclgLZybP+u8fOkFuPTTRKZzYXpgSjAR7kmq0jDOW3zdlKWRTcY3tu7VQq1CwU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366201; c=relaxed/simple; bh=xHPSVUzH2+0VMZ4mXonK0ay71tTFip9oeZ33YQSRYtw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pw07YIwWVQU8OqyLRr4UPNGNjDzjPlsUziQoBfh93O1DO5H48i7k7R1VZBGslJ0KZVF4sncM9tqLnRZFswyVYmgZhwLuVu9odP++PmsRPfVvWcPZhfkwH50aZmmA+1J0Ge/YGQvEISiQjosrsvECJzzgXnBE0SPJ8TOGd4oTnLw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=q9KHqMNQ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="q9KHqMNQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 404F6C116C6; Fri, 13 Mar 2026 01:43:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773366200; bh=xHPSVUzH2+0VMZ4mXonK0ay71tTFip9oeZ33YQSRYtw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=q9KHqMNQ66kDYEYukMRLiTizjaKboBWqul3iQckRCv5OELRw42bGnC/CEtZWVMqdn EHGRusYwlF8GiuCRNOuCnp+NJzVNgw/oi9PZnqZyM1gWPsq1LYpMV/17Ww62D7TwvE j93mUx4QiBAM8/GBp8b/asRQwUUPexoS82H0kbn0MSpxIqoZzglRHppV9p9X5Fry3e mYq3IKDfFi6JvZwHuA3xuRKdatIBISsUBuoRB2Z5dTUzhCrbQCOEnRQ216gYMnVV0b MPHYpVtMui/dBkqrD3ff/ptdNfbq1tH+Z1pbiGzgPfDLFN6cT8/tSB7UvbLcV6JUcA IFWcJjiOeRaIQ== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Gang Yan , Geliang Tang Subject: [RFC mptcp-next v9 04/10] mptcp: update mptcp_check_readable Date: Fri, 13 Mar 2026 09:42:46 +0800 Message-ID: <3a0a823d6656c19c78feac59943055a01a2d4d01.1773365606.git.tanggeliang@kylinos.cn> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Gang Yan 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 Signed-off-by: Geliang Tang Signed-off-by: Gang Yan --- 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); } =20 -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); } =20 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 |=3D EPOLLIN | EPOLLRDNORM | EPOLLRDHUP; =20 if (state !=3D TCP_SYN_SENT && state !=3D TCP_SYN_RECV) { - mask |=3D mptcp_check_readable(sk); + if (mptcp_stream_is_readable(sk)) + mask |=3D EPOLLIN | EPOLLRDNORM; if (shutdown & SEND_SHUTDOWN) mask |=3D EPOLLOUT | EPOLLWRNORM; else --=20 2.53.0 From nobody Sun Mar 22 08:25:58 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5F7F52F069D for ; Fri, 13 Mar 2026 01:43:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366203; cv=none; b=pFiTYIS/Spmu58E9kmDBIzS5bFfGhN5GFHi2lXcWXCEkCs/ZlEtem2Tq5PwUEict+ODeDxjO7zaXnsuXFxjHx2GxMjl+UxxHgNhumD5Gj6KU+ZQlmO2HfveO8unT+b1QQHiy5g9DupEViub0prCFg2dLorQkN6p4cu8WB73iaRM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366203; c=relaxed/simple; bh=47uypetk96GpSk+m+WFMeHEEHzARkkkKR2bV17xw7Xk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fu48C8p+hhNusuO0w/nQ5ic2uguVI7AqAhYmwKx/tznplqNAa4hjnND49CRQ5z8POKlTs9tf4nfIe/OVxni4K1H5VfQmfVv3nyFOfpsiWmCVb+2u4KGt8MrFyr6ofCIdt/y7gqye6s7h/EizUfqTEOn13lv1tIkMHWvGltgbego= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=W65CdR+p; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="W65CdR+p" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6866BC116C6; Fri, 13 Mar 2026 01:43:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773366202; bh=47uypetk96GpSk+m+WFMeHEEHzARkkkKR2bV17xw7Xk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=W65CdR+pBrxc5XpAOB3B0KhslrNpyhVCIMTLs9gy/oDMYgM3betZR/ACzpUDNjNZE lllc8tSMo/j+IEU79MNo00RTnt6LRaPb+fqC+gmVB2u8TdawIeasZ5+nr2yKqsNkSU d0UTgwsUnzOFhJh9DcWQ7LER0ACIO2d+b5/K36hStKMBxlWwtu6wkDkqb+5j4RvVsw D38Owjj8cyP6cRDqrmNrzX1B8sxpiBypDH45sjLrrNr2AUuXNN4xw+Z9YgosK7g8Ka Mq5/mCnSJFkXrUwkfpV522n9F677NYc7d3OM5GLcuxX5frGjKOxYh/aGm5eM0LBbaf SoFfbEzPoQU+A== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang , Gang Yan Subject: [RFC mptcp-next v9 05/10] mptcp: avoid deadlocks in read_sock path Date: Fri, 13 Mar 2026 09:42:47 +0800 Message-ID: <0c7c925402d4419989e7349c5099b4d80288df9c.1773365606.git.tanggeliang@kylinos.cn> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Geliang Tang 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 Signed-off-by: Gang Yan Signed-off-by: Geliang Tang --- 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) =20 static void mptcp_subflow_cleanup_rbuf(struct sock *ssk, int copied) { - bool slow; - - slow =3D 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); } =20 static bool mptcp_subflow_could_cleanup(const struct sock *ssk, bool rx_em= pty) @@ -2152,14 +2151,14 @@ static void mptcp_rcv_space_adjust(struct mptcp_soc= k *msk, int copied) */ mptcp_for_each_subflow(msk, subflow) { struct sock *ssk; - bool slow; =20 ssk =3D mptcp_subflow_tcp_sock(subflow); - slow =3D 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); } } =20 @@ -2232,7 +2231,8 @@ static bool mptcp_move_skbs(struct sock *sk) bool enqueued =3D false; u32 moved; =20 - mptcp_data_lock(sk); + if (!mptcp_data_trylock(sk)) + return false; while (mptcp_can_spool_backlog(sk, &skbs)) { mptcp_data_unlock(sk); enqueued |=3D __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 { }; =20 #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) =20 #define mptcp_for_each_subflow(__msk, __subflow) \ --=20 2.53.0 From nobody Sun Mar 22 08:25:58 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BADA42F069D for ; Fri, 13 Mar 2026 01:43:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366204; cv=none; b=GxTt6iTI65Mrs6iG1vSAFb0dD+h3dzKsjcIhrSj/Gb1H/0f9vsCYWcS0EGGaNj7GoIobm1zFTfdMjmBtBuqfNcLeyeN++h8TkGw8tss6hiN37E6bDEmAkCCXgZEyARvQEux+VJc0IY165bT+vxFgRY/Bi/eQzRbpuw1U9k8WKiU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366204; c=relaxed/simple; bh=f8XUfNkgew9qrXUufvteNQ1M+fH5wTGUU10eLjWAxFU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XGBxzK/X3GIL1aE/4pgbARKzWhRnkrWG/lUft/CUk9pAPwX0TovVgb0YKB+qZl0XvOSjDtvY8IMPZfc3VJztoTno/1cQNDVAA1+9gPNY1osClycjPsi72k38aMePgCURQYlC9Q3rnVEvgf/lgSEsPB5vbvmUy++tXMOickMFr3I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=CBBAU7PC; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="CBBAU7PC" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 833D2C4CEF7; Fri, 13 Mar 2026 01:43:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773366204; bh=f8XUfNkgew9qrXUufvteNQ1M+fH5wTGUU10eLjWAxFU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CBBAU7PCz00G7hejDTKgJhLJhjPRT5+PnBeBlbulU9CLQMxjG+E7VaUg8qUzaeMFY up96u26dCOk0G1CO+AK/vPyJWlq3PnLrQv/aDtDuKKNXngOhb/GciEleNahDePDJKb 7CJ+Phb9M59fdMy6BSwI367dMn/LQeJsdyWEpqVMIhHNajGLK1goCj6Quj3x5sPtAv 1q/plFTrBEatK9yLRsA0sk3n+6XaUNw+3s1IHU77Q45JhZJgUqrchn/LjFVWCgLG7x MqMGWEITWw/6iKyMjtjyTNcK1oboY7aO89E53ssDGetI+svmWANWY2BtiBF5VEA/kX WOseILC10DPSA== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang , Gang Yan Subject: [RFC mptcp-next v9 06/10] mptcp: implement tls_mptcp_ops Date: Fri, 13 Mar 2026 09:42:48 +0800 Message-ID: <9ebfafbf31bf5915c59d942e9eca7a94cf36e765.1773365606.git.tanggeliang@kylinos.cn> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Geliang Tang 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 Signed-off-by: Gang Yan Signed-off-by: Geliang Tang --- 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; =20 +extern struct tls_prot_ops tls_mptcp_ops; + #ifdef CONFIG_MPTCP void mptcp_init(void); =20 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) =20 /* 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); =20 /* 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 msgh= dr *msg, int *copied, } =20 /* 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 =3D tcp_sk(sk); + struct sock *sk =3D (struct sock *)tp; =20 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 =3D (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); =20 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 #include #include +#include #include #include "protocol.h" #include "mib.h" =20 -static unsigned int mptcp_inq_hint(const struct sock *sk); +static unsigned int mptcp_inq_hint(struct sock *sk); =20 #define CREATE_TRACE_POINTS #include @@ -1885,7 +1886,7 @@ static void mptcp_rps_record_subflows(const struct mp= tcp_sock *msk) } } =20 -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 =3D mptcp_sk(sk); struct page_frag *pfrag; @@ -1896,8 +1897,6 @@ static int mptcp_sendmsg(struct sock *sk, struct msgh= dr *msg, size_t len) /* silently ignore everything else */ msg->msg_flags &=3D MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | MSG_FASTOPEN; =20 - lock_sock(sk); - mptcp_rps_record_subflows(msk); =20 if (unlikely(inet_test_bit(DEFER_CONNECT, sk) || @@ -2005,7 +2004,6 @@ static int mptcp_sendmsg(struct sock *sk, struct msgh= dr *msg, size_t len) __mptcp_push_pending(sk, msg->msg_flags); =20 out: - release_sock(sk); return copied; =20 do_error: @@ -2016,6 +2014,17 @@ static int mptcp_sendmsg(struct sock *sk, struct msg= hdr *msg, size_t len) goto out; } =20 +static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) +{ + int ret; + + lock_sock(sk); + ret =3D mptcp_sendmsg_locked(sk, msg, len); + release_sock(sk); + + return ret; +} + static void mptcp_rcv_space_adjust(struct mptcp_sock *msk, int copied); =20 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; } =20 -static unsigned int mptcp_inq_hint(const struct sock *sk) +static int mptcp_inq(struct sock *sk) { const struct mptcp_sock *msk =3D 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; } =20 + return 0; +} + +static unsigned int mptcp_inq_hint(struct sock *sk) +{ + unsigned int inq =3D mptcp_inq(sk); + + if (inq) + return inq; + if (sk->sk_state =3D=3D TCP_CLOSE || (sk->sk_shutdown & RCV_SHUTDOWN)) return 1; =20 @@ -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 =3D mptcp_sk(sk); + struct sk_buff *skb; + size_t left; + u32 offset; + + msk_owned_by_me(msk); + + if (sk->sk_state =3D=3D TCP_LISTEN) + return; + + left =3D len; + while (left && (skb =3D mptcp_recv_skb(sk, &offset)) !=3D NULL) { + int used; + + used =3D min_t(size_t, skb->len - offset, left); + msk->bytes_consumed +=3D used; + MPTCP_SKB_CB(skb)->offset +=3D used; + MPTCP_SKB_CB(skb)->map_seq +=3D used; + left -=3D 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 !=3D 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 =3D mptcp_sk(sk); + struct mptcp_subflow_context *subflow; + + mptcp_for_each_subflow(msk, subflow) { + struct sock *ssk =3D mptcp_subflow_tcp_sock(subflow); + bool slow; + + slow =3D 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 =3D { + .protocol =3D IPPROTO_MPTCP, + .inq =3D mptcp_inq, + .sendmsg_locked =3D mptcp_sendmsg_locked, + .recv_skb =3D mptcp_recv_skb, + .read_sock =3D mptcp_read_sock, + .read_done =3D mptcp_read_done, + .get_skb_off =3D mptcp_get_skb_off, + .get_skb_seq =3D mptcp_get_skb_seq, + .poll =3D mptcp_poll, + .epollin_ready =3D mptcp_epollin_ready, + .check_app_limited =3D 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, sock= ptr_t optval, tls_sw_strparser_arm(sk, ctx); } =20 + if (conf =3D=3D TLS_HW && sk->sk_protocol =3D=3D IPPROTO_MPTCP) + return -EOPNOTSUPP; + if (tx) ctx->tx_conf =3D conf; else @@ -1346,6 +1349,9 @@ static int __init tls_register(void) tcp_register_ulp(&tcp_tls_ulp_ops); =20 tls_register_prot_ops(&tls_tcp_ops); +#ifdef CONFIG_MPTCP + tls_register_prot_ops(&tls_mptcp_ops); +#endif =20 return 0; err_strp: --=20 2.53.0 From nobody Sun Mar 22 08:25:58 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1D9A12F5A34 for ; Fri, 13 Mar 2026 01:43:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366207; cv=none; b=W6nyHXtOjv3InVSfrbxbUIho+50AnOCimz3xpcfGldZsQAvwY7vv47nK4h03ppg3nxNUyct5d2UmFCO+NMS+QukJ23e6vCxST25x3iPbMvq0KdDSLtGRk2uOfOVWyBBCQuF0RQ2D44cAAcdan5SajSGN4FOOIyzFD/6SB74Gpvk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366207; c=relaxed/simple; bh=VqtC2nHB/FD4IihVVuPM2Gu6f59yiNCOfOu1IMYHtxo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oErKiKBaew2qtP+7b2YSe72RcTzCoyIKnxTzLCEGVaYUZKsOgC7Dw0ukcPSjNpbMu2/zmjmnewYkMsM+z2IIRHyRCGDSOuP0hEge4I73e+21WhCc86tc1hGwiMNtm7G0bN+DtW8rf3o3F9640UVYIRsRKb2JkS+JTpKRlyNlppo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EYY0/16r; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="EYY0/16r" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4AE01C116C6; Fri, 13 Mar 2026 01:43:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773366206; bh=VqtC2nHB/FD4IihVVuPM2Gu6f59yiNCOfOu1IMYHtxo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EYY0/16r47AeU3aBjQG6LnLuDXgMz/owPs25pLuZxSd5hwfXJ7WohNWT6yJ4bXGwO PkODGxanfpH1dEYN5ltY3yp14T9VkBpHqsIBES0/NYBEqr9C4rrKgk543GNbh7bLAV rIcbqd3QqQJYgH7bpyc0oX5aDyy9YQl+tl26m1ROeRucaOWNnQXX4gJMQu9g9gpUA/ +qiesIykQLRGmGizAgVfKh3InXDBBIJVD2Lf6NIwHK6a+Qzc8GgkkUb3ZSJQKEOmVB YmuXueyMcpHjFAWjcbE3/qeVRaZZooVJdLG9XpEtVh5Brvio5m9g0fzd0pOmaSe+iP zDGUk3to30B4Q== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang , Gang Yan Subject: [RFC mptcp-next v9 07/10] mptcp: update ULP getsockopt Date: Fri, 13 Mar 2026 09:42:49 +0800 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Geliang Tang 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 Signed-off-by: Gang Yan Signed-off-by: Geliang Tang --- 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); =20 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; } =20 +int tcp_sock_get_ulp(struct sock *sk, sockptr_t optval, sockptr_t optlen) +{ + struct inet_connection_sock *icsk =3D inet_csk(sk); + int len; + + if (copy_from_sockptr(&len, optlen, sizeof(int))) + return -EFAULT; + len =3D min_t(unsigned int, len, TCP_ULP_NAME_MAX); + if (!icsk->icsk_ulp_ops) { + len =3D 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; =20 case TCP_ULP: - if (copy_from_sockptr(&len, optlen, sizeof(int))) - return -EFAULT; - len =3D min_t(unsigned int, len, TCP_ULP_NAME_MAX); - if (!icsk->icsk_ulp_ops) { - len =3D 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); =20 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 *m= sk, char __user *optval, return 0; } =20 +static int mptcp_getsockopt_tcp_ulp(struct sock *sk, char __user *optval, + int __user *optlen) +{ + int ret; + + lock_sock(sk); + ret =3D 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, =20 switch (optname) { case TCP_ULP: + return mptcp_getsockopt_tcp_ulp(sk, optval, optlen); case TCP_CONGESTION: case TCP_INFO: case TCP_CC_INFO: --=20 2.53.0 From nobody Sun Mar 22 08:25:58 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 192D72FC881 for ; Fri, 13 Mar 2026 01:43:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366209; cv=none; b=SoKSO4Y3Li12Os4g1kpB3Mi852bo+Sp13GnM5nDCDqbw9eaM7/T0KSaDUbyTUTpBoxIL6wg9xArq6YVN2hqmnfUw/a3QVwVXIqJiO7rZrey/A9B9XyarcLtsSQUPi6hyXNDh8L7clSbC2G5QA+CD7j45dXOJvAisqyk9eu7OXUU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366209; c=relaxed/simple; bh=/0ztLZK2AsduRGL4EJz/5PARAS04RD6fMRVCyipRjLo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TqCUURwUbk5NoiqogjsOMsj/9pi5uccaLtNBMOc42oZ+h9efqDYT8GFVUbLB+tr6+dNYhpoRm8fPvBjk8MggyGIH1GDMC1obnzVck2e/6FPLvHykIpNkoV7dVhRzZxX9V2lw2Y2KX0ZJYBWzwTpGR9dRyL0hmwCAYwDIelLY/5A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Z+/UEaQT; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Z+/UEaQT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 706C8C116C6; Fri, 13 Mar 2026 01:43:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773366209; bh=/0ztLZK2AsduRGL4EJz/5PARAS04RD6fMRVCyipRjLo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Z+/UEaQTt6jGNB4x3keM08Y6fRhRTdsWSE6NGgLHHNh9w+MnBaLm7EpoNTzJGPV8/ mZjYvFnXHaZDW8suitzR+Zno0h1RndNv0aaUOuWx7oXXiFsW0uEjcFW9Ovi98LAw3N i5fenmpP0ZsTLv+yE2f8WTpzioGFQ7LRQoL8dtbo/HfWgvvldXndqRlW2ioGDztxfI HwJIoNSYdvKDUnVIKWycWqECX6bwfZFAAk62i2M7Eni0YySUzOTJ5nb2SJDRPUYJHO kbVbEGwrxTbmXbVTughANsSAony6Wkf12ffMByNQN2xyynqz6/1ftAYoH7C0KaTFMR YaIj3S8qMaCgA== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang , Gang Yan Subject: [RFC mptcp-next v9 08/10] mptcp: enable TLS setsockopt Date: Fri, 13 Mar 2026 09:42:50 +0800 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Geliang Tang 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 Signed-off-by: Gang Yan Signed-off-by: Geliang Tang --- 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 optle= n); =20 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; } =20 +int tcp_sock_set_ulp(struct sock *sk, sockptr_t optval, unsigned int optle= n) +{ + char name[TCP_ULP_NAME_MAX]; + int err =3D 0; + size_t len; + int val; + + if (optlen < 1) + return -EINVAL; + + len =3D min_t(long, TCP_ULP_NAME_MAX - 1, optlen); + val =3D strncpy_from_sockptr(name, optval, len); + if (val < 0) + return -EFAULT; + name[val] =3D 0; + + sockopt_lock_sock(sk); + err =3D 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, in= t optname, sockopt_release_sock(sk); return err; } - case TCP_ULP: { - char name[TCP_ULP_NAME_MAX]; - - if (optlen < 1) - return -EINVAL; - - val =3D strncpy_from_sockptr(name, optval, - min_t(long, TCP_ULP_NAME_MAX - 1, - optlen)); - if (val < 0) - return -EFAULT; - name[val] =3D 0; - - sockopt_lock_sock(sk); - err =3D 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 =3D 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 #include #include +#include #include "protocol.h" =20 #define MIN_INFO_OPTLEN_SIZE 16 @@ -567,6 +568,7 @@ static bool mptcp_supported_sockopt(int level, int optn= ame) case TCP_FASTOPEN_CONNECT: case TCP_FASTOPEN_KEY: case TCP_FASTOPEN_NO_COOKIE: + case TCP_ULP: return true; } =20 @@ -576,6 +578,13 @@ static bool mptcp_supported_sockopt(int level, int opt= name) * TCP_REPAIR_WINDOW are not supported, better avoid this mess */ } + if (level =3D=3D SOL_TLS) { + switch (optname) { + case TLS_TX: + case TLS_RX: + return true; + } + } return false; } =20 @@ -815,6 +824,20 @@ static int mptcp_setsockopt_all_sf(struct mptcp_sock *= msk, int level, return ret; } =20 +static int mptcp_setsockopt_tcp_ulp(struct sock *sk, sockptr_t optval, + unsigned int optlen) +{ + char ulp[4] =3D ""; + + 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, =20 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: --=20 2.53.0 From nobody Sun Mar 22 08:25:58 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 926973093CB for ; Fri, 13 Mar 2026 01:43:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366211; cv=none; b=O5rlou012/Z5Fn5nhcmq5sug2ubfW3GYNqOpvsGVa+yhpbbx1A0jjZvt4vvteD49Z1YuFnDDkO0VfoglXAQZJxoPP6S6Aim+t4YpzT1jWCdICYyolJHrGuzpdxwxo2cFcLNRKnwQr7J7Umcp58QjKGa+36gLvgEFrXcAhaE5oTg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366211; c=relaxed/simple; bh=vHXNBO8jXZDa1sFTamr2m/WIvPLuUs0l79eTwuIhZiU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Q0Ad4ypxKSWORz1VOrgLwL/9SIwSt+hadaQonT9+Sll+DnR5F6PTteFpTYOsC1N/REOYXy5tA6S1NRYlkSVBid/t6b82rt1Jr9RvKUwYn8z3LozyW0dlIMnE7UjYB7LPhRspMhfeBC6G382Wn1DNxUBqO9rc8d0Gdlbk7p9S1Ks= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PiY0RpTg; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PiY0RpTg" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7DE34C4CEF7; Fri, 13 Mar 2026 01:43:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773366211; bh=vHXNBO8jXZDa1sFTamr2m/WIvPLuUs0l79eTwuIhZiU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PiY0RpTg6rSOXyfyojWYxl8OkI1ukfn7vjHO/ZECvK/LL66ys2fMkiXHEHN+kjqrW VlzY6bG6OC1yPNQ8+de/uIia8fz48j+NAtfQ7xWAXqXWKlwh+Ctl4RZ8TS1erfHJ85 OrcPBrb13SDOE/JmebIAJ0bp5Y4K3MxX19z06LsqQOUA/IEVZvg/Ux73EO5hkaxq24 YbUYz1qvy/agWGMOW466I2492vGiAHIacp0AcE13Rzn0TUYvm7xmii5xVVk1M/RMQz XwsV/zV4cCup0iVYGNcADx+EkzaA6L/xa8tkhzO8pX7O35PiTLw/OY3PK4ILqGcK+G +e1jJuxd+bpAA== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang , Dust Li , Gang Yan Subject: [RFC mptcp-next v9 09/10] selftests: mptcp: connect: set smc instead of tls Date: Fri, 13 Mar 2026 09:42:51 +0800 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Geliang Tang 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 Co-developed-by: Gang Yan Signed-off-by: Gang Yan Signed-off-by: Geliang Tang --- 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/selft= ests/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=3Dm CONFIG_NFT_TPROXY=3Dm CONFIG_SYN_COOKIES=3Dy CONFIG_VETH=3Dy +CONFIG_TLS=3Dy diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/test= ing/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, unsig= ned int line) if (ret =3D=3D 0) X("setsockopt"); } else if (proto =3D=3D IPPROTO_MPTCP) { - ret =3D do_ulp_so(sock, "tls"); + ret =3D do_ulp_so(sock, "smc"); if (ret !=3D -1) X("setsockopt"); } --=20 2.53.0 From nobody Sun Mar 22 08:25:58 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C4891314A64 for ; Fri, 13 Mar 2026 01:43:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366213; cv=none; b=dk8EayjuDoGaKFG0xGAvQcniGPVvPcMjS1QCxbj1R6zGV1GUdpYlg1RtF8uNKsRy/AHi83Duky4nnavMWuWDrQ1GvKz6W4k2oWqpL7q+dvv7blj4y4teyZwHCtdQ3r16gpKQeCj9UhIbjQHH+zc3ZKGp583o1MFyMrCoNU0a+CM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773366213; c=relaxed/simple; bh=N0ipbJ2ahh9mwNUX65M9UCh9qvTKBjPjl9RJyBeny3c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sIKcfyQug7eTknAkOovb348bBFzQDjg7SKniZUUV1tsgZVole6t+HmVFkx7qzUOmE56morEybqrdgejXQvTzVxBZgxzZwxL6A8Dh/w0/xXZKxOrnpBdWS9tk6L5/wP6I5Ocp4fd+UcRQ++9AxV5dT/s96hov46sIHMRqLuTYDXM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PuZChfSS; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PuZChfSS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EBBEAC2BC87; Fri, 13 Mar 2026 01:43:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773366213; bh=N0ipbJ2ahh9mwNUX65M9UCh9qvTKBjPjl9RJyBeny3c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PuZChfSSdGuSb1zueagEzweBGz9dNrc2JJE+R6D9SLeNy2uMxSGARSMDXeMQ68lW5 i9ln/RDu4YsLISwR6/vRhCrEnCQfus7k2vhnZs6kib/7xw6DUjpH0PnA8NAtOlGjbT KbpVI5y89Q8YySE+m4e0hwfcg+pP71O9kSp+qfsaWl3JyuPuqwwwYXYS92tCX8FTov Wz/t4MeF28XHGasd/X/T7ICBWj/LCzEFUqSvLDJaMmtdDBmQE8IHE+NIPvfPHMZJ90 Qos6+G/vFqIL6WpfwLmCgbMWl0q5xrUq9dNYAzivLRybDoN4f1K+OaIu+FUN31XEXa NmfXZ5xXVkQzg== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang , Gang Yan Subject: [RFC mptcp-next v9 10/10] selftests: mptcp: connect: add TLS tests Date: Fri, 13 Mar 2026 09:42:52 +0800 Message-ID: <401c3b38f70fce67e3e827a819217fd40de44f09.1773365606.git.tanggeliang@kylinos.cn> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Geliang Tang 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 Signed-off-by: Gang Yan Signed-off-by: Geliang Tang --- .../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/test= ing/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 #include #include +#include =20 extern int optind; =20 @@ -89,6 +90,7 @@ struct cfg_cmsg_types { struct cfg_sockopt_types { unsigned int transparent:1; unsigned int mptfo:1; + unsigned int tls:1; }; =20 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)); } =20 +static void do_setsockopt_tls(int fd) +{ + struct tls12_crypto_info_aes_gcm_128 tls_tx =3D { + .info =3D { + .version =3D TLS_1_2_VERSION, + .cipher_type =3D TLS_CIPHER_AES_GCM_128, + }, + }; + struct tls12_crypto_info_aes_gcm_128 tls_rx =3D { + .info =3D { + .version =3D TLS_1_2_VERSION, + .cipher_type =3D TLS_CIPHER_AES_GCM_128, + }, + }; + int err; + + err =3D do_ulp_so(fd, "tls"); + if (err) + xerror("setsockopt TCP_ULP"); + + err =3D setsockopt(fd, SOL_TLS, TLS_TX, (void *)&tls_tx, sizeof(tls_tx)); + if (err) + xerror("setsockopt TLS_TX"); + + err =3D 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, unsig= ned int line) X("getsockopt"); =20 if (buflen > 0) { - if (strcmp(buf, "mptcp") !=3D 0) + if (strcmp(buf, "mptcp") !=3D 0 && strcmp(buf, "tls") !=3D 0) xerror("unexpected ULP '%s' for proto %d at line %u", buf, proto, line); ret =3D do_ulp_so(sock, "tls"); if (ret =3D=3D 0) @@ -422,8 +453,11 @@ static int sock_connect_mptcp(const char * const remot= eaddr, } =20 freeaddrinfo(addr); - if (sock !=3D -1) + if (sock !=3D -1) { SOCK_TEST_TCPULP(sock, proto); + if (cfg_sockopt_types.tls) + do_setsockopt_tls(sock); + } return sock; } =20 @@ -684,6 +718,8 @@ static int copyfd_io_poll(int infd, int peerfd, int out= fd, =20 /* Else, still have data to transmit */ } else if (len < 0) { + if (errno =3D=3D EAGAIN) + continue; if (cfg_rcv_trunc) return 0; perror("read"); @@ -1212,6 +1248,8 @@ int main_loop_s(int listensock) } =20 SOCK_TEST_TCPULP(remotesock, 0); + if (cfg_sockopt_types.tls) + do_setsockopt_tls(remotesock); =20 memset(&winfo, 0, sizeof(winfo)); err =3D copyfd_io(fd, remotesock, 1, true, &winfo); @@ -1312,6 +1350,11 @@ static void parse_setsock_options(const char *name) return; } =20 + if (strncmp(name, "TLS", len) =3D=3D 0) { + cfg_sockopt_types.tls =3D 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/tes= ting/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=3D1 } =20 +run_tests_tls() +{ + TEST_GROUP=3D"TLS" + local lret=3D0 + + 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=3D$? + if [ $lret -ne 0 ]; then + ret=3D$lret + return 1 + fi + + do_transfer "$ns1" "$ns2" MPTCP MPTCP "dead:beef:1::1" "::" "-o TLS" + lret=3D$? + if [ $lret -ne 0 ]; then + ret=3D$lret + return 1 + fi + + mptcp_lib_pr_info "with TLS end" +} + display_time() { time_end=3D$(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" =20 +run_tests_tls +log_if_error "Tests with TLS have failed" + display_time mptcp_lib_result_print_all_tap exit ${final_ret} --=20 2.53.0