Re: [PATCH net 2/2] selftests/net: packetdrill: add tcp_urg_ptr_retransmit
From: Eric Dumazet
Date: Wed Aug 26 2026 - 11:53:19 EST
On Wed, Aug 26, 2026 at 4:12 PM Jiayuan Chen <jiayuan.chen@xxxxxxxxx> wrote:
>
> Drive a connection into urgent mode and force a multi-segment retransmit,
> checking that each retransmitted segment keeps its own urg_ptr.
>
> The test asserts the fixed behaviour: the hole is retransmitted as two
> independent skbs, each with its own urg_ptr (5001 and 4001) and no PSH.
> An unpatched kernel instead sends one super-skb whose GSO split copies
> urg_ptr onto the second segment and also sets PSH there, so on an unpatched
> kernel the mismatch shows up on the PSH bit (actual P.U ... urg 5001) before
> the urg_ptr:
>
> tcp_urg_ptr_retransmit.pkt:63: live packet field tcp_psh:
> expected: 0 (0x0) vs actual: 1 (0x1)
> script packet: .U 1001:2001(1000) ack 1
> actual packet: P.U 1001:2001(1000) ack 1 win 1050
>
> After the fix the retransmit carries a per-segment urg_ptr and the test
> passes.
>
> Signed-off-by: Jiayuan Chen <jiayuan.chen@xxxxxxxxx>
> ---
> .../packetdrill/tcp_urg_ptr_retransmit.pkt | 65 +++++++++++++++++++
> 1 file changed, 65 insertions(+)
> create mode 100644 tools/testing/selftests/net/packetdrill/tcp_urg_ptr_retransmit.pkt
>
> diff --git a/tools/testing/selftests/net/packetdrill/tcp_urg_ptr_retransmit.pkt b/tools/testing/selftests/net/packetdrill/tcp_urg_ptr_retransmit.pkt
> new file mode 100644
> index 000000000000..22f750ce09c1
> --- /dev/null
> +++ b/tools/testing/selftests/net/packetdrill/tcp_urg_ptr_retransmit.pkt
> @@ -0,0 +1,65 @@
> +// SPDX-License-Identifier: GPL-2.0
> +--ip_version=ipv4
> +//
> +// Reproduce urg_ptr being copied across segments on a multi-segment retransmit
> +// in urgent mode (regression since 10d3be569243).
> +//
> +// server (kernel, under test) client (packetdrill)
> +// | write(5000): 1:1001 .. 4001:5001 | mss 1000 from
> +// | -------------------------------------------> | the client SYN
> +// | send(MSG_OOB): 5001:5002 urg 1 | snd_up = 5002
> +// | -------------------------------------------> |
> +// | SACK 2001:5002, leaving hole 1:2001|
> +// | <------------------------------------------- |
> +// | retransmit hole 1:2001 as ONE skb: |
> +// | seq=1, 2 segments, urg_ptr = 5002-1 = 5001|
> +// | tun tso off -> software GSO splits it: |
> +// | seg A 1:1001 urg_ptr 5001 (correct) |
> +// | seg B 1001:2001 urg_ptr ? |
> +// | want 5002-1001 = 4001 |
> +// | bug inherits 5001 <- caught here |
> +// | -------------------------------------------> |
> +//
> +
> +`./defaults.sh`
> +
> + 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
> +
> +// 1. client force mss=1000
> + +.1 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7>
> + +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8>
> + +.1 < . 1:1(0) ack 1 win 320
> + +0 accept(3, ..., ...) = 4
> +
> +// 2. server sends 5000 bytes; TSO on, so packetdrill sees whole super-skbs
> + +0 write(4, ..., 5000) = 5000
> + +0 > P. 1:5001(5000) ack 1
> +
> +// 3. server send OOB
> + +0 send(4, ..., 1, MSG_OOB) = 1
> + +0 > PU. 5001:5002(1) ack 1 urg 1
> +
> +// We could disable GSO at the start of the script, but then the PSH flag on
> +// the 5 initial server segments is not deterministic and hard to match. Keep
> +// TSO on for the initial send (one super-skb, stable PSH) and disable it only
> +// here, so software GSO splits the retransmit and each segment's urg_ptr is
> +// checked on the wire.
> + +0 `ethtool -K tun0 tso off gso off gro off lro off 2>/dev/null`
nit: I suspect "ethtool -K tun0 tso off" is enough.
Reviewed-by: Eric Dumazet <edumazet@xxxxxxxxxx>