Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Soham Chakradeo and committed by
Jakub Kicinski
5d4cadef 6f669205

+319
+53
tools/testing/selftests/net/packetdrill/tcp_limited_transmit_limited-transmit-no-sack.pkt
··· 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
+50
tools/testing/selftests/net/packetdrill/tcp_limited_transmit_limited-transmit-sack.pkt
··· 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
+26
tools/testing/selftests/net/packetdrill/tcp_sendfile_sendfile-simple.pkt
··· 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
+42
tools/testing/selftests/net/packetdrill/tcp_syscall_bad_arg_fastopen-invalid-buf-ptr.pkt
··· 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`
+30
tools/testing/selftests/net/packetdrill/tcp_syscall_bad_arg_sendmsg-empty-iov.pkt
··· 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
+25
tools/testing/selftests/net/packetdrill/tcp_syscall_bad_arg_syscall-invalid-buf-ptr.pkt
··· 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)
+37
tools/testing/selftests/net/packetdrill/tcp_user_timeout_user-timeout-probe.pkt
··· 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
+32
tools/testing/selftests/net/packetdrill/tcp_user_timeout_user_timeout.pkt
··· 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)
+24
tools/testing/selftests/net/packetdrill/tcp_validate_validate-established-no-flags.pkt
··· 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