On Wed, Aug 26, 2026 at 4:12 PM Jiayuan Chen <[email protected]> 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 <[email protected]> > --- > .../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 <[email protected]>

