From: Jiayuan Chen <jiayuan.chen@linux.dev>
To: netdev@vger.kernel.org
Cc: Eric Dumazet <edumazet@google.com>,
Neal Cardwell <ncardwell@google.com>,
Kuniyuki Iwashima <kuniyu@google.com>,
"David S. Miller" <davem@davemloft.net>,
David Ahern <dsahern@kernel.org>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>, Shuah Khan <shuah@kernel.org>,
linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org
Subject: Re: [PATCH net v2 2/2] selftests/net: packetdrill: cover RFC 5961 5.2 challenge ACK on both edges
Date: Wed, 22 Apr 2026 10:38:22 +0800 [thread overview]
Message-ID: <615b2902-597e-49dc-9bfa-621c7e072b5d@linux.dev> (raw)
In-Reply-To: <20260421014128.289362-3-jiayuan.chen@linux.dev>
On 4/21/26 9:41 AM, Jiayuan Chen wrote:
> RFC 5961 Section 5.2 / RFC 793 Section 3.9 require a challenge ACK
> whenever an incoming SEG.ACK falls outside
> [SND.UNA - MAX.SND.WND, SND.NXT]. There is currently no packetdrill
> coverage for either edge.
>
> Add tcp_rfc5961_ack-out-of-window.pkt, which in a single passive-open
> connection exercises:
>
> - Upper edge (SEG.ACK > SND.NXT): peer ACKs data that was never
> sent before the server has transmitted anything.
> - Lower edge (SEG.ACK < SND.UNA - MAX.SND.WND): after the server
> has sent 2000 bytes (the peer-advertised rwnd forces two 1000-byte
> segments, both acknowledged), peer sends an ACK that is older
> than the acceptable window.
>
> Both cases must elicit a challenge ACK
> <SEQ = SND.NXT, ACK = RCV.NXT, CTL = ACK>. The per-socket RFC 5961
> Section 7 rate limit is disabled for the duration of the test so that
> both challenge ACKs can fire back-to-back.
>
> Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
> Reviewed-by: Eric Dumazet <edumazet@google.com>
> ---
> .../tcp_rfc5961_ack-out-of-window.pkt | 46 +++++++++++++++++++
> 1 file changed, 46 insertions(+)
> create mode 100644 tools/testing/selftests/net/packetdrill/tcp_rfc5961_ack-out-of-window.pkt
>
> diff --git a/tools/testing/selftests/net/packetdrill/tcp_rfc5961_ack-out-of-window.pkt b/tools/testing/selftests/net/packetdrill/tcp_rfc5961_ack-out-of-window.pkt
> new file mode 100644
> index 000000000000..44d54c812820
> --- /dev/null
> +++ b/tools/testing/selftests/net/packetdrill/tcp_rfc5961_ack-out-of-window.pkt
> @@ -0,0 +1,46 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// RFC 5961 Section 5.2 / RFC 793 Section 3.9: an incoming segment's
> +// ACK value must lie in [SND.UNA - MAX.SND.WND, SND.NXT]; otherwise
> +// the receiver MUST discard the segment and send a challenge ACK
> +// back. Exercise both edges of that window in a single connection.
> +
> +`./defaults.sh
> +sysctl -q net.ipv4.tcp_invalid_ratelimit=0
> +`
> +
> + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
> + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
> + +0 bind(3, ..., ...) = 0
> + +0 listen(3, 1) = 0
> +
> +// Three-way handshake. Peer advertises rwnd = 1000 (no wscale), so
> +// MAX.SND.WND is tracked as 1000.
> + +0 < S 0:0(0) win 1000 <mss 1000,sackOK,nop,nop,nop,wscale 0>
> + +0 > S. 0:0(0) ack 1 <...>
> ++.1 < . 1:1(0) ack 1 win 1000
> + +0 accept(3, ..., ...) = 4
> +
> +// ---- Upper edge: SEG.ACK > SND.NXT --------------------------------
> +// Server has sent nothing yet, so SND.UNA = SND.NXT = 1.
> +// Peer sends a pure ACK with SEG.ACK = 2, beyond SND.NXT.
> + +0 < . 1:1(0) ack 2 win 1000
> +// Expect a challenge ACK: <SEQ = SND.NXT = 1, ACK = RCV.NXT = 1>.
> + +0 > . 1:1(0) ack 1
> +
> +// Advance SND.UNA past MAX.SND.WND so that the lower edge becomes
> +// reachable. Write 2000 bytes; the peer's rwnd of 1000 forces two
> +// 1000-byte segments, each acknowledged in turn.
> + +0 write(4, ..., 2000) = 2000
> + +0 > P. 1:1001(1000) ack 1
> ++.01 < . 1:1(0) ack 1001 win 1000
> + +0 > P. 1001:2001(1000) ack 1
> ++.01 < . 1:1(0) ack 2001 win 1000
> +// Now SND.UNA = SND.NXT = 2001, MAX.SND.WND = 1000, bytes_acked = 2000.
> +
> +// ---- Lower edge: SEG.ACK < SND.UNA - MAX.SND.WND ------------------
> +// SND.UNA - MAX.SND.WND = 2001 - 1000 = 1001, so SEG.ACK = 1000 falls
> +// below the acceptable range.
> + +0 < . 1:1(0) ack 1000 win 1000
> +// Expect a challenge ACK: <SEQ = SND.NXT = 2001, ACK = RCV.NXT = 1>.
> + +0 > . 2001:2001(0) ack 1
https://sashiko.dev/#/patchset/20260421014128.289362-1-jiayuan.chen%40linux.dev
I don't think the AI's concern holds, but I think I can split
write(2000) into write(1000)
so the test doesn't rely on kernel internals.
prev parent reply other threads:[~2026-04-22 2:38 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-21 1:40 [PATCH net v2 0/2] tcp: symmetric challenge ACK for SEG.ACK > SND.NXT Jiayuan Chen
2026-04-21 1:41 ` [PATCH net v2 1/2] tcp: send a challenge ACK on " Jiayuan Chen
2026-04-21 1:41 ` [PATCH net v2 2/2] selftests/net: packetdrill: cover RFC 5961 5.2 challenge ACK on both edges Jiayuan Chen
2026-04-22 2:38 ` Jiayuan Chen [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=615b2902-597e-49dc-9bfa-621c7e072b5d@linux.dev \
--to=jiayuan.chen@linux.dev \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=kuniyu@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=ncardwell@google.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=shuah@kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.