From nobody Thu Jun 25 01:35:31 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 4FF6A314D35 for ; Fri, 24 Apr 2026 10:39:00 +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=1777027140; cv=none; b=Xh/4L4pQCis1MsF09dyEX6EeqYUJQGINWk3KH+nUx/x5q5eHYh2ESGEjJrbK+ZFWAP8vgg1B5kYN2yMgTQI1LJD6RnFADcxdb0+0CAgw+nlqsZDCfKlCuw2LOFepDPh2yXj2vdllY29HdF8iXok9wJBZ//mRciJ7VlVzASXxZ54= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777027140; c=relaxed/simple; bh=vH9GvOuvFNjqaTZkkNTe9MPmBlrFcscM6IVaZz5QB+Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kpFcZ8hEzQVs71ZYxN68kSvcJyLgoGLevHHbNeVFoqh7ETffie+BQ9JUHHMrUJbe1sVetqWRrbEquTqxNDNFixgptyBxkRH77bnfzPMVB7k1zTKMU116A7iVAFXA+lBkZowcaQuwYFbwGzdFDYLuJ5ZxRc/mNdPKflpJWrH8AaQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=h3GakBZK; 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="h3GakBZK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E244FC2BCB4; Fri, 24 Apr 2026 10:38:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777027140; bh=vH9GvOuvFNjqaTZkkNTe9MPmBlrFcscM6IVaZz5QB+Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=h3GakBZKApTQKtB2U0aWd0ImKHfKTIokmT75xUyCZd6GNTRZDk08xLFmA6wCUeA6i VaFrZF/Z7I6y7+vCZIUoYjmOYqVTgBz9F8ovi3IVR6d3IaFJolMgSLMZ2aViR18voN xvp9NLvxE0+cDXUgnYyvUP9PVQP9sVHbb/IGLgt6dMpUo6kAVRLGxh9icwKz1GV/vn COWltQoBDQczeyxDeLF5O31/XUzE2C/P8J6yQv9MnKhd/pGP7m06CSPRMNQV8mcuZJ EXt0+K/tURHsg1H1WN4I4xh5oRrTApGFdrAh4P3G6ognBsmQz1Z12ZdhtTew0HT7kR PUuIAMBlkFyaw== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang , Gang Yan Subject: [RFC mptcp-next v17 03/15] tls: add tls_prot_ops pointer to tls_proto Date: Fri, 24 Apr 2026 18:38:27 +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 A pointer to struct tls_prot_ops, named 'ops', has been added to struct tls_proto. The places originally calling TLS-specific helpers have now been modified to indirectly invoke them via 'ops' pointer in tls_proto. In tls_build_proto(), proto->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 | 20 ++++++++++++++++---- net/tls/tls_strp.c | 32 +++++++++++++++++++++----------- net/tls/tls_sw.c | 6 ++++-- 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/include/net/tls.h b/include/net/tls.h index 032a618d4a87..b6e355350352 100644 --- a/include/net/tls.h +++ b/include/net/tls.h @@ -249,6 +249,7 @@ struct tls_proto { refcount_t refcnt; struct list_head list; const struct proto *prot; + const struct tls_prot_ops *ops; struct proto prots[TLS_NUM_PROTS][TLS_NUM_CONFIG][TLS_NUM_CONFIG]; struct proto_ops proto_ops[TLS_NUM_PROTS][TLS_NUM_CONFIG][TLS_NUM_CONFIG]; }; diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index 76faed44fcad..6cb52e285177 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c @@ -225,13 +225,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->proto->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->proto->ops->sendmsg_locked(sk, &msg, size); =20 if (ret !=3D size) { if (ret > 0) { @@ -465,14 +465,16 @@ 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); + if (!tls_ctx || !tls_ctx->proto || !tls_ctx->proto->ops) + return 0; + mask =3D tls_ctx->proto->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 @@ -1030,6 +1032,7 @@ static struct tls_proto *tls_build_proto(struct sock = *sk) { int ip_ver =3D sk->sk_family =3D=3D AF_INET6 ? TLSV6 : TLSV4; struct proto *prot =3D READ_ONCE(sk->sk_prot); + struct tls_prot_ops *ops; struct tls_proto *proto; =20 mutex_lock(&tls_proto_mutex); @@ -1037,11 +1040,20 @@ static struct tls_proto *tls_build_proto(struct soc= k *sk) if (proto) goto out; =20 + rcu_read_lock(); + ops =3D tls_prot_ops_find(sk->sk_protocol); + if (!ops) { + rcu_read_unlock(); + goto out; + } + rcu_read_unlock(); + proto =3D kzalloc_obj(*proto, GFP_KERNEL); if (!proto) goto out; =20 proto->prot =3D prot; + proto->ops =3D ops; refcount_set(&proto->refcnt, 1); build_protos(proto->prots[ip_ver], prot); build_proto_ops(proto->proto_ops[ip_ver], diff --git a/net/tls/tls_strp.c b/net/tls/tls_strp.c index 98e12f0ff57e..763f9a06589e 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 =3D tls_get_ctx(strp->sk); struct sk_buff *skb; =20 if (strp->copy_mode) @@ -132,7 +133,7 @@ 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->proto->ops->read_done(strp->sk, strp->stm.full_len); strp->copy_mode =3D 1; =20 return 0; @@ -376,6 +377,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 +385,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->proto->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 +401,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->proto->ops->epollin_ready(strp->sk))) return 0; =20 shinfo =3D skb_shinfo(strp->anchor); @@ -434,12 +437,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->proto->ops->get_skb_seq(first); =20 /* Make sure there's no duplicate data in the queue, * and the decrypted status matches. @@ -449,7 +453,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->proto->ops->get_skb_seq(skb) !=3D seq) return false; if (skb_cmp_decrypted(first, skb)) return false; @@ -460,11 +464,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->proto->ops->recv_skb(strp->sk, &offset); if (WARN_ON_ONCE(!first)) return; =20 @@ -483,6 +487,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) { + int inq =3D tls_get_ctx(strp->sk)->proto->ops->inq(strp->sk); struct strp_msg *rxm; struct tls_msg *tlm; =20 @@ -490,7 +495,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(inq < strp->stm.full_len)) { WRITE_ONCE(strp->msg_ready, 0); memset(&strp->stm, 0, sizeof(strp->stm)); return false; @@ -511,9 +516,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->proto->ops->inq(strp->sk); if (inq < 1) return 0; =20 @@ -556,6 +562,8 @@ void tls_strp_check_rcv(struct tls_strparser *strp) /* Lower sock lock held */ void tls_strp_data_ready(struct tls_strparser *strp) { + struct tls_context *ctx =3D tls_get_ctx(strp->sk); + /* This check is needed to synchronize with do_tls_strp_work. * do_tls_strp_work acquires a process lock (lock_sock) whereas * the lock held here is bh_lock_sock. The two locks can be @@ -563,7 +571,7 @@ void tls_strp_data_ready(struct tls_strparser *strp) * allows a thread in BH context to safely check if the process * lock is held. In this case, if the lock is held, queue work. */ - if (sock_owned_by_user_nocheck(strp->sk)) { + if (ctx->proto->ops->lock_is_held(strp->sk)) { queue_work(tls_strp_wq, &strp->work); return; } @@ -583,10 +591,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->proto->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 94d2ae0daa8c..34b9359cb0c0 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -1963,13 +1963,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) { + int inq =3D tls_get_ctx(sk)->proto->ops->inq(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 && inq > max_rec) return false; =20 *flushed_at =3D done; @@ -2451,6 +2452,7 @@ int tls_rx_msg_size(struct tls_strparser *strp, struc= t sk_buff *skb) { struct tls_context *tls_ctx =3D tls_get_ctx(strp->sk); struct tls_prot_info *prot =3D &tls_ctx->prot_info; + u32 seq =3D tls_ctx->proto->ops->get_skb_seq(skb); char header[TLS_HEADER_SIZE + TLS_MAX_IV_SIZE]; size_t cipher_overhead; size_t data_len =3D 0; @@ -2498,7 +2500,7 @@ int tls_rx_msg_size(struct tls_strparser *strp, struc= t sk_buff *skb) } =20 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