Netdev List
 help / color / mirror / Atom feed
From: Rishikesh Jethwani <rjethwani@purestorage.com>
To: netdev@vger.kernel.org
Cc: Rishikesh Jethwani <rjethwani@purestorage.com>,
	John Fastabend <john.fastabend@gmail.com>,
	Jakub Kicinski <kuba@kernel.org>,
	Sabrina Dubroca <sd@queasysnail.net>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@kernel.org>,
	Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>,
	Dirk van der Merwe <dirk.vandermerwe@netronome.com>,
	linux-kernel@vger.kernel.org
Subject: [PATCH net v2 4/4] tls: device: fix next-record queued checks in core-driven RX resync
Date: Thu, 22 Oct 2026 16:15:00 -0600	[thread overview]
Message-ID: <20261022221732.1397620-5-rjethwani@purestorage.com> (raw)
In-Reply-To: <20261022221732.1397620-1-rjethwani@purestorage.com>

TLS_OFFLOAD_SYNC_TYPE_CORE_NEXT_HINT resync tells the device where the
next record starts. That is only useful if the device has not yet seen
the next record's header, so both places that send the hint first check
whether any of the next record is already queued on the socket, using
tcp_inq(). tcp_inq() counts from copied_seq, so the checks are only
right if they know how much of the current record has been consumed.

tls_device_core_ctrl_rx_resync() runs when a record is entirely
encrypted and checks tcp_inq() > rxm->full_len. With the original
strparser the record had already been read out, so this asked for more
than a whole record beyond the current one instead of any data at all,
contrary to the intent stated in the commit that added it. Since the
TLS-specific strparser the check is correct in its normal mode, where
the record is still queued, but copy mode has consumed the record and
keeps the original error. The hint can then be sent immediately for a
boundary the device has already passed.

tls_device_rx_resync_new_rec() runs when a new record header is parsed
and checks tcp_inq() > rcd_len, relying on the queue still holding the
record being parsed. That does not hold once part of the record has
been consumed: in copy mode, and with the original strparser, which
also consumed incomplete headers before parsing them. The check then
underestimates what is queued and can send the hint after the next
header has arrived, too late for the device to use it.

In both cases the attempt is wasted and the next try is made only after
backoff, keeping the stream on software decryption longer.

Count from the record start instead of copied_seq. With the record
start now tracked by the strparser in both modes, rcv_nxt minus that
start is the number of bytes received for this record and beyond,
regardless of how much has been consumed. The
tls_device_rx_resync_nh_delay tracepoint now reports received sequence
space from the record start, including data already consumed in copy
mode. A FIN right after the record now counts as queued data, which
only defers a hint that could not be used, since no record can follow
it.

Only drivers using TLS_OFFLOAD_SYNC_TYPE_CORE_NEXT_HINT are affected.

Found by code inspection while working on TLS 1.3 hardware offload
support.

Fixes: f953d33ba122 ("net/tls: add kernel-driven TLS RX resync")
Signed-off-by: Rishikesh Jethwani <rjethwani@purestorage.com>
---
 net/tls/tls_device.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c
index a6c4d0cc54c7..8181564600c1 100644
--- a/net/tls/tls_device.c
+++ b/net/tls/tls_device.c
@@ -805,10 +805,10 @@ void tls_device_rx_resync_new_rec(struct sock *sk, u32 rcd_len, u32 seq)
 		if (likely(!rx_ctx->resync_nh_do_now))
 			return;
 
-		/* head of next rec is already in, note that the sock_inq will
-		 * include the currently parsed message when called from parser
+		/* head of next rec is already in, count from the record start
+		 * since copy mode may have consumed part of it already
 		 */
-		sock_data = tcp_inq(sk);
+		sock_data = READ_ONCE(tcp_sk(sk)->rcv_nxt) - seq;
 		if (sock_data > rcd_len) {
 			trace_tls_device_rx_resync_nh_delay(sk, sock_data,
 							    rcd_len);
@@ -841,6 +841,7 @@ static void tls_device_core_ctrl_rx_resync(struct tls_context *tls_ctx,
 {
 	struct tls_sw_context_rx *sw_ctx = tls_sw_ctx_rx(tls_ctx);
 	struct strp_msg *rxm;
+	u32 next_seq;
 
 	/* device will request resyncs by itself based on stream scan */
 	if (ctx->resync_type != TLS_OFFLOAD_SYNC_TYPE_CORE_NEXT_HINT)
@@ -866,9 +867,10 @@ static void tls_device_core_ctrl_rx_resync(struct tls_context *tls_ctx,
 		ctx->resync_nh.decrypted_tgt += TLS_DEVICE_RESYNC_NH_MAX_IVAL;
 
 	rxm = strp_msg(skb);
+	next_seq = tls_strp_msg_seq(sw_ctx) + rxm->full_len;
 
 	/* head of next rec is already in, parser will sync for us */
-	if (tcp_inq(sk) > rxm->full_len) {
+	if (after(READ_ONCE(tcp_sk(sk)->rcv_nxt), next_seq)) {
 		trace_tls_device_rx_resync_nh_schedule(sk);
 		ctx->resync_nh_do_now = 1;
 	} else {
@@ -878,9 +880,7 @@ static void tls_device_core_ctrl_rx_resync(struct tls_context *tls_ctx,
 		memcpy(rcd_sn, tls_ctx->rx.rec_seq, prot->rec_seq_size);
 		tls_bigint_increment(rcd_sn, prot->rec_seq_size);
 
-		tls_device_resync_rx(tls_ctx, sk,
-				     tls_strp_msg_seq(sw_ctx) +
-				     rxm->full_len, rcd_sn);
+		tls_device_resync_rx(tls_ctx, sk, next_seq, rcd_sn);
 	}
 }
 
-- 
2.50.1


      parent reply	other threads:[~2026-10-22 22:17 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-22 22:14 [PATCH net v2 0/4] tls: device: fix RX record start tracking after strparser rework Rishikesh Jethwani
2026-10-22 22:14 ` [PATCH net v2 1/4] tls: device: fix record start in the tls_device_decrypted tracepoint Rishikesh Jethwani
2026-10-22 22:14 ` [PATCH net v2 2/4] tls: device: fix next-record sequence in core-driven RX resync Rishikesh Jethwani
2026-10-26 22:48   ` netdev-bot+sashiko
2026-10-27 17:52     ` Rishikesh Jethwani
2026-10-22 22:14 ` [PATCH net v2 3/4] tls: device: fix record start reported to RX resync in copy mode Rishikesh Jethwani
2026-10-22 22:15 ` Rishikesh Jethwani [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261022221732.1397620-5-rjethwani@purestorage.com \
    --to=rjethwani@purestorage.com \
    --cc=davem@davemloft.net \
    --cc=dirk.vandermerwe@netronome.com \
    --cc=edumazet@kernel.org \
    --cc=horms@kernel.org \
    --cc=john.fastabend@gmail.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=sd@queasysnail.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox