Skip to content

Commit 5d4cade

Browse files
sohamch-gitkuba-moo
authored andcommitted
selftests/net: packetdrill: import tcp/user_timeout, tcp/validate, tcp/sendfile, tcp/limited-transmit, tcp/syscall_bad_arg
Use the standard import and testing method, as described in the import of tcp/ecn and tcp/close , tcp/sack , tcp/tcp_info. Signed-off-by: Willem de Bruijn <willemb@google.com> Signed-off-by: Soham Chakradeo <sohamch@google.com> Link: https://patch.msgid.link/20241217185203.297935-5-sohamch.kernel@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 6f66920 commit 5d4cade

9 files changed

+319
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
// Test RFC 3042 "Limited Transmit": "sending a new data segment in
3+
// response to each of the first two duplicate acknowledgments that
4+
// arrive at the sender".
5+
// This variation tests a receiver that doesn't support SACK.
6+
7+
`./defaults.sh`
8+
9+
// Establish a connection.
10+
0 socket(..., SOCK_STREAM, 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+
+.1 < S 0:0(0) win 32792 <mss 1000,nop,wscale 7>
16+
+0 > S. 0:0(0) ack 1 <mss 1460,nop,wscale 8>
17+
+.1 < . 1:1(0) ack 1 win 320
18+
+0 accept(3, ..., ...) = 4
19+
20+
// Write some data, and send the initial congestion window.
21+
+0 write(4, ..., 15000) = 15000
22+
+0 > P. 1:10001(10000) ack 1
23+
24+
// Limited transmit: on first dupack, send a new data segment.
25+
+.11 < . 1:1(0) ack 1 win 320
26+
+0 > . 10001:11001(1000) ack 1
27+
28+
// Limited transmit: on second dupack, send a new data segment.
29+
+.01 < . 1:1(0) ack 1 win 320
30+
+0 > . 11001:12001(1000) ack 1
31+
32+
// It turned out to be reordering, not loss.
33+
// We have one packet newly acked (1001:3001 were DUP-ACK'd)
34+
// So we revert state back to Open. Slow start cwnd from 10 to 11
35+
// and send 11 - 9 = 2 packets
36+
+.01 < . 1:1(0) ack 3001 win 320
37+
+0 > P. 12001:14001(2000) ack 1
38+
39+
+.02 < . 1:1(0) ack 5001 win 320
40+
+0 > P. 14001:15001(1000) ack 1
41+
42+
// Client gradually ACKs all data.
43+
+.02 < . 1:1(0) ack 7001 win 320
44+
+.02 < . 1:1(0) ack 9001 win 320
45+
+.02 < . 1:1(0) ack 11001 win 320
46+
+.02 < . 1:1(0) ack 13001 win 320
47+
+.02 < . 1:1(0) ack 15001 win 320
48+
49+
// Clean up.
50+
+.17 close(4) = 0
51+
+0 > F. 15001:15001(0) ack 1
52+
+.1 < F. 1:1(0) ack 15002 win 257
53+
+0 > . 15002:15002(0) ack 2
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+
// Test RFC 3042 "Limited Transmit": "sending a new data segment in
3+
// response to each of the first two duplicate acknowledgments that
4+
// arrive at the sender".
5+
// This variation tests a receiver that supports SACK.
6+
7+
`./defaults.sh`
8+
9+
// Establish a connection.
10+
0 socket(..., SOCK_STREAM, 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+
+.1 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7>
16+
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8>
17+
+.1 < . 1:1(0) ack 1 win 320
18+
+0 accept(3, ..., ...) = 4
19+
20+
// Write some data, and send the initial congestion window.
21+
+0 write(4, ..., 15000) = 15000
22+
+0 > P. 1:10001(10000) ack 1
23+
24+
// Limited transmit: on first dupack, send a new data segment.
25+
+.11 < . 1:1(0) ack 1 win 320 <sack 1001:2001,nop,nop>
26+
+0 > . 10001:11001(1000) ack 1
27+
28+
// Limited transmit: on second dupack, send a new data segment.
29+
+.01 < . 1:1(0) ack 1 win 320 <sack 1001:3001,nop,nop>
30+
+0 > . 11001:12001(1000) ack 1
31+
32+
// It turned out to be reordering, not loss.
33+
+.01 < . 1:1(0) ack 3001 win 320
34+
+0 > P. 12001:14001(2000) ack 1
35+
36+
+.02 < . 1:1(0) ack 5001 win 320
37+
+0 > P. 14001:15001(1000) ack 1
38+
39+
// Client gradually ACKs all data.
40+
+.02 < . 1:1(0) ack 7001 win 320
41+
+.02 < . 1:1(0) ack 9001 win 320
42+
+.02 < . 1:1(0) ack 11001 win 320
43+
+.02 < . 1:1(0) ack 13001 win 320
44+
+.02 < . 1:1(0) ack 15001 win 320
45+
46+
// Clean up.
47+
+.17 close(4) = 0
48+
+0 > F. 15001:15001(0) ack 1
49+
+.1 < F. 1:1(0) ack 15002 win 257
50+
+0 > . 15002:15002(0) ack 2
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+
// Simplest possible test of open() and then sendfile().
3+
// We write some zeroes into a file (since packetdrill expects payloads
4+
// to be all zeroes) and then open() the file, then use sendfile()
5+
// and verify that the correct number of zeroes goes out.
6+
7+
`./defaults.sh
8+
/bin/rm -f /tmp/testfile
9+
/bin/dd bs=1 count=5 if=/dev/zero of=/tmp/testfile status=none
10+
`
11+
12+
// Initialize connection
13+
0 socket(..., SOCK_STREAM, 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+
18+
+0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 10>
19+
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8>
20+
+0 < . 1:1(0) ack 1 win 514
21+
22+
+0 accept(3, ..., ...) = 4
23+
24+
+0 open("/tmp/testfile", O_RDONLY) = 5
25+
+0 sendfile(4, 5, [0], 5) = 5
26+
+0 > P. 1:6(5) ack 1
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
// Test TCP fastopen behavior with NULL as buffer pointer, but a non-zero
3+
// buffer length.
4+
`./defaults.sh
5+
./set_sysctls.py /proc/sys/net/ipv4/tcp_timestamps=0`
6+
7+
// Cache warmup: send a Fast Open cookie request
8+
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
9+
+0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
10+
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN_CONNECT, [1], 4) = 0
11+
+0 connect(3, ..., ...) = -1 EINPROGRESS (Operation is now in progress)
12+
+0 > S 0:0(0) <mss 1460,nop,nop,sackOK,nop,wscale 8,FO,nop,nop>
13+
+0 < S. 123:123(0) ack 1 win 14600 <mss 1460,nop,nop,sackOK,nop,wscale 6,FO abcd1234,nop,nop>
14+
+0 > . 1:1(0) ack 1
15+
+0 close(3) = 0
16+
+0 > F. 1:1(0) ack 1
17+
+0 < F. 1:1(0) ack 2 win 92
18+
+0 > . 2:2(0) ack 2
19+
20+
// Test with MSG_FASTOPEN without TCP_FASTOPEN_CONNECT.
21+
+0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4
22+
+0 fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0
23+
+0 sendto(4, NULL, 1, MSG_FASTOPEN, ..., ...) = -1
24+
+0 close(4) = 0
25+
26+
// Test with TCP_FASTOPEN_CONNECT without MSG_FASTOPEN.
27+
+0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 5
28+
+0 fcntl(5, F_SETFL, O_RDWR|O_NONBLOCK) = 0
29+
+0 setsockopt(5, SOL_TCP, TCP_FASTOPEN_CONNECT, [1], 4) = 0
30+
+0 connect(5, ..., ...) = 0
31+
+0 sendto(5, NULL, 1, 0, ..., ...) = -1
32+
+0 close(5) = 0
33+
34+
// Test with both TCP_FASTOPEN_CONNECT and MSG_FASTOPEN.
35+
+0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 6
36+
+0 fcntl(6, F_SETFL, O_RDWR|O_NONBLOCK) = 0
37+
+0 setsockopt(6, SOL_TCP, TCP_FASTOPEN_CONNECT, [1], 4) = 0
38+
+0 connect(6, ..., ...) = 0
39+
+0 sendto(6, NULL, 1, MSG_FASTOPEN, ..., ...) = -1
40+
+0 close(6) = 0
41+
42+
`/tmp/sysctl_restore_${PPID}.sh`
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
// Test that we correctly skip zero-length IOVs.
3+
`./defaults.sh`
4+
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
5+
+0 setsockopt(3, SOL_SOCKET, SO_ZEROCOPY, [1], 4) = 0
6+
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
7+
+0 bind(3, ..., ...) = 0
8+
+0 listen(3, 1) = 0
9+
10+
+0 < S 0:0(0) win 32792 <mss 1000,nop,wscale 7>
11+
+0 > S. 0:0(0) ack 1 <mss 1460,nop,wscale 8>
12+
+.01 < . 1:1(0) ack 1 win 257
13+
+0 accept(3, ..., ...) = 4
14+
+0 setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0
15+
16+
+0 sendmsg(4, {msg_name(...)=...,
17+
msg_iov(4)=[{..., 0}, {..., 40}, {..., 0}, {..., 20}],
18+
msg_flags=0}, 0) = 60
19+
+0 > P. 1:61(60) ack 1
20+
+.01 < . 1:1(0) ack 61 win 257
21+
22+
+0 sendmsg(4, {msg_name(...)=...,
23+
msg_iov(4)=[{..., 0}, {..., 0}, {..., 0}, {..., 0}],
24+
msg_flags=0}, MSG_ZEROCOPY) = 0
25+
26+
+0 sendmsg(4, {msg_name(...)=...,
27+
msg_iov(4)=[{..., 0}, {..., 10}, {..., 0}, {..., 50}],
28+
msg_flags=0}, MSG_ZEROCOPY) = 60
29+
+0 > P. 61:121(60) ack 1
30+
+.01 < . 1:1(0) ack 121 win 257
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
// Test kernel behavior with NULL as buffer pointer
3+
4+
`./defaults.sh`
5+
6+
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
7+
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
8+
+0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
9+
+0 bind(3, ..., ...) = 0
10+
+0 listen(3, 1) = 0
11+
12+
+0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 10>
13+
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8>
14+
+.2 < . 1:1(0) ack 1 win 514
15+
16+
+0 accept(3, ..., ...) = 4
17+
18+
+0 write(4, NULL, 1000) = -1 EFAULT (Bad address)
19+
+0 send(4, NULL, 1000, 0) = -1 EFAULT (Bad address)
20+
+0 sendto(4, NULL, 1000, 0, ..., ...) = -1 EFAULT (Bad address)
21+
22+
+0 < . 1:1001(1000) ack 1 win 200
23+
+0 read(4, NULL, 1000) = -1 EFAULT (Bad address)
24+
+0 recv(4, NULL, 1000, 0) = -1 EFAULT (Bad address)
25+
+0 recvfrom(4, NULL, 1000, 0, ..., ...) = -1 EFAULT (Bad address)
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+
`./defaults.sh`
4+
5+
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
6+
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
7+
+0 bind(3, ..., ...) = 0
8+
+0 listen(3, 1) = 0
9+
10+
11+
+0 < S 0:0(0) win 0 <mss 1460>
12+
+0 > S. 0:0(0) ack 1 <mss 1460>
13+
14+
+.1 < . 1:1(0) ack 1 win 65530
15+
+0 accept(3, ..., ...) = 4
16+
17+
+0 setsockopt(4, SOL_TCP, TCP_USER_TIMEOUT, [3000], 4) = 0
18+
+0 write(4, ..., 24) = 24
19+
+0 > P. 1:25(24) ack 1
20+
+.1 < . 1:1(0) ack 25 win 65530
21+
+0 %{ assert tcpi_probes == 0, tcpi_probes; \
22+
assert tcpi_backoff == 0, tcpi_backoff }%
23+
24+
// install a qdisc dropping all packets
25+
+0 `tc qdisc delete dev tun0 root 2>/dev/null ; tc qdisc add dev tun0 root pfifo limit 0`
26+
+0 write(4, ..., 24) = 24
27+
// When qdisc is congested we retry every 500ms
28+
// (TCP_RESOURCE_PROBE_INTERVAL) and therefore
29+
// we retry 6 times before hitting 3s timeout.
30+
// First verify that the connection is alive:
31+
+3.250 write(4, ..., 24) = 24
32+
// Now verify that shortly after that the socket is dead:
33+
+.100 write(4, ..., 24) = -1 ETIMEDOUT (Connection timed out)
34+
35+
+0 %{ assert tcpi_probes == 6, tcpi_probes; \
36+
assert tcpi_backoff == 0, tcpi_backoff }%
37+
+0 close(4) = 0
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+
`./defaults.sh`
3+
4+
// Initialize connection
5+
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
6+
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
7+
+0 bind(3, ..., ...) = 0
8+
+0 listen(3, 1) = 0
9+
10+
+0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop>
11+
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK>
12+
+.1 < . 1:1(0) ack 1 win 32792
13+
14+
15+
+0 accept(3, ..., ...) = 4
16+
17+
// Okay, we received nothing, and decide to close this idle socket.
18+
// We set TCP_USER_TIMEOUT to 3 seconds because really it is not worth
19+
// trying hard to cleanly close this flow, at the price of keeping
20+
// a TCP structure in kernel for about 1 minute !
21+
+2 setsockopt(4, SOL_TCP, TCP_USER_TIMEOUT, [3000], 4) = 0
22+
+0 close(4) = 0
23+
24+
+0 > F. 1:1(0) ack 1
25+
+.3~+.400 > F. 1:1(0) ack 1
26+
+.3~+.400 > F. 1:1(0) ack 1
27+
+.6~+.800 > F. 1:1(0) ack 1
28+
29+
// We finally receive something from the peer, but it is way too late
30+
// Our socket vanished because TCP_USER_TIMEOUT was really small
31+
+0 < . 1:2(1) ack 1 win 32792
32+
+0 > R 1:1(0)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
// Verify that established connections drop a segment without the ACK flag set.
3+
4+
`./defaults.sh`
5+
6+
// Create a socket.
7+
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
8+
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
9+
+0 bind(3, ..., ...) = 0
10+
+0 listen(3, 1) = 0
11+
12+
// Establish a connection.
13+
+0 < S 0:0(0) win 20000 <mss 1000,sackOK,nop,nop>
14+
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK>
15+
+.01 < . 1:1(0) ack 1 win 20000
16+
+0 accept(3, ..., ...) = 4
17+
18+
// Receive a segment with no flags set, verify that it's not enqueued.
19+
+.01 < - 1:1001(1000) win 20000
20+
+0 ioctl(4, SIOCINQ, [0]) = 0
21+
22+
// Receive a segment with ACK flag set, verify that it is enqueued.
23+
+.01 < . 1:1001(1000) ack 1 win 20000
24+
+0 ioctl(4, SIOCINQ, [1000]) = 0

0 commit comments

Comments
 (0)