Skip to content

Commit 4363d18

Browse files
committed
Merge branch 'selftest-packetdrill-import-tfo-server-tests'
Kuniyuki Iwashima says: ==================== selftest: packetdrill: Import TFO server tests. The series imports 15 TFO server tests from google/packetdrill and adds 2 more tests. The repository has two versions of tests for most scenarios; one uses the non-experimental option (34), and the other uses the experimental option (255) with 0xF989. Basically, we only import the non-experimental version of tests, and for the experimental option, tcp_fastopen_server_experimental_option.pkt is added. The following tests are not (yet) imported: * icmp-baseline.pkt * simple1.pkt / simple2.pkt / simple3.pkt The former is completely covered by icmp-before-accept.pkt. The later's delta is the src/dst IP pair to generate a different cookie, but supporting dualstack requires churn in ksft_runner.sh, so defered to future series. Also, sockopt-fastopen-key.pkt covers the same function. The following tests have the experimental version only, so converted to the non-experimental option: * client-ack-dropped-then-recovery-ms-timestamps.pkt * sockopt-fastopen-key.pkt For the imported tests, these common changes are applied. * Add SPDX header * Adjust path to default.sh * Adjust sysctl w/ set_sysctls.py * Use TFO_COOKIE instead of a raw hex value * Use SOCK_NONBLOCK for socket() not to block accept() * Add assertions for TCP state if commented * Remove unnecessary delay (e.g. +0.1 setsockopt(SO_REUSEADDR), etc) With this series, except for simple{1,2,3}.pkt, we can remove TFO server tests in google/packetdrill. ==================== Link: https://patch.msgid.link/20250927213022.1850048-1-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 4ed9db2 + 9b62d53 commit 4363d18

20 files changed

Lines changed: 611 additions & 6 deletions

tools/testing/selftests/net/packetdrill/defaults.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ sysctl -q net.ipv4.tcp_pacing_ss_ratio=200
5151
sysctl -q net.ipv4.tcp_pacing_ca_ratio=120
5252
sysctl -q net.ipv4.tcp_notsent_lowat=4294967295 > /dev/null 2>&1
5353

54-
sysctl -q net.ipv4.tcp_fastopen=0x70403
54+
sysctl -q net.ipv4.tcp_fastopen=0x3
55+
# Use TFO_COOKIE in ksft_runner.sh for this key.
5556
sysctl -q net.ipv4.tcp_fastopen_key=a1a1a1a1-b2b2b2b2-c3c3c3c3-d4d4d4d4
5657

5758
sysctl -q net.ipv4.tcp_syncookies=1

tools/testing/selftests/net/packetdrill/ksft_runner.sh

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@ declare -A ip_args=(
99
--gateway_ip=192.168.0.1
1010
--netmask_ip=255.255.0.0
1111
--remote_ip=192.0.2.1
12+
-D TFO_COOKIE=3021b9d889017eeb
13+
-D TFO_COOKIE_ZERO=b7c12350a90dc8f5
1214
-D CMSG_LEVEL_IP=SOL_IP
1315
-D CMSG_TYPE_RECVERR=IP_RECVERR"
1416
[ipv6]="--ip_version=ipv6
1517
--mtu=1520
1618
--local_ip=fd3d:0a0b:17d6::1
1719
--gateway_ip=fd3d:0a0b:17d6:8888::1
1820
--remote_ip=fd3d:fa7b:d17d::1
21+
-D TFO_COOKIE=c1d1e9742a47a9bc
22+
-D TFO_COOKIE_ZERO=82af1a8f9a205c34
1923
-D CMSG_LEVEL_IP=SOL_IPV6
2024
-D CMSG_TYPE_RECVERR=IPV6_RECVERR"
2125
)
@@ -48,11 +52,11 @@ elif [[ ! "$ip_versions" =~ ^ipv[46]$ ]]; then
4852
fi
4953

5054
ktap_print_header
51-
ktap_set_plan 2
55+
ktap_set_plan $(echo $ip_versions | wc -w)
5256

5357
for ip_version in $ip_versions; do
5458
unshare -n packetdrill ${ip_args[$ip_version]} ${optargs[@]} $script > /dev/null \
55-
&& ktap_test_pass $ip_version || $failfunc $ip_version
59+
&& ktap_test_pass $ip_version || $failfunc $ip_version
5660
done
5761

