* [PATCH v1 net-next 00/12] selftest: packetdrill: Import TFO server tests.
@ 2025-09-26 21:28 Kuniyuki Iwashima
2025-09-26 21:28 ` [PATCH v1 net-next 01/12] selftest: packetdrill: Require explicit setsockopt(TCP_FASTOPEN) Kuniyuki Iwashima
` (11 more replies)
0 siblings, 12 replies; 14+ messages in thread
From: Kuniyuki Iwashima @ 2025-09-26 21:28 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
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 default.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.
Kuniyuki Iwashima (12):
selftest: packetdrill: Require explicit setsockopt(TCP_FASTOPEN).
selftest: packetdrill: Define common TCP Fast Open cookie.
selftest: packetdrill: Import TFO server basic tests.
selftest: packetdrill: Add test for TFO_SERVER_WO_SOCKOPT1.
selftest: packetdrill: Add test for experimental option.
selftest: packetdrill: Import opt34/fin-close-socket.pkt.
selftest: packetdrill: Import opt34/icmp-before-accept.pkt.
selftest: packetdrill: Import opt34/reset-* tests.
selftest: packetdrill: Import opt34/*-trigger-rst.pkt.
selftest: packetdrill: Refine
tcp_fastopen_server_reset-after-disconnect.pkt.
selftest: packetdrill: Import sockopt-fastopen-key.pkt
selftest: packetdrill: Import
client-ack-dropped-then-recovery-ms-timestamps.pkt
.../selftests/net/packetdrill/defaults.sh | 3 +-
.../selftests/net/packetdrill/ksft_runner.sh | 6 +-
..._fastopen_server_basic-cookie-not-reqd.pkt | 32 ++++++++
...cp_fastopen_server_basic-no-setsockopt.pkt | 21 ++++++
...fastopen_server_basic-non-tfo-listener.pkt | 26 +++++++
...cp_fastopen_server_basic-pure-syn-data.pkt | 50 +++++++++++++
.../tcp_fastopen_server_basic-rw.pkt | 23 ++++++
...tcp_fastopen_server_basic-zero-payload.pkt | 26 +++++++
...ck-dropped-then-recovery-ms-timestamps.pkt | 46 ++++++++++++
...cp_fastopen_server_experimental_option.pkt | 37 ++++++++++
.../tcp_fastopen_server_fin-close-socket.pkt | 30 ++++++++
...tcp_fastopen_server_icmp-before-accept.pkt | 49 ++++++++++++
...tcp_fastopen_server_reset-after-accept.pkt | 37 ++++++++++
...cp_fastopen_server_reset-before-accept.pkt | 32 ++++++++
...en_server_reset-close-with-unread-data.pkt | 32 ++++++++
...p_fastopen_server_reset-non-tfo-socket.pkt | 37 ++++++++++
...p_fastopen_server_sockopt-fastopen-key.pkt | 74 +++++++++++++++++++
...pen_server_trigger-rst-listener-closed.pkt | 21 ++++++
...fastopen_server_trigger-rst-reconnect.pkt} | 10 ++-
..._server_trigger-rst-unread-data-closed.pkt | 23 ++++++
20 files changed, 610 insertions(+), 5 deletions(-)
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-cookie-not-reqd.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-no-setsockopt.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-non-tfo-listener.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-pure-syn-data.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-rw.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-zero-payload.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_client-ack-dropped-then-recovery-ms-timestamps.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_experimental_option.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_fin-close-socket.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_icmp-before-accept.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-after-accept.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-before-accept.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-close-with-unread-data.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-non-tfo-socket.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_sockopt-fastopen-key.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_trigger-rst-listener-closed.pkt
rename tools/testing/selftests/net/packetdrill/{tcp_fastopen_server_reset-after-disconnect.pkt => tcp_fastopen_server_trigger-rst-reconnect.pkt} (66%)
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_trigger-rst-unread-data-closed.pkt
--
2.51.0.536.g15c5d4f767-goog
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v1 net-next 01/12] selftest: packetdrill: Require explicit setsockopt(TCP_FASTOPEN).
2025-09-26 21:28 [PATCH v1 net-next 00/12] selftest: packetdrill: Import TFO server tests Kuniyuki Iwashima
@ 2025-09-26 21:28 ` Kuniyuki Iwashima
2025-09-26 21:28 ` [PATCH v1 net-next 02/12] selftest: packetdrill: Define common TCP Fast Open cookie Kuniyuki Iwashima
` (10 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Kuniyuki Iwashima @ 2025-09-26 21:28 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
To enable TCP Fast Open on a server, net.ipv4.tcp_fastopen must
have 0x2 (TFO_SERVER_ENABLE), and we need to do either
1. Call setsockopt(TCP_FASTOPEN) for the socket
2. Set 0x400 (TFO_SERVER_WO_SOCKOPT1) additionally to net.ipv4.tcp_fastopen
The default.sh sets 0x70403 so that each test does not need setsockopt().
(0x1 is TFO_CLIENT_ENABLE, and 0x70000 is ...???)
However, some tests overwrite net.ipv4.tcp_fastopen without
TFO_SERVER_WO_SOCKOPT1 and forgot setsockopt(TCP_FASTOPEN).
For example, pure-syn-data.pkt [0] tests non-TFO servers unintentionally,
except in the first scenario.
To prevent such an accident, let's require explicit setsockopt().
TFO_CLIENT_ENABLE will be restored when client tests are added.
Link: https://github.com/google/packetdrill/blob/bfc96251310f/gtests/net/tcp/fastopen/server/opt34/pure-syn-data.pkt #[0]
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
tools/testing/selftests/net/packetdrill/defaults.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/net/packetdrill/defaults.sh b/tools/testing/selftests/net/packetdrill/defaults.sh
index 1095a7b22f44..6b0ca8e738a2 100755
--- a/tools/testing/selftests/net/packetdrill/defaults.sh
+++ b/tools/testing/selftests/net/packetdrill/defaults.sh
@@ -51,7 +51,7 @@ sysctl -q net.ipv4.tcp_pacing_ss_ratio=200
sysctl -q net.ipv4.tcp_pacing_ca_ratio=120
sysctl -q net.ipv4.tcp_notsent_lowat=4294967295 > /dev/null 2>&1
-sysctl -q net.ipv4.tcp_fastopen=0x70403
+sysctl -q net.ipv4.tcp_fastopen=0x2
sysctl -q net.ipv4.tcp_fastopen_key=a1a1a1a1-b2b2b2b2-c3c3c3c3-d4d4d4d4
sysctl -q net.ipv4.tcp_syncookies=1
--
2.51.0.536.g15c5d4f767-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v1 net-next 02/12] selftest: packetdrill: Define common TCP Fast Open cookie.
2025-09-26 21:28 [PATCH v1 net-next 00/12] selftest: packetdrill: Import TFO server tests Kuniyuki Iwashima
2025-09-26 21:28 ` [PATCH v1 net-next 01/12] selftest: packetdrill: Require explicit setsockopt(TCP_FASTOPEN) Kuniyuki Iwashima
@ 2025-09-26 21:28 ` Kuniyuki Iwashima
2025-09-26 21:28 ` [PATCH v1 net-next 03/12] selftest: packetdrill: Import TFO server basic tests Kuniyuki Iwashima
` (9 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Kuniyuki Iwashima @ 2025-09-26 21:28 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
TCP Fast Open cookie is generated in __tcp_fastopen_cookie_gen_cipher().
The cookie value is generated from src/dst IPs and a key configured by
setsockopt(TCP_FASTOPEN_KEY) or net.ipv4.tcp_fastopen_key.
The default.sh sets net.ipv4.tcp_fastopen_key, and the original packetdrill
defines the corresponding cookie as TFO_COOKIE in run_all.py. [0]
Then, each test does not need to care about the value, and we can easily
update TFO_COOKIE in case __tcp_fastopen_cookie_gen_cipher() changes the
algorithm.
However, some tests use the bare hex value for specific IPv4 addresses
and do not support IPv6.
Let's define the same TFO_COOKIE in ksft_runner.sh.
We will replace such bare hex values with TFO_COOKIE except for a single
test for setsockopt(TCP_FASTOPEN_KEY).
While at it, misalignment in ksft_runner.sh is fixed up.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
tools/testing/selftests/net/packetdrill/defaults.sh | 1 +
tools/testing/selftests/net/packetdrill/ksft_runner.sh | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/net/packetdrill/defaults.sh b/tools/testing/selftests/net/packetdrill/defaults.sh
index 6b0ca8e738a2..b9d4c7d74577 100755
--- a/tools/testing/selftests/net/packetdrill/defaults.sh
+++ b/tools/testing/selftests/net/packetdrill/defaults.sh
@@ -51,6 +51,7 @@ sysctl -q net.ipv4.tcp_pacing_ss_ratio=200
sysctl -q net.ipv4.tcp_pacing_ca_ratio=120
sysctl -q net.ipv4.tcp_notsent_lowat=4294967295 > /dev/null 2>&1
+# Use TFO_COOKIE in ksft_runner.sh for this key.
sysctl -q net.ipv4.tcp_fastopen=0x2
sysctl -q net.ipv4.tcp_fastopen_key=a1a1a1a1-b2b2b2b2-c3c3c3c3-d4d4d4d4
diff --git a/tools/testing/selftests/net/packetdrill/ksft_runner.sh b/tools/testing/selftests/net/packetdrill/ksft_runner.sh
index 0ae6eeeb1a8e..04ba8fecbedb 100755
--- a/tools/testing/selftests/net/packetdrill/ksft_runner.sh
+++ b/tools/testing/selftests/net/packetdrill/ksft_runner.sh
@@ -9,6 +9,7 @@ declare -A ip_args=(
--gateway_ip=192.168.0.1
--netmask_ip=255.255.0.0
--remote_ip=192.0.2.1
+ -D TFO_COOKIE=3021b9d889017eeb
-D CMSG_LEVEL_IP=SOL_IP
-D CMSG_TYPE_RECVERR=IP_RECVERR"
[ipv6]="--ip_version=ipv6
@@ -16,6 +17,7 @@ declare -A ip_args=(
--local_ip=fd3d:0a0b:17d6::1
--gateway_ip=fd3d:0a0b:17d6:8888::1
--remote_ip=fd3d:fa7b:d17d::1
+ -D TFO_COOKIE=c1d1e9742a47a9bc
-D CMSG_LEVEL_IP=SOL_IPV6
-D CMSG_TYPE_RECVERR=IPV6_RECVERR"
)
@@ -52,7 +54,7 @@ ktap_set_plan 2
for ip_version in $ip_versions; do
unshare -n packetdrill ${ip_args[$ip_version]} ${optargs[@]} $script > /dev/null \
- && ktap_test_pass $ip_version || $failfunc $ip_version
+ && ktap_test_pass $ip_version || $failfunc $ip_version
done
ktap_finished
--
2.51.0.536.g15c5d4f767-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v1 net-next 03/12] selftest: packetdrill: Import TFO server basic tests.
2025-09-26 21:28 [PATCH v1 net-next 00/12] selftest: packetdrill: Import TFO server tests Kuniyuki Iwashima
2025-09-26 21:28 ` [PATCH v1 net-next 01/12] selftest: packetdrill: Require explicit setsockopt(TCP_FASTOPEN) Kuniyuki Iwashima
2025-09-26 21:28 ` [PATCH v1 net-next 02/12] selftest: packetdrill: Define common TCP Fast Open cookie Kuniyuki Iwashima
@ 2025-09-26 21:28 ` Kuniyuki Iwashima
2025-09-26 21:28 ` [PATCH v1 net-next 04/12] selftest: packetdrill: Add test for TFO_SERVER_WO_SOCKOPT1 Kuniyuki Iwashima
` (8 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Kuniyuki Iwashima @ 2025-09-26 21:28 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
This imports basic TFO server tests from google/packetdrill.
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.
This only imports the following tests of the non-experimental version
placed in [0]. I will add a specific test for the experimental option
handling later.
| TFO | Cookie | Payload |
---------------------------+-----+--------+---------+
basic-rw.pkt | yes | yes | yes |
basic-zero-payload.pkt | yes | yes | no |
basic-cookie-not-reqd.pkt | yes | no | yes |
basic-non-tfo-listener.pkt | no | yes | yes |
pure-syn-data.pkt | yes | no | yes |
The original pure-syn-data.pkt missed setsockopt(TCP_FASTOPEN) and did
not test TFO server in some scenarios unintentionally, so setsockopt()
is added where needed. In addition, non-TFO scenario is stripped as
it is covered by basic-non-tfo-listener.pkt. Also, I added basic- prefix.
Link: https://github.com/google/packetdrill/tree/bfc96251310f/gtests/net/tcp/fastopen/server/opt34 #[0]
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
..._fastopen_server_basic-cookie-not-reqd.pkt | 32 ++++++++++++
...fastopen_server_basic-non-tfo-listener.pkt | 26 ++++++++++
...cp_fastopen_server_basic-pure-syn-data.pkt | 50 +++++++++++++++++++
.../tcp_fastopen_server_basic-rw.pkt | 23 +++++++++
...tcp_fastopen_server_basic-zero-payload.pkt | 26 ++++++++++
5 files changed, 157 insertions(+)
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-cookie-not-reqd.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-non-tfo-listener.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-pure-syn-data.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-rw.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-zero-payload.pkt
diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-cookie-not-reqd.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-cookie-not-reqd.pkt
new file mode 100644
index 000000000000..32aff9bc4052
--- /dev/null
+++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-cookie-not-reqd.pkt
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Basic TFO server test
+//
+// Test TFO_SERVER_COOKIE_NOT_REQD flag on receiving
+// SYN with data but without Fast Open cookie option.
+
+`./defaults.sh
+ ./set_sysctls.py /proc/sys/net/ipv4/tcp_fastopen=0x202`
+
+ 0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+// Since TFO_SERVER_COOKIE_NOT_REQD, a TFO socket will be created with
+// the data accepted.
+ +0 < S 0:1000(1000) win 32792 <mss 1460,sackOK,nop,nop>
+ +0 > S. 0:0(0) ack 1001 <mss 1460,nop,nop,sackOK>
+ +0 accept(3, ..., ...) = 4
+ +0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
+ +0 read(4, ..., 1024) = 1000
+
+// Data After SYN will be accepted too.
+ +0 < . 1001:2001(1000) ack 1 win 5840
+ +0 > . 1:1(0) ack 2001
+
+// Should change the implementation later to set the SYN flag as well.
+ +0 read(4, ..., 1024) = 1000
+ +0 write(4, ..., 1000) = 1000
+ +0 > P. 1:1001(1000) ack 2001
diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-non-tfo-listener.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-non-tfo-listener.pkt
new file mode 100644
index 000000000000..4a00e0d994f2
--- /dev/null
+++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-non-tfo-listener.pkt
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Basic TFO server test
+//
+// Server w/o TCP_FASTOPEN socket option
+
+`./defaults.sh`
+
+ 0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+
+ +0 < S 0:10(10) win 32792 <mss 1460,sackOK,FO TFO_COOKIE>
+
+// Data is ignored since TCP_FASTOPEN is not set on the listener
+ +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK>
+
+ +0 accept(3, ..., ...) = -1 EAGAIN (Resource temporarily unavailable)
+
+// The above should block until ack comes in below.
+ +0 < . 1:31(30) ack 1 win 5840
+ +0 accept(3, ..., ...) = 4
+
+ +0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
+ +0 read(4, ..., 512) = 30
diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-pure-syn-data.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-pure-syn-data.pkt
new file mode 100644
index 000000000000..345ed26ff7f8
--- /dev/null
+++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-pure-syn-data.pkt
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Basic TFO server test
+//
+// Test that TFO-enabled server would not respond SYN-ACK with any TFO option
+// when receiving a pure SYN-data. It should respond a pure SYN-ack.
+
+`./defaults.sh`
+
+ 0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+ +0 < S 999000:999040(40) win 32792 <mss 1460,sackOK,TS val 100 ecr 100,nop,wscale 6>
+ +0 > S. 1234:1234(0) ack 999001 <mss 1460,sackOK,TS val 100 ecr 100,nop,wscale 8>
+ +0 < . 1:1(0) ack 1 win 100
+ +0 accept(3, ..., ...) = 4
+ +0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
+ +0 close(3) = 0
+
+// Test ECN-setup SYN with ECN disabled because this has happened in reality
+ +0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+ +0 < SEW 999000:999040(40) win 32792 <mss 1460,sackOK,TS val 100 ecr 100,nop,wscale 6>
+ +0 > S. 1234:1234(0) ack 999001 <mss 1460,sackOK,TS val 100 ecr 100,nop,wscale 8>
+ +0 < . 1:1(0) ack 1 win 100
+ +0 accept(3, ..., ...) = 4
+ +0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
+ +0 close(3) = 0
+
+// Test ECN-setup SYN w/ ECN enabled
+ +0 `sysctl -q net.ipv4.tcp_ecn=2`
+ +0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+ +0 < SEW 999000:999040(40) win 32792 <mss 1460,sackOK,TS val 100 ecr 100,nop,wscale 6>
+ +0 > SE. 1234:1234(0) ack 999001 <mss 1460,sackOK,TS val 100 ecr 100,nop,wscale 8>
+ +0 < . 1:1(0) ack 1 win 100
+ +0 accept(3, ..., ...) = 4
+ +0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
+ +0 close(3) = 0
diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-rw.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-rw.pkt
new file mode 100644
index 000000000000..98e6f84497cd
--- /dev/null
+++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-rw.pkt
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Basic TFO server test
+//
+// Test TFO server with SYN that has TFO cookie and data.
+
+`./defaults.sh`
+
+ 0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+ +0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
+ +0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
+
+ +0 accept(3, ..., ...) = 4
+ +0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
+
+ +0 read(4, ..., 512) = 10
+ +0 write(4, ..., 100) = 100
+ +0 > P. 1:101(100) ack 11
diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-zero-payload.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-zero-payload.pkt
new file mode 100644
index 000000000000..95b1047ffdd5
--- /dev/null
+++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-zero-payload.pkt
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Basic TFO server test
+//
+// Test zero-payload packet w/ valid TFO cookie - a TFO socket will
+// still be created and accepted but read() will not return until a
+// later pkt with 10 byte.
+
+`./defaults.sh`
+
+ 0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+ +0 < S 0:0(0) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
+ +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK>
+ +0 accept(3, ..., ...) = 4
+ +0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
+
+// A TFO socket is created and is writable.
+ +0 write(4, ..., 100) = 100
+ +0 > P. 1:101(100) ack 1
+ +0...0.300 read(4, ..., 512) = 10
+ +.3 < P. 1:11(10) ack 1 win 5840
--
2.51.0.536.g15c5d4f767-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v1 net-next 04/12] selftest: packetdrill: Add test for TFO_SERVER_WO_SOCKOPT1.
2025-09-26 21:28 [PATCH v1 net-next 00/12] selftest: packetdrill: Import TFO server tests Kuniyuki Iwashima
` (2 preceding siblings ...)
2025-09-26 21:28 ` [PATCH v1 net-next 03/12] selftest: packetdrill: Import TFO server basic tests Kuniyuki Iwashima
@ 2025-09-26 21:28 ` Kuniyuki Iwashima
2025-09-26 21:28 ` [PATCH v1 net-next 05/12] selftest: packetdrill: Add test for experimental option Kuniyuki Iwashima
` (7 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Kuniyuki Iwashima @ 2025-09-26 21:28 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
TFO_SERVER_WO_SOCKOPT1 is no longer enabled by default, and
each server test requires setsockopt(TCP_FASTOPEN).
Let's add a basic test for TFO_SERVER_WO_SOCKOPT1.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
...cp_fastopen_server_basic-no-setsockopt.pkt | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-no-setsockopt.pkt
diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-no-setsockopt.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-no-setsockopt.pkt
new file mode 100644
index 000000000000..649997a58099
--- /dev/null
+++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_basic-no-setsockopt.pkt
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Basic TFO server test
+//
+// Test TFO_SERVER_WO_SOCKOPT1 without setsockopt(TCP_FASTOPEN)
+
+`./defaults.sh
+ ./set_sysctls.py /proc/sys/net/ipv4/tcp_fastopen=0x402`
+
+ 0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+
+ +0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
+ +0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
+
+ +0 accept(3, ..., ...) = 4
+ +0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
+
+ +0 read(4, ..., 512) = 10
--
2.51.0.536.g15c5d4f767-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v1 net-next 05/12] selftest: packetdrill: Add test for experimental option.
2025-09-26 21:28 [PATCH v1 net-next 00/12] selftest: packetdrill: Import TFO server tests Kuniyuki Iwashima
` (3 preceding siblings ...)
2025-09-26 21:28 ` [PATCH v1 net-next 04/12] selftest: packetdrill: Add test for TFO_SERVER_WO_SOCKOPT1 Kuniyuki Iwashima
@ 2025-09-26 21:28 ` Kuniyuki Iwashima
2025-09-26 21:29 ` [PATCH v1 net-next 06/12] selftest: packetdrill: Import opt34/fin-close-socket.pkt Kuniyuki Iwashima
` (6 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Kuniyuki Iwashima @ 2025-09-26 21:28 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
The only difference between non-experimental vs experimental TFO
option handling is SYN+ACK generation.
When tcp_parse_fastopen_option() parses a TFO option, it sets
tcp_fastopen_cookie.exp to false if the option number is 34,
and true if 255.
The value is carried to tcp_options_write() to generate a TFO option
with the same option number.
Other than that, all the TFO handling is the same and the kernel must
generate the same cookie regardless of the option number.
Let's add a test for the handling so that we can consolidate
fastopen/server/ tests and fastopen/server/opt34 tests.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
...cp_fastopen_server_experimental_option.pkt | 37 +++++++++++++++++++
1 file changed, 37 insertions(+)
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_experimental_option.pkt
diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_experimental_option.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_experimental_option.pkt
new file mode 100644
index 000000000000..c3cb0e8bdcf8
--- /dev/null
+++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_experimental_option.pkt
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Test the Experimental Option
+//
+// SYN w/ FOEXP w/o cookie must generates SYN+ACK w/ FOEXP
+// w/ a valid cookie, and the cookie must be the same one
+// with one generated by IANA FO
+
+`./defaults.sh`
+
+// Request a TFO cookie by Experimental Option
+// This must generate the same TFO_COOKIE
+ 0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+ +0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FOEXP>
+ +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,FOEXP TFO_COOKIE>
+
+ +0 close(3) = 0
+
+// Test if FOEXP with a valid cookie creates a TFO socket
+ 0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+ +0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FOEXP TFO_COOKIE>
+ +0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
+
+ +0 accept(3, ..., ...) = 4
+ +0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
+
+ +0 read(4, ..., 512) = 10
--
2.51.0.536.g15c5d4f767-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v1 net-next 06/12] selftest: packetdrill: Import opt34/fin-close-socket.pkt.
2025-09-26 21:28 [PATCH v1 net-next 00/12] selftest: packetdrill: Import TFO server tests Kuniyuki Iwashima
` (4 preceding siblings ...)
2025-09-26 21:28 ` [PATCH v1 net-next 05/12] selftest: packetdrill: Add test for experimental option Kuniyuki Iwashima
@ 2025-09-26 21:29 ` Kuniyuki Iwashima
2025-09-26 21:29 ` [PATCH v1 net-next 07/12] selftest: packetdrill: Import opt34/icmp-before-accept.pkt Kuniyuki Iwashima
` (5 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Kuniyuki Iwashima @ 2025-09-26 21:29 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
This imports the non-experimental version of fin-close-socket.pkt.
This file tests the scenario where a TFO child socket's state
transitions from SYN_RECV to CLOSE_WAIT before accept()ed.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
.../tcp_fastopen_server_fin-close-socket.pkt | 30 +++++++++++++++++++
1 file changed, 30 insertions(+)
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_fin-close-socket.pkt
diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_fin-close-socket.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_fin-close-socket.pkt
new file mode 100644
index 000000000000..dc09f8d9a381
--- /dev/null
+++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_fin-close-socket.pkt
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Send a FIN pkt with the ACK bit to a TFO socket.
+// The socket will go to TCP_CLOSE_WAIT state and data can be
+// read until the socket is closed, at which time a FIN will be sent.
+
+`./defaults.sh`
+
+ 0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+ +0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
+ +0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
+
+// FIN is acked and the socket goes to TCP_CLOSE_WAIT state
+// in tcp_fin() called from tcp_data_queue().
+ +0 < F. 11:11(0) ack 1 win 32792
+ +0 > . 1:1(0) ack 12
+
+ +0 accept(3, ..., ...) = 4
+ +0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
+ +0 %{ assert tcpi_state == TCP_CLOSE_WAIT, tcpi_state }%
+
+ +0 read(4, ..., 512) = 10
+ +0 close(4) = 0
+ +0 > F. 1:1(0) ack 12
+ * > F. 1:1(0) ack 12
--
2.51.0.536.g15c5d4f767-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v1 net-next 07/12] selftest: packetdrill: Import opt34/icmp-before-accept.pkt.
2025-09-26 21:28 [PATCH v1 net-next 00/12] selftest: packetdrill: Import TFO server tests Kuniyuki Iwashima
` (5 preceding siblings ...)
2025-09-26 21:29 ` [PATCH v1 net-next 06/12] selftest: packetdrill: Import opt34/fin-close-socket.pkt Kuniyuki Iwashima
@ 2025-09-26 21:29 ` Kuniyuki Iwashima
2025-09-27 9:57 ` Kuniyuki Iwashima
2025-09-26 21:29 ` [PATCH v1 net-next 08/12] selftest: packetdrill: Import opt34/reset-* tests Kuniyuki Iwashima
` (4 subsequent siblings)
11 siblings, 1 reply; 14+ messages in thread
From: Kuniyuki Iwashima @ 2025-09-26 21:29 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
This imports the non-experimental version of icmp-before-accept.pkt.
This file tests the scenario where an ICMP unreachable packet for a
not-yet-accept()ed socket changes its state to TCP_CLOSE, but the
SYN data must be read without error, and the following read() returns
EHOSTUNREACH.
Note that this test support only IPv4 as icmp is used.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
...tcp_fastopen_server_icmp-before-accept.pkt | 49 +++++++++++++++++++
1 file changed, 49 insertions(+)
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_icmp-before-accept.pkt
diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_icmp-before-accept.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_icmp-before-accept.pkt
new file mode 100644
index 000000000000..d5543672e2bd
--- /dev/null
+++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_icmp-before-accept.pkt
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Send an ICMP host_unreachable pkt to a pending SYN_RECV req.
+//
+// If it's a TFO req, the ICMP error will cause it to switch
+// to TCP_CLOSE state but remains in the acceptor queue.
+
+--ip_version=ipv4
+
+`./defaults.sh`
+
+ 0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+ +0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
+ +0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
+
+// Out-of-window icmp is ignored but accounted.
+ +0 `nstat > /dev/null`
+ +0 < icmp unreachable [5000:6000(1000)]
+ +0 `nstat | grep TcpExtOutOfWindowIcmps > /dev/null`
+
+// Valid ICMP unreach.
+ +0 < icmp unreachable host_unreachable [0:10(10)]
+
+// Unlike the non-TFO case, the req is still there to be accepted.
+ +0 accept(3, ..., ...) = 4
+ +0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
+
+// tcp_done_with_error() in tcp_v4_err() sets sk->sk_state
+// to TCP_CLOSE
+ +0 %{ assert tcpi_state == TCP_CLOSE, tcpi_state }%
+
+// The 1st read will succeed and return the data in SYN
+ +0 read(4, ..., 512) = 10
+
+// The 2nd read will fail.
+ +0 read(4, ..., 512) = -1 EHOSTUNREACH (No route to host)
+
+// But is no longer writable because it's in TCP_CLOSE state.
+ +0 write(4, ..., 100) = -1 EPIPE (Broken Pipe)
+
+// inbound pkt will trigger RST because the socket has been moved
+// off the TCP hash tables.
+ +0 < . 1:1(0) ack 1 win 32792
+ +0 > R 1:1(0)
--
2.51.0.536.g15c5d4f767-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v1 net-next 08/12] selftest: packetdrill: Import opt34/reset-* tests.
2025-09-26 21:28 [PATCH v1 net-next 00/12] selftest: packetdrill: Import TFO server tests Kuniyuki Iwashima
` (6 preceding siblings ...)
2025-09-26 21:29 ` [PATCH v1 net-next 07/12] selftest: packetdrill: Import opt34/icmp-before-accept.pkt Kuniyuki Iwashima
@ 2025-09-26 21:29 ` Kuniyuki Iwashima
2025-09-26 21:29 ` [PATCH v1 net-next 09/12] selftest: packetdrill: Import opt34/*-trigger-rst.pkt Kuniyuki Iwashima
` (3 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Kuniyuki Iwashima @ 2025-09-26 21:29 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
This imports the non-experimental version of opt34/reset-*.pkt.
| Child | RST | sk_err |
---------------------------------+---------+-------------------------------+---------+
reset-after-accept.pkt | TFO | after accept(), SYN_RECV | read() |
reset-close-with-unread-data.pkt | TFO | after accept(), SYN_RECV | write() |
reset-before-accept.pkt | TFO | before accept(), SYN_RECV | read() |
reset-non-tfo-socket.pkt | non-TFO | before accept(), ESTABLISHED | write() |
The first 3 files test scenarios where a SYN_RECV socket receives RST
before/after accept() and data in SYN must be read() without error,
but the following read() or fist write() will return ECONNRESET.
The last test is similar but with non-TFO socket.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
...tcp_fastopen_server_reset-after-accept.pkt | 37 +++++++++++++++++++
...cp_fastopen_server_reset-before-accept.pkt | 32 ++++++++++++++++
...en_server_reset-close-with-unread-data.pkt | 32 ++++++++++++++++
...p_fastopen_server_reset-non-tfo-socket.pkt | 37 +++++++++++++++++++
4 files changed, 138 insertions(+)
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-after-accept.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-before-accept.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-close-with-unread-data.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-non-tfo-socket.pkt
diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-after-accept.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-after-accept.pkt
new file mode 100644
index 000000000000..040d5547ed80
--- /dev/null
+++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-after-accept.pkt
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Send a RST to a TFO socket after it has been accepted.
+//
+// First read() will return all the data and this is consistent
+// with the non-TFO case. Second read will return -1
+
+`./defaults.sh`
+
+ 0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+ +0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
+ +0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
+
+ +0 accept(3, ..., ...) = 4
+ +0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
+ +0 %{ assert tcpi_state == TCP_SYN_RECV, tcpi_state }%
+
+// 1st read will return the data from SYN.
+// tcp_reset() sets sk->sk_err to ECONNRESET for SYN_RECV.
+ +0 < R. 11:11(0) win 32792
+ +0 %{ assert tcpi_state == TCP_CLOSE, tcpi_state }%
+
+// This one w/o ACK bit will cause the same effect.
+// +0 < R 11:11(0) win 32792
+// See Step 2 in tcp_validate_incoming().
+
+// found_ok_skb in tcp_recvmsg_locked()
+ +0 read(4, ..., 512) = 10
+
+// !copied && sk->sk_err -> sock_error(sk)
+ +0 read(4, ..., 512) = -1 ECONNRESET (Connection reset by peer)
+ +0 close(4) = 0
diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-before-accept.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-before-accept.pkt
new file mode 100644
index 000000000000..7f9de6c66cbd
--- /dev/null
+++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-before-accept.pkt
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Send a RST to a TFO socket before it is accepted.
+//
+// The socket won't go away and after it's accepted the data
+// in the SYN pkt can still be read. But that's about all that
+// the acceptor can do with the socket.
+
+`./defaults.sh`
+
+ 0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+ +0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,nop,wscale 7,FO TFO_COOKIE,nop,nop>
+ +0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK,nop,wscale 8>
+
+// 1st read will return the data from SYN.
+ +0 < R. 11:11(0) win 257
+
+// This one w/o ACK bit will cause the same effect.
+// +0 < R 11:11(0) win 257
+
+ +0 accept(3, ..., ...) = 4
+ +0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
+ +0 %{ assert tcpi_state == TCP_CLOSE, tcpi_state }%
+
+ +0 read(4, ..., 512) = 10
+ +0 read(4, ..., 512) = -1 ECONNRESET (Connection reset by peer)
+ +0 close(4) = 0
diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-close-with-unread-data.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-close-with-unread-data.pkt
new file mode 100644
index 000000000000..548a87701b5d
--- /dev/null
+++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-close-with-unread-data.pkt
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Send a RST to a TFO socket after it is accepted.
+//
+// The socket will change to TCP_CLOSE state with pending data so
+// write() will fail. Pending data can be still be read and close()
+// won't trigger RST if data is not read
+//
+// 565b7b2d2e63 ("tcp: do not send reset to already closed sockets")
+// https://lore.kernel.org/netdev/4C1A2502.1030502@openvz.org/
+
+`./defaults.sh`
+
+ 0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+ +0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop, FO TFO_COOKIE,nop,nop>
+ +0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
+
+ +0 accept(3, ..., ...) = 4
+ +0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
+ +0 %{ assert tcpi_state == TCP_SYN_RECV, tcpi_state }%
+
+// tcp_done() sets sk->sk_state to TCP_CLOSE and clears tp->fastopen_rsk
+ +0 < R. 11:11(0) win 32792
+ +0 %{ assert tcpi_state == TCP_CLOSE, tcpi_state }%
+
+ +0 write(4, ..., 100) = -1 ECONNRESET(Connection reset by peer)
+ +0 close(4) = 0
diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-non-tfo-socket.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-non-tfo-socket.pkt
new file mode 100644
index 000000000000..20090bf77655
--- /dev/null
+++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-non-tfo-socket.pkt
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Send a RST to a fully established socket with pending data before
+// it is accepted.
+//
+// The socket with pending data won't go away and can still be accepted
+// with data read. But it will be in TCP_CLOSE state.
+
+`./defaults.sh`
+
+ 0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+// Invalid cookie, so accept() fails.
+ +0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FO aaaaaaaaaaaaaaaa,nop,nop>
+ +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK, FO TFO_COOKIE,nop,nop>
+
+ +0 accept(3, ..., ...) = -1 EAGAIN (Resource temporarily unavailable)
+
+// Complete 3WHS and send data and RST
+ +0 < . 1:1(0) ack 1 win 32792
+ +0 < . 1:11(10) ack 1 win 32792
+ +0 < R. 11:11(0) win 32792
+
+// A valid reset won't make the fully-established socket go away.
+// It's just that the acceptor will get a dead, unusable socket
+// in TCP_CLOSE state.
+ +0 accept(3, ..., ...) = 4
+ +0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
+ +0 %{ assert tcpi_state == TCP_CLOSE, tcpi_state }%
+
+ +0 write(4, ..., 100) = -1 ECONNRESET(Connection reset by peer)
+ +0 read(4, ..., 512) = 10
+ +0 read(4, ..., 512) = 0
--
2.51.0.536.g15c5d4f767-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v1 net-next 09/12] selftest: packetdrill: Import opt34/*-trigger-rst.pkt.
2025-09-26 21:28 [PATCH v1 net-next 00/12] selftest: packetdrill: Import TFO server tests Kuniyuki Iwashima
` (7 preceding siblings ...)
2025-09-26 21:29 ` [PATCH v1 net-next 08/12] selftest: packetdrill: Import opt34/reset-* tests Kuniyuki Iwashima
@ 2025-09-26 21:29 ` Kuniyuki Iwashima
2025-09-26 21:29 ` [PATCH v1 net-next 10/12] selftest: packetdrill: Refine tcp_fastopen_server_reset-after-disconnect.pkt Kuniyuki Iwashima
` (2 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Kuniyuki Iwashima @ 2025-09-26 21:29 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
This imports the non-experimental version of opt34/*-trigger-rst.pkt.
| accept() | SYN data |
-----------------------------------+----------+----------+
listener-closed-trigger-rst.pkt | no | unread |
unread-data-closed-trigger-rst.pkt | yes | unread |
Both files test that close()ing a SYN_RECV socket with unread SYN data
triggers RST.
The files are renamed to have the common prefix, trigger-rst.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
...pen_server_trigger-rst-listener-closed.pkt | 21 +++++++++++++++++
..._server_trigger-rst-unread-data-closed.pkt | 23 +++++++++++++++++++
2 files changed, 44 insertions(+)
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_trigger-rst-listener-closed.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_trigger-rst-unread-data-closed.pkt
diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_trigger-rst-listener-closed.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_trigger-rst-listener-closed.pkt
new file mode 100644
index 000000000000..e82e06da44c9
--- /dev/null
+++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_trigger-rst-listener-closed.pkt
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Close a listener socket with pending TFO child.
+// This will trigger RST pkt to go out.
+
+`./defaults.sh`
+
+ 0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+ +0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
+ +0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
+
+// RST pkt is generated for each not-yet-accepted TFO child.
+// inet_csk_listen_stop() -> inet_child_forget() -> tcp_disconnect()
+// -> tcp_need_reset() is true for SYN_RECV
+ +0 close(3) = 0
+ +0 > R. 1:1(0) ack 11
diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_trigger-rst-unread-data-closed.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_trigger-rst-unread-data-closed.pkt
new file mode 100644
index 000000000000..09fb63f78a0e
--- /dev/null
+++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_trigger-rst-unread-data-closed.pkt
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Close a TFO socket with unread data.
+// This will trigger a RST pkt.
+
+`./defaults.sh`
+
+ 0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+ +0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
+ +0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
+
+ +0 accept(3, ..., ...) = 4
+ +0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
+ +0 %{ assert tcpi_state == TCP_SYN_RECV, tcpi_state }%
+
+// data_was_unread == true in __tcp_close()
+ +0 close(4) = 0
+ +0 > R. 1:1(0) ack 11
--
2.51.0.536.g15c5d4f767-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v1 net-next 10/12] selftest: packetdrill: Refine tcp_fastopen_server_reset-after-disconnect.pkt.
2025-09-26 21:28 [PATCH v1 net-next 00/12] selftest: packetdrill: Import TFO server tests Kuniyuki Iwashima
` (8 preceding siblings ...)
2025-09-26 21:29 ` [PATCH v1 net-next 09/12] selftest: packetdrill: Import opt34/*-trigger-rst.pkt Kuniyuki Iwashima
@ 2025-09-26 21:29 ` Kuniyuki Iwashima
2025-09-26 21:29 ` [PATCH v1 net-next 11/12] selftest: packetdrill: Import sockopt-fastopen-key.pkt Kuniyuki Iwashima
2025-09-26 21:29 ` [PATCH v1 net-next 12/12] selftest: packetdrill: Import client-ack-dropped-then-recovery-ms-timestamps.pkt Kuniyuki Iwashima
11 siblings, 0 replies; 14+ messages in thread
From: Kuniyuki Iwashima @ 2025-09-26 21:29 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
These changes are applied to follow the imported packetdrill tests.
* Call setsockopt(TCP_FASTOPEN)
* Remove unnecessary accept() delay
* Add assertion for TCP states
* Rename to tcp_fastopen_server_trigger-rst-reconnect.pkt.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
...t => tcp_fastopen_server_trigger-rst-reconnect.pkt} | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
rename tools/testing/selftests/net/packetdrill/{tcp_fastopen_server_reset-after-disconnect.pkt => tcp_fastopen_server_trigger-rst-reconnect.pkt} (66%)
diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-after-disconnect.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_trigger-rst-reconnect.pkt
similarity index 66%
rename from tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-after-disconnect.pkt
rename to tools/testing/selftests/net/packetdrill/tcp_fastopen_server_trigger-rst-reconnect.pkt
index 26794e7ddfd5..2a148bb14cbf 100644
--- a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_reset-after-disconnect.pkt
+++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_trigger-rst-reconnect.pkt
@@ -1,26 +1,30 @@
// SPDX-License-Identifier: GPL-2.0
`./defaults.sh
- ./set_sysctls.py /proc/sys/net/ipv4/tcp_fastopen=0x602 /proc/sys/net/ipv4/tcp_timestamps=0`
+ ./set_sysctls.py /proc/sys/net/ipv4/tcp_timestamps=0`
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
- +0 < S 0:10(10) win 32792 <mss 1460,nop,nop,sackOK>
+ +0 < S 0:10(10) win 32792 <mss 1460,nop,nop,sackOK,nop,nop,FO TFO_COOKIE>
+0 > S. 0:0(0) ack 11 win 65535 <mss 1460,nop,nop,sackOK>
// sk->sk_state is TCP_SYN_RECV
- +.1 accept(3, ..., ...) = 4
+ +0 accept(3, ..., ...) = 4
+ +0 %{ assert tcpi_state == TCP_SYN_RECV, tcpi_state }%
// tcp_disconnect() sets sk->sk_state to TCP_CLOSE
+0 connect(4, AF_UNSPEC, ...) = 0
+0 > R. 1:1(0) ack 11 win 65535
+ +0 %{ assert tcpi_state == TCP_CLOSE, tcpi_state }%
// connect() sets sk->sk_state to TCP_SYN_SENT
+0 fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0
+0 connect(4, ..., ...) = -1 EINPROGRESS (Operation is now in progress)
+0 > S 0:0(0) win 65535 <mss 1460,nop,nop,sackOK,nop,wscale 8>
+ +0 %{ assert tcpi_state == TCP_SYN_SENT, tcpi_state }%
// tp->fastopen_rsk must be NULL
+1 > S 0:0(0) win 65535 <mss 1460,nop,nop,sackOK,nop,wscale 8>
--
2.51.0.536.g15c5d4f767-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v1 net-next 11/12] selftest: packetdrill: Import sockopt-fastopen-key.pkt
2025-09-26 21:28 [PATCH v1 net-next 00/12] selftest: packetdrill: Import TFO server tests Kuniyuki Iwashima
` (9 preceding siblings ...)
2025-09-26 21:29 ` [PATCH v1 net-next 10/12] selftest: packetdrill: Refine tcp_fastopen_server_reset-after-disconnect.pkt Kuniyuki Iwashima
@ 2025-09-26 21:29 ` Kuniyuki Iwashima
2025-09-26 21:29 ` [PATCH v1 net-next 12/12] selftest: packetdrill: Import client-ack-dropped-then-recovery-ms-timestamps.pkt Kuniyuki Iwashima
11 siblings, 0 replies; 14+ messages in thread
From: Kuniyuki Iwashima @ 2025-09-26 21:29 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
sockopt-fastopen-key.pkt does not have the non-experimental
version, so the Experimental version is converted, FOEXP -> FO.
The test sets net.ipv4.tcp_fastopen_key=0-0-0-0 and instead
sets another key via setsockopt(TCP_FASTOPEN_KEY).
The first listener generates a valid cookie in response to TFO
option without cookie, and the second listner creates a TFO socket
using the valid cookie.
TCP_FASTOPEN_KEY is adjusted to use the common key in default.sh
so that we can use TFO_COOKIE and support dualstack. Similarly,
TFO_COOKIE_ZERO for the 0-0-0-0 key is defined.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
.../selftests/net/packetdrill/ksft_runner.sh | 2 +
...p_fastopen_server_sockopt-fastopen-key.pkt | 74 +++++++++++++++++++
2 files changed, 76 insertions(+)
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_sockopt-fastopen-key.pkt
diff --git a/tools/testing/selftests/net/packetdrill/ksft_runner.sh b/tools/testing/selftests/net/packetdrill/ksft_runner.sh
index 04ba8fecbedb..32115791985b 100755
--- a/tools/testing/selftests/net/packetdrill/ksft_runner.sh
+++ b/tools/testing/selftests/net/packetdrill/ksft_runner.sh
@@ -10,6 +10,7 @@ declare -A ip_args=(
--netmask_ip=255.255.0.0
--remote_ip=192.0.2.1
-D TFO_COOKIE=3021b9d889017eeb
+ -D TFO_COOKIE_ZERO=b7c12350a90dc8f5
-D CMSG_LEVEL_IP=SOL_IP
-D CMSG_TYPE_RECVERR=IP_RECVERR"
[ipv6]="--ip_version=ipv6
@@ -18,6 +19,7 @@ declare -A ip_args=(
--gateway_ip=fd3d:0a0b:17d6:8888::1
--remote_ip=fd3d:fa7b:d17d::1
-D TFO_COOKIE=c1d1e9742a47a9bc
+ -D TFO_COOKIE_ZERO=82af1a8f9a205c34
-D CMSG_LEVEL_IP=SOL_IPV6
-D CMSG_TYPE_RECVERR=IPV6_RECVERR"
)
diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_sockopt-fastopen-key.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_sockopt-fastopen-key.pkt
new file mode 100644
index 000000000000..9f52d7de3436
--- /dev/null
+++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_sockopt-fastopen-key.pkt
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Test the server cookie is generated by aes64 encoding of remote and local
+// IP addresses with a master key specified via sockopt TCP_FASTOPEN_KEY
+//
+`./defaults.sh
+ ./set_sysctls.py /proc/sys/net/ipv4/tcp_fastopen_key=00000000-00000000-00000000-00000000`
+
+ 0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+
+// Set a key of a1a1a1a1-b2b2b2b2-c3c3c3c3-d4d4d4d4 (big endian).
+// This would produce a cookie of TFO_COOKIE like many other
+// tests (which the same key but set via sysctl).
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN_KEY,
+ "\xa1\xa1\xa1\xa1\xb2\xb2\xb2\xb2\xc3\xc3\xc3\xc3\xd4\xd4\xd4\xd4", 16) = 0
+
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+// Request a valid cookie TFO_COOKIE
+ +0 < S 1428932:1428942(10) win 10000 <mss 1012,nop,nop,FO,sackOK,TS val 1 ecr 0,nop,wscale 7>
+ +0 > S. 0:0(0) ack 1428933 <mss 1460,sackOK,TS val 10000 ecr 1,nop,wscale 8,FO TFO_COOKIE,nop,nop>
+ +0 < . 1:1(0) ack 1 win 257 <nop,nop,TS val 2 ecr 10000>
+ +0 accept(3, ..., ...) = 4
+ +0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
+
+ +0 close(4) = 0
+ +0 > F. 1:1(0) ack 1 <nop,nop,TS val 10001 ecr 2>
+ +0 < F. 1:1(0) ack 2 win 257 <nop,nop,TS val 3 ecr 10001>
+ +0 > . 2:2(0) ack 2 <nop,nop,TS val 10002 ecr 3>
+
+ +0 close(3) = 0
+
+// Restart the listener
+ +0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+// Test setting the key in the listen state, and produces an identical cookie
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN_KEY,
+ "\xa1\xa1\xa1\xa1\xb2\xb2\xb2\xb2\xc3\xc3\xc3\xc3\xd4\xd4\xd4\xd4", 16) = 0
+
+ +0 < S 6814000:6815000(1000) win 10000 <mss 1012,nop,nop,FO TFO_COOKIE,sackOK,TS val 10 ecr 0,nop,wscale 7>
+ +0 > S. 0:0(0) ack 6815001 <mss 1460,sackOK,TS val 10000 ecr 10,nop,wscale 8>
+ +0 accept(3, ..., ...) = 4
+ +0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
+ +0 < . 1001:1001(0) ack 1 win 257 <nop,nop,TS val 12 ecr 10000>
+ +0 read(4, ..., 8192) = 1000
+
+ +0 close(4) = 0
+ +0 > F. 1:1(0) ack 1001 <nop,nop,TS val 10101 ecr 12>
+ +0 < F. 1001:1001(0) ack 2 win 257 <nop,nop,TS val 112 ecr 10101>
+ +0 > . 2:2(0) ack 1002 <nop,nop,TS val 10102 ecr 112>
+
+ +0 close(3) = 0
+
+// Restart the listener
+ +0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+
+// Test invalid key length (must be 16 bytes)
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN_KEY, "", 0) = -1 (Invalid Argument)
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN_KEY, "", 3) = -1 (Invalid Argument)
+
+// Previous cookie won't be accepted b/c this listener uses the global key (0-0-0-0)
+ +0 < S 6814000:6815000(1000) win 10000 <mss 1012,nop,nop,FO TFO_COOKIE,sackOK,TS val 10 ecr 0,nop,wscale 7>
+ +0 > S. 0:0(0) ack 6814001 <mss 1460,sackOK,TS val 10000 ecr 10,nop,wscale 8,FO TFO_COOKIE_ZERO,nop,nop>
--
2.51.0.536.g15c5d4f767-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v1 net-next 12/12] selftest: packetdrill: Import client-ack-dropped-then-recovery-ms-timestamps.pkt
2025-09-26 21:28 [PATCH v1 net-next 00/12] selftest: packetdrill: Import TFO server tests Kuniyuki Iwashima
` (10 preceding siblings ...)
2025-09-26 21:29 ` [PATCH v1 net-next 11/12] selftest: packetdrill: Import sockopt-fastopen-key.pkt Kuniyuki Iwashima
@ 2025-09-26 21:29 ` Kuniyuki Iwashima
11 siblings, 0 replies; 14+ messages in thread
From: Kuniyuki Iwashima @ 2025-09-26 21:29 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
This also does not have the non-experimental version, so converted to FO.
The comment in .pkt explains the detailed scenario.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
...ck-dropped-then-recovery-ms-timestamps.pkt | 46 +++++++++++++++++++
1 file changed, 46 insertions(+)
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_client-ack-dropped-then-recovery-ms-timestamps.pkt
diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_client-ack-dropped-then-recovery-ms-timestamps.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_client-ack-dropped-then-recovery-ms-timestamps.pkt
new file mode 100644
index 000000000000..f75efd51ed0c
--- /dev/null
+++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_client-ack-dropped-then-recovery-ms-timestamps.pkt
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// A reproducer case for a TFO SYNACK RTO undo bug in:
+// 794200d66273 ("tcp: undo cwnd on Fast Open spurious SYNACK retransmit")
+// This sequence that tickles this bug is:
+// - Fast Open server receives TFO SYN with data, sends SYNACK
+// - (client receives SYNACK and sends ACK, but ACK is lost)
+// - server app sends some data packets
+// - (N of the first data packets are lost)
+// - server receives client ACK that has a TS ECR matching first SYNACK,
+// and also SACKs suggesting the first N data packets were lost
+// - server performs undo of SYNACK RTO, then immediately enters recovery
+// - buggy behavior in 794200d66273 then performed an undo that caused
+// the connection to be in a bad state, in CA_Open with retrans_out != 0
+
+// Check that outbound TS Val ticks are as we would expect with 1000 usec per
+// timestamp tick:
+--tcp_ts_tick_usecs=1000
+
+`./defaults.sh`
+
+// Initialize connection
+ 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+ +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+ +0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
+ +0 bind(3, ..., ...) = 0
+ +0 listen(3, 1) = 0
+
+ +0 < S 0:1000(1000) win 65535 <mss 1012,sackOK,TS val 1000 ecr 0,wscale 7,nop,nop,nop,FO TFO_COOKIE>
+ +0 > S. 0:0(0) ack 1001 <mss 1460,sackOK,TS val 2000 ecr 1000,nop,wscale 8>
+ +0 accept(3, ..., ...) = 4
+
+// Application writes more data
+ +.010 write(4, ..., 10000) = 10000
+ +0 > P. 1:5001(5000) ack 1001 <nop,nop,TS val 2010 ecr 1000>
+ +0 > P. 5001:10001(5000) ack 1001 <nop,nop,TS val 2010 ecr 1000>
+ +0 %{ assert tcpi_snd_cwnd == 10, tcpi_snd_cwnd }%
+
+ +0 < . 1001:1001(0) ack 1 win 257 <TS val 1010 ecr 2000,sack 2001:5001>
+ +0 > P. 1:2001(2000) ack 1001 <nop,nop,TS val 2010 ecr 1010>
+ +0 %{ assert tcpi_ca_state == TCP_CA_Recovery, tcpi_ca_state }%
+ +0 %{ assert tcpi_snd_cwnd == 7, tcpi_snd_cwnd }%
+
+ +0 < . 1001:1001(0) ack 1 win 257 <TS val 1011 ecr 2000,sack 2001:6001>
+ +0 %{ assert tcpi_ca_state == TCP_CA_Recovery, tcpi_ca_state }%
+ +0 %{ assert tcpi_snd_cwnd == 7, tcpi_snd_cwnd }%
--
2.51.0.536.g15c5d4f767-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v1 net-next 07/12] selftest: packetdrill: Import opt34/icmp-before-accept.pkt.
2025-09-26 21:29 ` [PATCH v1 net-next 07/12] selftest: packetdrill: Import opt34/icmp-before-accept.pkt Kuniyuki Iwashima
@ 2025-09-27 9:57 ` Kuniyuki Iwashima
0 siblings, 0 replies; 14+ messages in thread
From: Kuniyuki Iwashima @ 2025-09-27 9:57 UTC (permalink / raw)
To: kuniyu; +Cc: davem, edumazet, horms, kuba, kuni1840, netdev, pabeni
From: Kuniyuki Iwashima <kuniyu@google.com>
Date: Fri, 26 Sep 2025 21:29:01 +0000
> This imports the non-experimental version of icmp-before-accept.pkt.
>
> This file tests the scenario where an ICMP unreachable packet for a
> not-yet-accept()ed socket changes its state to TCP_CLOSE, but the
> SYN data must be read without error, and the following read() returns
> EHOSTUNREACH.
>
> Note that this test support only IPv4 as icmp is used.
>
> Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
> ---
> ...tcp_fastopen_server_icmp-before-accept.pkt | 49 +++++++++++++++++++
> 1 file changed, 49 insertions(+)
> create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_server_icmp-before-accept.pkt
>
> diff --git a/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_icmp-before-accept.pkt b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_icmp-before-accept.pkt
> new file mode 100644
> index 000000000000..d5543672e2bd
> --- /dev/null
> +++ b/tools/testing/selftests/net/packetdrill/tcp_fastopen_server_icmp-before-accept.pkt
> @@ -0,0 +1,49 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// Send an ICMP host_unreachable pkt to a pending SYN_RECV req.
> +//
> +// If it's a TFO req, the ICMP error will cause it to switch
> +// to TCP_CLOSE state but remains in the acceptor queue.
> +
> +--ip_version=ipv4
Sorry, I noticed selftest failed in patchwork while this test
itself succeeds.
I forgot to update ktap_set_plan in ksft_runner.sh in a5c10aa3d1ba.
I'll post v2 with this patch after 24h timer.
commit f4f03e74501ef4283d27716be37b5effa2b7e4db
Author: Kuniyuki Iwashima <kuniyu@google.com>
Date: Sat Sep 27 09:41:42 2025
selftest: packetdrill: Set ktap_set_plan properly for single protocol test.
The cited commit forgot to update the ktap_set_plan call.
ktap_set_plan sets the number of tests (KSFT_NUM_TESTS), which must
match the number of executed tests (KTAP_CNT_PASS + KTAP_CNT_SKIP +
KTAP_CNT_XFAIL) in ktap_finished.
Otherwise, the selftest exit()s with 1.
Let's adjust KSFT_NUM_TESTS based on supported protocols.
While at it, misalignment is fixed up.
Fixes: a5c10aa3d1ba ("selftests/net: packetdrill: Support single protocol test.")
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
diff --git a/tools/testing/selftests/net/packetdrill/ksft_runner.sh b/tools/testing/selftests/net/packetdrill/ksft_runner.sh
index 0ae6eeeb1a8e..3fa7c7f66caf 100755
--- a/tools/testing/selftests/net/packetdrill/ksft_runner.sh
+++ b/tools/testing/selftests/net/packetdrill/ksft_runner.sh
@@ -48,11 +48,11 @@ elif [[ ! "$ip_versions" =~ ^ipv[46]$ ]]; then
fi
ktap_print_header
-ktap_set_plan 2
+ktap_set_plan $(echo $ip_versions | wc -w)
for ip_version in $ip_versions; do
unshare -n packetdrill ${ip_args[$ip_version]} ${optargs[@]} $script > /dev/null \
- && ktap_test_pass $ip_version || $failfunc $ip_version
+ && ktap_test_pass $ip_version || $failfunc $ip_version
done
ktap_finished
--
pw-bot: cr
^ permalink raw reply related [flat|nested] 14+ messages in thread
end of thread, other threads:[~2025-09-27 9:58 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-26 21:28 [PATCH v1 net-next 00/12] selftest: packetdrill: Import TFO server tests Kuniyuki Iwashima
2025-09-26 21:28 ` [PATCH v1 net-next 01/12] selftest: packetdrill: Require explicit setsockopt(TCP_FASTOPEN) Kuniyuki Iwashima
2025-09-26 21:28 ` [PATCH v1 net-next 02/12] selftest: packetdrill: Define common TCP Fast Open cookie Kuniyuki Iwashima
2025-09-26 21:28 ` [PATCH v1 net-next 03/12] selftest: packetdrill: Import TFO server basic tests Kuniyuki Iwashima
2025-09-26 21:28 ` [PATCH v1 net-next 04/12] selftest: packetdrill: Add test for TFO_SERVER_WO_SOCKOPT1 Kuniyuki Iwashima
2025-09-26 21:28 ` [PATCH v1 net-next 05/12] selftest: packetdrill: Add test for experimental option Kuniyuki Iwashima
2025-09-26 21:29 ` [PATCH v1 net-next 06/12] selftest: packetdrill: Import opt34/fin-close-socket.pkt Kuniyuki Iwashima
2025-09-26 21:29 ` [PATCH v1 net-next 07/12] selftest: packetdrill: Import opt34/icmp-before-accept.pkt Kuniyuki Iwashima
2025-09-27 9:57 ` Kuniyuki Iwashima
2025-09-26 21:29 ` [PATCH v1 net-next 08/12] selftest: packetdrill: Import opt34/reset-* tests Kuniyuki Iwashima
2025-09-26 21:29 ` [PATCH v1 net-next 09/12] selftest: packetdrill: Import opt34/*-trigger-rst.pkt Kuniyuki Iwashima
2025-09-26 21:29 ` [PATCH v1 net-next 10/12] selftest: packetdrill: Refine tcp_fastopen_server_reset-after-disconnect.pkt Kuniyuki Iwashima
2025-09-26 21:29 ` [PATCH v1 net-next 11/12] selftest: packetdrill: Import sockopt-fastopen-key.pkt Kuniyuki Iwashima
2025-09-26 21:29 ` [PATCH v1 net-next 12/12] selftest: packetdrill: Import client-ack-dropped-then-recovery-ms-timestamps.pkt Kuniyuki Iwashima
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).