5862
ktap_finished
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
//
3+
// Basic TFO server test
4+
//
5+
// Test TFO_SERVER_COOKIE_NOT_REQD flag on receiving
6+
// SYN with data but without Fast Open cookie option.
7+
8+
`./defaults.sh
9+
./set_sysctls.py /proc/sys/net/ipv4/tcp_fastopen=0x202`
10+
11+
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
12+
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
13+
+0 bind(3, ..., ...) = 0
14+
+0 listen(3, 1) = 0
15+
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
16+
17+
// Since TFO_SERVER_COOKIE_NOT_REQD, a TFO socket will be created with
18+
// the data accepted.
19+
+0 < S 0:1000(1000) win 32792 <mss 1460,sackOK,nop,nop>
20+
+0 > S. 0:0(0) ack 1001 <mss 1460,nop,nop,sackOK>
21+
+0 accept(3, ..., ...) = 4
22+
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
23+
+0 read(4, ..., 1024) = 1000
24+
25+
// Data After SYN will be accepted too.
26+
+0 < . 1001:2001(1000) ack 1 win 5840
27+
+0 > . 1:1(0) ack 2001
28+
29+
// Should change the implementation later to set the SYN flag as well.
30+
+0 read(4, ..., 1024) = 1000
31+
+0 write(4, ..., 1000) = 1000
32+
+0 > P. 1:1001(1000) ack 2001
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
//
3+
// Basic TFO server test
4+
//
5+
// Test TFO_SERVER_WO_SOCKOPT1 without setsockopt(TCP_FASTOPEN)
6+
7+
`./defaults.sh
8+
./set_sysctls.py /proc/sys/net/ipv4/tcp_fastopen=0x402`
9+
10+
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
11+
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
12+
+0 bind(3, ..., ...) = 0
13+
+0 listen(3, 1) = 0
14+
15+
+0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
16+
+0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
17+
18+
+0 accept(3, ..., ...) = 4
19+
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
20+
21+
+0 read(4, ..., 512) = 10
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
//
3+
// Basic TFO server test
4+
//
5+
// Server w/o TCP_FASTOPEN socket option
6+
7+
`./defaults.sh`
8+
9+
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
10+
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
11+
+0 bind(3, ..., ...) = 0
12+
+0 listen(3, 1) = 0
13+
14+
+0 < S 0:10(10) win 32792 <mss 1460,sackOK,FO TFO_COOKIE>
15+
16+
// Data is ignored since TCP_FASTOPEN is not set on the listener
17+
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK>
18+
19+
+0 accept(3, ..., ...) = -1 EAGAIN (Resource temporarily unavailable)
20+
21+
// The above should block until ack comes in below.
22+
+0 < . 1:31(30) ack 1 win 5840
23+
+0 accept(3, ..., ...) = 4
24+
25+
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
26+
+0 read(4, ..., 512) = 30
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
//
3+
// Basic TFO server test
4+
//
5+
// Test that TFO-enabled server would not respond SYN-ACK with any TFO option
6+
// when receiving a pure SYN-data. It should respond a pure SYN-ack.
7+
8+
`./defaults.sh`
9+
10+
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
11+
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
12+
+0 bind(3, ..., ...) = 0
13+
+0 listen(3, 1) = 0
14+
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
15+
16+
+0 < S 999000:999040(40) win 32792 <mss 1460,sackOK,TS val 100 ecr 100,nop,wscale 6>
17+
+0 > S. 1234:1234(0) ack 999001 <mss 1460,sackOK,TS val 100 ecr 100,nop,wscale 8>
18+
+0 < . 1:1(0) ack 1 win 100
19+
+0 accept(3, ..., ...) = 4
20+
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
21+
+0 close(3) = 0
22+
23+
// Test ECN-setup SYN with ECN disabled because this has happened in reality
24+
+0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
25+
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
26+
+0 bind(3, ..., ...) = 0
27+
+0 listen(3, 1) = 0
28+
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
29+
30+
+0 < SEW 999000:999040(40) win 32792 <mss 1460,sackOK,TS val 100 ecr 100,nop,wscale 6>
31+
+0 > S. 1234:1234(0) ack 999001 <mss 1460,sackOK,TS val 100 ecr 100,nop,wscale 8>
32+
+0 < . 1:1(0) ack 1 win 100
33+
+0 accept(3, ..., ...) = 4
34+
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
35+
+0 close(3) = 0
36+
37+
// Test ECN-setup SYN w/ ECN enabled
38+
+0 `sysctl -q net.ipv4.tcp_ecn=2`
39+
+0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
40+
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
41+
+0 bind(3, ..., ...) = 0
42+
+0 listen(3, 1) = 0
43+
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
44+
45+
+0 < SEW 999000:999040(40) win 32792 <mss 1460,sackOK,TS val 100 ecr 100,nop,wscale 6>
46+
+0 > SE. 1234:1234(0) ack 999001 <mss 1460,sackOK,TS val 100 ecr 100,nop,wscale 8>
47+
+0 < . 1:1(0) ack 1 win 100
48+
+0 accept(3, ..., ...) = 4
49+
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
50+
+0 close(3) = 0
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
//
3+
// Basic TFO server test
4+
//
5+
// Test TFO server with SYN that has TFO cookie and data.
6+
7+
`./defaults.sh`
8+
9+
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
10+
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
11+
+0 bind(3, ..., ...) = 0
12+
+0 listen(3, 1) = 0
13+
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
14+
15+
+0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
16+
+0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
17+
18+
+0 accept(3, ..., ...) = 4
19+
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
20+
21+
+0 read(4, ..., 512) = 10
22+
+0 write(4, ..., 100) = 100
23+
+0 > P. 1:101(100) ack 11
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
//
3+
// Basic TFO server test
4+
//
5+
// Test zero-payload packet w/ valid TFO cookie - a TFO socket will
6+
// still be created and accepted but read() will not return until a
7+
// later pkt with 10 byte.
8+
9+
`./defaults.sh`
10+
11+
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
12+
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
13+
+0 bind(3, ..., ...) = 0
14+
+0 listen(3, 1) = 0
15+
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
16+
17+
+0 < S 0:0(0) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
18+
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK>
19+
+0 accept(3, ..., ...) = 4
20+
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
21+
22+
// A TFO socket is created and is writable.
23+
+0 write(4, ..., 100) = 100
24+
+0 > P. 1:101(100) ack 1
25+
+0...0.300 read(4, ..., 512) = 10
26+
+.3 < P. 1:11(10) ack 1 win 5840
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
//
3+
// A reproducer case for a TFO SYNACK RTO undo bug in:
4+
// 794200d66273 ("tcp: undo cwnd on Fast Open spurious SYNACK retransmit")
5+
// This sequence that tickles this bug is:
6+
// - Fast Open server receives TFO SYN with data, sends SYNACK
7+
// - (client receives SYNACK and sends ACK, but ACK is lost)
8+
// - server app sends some data packets
9+
// - (N of the first data packets are lost)
10+
// - server receives client ACK that has a TS ECR matching first SYNACK,
11+
// and also SACKs suggesting the first N data packets were lost
12+
// - server performs undo of SYNACK RTO, then immediately enters recovery
13+
// - buggy behavior in 794200d66273 then performed an undo that caused
14+
// the connection to be in a bad state, in CA_Open with retrans_out != 0
15+
16+
// Check that outbound TS Val ticks are as we would expect with 1000 usec per
17+
// timestamp tick:
18+
--tcp_ts_tick_usecs=1000
19+
20+
`./defaults.sh`
21+
22+
// Initialize connection
23+
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
24+
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
25+
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
26+
+0 bind(3, ..., ...) = 0
27+
+0 listen(3, 1) = 0
28+
29+
+0 < S 0:1000(1000) win 65535 <mss 1012,sackOK,TS val 1000 ecr 0,wscale 7,nop,nop,nop,FO TFO_COOKIE>
30+
+0 > S. 0:0(0) ack 1001 <mss 1460,sackOK,TS val 2000 ecr 1000,nop,wscale 8>
31+
+0 accept(3, ..., ...) = 4
32+
33+
// Application writes more data
34+
+.010 write(4, ..., 10000) = 10000
35+
+0 > P. 1:5001(5000) ack 1001 <nop,nop,TS val 2010 ecr 1000>
36+
+0 > P. 5001:10001(5000) ack 1001 <nop,nop,TS val 2010 ecr 1000>
37+
+0 %{ assert tcpi_snd_cwnd == 10, tcpi_snd_cwnd }%
38+
39+
+0 < . 1001:1001(0) ack 1 win 257 <TS val 1010 ecr 2000,sack 2001:5001>
40+
+0 > P. 1:2001(2000) ack 1001 <nop,nop,TS val 2010 ecr 1010>
41+
+0 %{ assert tcpi_ca_state == TCP_CA_Recovery, tcpi_ca_state }%
42+
+0 %{ assert tcpi_snd_cwnd == 7, tcpi_snd_cwnd }%
43+
44+
+0 < . 1001:1001(0) ack 1 win 257 <TS val 1011 ecr 2000,sack 2001:6001>
45+
+0 %{ assert tcpi_ca_state == TCP_CA_Recovery, tcpi_ca_state }%
46+
+0 %{ assert tcpi_snd_cwnd == 7, tcpi_snd_cwnd }%
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
//
3+
// Test the Experimental Option
4+
//
5+
// SYN w/ FOEXP w/o cookie must generates SYN+ACK w/ FOEXP
6+
// w/ a valid cookie, and the cookie must be the same one
7+
// with one generated by IANA FO
8+
9+
`./defaults.sh`
10+
11+
// Request a TFO cookie by Experimental Option
12+
// This must generate the same TFO_COOKIE
13+
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
14+
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
15+
+0 bind(3, ..., ...) = 0
16+
+0 listen(3, 1) = 0
17+
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
18+
19+
+0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FOEXP>
20+
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,FOEXP TFO_COOKIE>
21+
22+
+0 close(3) = 0
23+
24+
// Test if FOEXP with a valid cookie creates a TFO socket
25+
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
26+
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
27+
+0 bind(3, ..., ...) = 0
28+
+0 listen(3, 1) = 0
29+
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
30+
31+
+0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FOEXP TFO_COOKIE>
32+
+0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
33+
34+
+0 accept(3, ..., ...) = 4
35+
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
36+
37+
+0 read(4, ..., 512) = 10

0 commit comments

Comments
 (0)