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

Merge branch 'selftests-net-packetdrill-import-multiple-tests'

Soham Chakradeo says:

====================
selftests/net: packetdrill: import multiple tests

Import tests for the following features (folder names in brackets):
ECN (ecn) : RFC 3168
Close (close) : RFC 9293
TCP_INFO (tcp_info) : RFC 9293
Fast recovery (fast_recovery) : RFC 5681
Timestamping (timestamping) : RFC 1323
Nagle (nagle) : RFC 896
Selective Acknowledgments (sack) : RFC 2018
Recent Timestamp (ts_recent) : RFC 1323
Send file (sendfile)
Syscall bad arg (syscall_bad_arg)
Validate (validate)
Blocking (blocking)
Splice (splice)
End of record (eor)
Limited transmit (limited_transmit)

Procedure to import and test the packetdrill tests into upstream linux
is explained in the first patch of this series

These tests have many authors. We only import them here from
github.com/google/packetdrill. Thanks to the following authors fo their
contributions over the years to these tests: Neal Cardwell, Shuo Chen,
Yuchung Cheng, Jerry Chu, Eric Dumazet, Luke Hsiao, Priyaranjan Jha,
Chonggang Li, Tanner Love, John Sperbeck, Wei Wang and Maciej
Żenczykowski. For more info see the original github commits, such as
https://github.com/google/packetdrill/commit/8229c94928ac.
====================

Link: https://patch.msgid.link/20241217185203.297935-1-sohamch.kernel@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+1844
+18
tools/testing/selftests/net/packetdrill/tcp_blocking_blocking-accept.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test for blocking accept. 3 + 4 + `./defaults.sh` 5 + 6 + // Establish a connection. 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 + +0...0.200 accept(3, ..., ...) = 4 12 + 13 + +.1 < S 0:0(0) win 32792 <mss 1000,nop,wscale 7> 14 + +0 > S. 0:0(0) ack 1 <mss 1460,nop,wscale 8> 15 + +.1 < . 1:1(0) ack 1 win 257 16 + 17 + +.1 write(4, ..., 2000) = 2000 18 + +0 > P. 1:2001(2000) ack 1
+13
tools/testing/selftests/net/packetdrill/tcp_blocking_blocking-connect.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test for blocking connect. 3 + 4 + `./defaults.sh` 5 + 6 + // Establish a connection. 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + 9 + +.1...0.200 connect(3, ..., ...) = 0 10 + 11 + +0 > S 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 12 + +.1 < S. 0:0(0) ack 1 win 5792 <mss 1460,nop,wscale 2,nop,nop,sackOK> 13 + +0 > . 1:1(0) ack 1
+29
tools/testing/selftests/net/packetdrill/tcp_blocking_blocking-read.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test for blocking read. 3 + --tolerance_usecs=10000 4 + 5 + `./defaults.sh` 6 + 7 + // Establish a connection. 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 9 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 10 + +0 bind(3, ..., ...) = 0 11 + +0 listen(3, 1) = 0 12 + 13 + +.1 < S 0:0(0) win 32792 <mss 1000,nop,wscale 7> 14 + +0 > S. 0:0(0) ack 1 <mss 1460,nop,wscale 8> 15 + +.1 < . 1:1(0) ack 1 win 257 16 + +0 accept(3, ..., ...) = 4 17 + 18 + +0...0.100 read(4, ..., 2000) = 2000 19 + +.1 < P. 1:2001(2000) ack 1 win 257 20 + +0 > . 1:1(0) ack 2001 21 + 22 + +.1...0.200 read(4, ..., 2000) = 2000 23 + +.1 < P. 2001:4001(2000) ack 1 win 257 24 + +0 > . 1:1(0) ack 4001 25 + 26 + +.1 < P. 4001:6001(2000) ack 1 win 257 27 + +0 > . 1:1(0) ack 6001 28 + +0...0.000 read(4, ..., 1000) = 1000 29 + +0...0.000 read(4, ..., 1000) = 1000
+35
tools/testing/selftests/net/packetdrill/tcp_blocking_blocking-write.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test for blocking write. 3 + --tolerance_usecs=10000 4 + 5 + `./defaults.sh 6 + ./set_sysctls.py /proc/sys/net/ipv4/tcp_min_tso_segs=10 7 + ` 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 50000 <mss 1000,nop,wscale 0> 16 + +0 > S. 0:0(0) ack 1 <mss 1460,nop,wscale 8> 17 + +.1 < . 1:1(0) ack 1 win 50000 18 + +0 accept(3, ..., ...) = 4 19 + 20 + // Kernel doubles our value -> sk->sk_sndbuf is set to 42000 21 + +0 setsockopt(4, SOL_SOCKET, SO_SNDBUF, [21000], 4) = 0 22 + +0 getsockopt(4, SOL_SOCKET, SO_SNDBUF, [42000], [4]) = 0 23 + 24 + // A write of 60000 does not block. 25 + +0...0.300 write(4, ..., 61000) = 61000 // this write() blocks 26 + 27 + +.1 < . 1:1(0) ack 10001 win 50000 28 + 29 + +.1 < . 1:1(0) ack 30001 win 50000 30 + 31 + // This ACK should wakeup the write(). An ACK of 35001 does not. 32 + +.1 < . 1:1(0) ack 36001 win 50000 33 + 34 + // Reset to sysctls defaults. 35 + `/tmp/sysctl_restore_${PPID}.sh`
+23
tools/testing/selftests/net/packetdrill/tcp_close_close-local-close-then-remote-fin.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test basic connection teardown where local process closes first: 3 + // the local process calls close() first, so we send a FIN, and receive an ACK. 4 + // Then we receive a FIN and ACK it. 5 + 6 + `./defaults.sh` 7 + 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 9 + +.01...0.011 connect(3, ..., ...) = 0 10 + +0 > S 0:0(0) <...> 11 + +0 < S. 0:0(0) ack 1 win 32768 <mss 1000,nop,wscale 6,nop,nop,sackOK> 12 + +0 > . 1:1(0) ack 1 13 + 14 + +0 write(3, ..., 1000) = 1000 15 + +0 > P. 1:1001(1000) ack 1 16 + +0 < . 1:1(0) ack 1001 win 257 17 + 18 + +0 close(3) = 0 19 + +0 > F. 1001:1001(0) ack 1 20 + +0 < . 1:1(0) ack 1002 win 257 21 + 22 + +0 < F. 1:1(0) ack 1002 win 257 23 + +0 > . 1002:1002(0) ack 2
+21
tools/testing/selftests/net/packetdrill/tcp_close_close-on-syn-sent.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test to make sure no RST is being sent when close() 3 + // is called on a socket with SYN_SENT state. 4 + 5 + `./defaults.sh` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 9 + 10 + +0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) 11 + +0 > S 0:0(0) <...> 12 + 13 + // Application decideds to close the socket in SYN_SENT state 14 + // Make sure no RST is sent after close(). 15 + +0 close(3) = 0 16 + 17 + // Receive syn-ack to trigger the send side packet examination: 18 + // If a RESET were sent right after close(), it would have failed with 19 + // a mismatched timestamp. 20 + +.1 < S. 0:0(0) ack 1 win 32000 <mss 1460,nop,wscale 7> 21 + +0 > R 1:1(0)
+36
tools/testing/selftests/net/packetdrill/tcp_close_close-remote-fin-then-close.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Verify behavior for the sequence: remote side sends FIN, then we close(). 3 + // Since the remote side (client) closes first, we test our LAST_ACK code path. 4 + 5 + `./defaults.sh` 6 + 7 + // Initialize a server socket. 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 9 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 10 + +0 bind(3, ..., ...) = 0 11 + +0 listen(3, 1) = 0 12 + 13 + +0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7> 14 + +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 15 + +0 < . 1:1(0) ack 1 win 257 16 + 17 + +0 accept(3, ..., ...) = 4 18 + 19 + // Client closes first. 20 + +.01 < F. 1:1(0) ack 1 win 257 21 + +0 > . 1:1(0) ack 2 22 + 23 + // App notices that client closed. 24 + +0 read(4, ..., 1000) = 0 25 + 26 + // Then we close. 27 + +.01 close(4) = 0 28 + +0 > F. 1:1(0) ack 2 29 + 30 + // Client ACKs our FIN. 31 + +.01 < . 2:2(0) ack 2 win 257 32 + 33 + // Verify that we send RST in response to any incoming segments 34 + // (because the kernel no longer has any record of this socket). 35 + +.01 < . 2:2(0) ack 2 win 257 36 + +0 > R 2:2(0)
+21
tools/testing/selftests/net/packetdrill/tcp_ecn_ecn-uses-ect0.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test ECN: verify that Linux TCP ECN sending code uses ECT0 (not ECT1). 3 + // 4 + `./defaults.sh 5 + sysctl -q net.ipv4.tcp_ecn=1 # fully enabled 6 + ` 7 + 8 + // Initialize connection 9 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 10 + 11 + // ECN handshake: send EW flags in SYN packet, E flag in SYN-ACK response 12 + +.002 ... 0.004 connect(4, ..., ...) = 0 13 + 14 + +0 > SEW 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 15 + +.002 < SE. 0:0(0) ack 1 win 32767 <mss 1000,nop,wscale 6,nop,nop,sackOK> 16 + +0 > . 1:1(0) ack 1 17 + 18 + // Write 1 MSS. 19 + +.002 write(4, ..., 1000) = 1000 20 + // Send 1 MSS with ect0. 21 + +0 > [ect0] P. 1:1001(1000) ack 1
+38
tools/testing/selftests/net/packetdrill/tcp_eor_no-coalesce-large.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test TCP does not append any data from consequent writes to the tail 3 + // skb created for the chunk. The large chunk itself should be packetized as 4 + // usual. 5 + `./defaults.sh 6 + ` 7 + 8 + // Initialize connection 9 + 0 socket(..., SOCK_STREAM, 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:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 10> 15 + +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 16 + +.01 < . 1:1(0) ack 1 win 514 17 + 18 + +0 accept(3, ..., ...) = 4 19 + 20 + // Write a 10400B chunk to fill the ICW, and have a 400 byte skb sitting on 21 + // the tail. 22 + +0 write(4, ..., 10400) = 10400 23 + 24 + // Write another 10040B chunk with no coalescing options. 25 + +0 send(4, ..., 10400, MSG_EOR) = 10400 26 + 27 + // Write a 2KB chunk. This chunk should not be appended to the packets created 28 + // the previous chunk. 29 + +0 write(4, ..., 2000) = 2000 30 + 31 + +0 > P. 1:10001(10000) ack 1 32 + +.001 < . 1:1(0) ack 10001 win 514 33 + // Now we have enough room to send out the 2 x 400B packets out. 34 + +0 > P. 10001:20801(10800) ack 1 35 + +.001 < . 1:1(0) ack 20801 win 514 36 + // This 2KB packet should be sent alone. 37 + +0 > P. 20801:22801(2000) ack 1 38 + +.001 < . 1:1(0) ack 22801 win 514
+72
tools/testing/selftests/net/packetdrill/tcp_eor_no-coalesce-retrans.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test TCP does not append any data from consequent writes to the tail 3 + // skb created for the chunk. Also, when packets are retransmitted, they 4 + // will not be coalesce into the same skb. 5 + `./defaults.sh 6 + ` 7 + 8 + // Initialize connection 9 + 0 socket(..., SOCK_STREAM, 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:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 10> 15 + +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 16 + +.01 < . 1:1(0) ack 1 win 514 17 + 18 + +0 accept(3, ..., ...) = 4 19 + 20 + // Write a 10400B chunk to fill the ICW, and have a 400 byte skb sitting on 21 + // the tail. 22 + +0 write(4, ..., 10400) = 10400 23 + 24 + // Write 10 400B chunks with no coalescing options. 25 + +0 send(4, ..., 400, MSG_EOR) = 400 26 + +0 send(4, ..., 400, MSG_EOR) = 400 27 + +0 send(4, ..., 400, MSG_EOR) = 400 28 + +0 send(4, ..., 400, MSG_EOR) = 400 29 + +0 send(4, ..., 400, MSG_EOR) = 400 30 + +0 send(4, ..., 400, MSG_EOR) = 400 31 + +0 send(4, ..., 400, MSG_EOR) = 400 32 + +0 send(4, ..., 400, MSG_EOR) = 400 33 + +0 send(4, ..., 400, MSG_EOR) = 400 34 + +0 send(4, ..., 400, MSG_EOR) = 400 35 + // This chunk should not be appended to the skbs created for the previous chunk. 36 + +0 write(4, ..., 10000) = 10000 37 + 38 + +0 > P. 1:10001(10000) ack 1 39 + +.001 < . 1:1(0) ack 10001 win 514 40 + // Now we have enough room to send out the 2 x 400B packets out. 41 + +0 > P. 10001:10801(800) ack 1 42 + // The 9 remaining 400B chunks should be sent as individual packets. 43 + +0 > P. 10801:11201(400) ack 1 44 + +0 > P. 11201:11601(400) ack 1 45 + +0 > P. 11601:12001(400) ack 1 46 + +0 > P. 12001:12401(400) ack 1 47 + +0 > P. 12401:12801(400) ack 1 48 + +0 > P. 12801:13201(400) ack 1 49 + +0 > P. 13201:13601(400) ack 1 50 + +0 > P. 13601:14001(400) ack 1 51 + +0 > P. 14001:14401(400) ack 1 52 + // The last 10KB chunk should be sent separately. 53 + +0 > P. 14401:24401(10000) ack 1 54 + 55 + +.001 < . 1:1(0) ack 10401 win 514 56 + +.001 < . 1:1(0) ack 10801 win 514 57 + +.001 < . 1:1(0) ack 11201 win 514 58 + +.001 < . 1:1(0) ack 11601 win 514 59 + +.001 < . 1:1(0) ack 12001 win 514 <sack 13201:14401,nop,nop> 60 + // TCP should fill the hole but no coalescing should happen, and all 61 + // retransmissions should be sent out as individual packets. 62 + 63 + // Note : This is timeout based retransmit. 64 + // Do not put +0 here or flakes will come back. 65 + +.004~+.008 > P. 12001:12401(400) ack 1 66 + 67 + +.001 < . 1:1(0) ack 12401 win 514 <sack 13201:14401,nop,nop> 68 + +0 > P. 12401:12801(400) ack 1 69 + +0 > P. 12801:13201(400) ack 1 70 + +.001 < . 1:1(0) ack 12801 win 514 <sack 13201:14401,nop,nop> 71 + +.001 < . 1:1(0) ack 14401 win 514 72 + +.001 < . 1:1(0) ack 24401 win 514
+36
tools/testing/selftests/net/packetdrill/tcp_eor_no-coalesce-small.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test TCP does not append any data from consequent writes to the tail 3 + // skb created for the chunk. 4 + `./defaults.sh 5 + ` 6 + 7 + // Initialize connection 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 9 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 10 + +0 bind(3, ..., ...) = 0 11 + +0 listen(3, 1) = 0 12 + 13 + +0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 10> 14 + +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 15 + +.01 < . 1:1(0) ack 1 win 514 16 + 17 + +0 accept(3, ..., ...) = 4 18 + 19 + // Write a 10400B chunk to fill the ICW, and have a 400 byte skb sitting on 20 + // the tail. 21 + +0 write(4, ..., 10400) = 10400 22 + 23 + // Write a 400B chunk with no coalescing options. 24 + +0 send(4, ..., 400, MSG_EOR) = 400 25 + 26 + // This chunk should not be appended to the skbs created for the previous chunk. 27 + +0 write(4, ..., 10000) = 10000 28 + 29 + +0 > P. 1:10001(10000) ack 1 30 + +.001 < . 1:1(0) ack 10001 win 514 31 + // Now we have enough room to send out the 2 x 400B packets out. 32 + +0 > P. 10001:10801(800) ack 1 33 + +0 > P. 10801:20801(10000) ack 1 34 + +.001 < . 1:1(0) ack 10401 win 514 35 + +.001 < . 1:1(0) ack 10801 win 514 36 + +.001 < . 1:1(0) ack 20801 win 514
+66
tools/testing/selftests/net/packetdrill/tcp_eor_no-coalesce-subsequent.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test TCP does not append any data from consequent writes to the tail 3 + // skb created for the chunk even though we have 10 back-to-back small 4 + // writes. 5 + `./defaults.sh 6 + ` 7 + 8 + // Initialize connection 9 + 0 socket(..., SOCK_STREAM, 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:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 10> 15 + +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 16 + +.01 < . 1:1(0) ack 1 win 514 17 + 18 + +0 accept(3, ..., ...) = 4 19 + 20 + // Write a 10400B chunk to fill the ICW, and have a 400 byte skb sitting on 21 + // the tail. 22 + +0 write(4, ..., 10400) = 10400 23 + 24 + // Write 10 400B chunks with no coalescing options. 25 + +0 send(4, ..., 400, MSG_EOR) = 400 26 + +0 send(4, ..., 400, MSG_EOR) = 400 27 + +0 send(4, ..., 400, MSG_EOR) = 400 28 + +0 send(4, ..., 400, MSG_EOR) = 400 29 + +0 send(4, ..., 400, MSG_EOR) = 400 30 + +0 send(4, ..., 400, MSG_EOR) = 400 31 + +0 send(4, ..., 400, MSG_EOR) = 400 32 + +0 send(4, ..., 400, MSG_EOR) = 400 33 + +0 send(4, ..., 400, MSG_EOR) = 400 34 + +0 send(4, ..., 400, MSG_EOR) = 400 35 + // This chunk should not be appended to the skbs created for the previous chunk. 36 + +0 write(4, ..., 10000) = 10000 37 + 38 + +0 > P. 1:10001(10000) ack 1 39 + +.001 < . 1:1(0) ack 10001 win 514 40 + // Now we have enough room to send out the 2 x 400B packets out. 41 + +0 > P. 10001:10801(800) ack 1 42 + // The 9 remaining 400B chunks should be sent as individual packets. 43 + +0 > P. 10801:11201(400) ack 1 44 + +0 > P. 11201:11601(400) ack 1 45 + +0 > P. 11601:12001(400) ack 1 46 + +0 > P. 12001:12401(400) ack 1 47 + +0 > P. 12401:12801(400) ack 1 48 + +0 > P. 12801:13201(400) ack 1 49 + +0 > P. 13201:13601(400) ack 1 50 + +0 > P. 13601:14001(400) ack 1 51 + +0 > P. 14001:14401(400) ack 1 52 + // The last 10KB chunk should be sent separately. 53 + +0 > P. 14401:24401(10000) ack 1 54 + 55 + +.001 < . 1:1(0) ack 10401 win 514 56 + +.001 < . 1:1(0) ack 10801 win 514 57 + +.001 < . 1:1(0) ack 11201 win 514 58 + +.001 < . 1:1(0) ack 11601 win 514 59 + +.001 < . 1:1(0) ack 12001 win 514 60 + +.001 < . 1:1(0) ack 12401 win 514 61 + +.001 < . 1:1(0) ack 12801 win 514 62 + +.001 < . 1:1(0) ack 13201 win 514 63 + +.001 < . 1:1(0) ack 13601 win 514 64 + +.001 < . 1:1(0) ack 14001 win 514 65 + +.001 < . 1:1(0) ack 14401 win 514 66 + +.001 < . 1:1(0) ack 24401 win 514
+72
tools/testing/selftests/net/packetdrill/tcp_fast_recovery_prr-ss-10pkt-lost-1.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test PRR-slowstart implementation. 3 + // In this variant we test a simple case where in-flight == ssthresh 4 + // all the way through recovery, so during fast recovery we send one segment 5 + // for each segment SACKed/ACKed. 6 + 7 + // Set up config. 8 + `./defaults.sh` 9 + 10 + // Establish a connection. 11 + 0 socket(..., SOCK_STREAM, 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 + 16 + +.1 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7> 17 + +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 18 + // RTT 100ms 19 + +.1 < . 1:1(0) ack 1 win 320 20 + +0 accept(3, ..., ...) = 4 21 + 22 + // Send 10 data segments. 23 + +0 write(4, ..., 10000) = 10000 24 + +0 > P. 1:10001(10000) ack 1 25 + 26 + // Lost packet 1:1001. 27 + +.11 < . 1:1(0) ack 1 win 320 <sack 1001:2001,nop,nop> 28 + +.01 < . 1:1(0) ack 1 win 320 <sack 1001:3001,nop,nop> 29 + +.01 < . 1:1(0) ack 1 win 320 <sack 1001:4001,nop,nop> 30 + // Enter fast recovery. 31 + +0 > . 1:1001(1000) ack 1 32 + +.01 %{ 33 + assert tcpi_ca_state == TCP_CA_Recovery, tcpi_ca_state 34 + assert tcpi_snd_cwnd == 7, tcpi_snd_cwnd 35 + assert tcpi_snd_ssthresh == 7, tcpi_snd_ssthresh 36 + }% 37 + 38 + // Write some more, which we will send 1 MSS at a time, 39 + // as in-flight segments are SACKed or ACKed. 40 + +.01 write(4, ..., 7000) = 7000 41 + 42 + +.01 < . 1:1(0) ack 1 win 320 <sack 1001:5001,nop,nop> 43 + +0 > . 10001:11001(1000) ack 1 44 + 45 + +.01 < . 1:1(0) ack 1 win 320 <sack 1001:6001,nop,nop> 46 + +0 > . 11001:12001(1000) ack 1 47 + 48 + +.01 < . 1:1(0) ack 1 win 320 <sack 1001:7001,nop,nop> 49 + +0 > . 12001:13001(1000) ack 1 50 + 51 + +.01 < . 1:1(0) ack 1 win 320 <sack 1001:8001,nop,nop> 52 + +0 > . 13001:14001(1000) ack 1 53 + 54 + +.01 < . 1:1(0) ack 1 win 320 <sack 1001:9001,nop,nop> 55 + +0 > . 14001:15001(1000) ack 1 56 + 57 + +.01 < . 1:1(0) ack 1 win 320 <sack 1001:10001,nop,nop> 58 + +0 > . 15001:16001(1000) ack 1 59 + 60 + +.02 < . 1:1(0) ack 10001 win 320 61 + +0 > P. 16001:17001(1000) ack 1 62 + // Leave fast recovery. 63 + +.01 %{ 64 + assert tcpi_ca_state == TCP_CA_Open, tcpi_ca_state 65 + assert tcpi_snd_cwnd == 7, tcpi_snd_cwnd 66 + assert tcpi_snd_ssthresh == 7, tcpi_snd_ssthresh 67 + }% 68 + 69 + +.03 < . 1:1(0) ack 12001 win 320 70 + +.02 < . 1:1(0) ack 14001 win 320 71 + +.02 < . 1:1(0) ack 16001 win 320 72 + +.02 < . 1:1(0) ack 17001 win 320
+50
tools/testing/selftests/net/packetdrill/tcp_fast_recovery_prr-ss-30pkt-lost-1_4-11_16.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test PRR-slowstart implementation. The sender sends 20 packets. Packet 3 + // 1 to 4, and 11 to 16 are dropped. 4 + `./defaults.sh` 5 + 6 + // Establish a connection. 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 + +0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7> 13 + +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 14 + 15 + +.01 < . 1:1(0) ack 1 win 320 16 + +0 accept(3, ..., ...) = 4 17 + 18 + // Write 20 data segments. 19 + +0 write(4, ..., 20000) = 20000 20 + +0 > P. 1:10001(10000) ack 1 21 + 22 + // Receive first DUPACK, entering PRR part 23 + +.01 < . 1:1(0) ack 1 win 320 <sack 4001:5001,nop,nop> 24 + +0 > . 10001:11001(1000) ack 1 25 + +.002 < . 1:1(0) ack 1 win 320 <sack 4001:6001,nop,nop> 26 + +0 > . 11001:12001(1000) ack 1 27 + +.002 < . 1:1(0) ack 1 win 320 <sack 4001:7001,nop,nop> 28 + +0 > . 1:1001(1000) ack 1 29 + +.002 < . 1:1(0) ack 1 win 320 <sack 4001:8001,nop,nop> 30 + +0 > . 1001:2001(1000) ack 1 31 + +.002 < . 1:1(0) ack 1 win 320 <sack 4001:9001,nop,nop> 32 + +0 > . 2001:3001(1000) ack 1 33 + +.002 < . 1:1(0) ack 1 win 320 <sack 4001:10001,nop,nop> 34 + +0 > . 3001:4001(1000) ack 1 35 + // Enter PRR CRB 36 + +.002 < . 1:1(0) ack 1 win 320 <sack 4001:11001,nop,nop> 37 + +0 > . 12001:13001(1000) ack 1 38 + +.002 < . 1:1(0) ack 1 win 320 <sack 4001:12001,nop,nop> 39 + +0 > . 13001:14001(1000) ack 1 40 + // Enter PRR slow start 41 + +.01 < . 1:1(0) ack 1001 win 320 <sack 4001:12001,nop,nop> 42 + +0 > P. 14001:16001(2000) ack 1 43 + +.002 < . 1:1(0) ack 1001 win 320 <sack 2001:12001,nop,nop> 44 + +0 > . 1001:2001(1000) ack 1 45 + +0 > . 16001:17001(1000) ack 1 46 + // inflight reaches ssthresh, goes into packet conservation mode 47 + +.002 < . 1:1(0) ack 1001 win 320 <sack 2001:13001,nop,nop> 48 + +0 > . 17001:18001(1000) ack 1 49 + +.002 < . 1:1(0) ack 1001 win 320 <sack 2001:14001,nop,nop> 50 + +0 > . 18001:19001(1000) ack 1
+43
tools/testing/selftests/net/packetdrill/tcp_fast_recovery_prr-ss-30pkt-lost1_4.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test PRR-slowstart implementation. The sender sends 20 packets. Packet 3 + // 1 to 4 are lost. The sender writes another 10 packets. 4 + `./defaults.sh` 5 + 6 + // Establish a connection. 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 + +0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7> 13 + +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 14 + 15 + +.01 < . 1:1(0) ack 1 win 320 16 + +0 accept(3, ..., ...) = 4 17 + 18 + // Send 20 data segments. 19 + +0 write(4, ..., 10000) = 10000 20 + +0 > P. 1:10001(10000) ack 1 21 + 22 + // Lost packet 1,2,3,4 23 + +.01 < . 1:1(0) ack 1 win 320 <sack 4001:5001,nop,nop> 24 + +.002 < . 1:1(0) ack 1 win 320 <sack 4001:6001,nop,nop> 25 + +0 < . 1:1(0) ack 1 win 320 <sack 4001:7001,nop,nop> 26 + +0 > . 1:1001(1000) ack 1 27 + +0 < . 1:1(0) ack 1 win 320 <sack 4001:8001,nop,nop> 28 + +0 > . 1001:2001(1000) ack 1 29 + +0 < . 1:1(0) ack 1 win 320 <sack 4001:9001,nop,nop> 30 + +0 > . 2001:3001(1000) ack 1 31 + +0 < . 1:1(0) ack 1 win 320 <sack 4001:10001,nop,nop> 32 + +0 > . 3001:4001(1000) ack 1 33 + 34 + // Receiver ACKs all data. 35 + +.01 < . 1:1(0) ack 1001 win 320 <sack 4001:10001,nop,nop> 36 + +0 < . 1:1(0) ack 2001 win 320 <sack 4001:10001,nop,nop> 37 + +0 < . 1:1(0) ack 3001 win 320 <sack 4001:10001,nop,nop> 38 + +0 < . 1:1(0) ack 10001 win 320 39 + 40 + // Writes another 10 packets, which the ssthresh*mss amount 41 + // should be sent right away 42 + +.01 write(4, ..., 10000) = 10000 43 + +0 > . 10001:17001(7000) ack 1
+41
tools/testing/selftests/net/packetdrill/tcp_fast_recovery_prr-ss-ack-below-snd_una-cubic.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test PRR-slowstart implementation. 3 + // In this variant we verify that the sender uses SACK info on an ACK 4 + // below snd_una. 5 + 6 + // Set up config. 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 + +0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 8> 16 + +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 17 + // RTT 10ms 18 + +.01 < . 1:1(0) ack 1 win 320 19 + +0 accept(3, ..., ...) = 4 20 + 21 + // Send 10 data segments. 22 + +0 write(4, ..., 10000) = 10000 23 + +0 > P. 1:10001(10000) ack 1 24 + 25 + // Lost packet 1:1001,4001:5001,7001:8001. 26 + +.01 < . 1:1(0) ack 1 win 320 <sack 1001:2001,nop,nop> 27 + +0 < . 1:1(0) ack 1 win 320 <sack 1001:3001,nop,nop> 28 + +0 < . 1:1(0) ack 1 win 320 <sack 1001:3001 8001:9001,nop,nop> 29 + +0 > . 1:1001(1000) ack 1 30 + 31 + +.012 < . 1:1(0) ack 4001 win 320 <sack 8001:9001,nop,nop> 32 + +0 > . 4001:7001(3000) ack 1 33 + 34 + +0 write(4, ..., 10000) = 10000 35 + 36 + // The following ACK was reordered - delayed so that it arrives with 37 + // an ACK field below snd_una. Here we check that the newly-SACKed 38 + // 2MSS at 5001:7001 cause us to send out 2 more MSS. 39 + +.002 < . 1:1(0) ack 3001 win 320 <sack 5001:7001,nop,nop> 40 + +0 > . 7001:8001(1000) ack 1 41 + +0 > . 10001:11001(1000) ack 1
+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
+40
tools/testing/selftests/net/packetdrill/tcp_nagle_https_client.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // This is a test inspired by an Android client app using SSL. This 3 + // test verifies using TCP_NODELAY would save application latency 4 + // (Perhaps even better with TCP_NAGLE). 5 + // 6 + `./defaults.sh 7 + ethtool -K tun0 tso off gso off 8 + ./set_sysctls.py /proc/sys/net/ipv4/tcp_timestamps=0` 9 + 10 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 11 + +0 fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0 12 + +0 setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0 13 + 14 + +0 connect(4, ..., ...) = -1 EINPROGRESS (Operation now in progress) 15 + +0 > S 0:0(0) <mss 1460,nop,nop,sackOK,nop,wscale 8> 16 + +.1 < S. 0:0(0) ack 1 win 5792 <mss 974,nop,nop,sackOK,nop,wscale 7> 17 + +0 > . 1:1(0) ack 1 18 + 19 + // SSL handshake (resumed session) 20 + +0 write(4, ..., 517) = 517 21 + +0 > P. 1:518(517) ack 1 22 + +.1 < . 1:1(0) ack 518 win 229 23 + 24 + +0 < P. 1:144(143) ack 1 win 229 25 + +0 > . 518:518(0) ack 144 26 + +0 read(4, ..., 1000) = 143 27 + 28 + // Application POST header (51B) and body (2002B) 29 + +0 write(4, ..., 51) = 51 30 + +0 > P. 518:569(51) ack 144 31 + +.03 write(4, ..., 2002) = 2002 32 + +0 > . 569:1543(974) ack 144 33 + +0 > P. 1543:2517(974) ack 144 34 + // Without disabling Nagle, this packet will not happen until the remote ACK. 35 + +0 > P. 2517:2571(54) ack 144 36 + 37 + +.1 < . 1:1(0) ack 2571 win 229 38 + 39 + // Reset sysctls 40 + `/tmp/sysctl_restore_${PPID}.sh`
+66
tools/testing/selftests/net/packetdrill/tcp_nagle_sendmsg_msg_more.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test the MSG_MORE flag will correctly corks the tiny writes 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 + +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 + // Disable Nagle by default on this socket. 15 + +0 setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0 16 + 17 + // Test the basic case: MSG_MORE overwrites TCP_NODELAY and enables Nagle. 18 + +0 sendmsg(4, {msg_name(...)=..., 19 + msg_iov(1)=[{..., 40}], msg_flags=0}, MSG_MORE) = 40 20 + +.21~+.215 > P. 1:41(40) ack 1 21 + +.01 < . 1:1(0) ack 41 win 257 22 + 23 + // Test unsetting MSG_MORE releases the packet 24 + +0 sendmsg(4, {msg_name(...)=..., 25 + msg_iov(1)=[{..., 100}], msg_flags=0}, MSG_MORE) = 100 26 + +.005 sendmsg(4, {msg_name(...)=..., 27 + msg_iov(1)=[{..., 160}], msg_flags=0}, MSG_MORE) = 160 28 + +.01 sendmsg(4, {msg_name(...)=..., 29 + msg_iov(3)=[{..., 100}, {..., 200}, {..., 195}], 30 + msg_flags=0}, MSG_MORE) = 495 31 + +.008 sendmsg(4, {msg_name(...)=..., 32 + msg_iov(1)=[{..., 5}], msg_flags=0}, 0) = 5 33 + +0 > P. 41:801(760) ack 1 34 + +.02 < . 1:1(0) ack 801 win 257 35 + 36 + 37 + // Test >MSS write will unleash MSS packets but hold on the remaining data. 38 + +.1 sendmsg(4, {msg_name(...)=..., 39 + msg_iov(1)=[{..., 3100}], msg_flags=0}, MSG_MORE) = 3100 40 + +0 > . 801:3801(3000) ack 1 41 + +.003 sendmsg(4, {msg_name(...)=..., 42 + msg_iov(1)=[{..., 50}], msg_flags=0}, MSG_MORE) = 50 43 + 44 + +.01 < . 1:1(0) ack 2801 win 257 45 + // Err... we relase the remaining right after the ACK? note that PUSH is reset 46 + +0 > . 3801:3951(150) ack 1 47 + 48 + // Test we'll hold on the subsequent writes when inflight (3801:3951) > 0 49 + +.001 sendmsg(4, {msg_name(...)=..., 50 + msg_iov(1)=[{..., 1}], msg_flags=0}, MSG_MORE) = 1 51 + +.002 sendmsg(4, {msg_name(...)=..., 52 + msg_iov(1)=[{..., 2}], msg_flags=0}, MSG_MORE) = 2 53 + +.003 sendmsg(4, {msg_name(...)=..., 54 + msg_iov(1)=[{..., 3}], msg_flags=0}, MSG_MORE) = 3 55 + +.004 sendmsg(4, {msg_name(...)=..., 56 + msg_iov(1)=[{..., 4}], msg_flags=0}, MSG_MORE) = 4 57 + +.02 < . 1:1(0) ack 3951 win 257 58 + +0 > . 3951:3961(10) ack 1 59 + +.02 < . 1:1(0) ack 3961 win 257 60 + 61 + 62 + // Test the case a MSG_MORE send followed by a write flushes the data 63 + +0 sendmsg(4, {msg_name(...)=..., 64 + msg_iov(1)=[{..., 20}], msg_flags=0}, MSG_MORE) = 20 65 + +.05 write(4, ..., 20) = 20 66 + +0 > P. 3961:4001(40) ack 1
+43
tools/testing/selftests/net/packetdrill/tcp_nagle_sockopt_cork_nodelay.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test TCP_CORK and TCP_NODELAY sockopt behavior 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 + +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 + // Set TCP_CORK sockopt to hold small packets 15 + +0 setsockopt(4, SOL_TCP, TCP_CORK, [1], 4) = 0 16 + 17 + +0 write(4, ..., 40) = 40 18 + +.05 write(4, ..., 40) = 40 19 + 20 + // Unset TCP_CORK should push pending bytes out 21 + +.01 setsockopt(4, SOL_TCP, TCP_CORK, [0], 4) = 0 22 + +0 > P. 1:81(80) ack 1 23 + +.01 < . 1:1(0) ack 81 win 257 24 + 25 + // Set TCP_CORK sockopt to hold small packets 26 + +0 setsockopt(4, SOL_TCP, TCP_CORK, [1], 4) = 0 27 + 28 + +0 write(4, ..., 40) = 40 29 + +.05 write(4, ..., 40) = 40 30 + 31 + // Set TCP_NODELAY sockopt should push pending bytes out 32 + +0 setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0 33 + +0 > P. 81:161(80) ack 1 34 + +.01 < . 1:1(0) ack 161 win 257 35 + 36 + // Set MSG_MORE to hold small packets 37 + +0 send(4, ..., 40, MSG_MORE) = 40 38 + +.05 send(4, ..., 40, MSG_MORE) = 40 39 + 40 + // Set TCP_NODELAY sockopt should push pending bytes out 41 + +.01 setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0 42 + +0 > . 161:241(80) ack 1 43 + +.01 < . 1:1(0) ack 241 win 257
+37
tools/testing/selftests/net/packetdrill/tcp_sack_sack-route-refresh-ip-tos.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Verify that setsockopt calls that force a route refresh do not 3 + // cause problems matching SACKs with packets in the write queue. 4 + // This variant tests IP_TOS. 5 + 6 + `./defaults.sh` 7 + 8 + // Establish a connection. 9 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 10 + +0 setsockopt(3, SOL_IP, IP_MTU_DISCOVER, [IP_PMTUDISC_DONT], 1) = 0 11 + +0...0.010 connect(3, ..., ...) = 0 12 + 13 + +0 > S 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 14 + +.01 < S. 0:0(0) ack 1 win 65535 <mss 1460,nop,wscale 2,nop,nop,sackOK> 15 + +0 > . 1:1(0) ack 1 16 + 17 + +.01 write(3, ..., 5840) = 5840 18 + +0 > P. 1:5841(5840) ack 1 19 + +.01 < . 1:1(0) ack 5841 win 65535 20 + 21 + +.01 write(3, ..., 5840) = 5840 22 + +0 > P. 5841:11681(5840) ack 1 23 + +.01 < . 1:1(0) ack 11681 win 65535 24 + 25 + +.01 write(3, ..., 14600) = 14600 26 + +0 > P. 11681:26281(14600) ack 1 27 + 28 + // Try the socket option that we know can force a route refresh. 29 + +0 setsockopt(3, SOL_IP, IP_TOS, [4], 1) = 0 30 + // Then revert to avoid routing/mangling/etc implications of that setting. 31 + +0 setsockopt(3, SOL_IP, IP_TOS, [0], 1) = 0 32 + 33 + // Verify that we do not retransmit the SACKed segments. 34 + +.01 < . 1:1(0) ack 13141 win 65535 <sack 16061:17521 20441:26281,nop,nop> 35 + +0 > . 13141:16061(2920) ack 1 36 + +0 > P. 17521:20441(2920) ack 1 37 + +.01 < . 1:1(0) ack 26281 win 65535
+64
tools/testing/selftests/net/packetdrill/tcp_sack_sack-shift-sacked-2-6-8-3-9-nofack.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test shifting of newly-SACKed ranges onto the previous already-SACKed skb. 3 + // This variant tests non-FACK SACK with SACKs coming in the order 4 + // 2 6 8 3 9, to test what happens when we get a new SACKed range 5 + // (for packet 3) that is on the right of an existing SACKed range 6 + // (for packet 2). 7 + 8 + `./defaults.sh` 9 + 10 + // Establish a connection and send 10 MSS. 11 + 0 socket(..., SOCK_STREAM, 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 + 16 + +0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7> 17 + +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 18 + +.1 < . 1:1(0) ack 1 win 1024 19 + +0 accept(3, ..., ...) = 4 20 + 21 + +0 write(4, ..., 10000) = 10000 22 + +0 > P. 1:10001(10000) ack 1 23 + 24 + +.1 < . 1:1(0) ack 1 win 257 <sack 2001:3001,nop,nop> 25 + +.001 < . 1:1(0) ack 1 win 257 <sack 2001:3001 6001:7001,nop,nop> 26 + +.001 < . 1:1(0) ack 1 win 257 <sack 2001:3001 6001:7001 8001:9001,nop,nop> 27 + 28 + // 3 SACKed packets, so we enter Fast Recovery. 29 + +0 > . 1:1001(1000) ack 1 30 + +0 %{ assert tcpi_ca_state == TCP_CA_Recovery, tcpi_ca_state }% 31 + +0 %{ assert tcpi_lost == 6, tcpi_lost }% 32 + 33 + // SACK for 3001:4001. 34 + // This SACK for an adjacent range causes the sender to 35 + // shift the newly-SACKed range onto the previous skb. 36 + +.007 < . 1:1(0) ack 1 win 257 <sack 2001:4001 6001:7001 8001:9001,nop,nop> 37 + +0 > . 1001:2001(1000) ack 1 38 + +0 %{ assert tcpi_lost == 5, tcpi_lost }% 39 + +0 %{ assert tcpi_reordering == 6, tcpi_reordering }% // 8001:9001 -> 3001:4001 is 6 40 + 41 + // SACK for 9001:10001. 42 + +.01 < . 1:1(0) ack 1 win 257 <sack 2001:4001 6001:7001 8001:10001,nop,nop> 43 + +0 %{ assert tcpi_lost == 5, tcpi_lost }% 44 + 45 + // ACK for 1:1001 as packets from t=0.303 arrive. 46 + +.083 < . 1:1(0) ack 1001 win 257 <sack 2001:4001 6001:7001 8001:10001,nop,nop> 47 + +0 %{ assert tcpi_lost == 4,tcpi_lost }% 48 + 49 + // ACK for 1:4001 as packets from t=0.310 arrive. 50 + +.017 < . 1:1(0) ack 4001 win 257 <sack 6001:7001 8001:10001,nop,nop> 51 + +0 %{ assert tcpi_lost == 3,tcpi_lost }% 52 + 53 + // ACK for 1:7001 as packets from t=0.320 arrive. 54 + +.01 < . 1:1(0) ack 7001 win 257 <sack 8001:10001,nop,nop> 55 + 56 + // ACK for all data as packets from t=0.403 arrive. 57 + +.1 < . 1:1(0) ack 10001 win 257 58 + +0 %{ 59 + assert tcpi_ca_state == TCP_CA_Open, tcpi_ca_state 60 + assert tcpi_unacked == 0, tcpi_unacked 61 + assert tcpi_sacked == 0, tcpi_sacked 62 + assert tcpi_lost == 0, tcpi_lost 63 + assert tcpi_retrans == 0, tcpi_retrans 64 + }%
+66
tools/testing/selftests/net/packetdrill/tcp_sack_sack-shift-sacked-7-3-4-8-9-fack.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test shifting of newly-SACKed ranges onto the previous already-SACKed skb. 3 + // This variant tests the case where we mark packets 0-4 lost, then 4 + // get a SACK for 3, and then a SACK for 4. 5 + 6 + `./defaults.sh` 7 + 8 + // Establish a connection and send 10 MSS. 9 + 0 socket(..., SOCK_STREAM, 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:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7> 15 + +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 16 + +.1 < . 1:1(0) ack 1 win 1024 17 + +0 accept(3, ..., ...) = 4 18 + 19 + +0 write(4, ..., 10000) = 10000 20 + +0 > P. 1:10001(10000) ack 1 21 + 22 + // SACK for 7001:8001. Using RACK we delay the fast retransmit. 23 + +.1 < . 1:1(0) ack 1 win 257 <sack 7001:8001,nop,nop> 24 + // RACK reordering timer 25 + +.027 > . 1:1001(1000) ack 1 26 + +0 %{ 27 + assert tcpi_ca_state == TCP_CA_Recovery, tcpi_ca_state 28 + assert tcpi_lost == 7, tcpi_lost # RACK thinks 1:7001 are lost 29 + assert tcpi_reordering == 3, tcpi_reordering 30 + }% 31 + 32 + // SACK for 3001:4001. 33 + +.002 < . 1:1(0) ack 1 win 257 <sack 3001:4001 7001:8001,nop,nop> 34 + +0 > . 1001:2001(1000) ack 1 35 + +0 %{ 36 + assert tcpi_lost == 6, tcpi_lost # since 3001:4001 is no longer lost 37 + assert tcpi_reordering == 5, tcpi_reordering # 7001:8001 -> 3001:4001 38 + }% 39 + 40 + // SACK for 4001:5001. 41 + // This SACK for an adjacent range causes the sender to 42 + // shift the newly-SACKed range onto the previous skb. 43 + // It uses the RFC3517 algorithm to mark 1:3001 lost 44 + // because >=3 higher-sequence packets are SACKed. 45 + +.002 < . 1:1(0) ack 1 win 257 <sack 3001:5001 7001:8001,nop,nop> 46 + +0 > . 2001:3001(1000) ack 1 47 + +0 %{ 48 + assert tcpi_lost == 5,tcpi_lost # SACK/RFC3517 thinks 1:3001 are lost 49 + }% 50 + 51 + // SACK for 8001:9001. 52 + +.002 < . 1:1(0) ack 1 win 257 <sack 3001:5001 7001:9001,nop,nop> 53 + 54 + // SACK for 9001:10001. 55 + +.002 < . 1:1(0) ack 1 win 257 <sack 3001:5001 7001:10001,nop,nop> 56 + +0 > . 5001:6001(1000) ack 1 57 + 58 + // To simplify clean-up, say we get an ACK for all data. 59 + +.1 < . 1:1(0) ack 10001 win 257 60 + +0 %{ 61 + assert tcpi_ca_state == TCP_CA_Open, tcpi_ca_state 62 + assert tcpi_unacked == 0, tcpi_unacked 63 + assert tcpi_sacked == 0, tcpi_sacked 64 + assert tcpi_lost == 0, tcpi_lost 65 + assert tcpi_retrans == 0, tcpi_retrans 66 + }%
+62
tools/testing/selftests/net/packetdrill/tcp_sack_sack-shift-sacked-7-5-6-8-9-fack.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test shifting of newly-SACKed ranges onto the previous already-SACKed skb. 3 + // This variant tests the case where we mark packets 0-4 lost, then 4 + // get a SACK for 5, and then a SACK for 6. 5 + 6 + `./defaults.sh` 7 + 8 + // Establish a connection and send 10 MSS. 9 + 0 socket(..., SOCK_STREAM, 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:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7> 15 + +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 16 + +.1 < . 1:1(0) ack 1 win 1024 17 + +0 accept(3, ..., ...) = 4 18 + 19 + +0 write(4, ..., 10000) = 10000 20 + +0 > P. 1:10001(10000) ack 1 21 + 22 + // SACK for 7001:8001. Using RACK we delay a fast retransmit. 23 + +.1 < . 1:1(0) ack 1 win 257 <sack 7001:8001,nop,nop> 24 + +.027 > . 1:1001(1000) ack 1 25 + +0 %{ 26 + assert tcpi_ca_state == TCP_CA_Recovery, tcpi_ca_state 27 + assert tcpi_lost == 7,tcpi_lost # RACK thinks 1:7001 are lost 28 + assert tcpi_reordering == 3, tcpi_reordering 29 + }% 30 + 31 + // SACK for 5001:6001. 32 + +0 < . 1:1(0) ack 1 win 257 <sack 5001:6001 7001:8001,nop,nop> 33 + +0 > . 1001:2001(1000) ack 1 34 + +0 %{ 35 + assert tcpi_lost == 6, tcpi_lost 36 + assert tcpi_reordering == 3, tcpi_reordering # 7001:8001 -> 5001:6001 is 3 37 + }% 38 + 39 + // SACK for 6001:7001. 40 + // This SACK for an adjacent range causes the sender to 41 + // shift the newly-SACKed range onto the previous skb. 42 + +0 < . 1:1(0) ack 1 win 257 <sack 5001:8001,nop,nop> 43 + +0 > . 2001:3001(1000) ack 1 44 + +0 %{ assert tcpi_lost == 5, tcpi_lost }% 45 + 46 + // SACK for 8001:9001. 47 + +0 < . 1:1(0) ack 1 win 257 <sack 5001:9001,nop,nop> 48 + +0 > . 3001:4001(1000) ack 1 49 + 50 + // SACK for 9001:10001. 51 + +0 < . 1:1(0) ack 1 win 257 <sack 5001:10001,nop,nop> 52 + +0 > . 4001:5001(1000) ack 1 53 + 54 + // To simplify clean-up, say we get an ACK for all data. 55 + +.1 < . 1:1(0) ack 10001 win 257 56 + +0 %{ 57 + assert tcpi_ca_state == TCP_CA_Open, tcpi_ca_state 58 + assert tcpi_unacked == 0, tcpi_unacked 59 + assert tcpi_sacked == 0, tcpi_sacked 60 + assert tcpi_lost == 0, tcpi_lost 61 + assert tcpi_retrans == 0, tcpi_retrans 62 + }%
+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
+20
tools/testing/selftests/net/packetdrill/tcp_splice_tcp_splice_loop_test.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + `./defaults.sh` 3 + 4 + // Initialize a server socket 5 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 6 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 7 + +0 setsockopt(3, SOL_IP, IP_FREEBIND, [1], 4) = 0 8 + +0 bind(3, ..., ...) = 0 9 + +0 listen(3, 1) = 0 10 + 11 + // Connection should get accepted 12 + +0 < S 0:0(0) win 32972 <mss 1460,nop,wscale 7> 13 + +0 > S. 0:0(0) ack 1 <...> 14 + +0 < . 1:1(0) ack 1 win 257 15 + +0 accept(3, ..., ...) = 4 16 + 17 + +0 pipe([5, 6]) = 0 18 + +0 < U. 1:101(100) ack 1 win 257 urg 100 19 + +0 splice(4, NULL, 6, NULL, 99, 0) = 99 20 + +0 splice(4, NULL, 6, NULL, 1, 0) = 0
+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)
+20
tools/testing/selftests/net/packetdrill/tcp_tcp_info_tcp-info-last_data_recv.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test tcpi_last_data_recv for active session 3 + `./defaults.sh` 4 + 5 + // Create a socket and set it to non-blocking. 6 + +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 7 + +0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR) 8 + +0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 9 + 10 + +0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) 11 + +0 > S 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 12 + +.030 < S. 0:0(0) ack 1 win 10000 <mss 1000,sackOK,nop,nop,nop,wscale 8> 13 + +0 > . 1:1(0) ack 1 14 + 15 + +1 %{ assert 990 <= tcpi_last_data_recv <= 1010, tcpi_last_data_recv }% 16 + 17 + +0 < . 1:1001(1000) ack 1 win 300 18 + +0 > . 1:1(0) ack 1001 19 + 20 + +0 %{ assert tcpi_last_data_recv <= 10, tcpi_last_data_recv }%
+54
tools/testing/selftests/net/packetdrill/tcp_tcp_info_tcp-info-rwnd-limited.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test rwnd limited time in tcp_info for client side. 3 + 4 + `./defaults.sh` 5 + 6 + // Create a socket and set it to non-blocking. 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR) 9 + +0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 10 + 11 + +0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) 12 + +0 > S 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 13 + 14 + // Server advertises 0 receive window. 15 + +.01 < S. 0:0(0) ack 1 win 0 <mss 1000,nop,nop,sackOK> 16 + 17 + +0 > . 1:1(0) ack 1 18 + +0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 19 + +0 fcntl(3, F_SETFL, O_RDWR) = 0 // set back to blocking 20 + 21 + // Make sure that initial rwnd limited time is 0. 22 + +0 %{ assert tcpi_rwnd_limited == 0, tcpi_rwnd_limited }% 23 + 24 + // Receive window limited time starts here. 25 + +0 write(3, ..., 1000) = 1000 26 + 27 + // Check that rwnd limited time in tcp_info is around 0.1s. 28 + +.1 %{ assert 98000 <= tcpi_rwnd_limited <= 110000, tcpi_rwnd_limited }% 29 + 30 + // Server opens the receive window. 31 + +.1 < . 1:1(0) ack 1 win 2000 32 + 33 + // Check that rwnd limited time in tcp_info is around 0.2s. 34 + +0 %{ assert 198000 <= tcpi_rwnd_limited <= 210000, tcpi_rwnd_limited }% 35 + 36 + +0 > P. 1:1001(1000) ack 1 37 + 38 + // Server advertises a very small receive window. 39 + +.03 < . 1:1(0) ack 1001 win 10 40 + 41 + // Receive window limited time starts again. 42 + +0 write(3, ..., 1000) = 1000 43 + 44 + // Server opens the receive window again. 45 + +.1 < . 1:1(0) ack 1001 win 2000 46 + // Check that rwnd limited time in tcp_info is around 0.3s 47 + // and busy time is 0.3 + 0.03 (server opened small window temporarily). 48 + +0 %{ assert 298000 <= tcpi_rwnd_limited <= 310000, tcpi_rwnd_limited;\ 49 + assert 328000 <= tcpi_busy_time <= 340000, tcpi_busy_time;\ 50 + }% 51 + 52 + +0 > P. 1001:2001(1000) ack 1 53 + +.02 < . 1:1(0) ack 2001 win 2000 54 + +0 %{ assert 348000 <= tcpi_busy_time <= 360000, tcpi_busy_time }%
+38
tools/testing/selftests/net/packetdrill/tcp_tcp_info_tcp-info-sndbuf-limited.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test send-buffer-limited time in tcp_info for client side. 3 + `./defaults.sh` 4 + 5 + // Create a socket and set it to non-blocking. 6 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 7 + +0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR) 8 + +0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 9 + 10 + +0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) 11 + +0 > S 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 12 + +.01 < S. 0:0(0) ack 1 win 10000 <mss 1000,sackOK,nop,nop,nop,wscale 8> 13 + +0 > . 1:1(0) ack 1 14 + +0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 15 + +0 fcntl(3, F_SETFL, O_RDWR) = 0 // set back to blocking 16 + +0 setsockopt(3, SOL_SOCKET, SO_SNDBUF, [10000], 4) = 0 17 + +0 getsockopt(3, SOL_SOCKET, SO_SNDBUF, [20000], [4]) = 0 18 + 19 + +.09...0.14 write(3, ..., 150000) = 150000 20 + 21 + +.01 < . 1:1(0) ack 10001 win 10000 22 + 23 + +.01 < . 1:1(0) ack 30001 win 10000 24 + 25 + // cwnd goes from 40(60KB) to 80(120KB), and that we hit the tiny sndbuf limit 10KB 26 + +.01 < . 1:1(0) ack 70001 win 10000 27 + 28 + +.02 < . 1:1(0) ack 95001 win 10000 29 + +0 %{ assert 19000 <= tcpi_sndbuf_limited <= 21000, tcpi_sndbuf_limited; \ 30 + assert 49000 <= tcpi_busy_time <= 52000, tcpi_busy_time; \ 31 + assert 0 == tcpi_rwnd_limited, tcpi_rwnd_limited }% 32 + 33 + // This ack frees up enough buffer so we are no longer 34 + // buffer limited (socket flag SOCK_NOSPACE is cleared) 35 + +.02 < . 1:1(0) ack 150001 win 10000 36 + +0 %{ assert 19000 <= tcpi_sndbuf_limited <= 21000, tcpi_sndbuf_limited;\ 37 + assert 69000 <= tcpi_busy_time <= 73000, tcpi_busy_time;\ 38 + assert 0 == tcpi_rwnd_limited, tcpi_rwnd_limited }%
+92
tools/testing/selftests/net/packetdrill/tcp_timestamping_client-only-last-byte.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test that tx timestamping sends timestamps only for 3 + // the last byte of each sendmsg. 4 + `./defaults.sh 5 + ` 6 + 7 + // Create a socket and set it to non-blocking. 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 9 + +0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR) 10 + +0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 11 + 12 + // Establish connection and verify that there was no error. 13 + +0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) 14 + +0 > S 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 15 + +.01 < S. 0:0(0) ack 1 win 20000 <mss 1000,nop,nop,sackOK> 16 + +0 > . 1:1(0) ack 1 17 + +0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 18 + +0 fcntl(3, F_SETFL, O_RDWR) = 0 // set back to blocking 19 + 20 + +0 setsockopt(3, SOL_SOCKET, SO_TIMESTAMPING, 21 + [SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_SOFTWARE | 22 + SOF_TIMESTAMPING_TX_ACK | SOF_TIMESTAMPING_SOFTWARE | 23 + SOF_TIMESTAMPING_OPT_ID], 4) = 0 24 + 25 + +0 write(3, ..., 11000) = 11000 26 + +0 > P. 1:10001(10000) ack 1 27 + +.01 < . 1:1(0) ack 10001 win 4000 28 + +0 > P. 10001:11001(1000) ack 1 29 + +.01 < . 1:1(0) ack 11001 win 4000 30 + 31 + // Make sure that internal TCP timestamps are not overwritten and we have sane 32 + // RTT measurement. 33 + +0 %{ 34 + assert 5000 <= tcpi_rtt <= 20000, 'srtt=%d us' % tcpi_rtt 35 + }% 36 + 37 + // SCM_TSTAMP_SCHED for the last byte should be received almost immediately 38 + // once 10001 is acked at t=20ms. 39 + // setsockopt(..., [SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_OPT_ID], ...) 40 + // is called after when SYN is acked. So, we expect the last byte of the first 41 + // chunk to have a timestamp key of 10999 (i.e., 11000 - 1). 42 + +0 recvmsg(3, {msg_name(...)=..., 43 + msg_iov(1)=[{...,0}], 44 + msg_flags=MSG_ERRQUEUE|MSG_TRUNC, 45 + msg_control=[ 46 + {cmsg_level=SOL_SOCKET, 47 + cmsg_type=SCM_TIMESTAMPING, 48 + cmsg_data={scm_sec=0,scm_nsec=20000000}}, 49 + {cmsg_level=CMSG_LEVEL_IP, 50 + cmsg_type=CMSG_TYPE_RECVERR, 51 + cmsg_data={ee_errno=ENOMSG, 52 + ee_origin=SO_EE_ORIGIN_TIMESTAMPING, 53 + ee_type=0, 54 + ee_code=0, 55 + ee_info=SCM_TSTAMP_SCHED, 56 + ee_data=10999}} 57 + ]}, MSG_ERRQUEUE) = 0 58 + // SCM_TSTAMP_SND for the last byte should be received almost immediately 59 + // once 10001 is acked at t=20ms. 60 + +0 recvmsg(3, {msg_name(...)=..., 61 + msg_iov(1)=[{...,0}], 62 + msg_flags=MSG_ERRQUEUE|MSG_TRUNC, 63 + msg_control=[ 64 + {cmsg_level=SOL_SOCKET, 65 + cmsg_type=SCM_TIMESTAMPING, 66 + cmsg_data={scm_sec=0,scm_nsec=20000000}}, 67 + {cmsg_level=CMSG_LEVEL_IP, 68 + cmsg_type=CMSG_TYPE_RECVERR, 69 + cmsg_data={ee_errno=ENOMSG, 70 + ee_origin=SO_EE_ORIGIN_TIMESTAMPING, 71 + ee_type=0, 72 + ee_code=0, 73 + ee_info=SCM_TSTAMP_SND, 74 + ee_data=10999}} 75 + ]}, MSG_ERRQUEUE) = 0 76 + // SCM_TSTAMP_ACK for the last byte should be received at t=30ms. 77 + +0 recvmsg(3, {msg_name(...)=..., 78 + msg_iov(1)=[{...,0}], 79 + msg_flags=MSG_ERRQUEUE|MSG_TRUNC, 80 + msg_control=[ 81 + {cmsg_level=SOL_SOCKET, 82 + cmsg_type=SCM_TIMESTAMPING, 83 + cmsg_data={scm_sec=0,scm_nsec=30000000}}, 84 + {cmsg_level=CMSG_LEVEL_IP, 85 + cmsg_type=CMSG_TYPE_RECVERR, 86 + cmsg_data={ee_errno=ENOMSG, 87 + ee_origin=SO_EE_ORIGIN_TIMESTAMPING, 88 + ee_type=0, 89 + ee_code=0, 90 + ee_info=SCM_TSTAMP_ACK, 91 + ee_data=10999}} 92 + ]}, MSG_ERRQUEUE) = 0
+91
tools/testing/selftests/net/packetdrill/tcp_timestamping_partial.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test tx timestamping for partial writes (IPv4). 3 + `./defaults.sh 4 + ` 5 + 6 + // Create a socket and set it to non-blocking. 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR) 9 + +0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 10 + 11 + // Establish connection and verify that there was no error. 12 + +0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) 13 + +0 > S 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 14 + +.01 < S. 0:0(0) ack 1 win 2000 <mss 1000,sackOK,TS val 700 ecr 100,nop,wscale 7> 15 + +0 > . 1:1(0) ack 1 <nop,nop,TS val 200 ecr 700> 16 + +0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 17 + 18 + +0 setsockopt(3, SOL_SOCKET, SO_SNDBUF, [1000], 4) = 0 19 + +0 setsockopt(3, SOL_SOCKET, SO_TIMESTAMPING, 20 + [SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_SOFTWARE | 21 + SOF_TIMESTAMPING_TX_ACK | SOF_TIMESTAMPING_SOFTWARE | 22 + SOF_TIMESTAMPING_OPT_ID], 4) = 0 23 + 24 + // We have a partial write. 25 + +0 write(3, ..., 10000) = 2964 26 + +0 > . 1:989(988) ack 1 <nop,nop,TS val 110 ecr 700> 27 + +0 > P. 989:1977(988) ack 1 <nop,nop,TS val 110 ecr 700> 28 + +.01 < . 1:1(0) ack 1977 win 92 <nop,nop,TS val 800 ecr 200> 29 + +0 > P. 1977:2965(988) ack 1 <nop,nop,TS val 114 ecr 800> 30 + +.01 < . 1:1(0) ack 2965 win 92 <nop,nop,TS val 800 ecr 200> 31 + 32 + // Make sure that internal TCP timestamps are not overwritten and we have sane 33 + // RTT measurement. 34 + +0 %{ 35 + assert 5000 <= tcpi_rtt <= 20000, 'srtt=%d us' % tcpi_rtt 36 + }% 37 + 38 + // SCM_TSTAMP_SCHED for the first chunk should be received almost immediately 39 + // after the first ack at t=20ms. 40 + +0 recvmsg(3, {msg_name(...)=..., 41 + msg_iov(1)=[{...,0}], 42 + msg_flags=MSG_ERRQUEUE|MSG_TRUNC, 43 + msg_control=[ 44 + {cmsg_level=SOL_SOCKET, 45 + cmsg_type=SCM_TIMESTAMPING, 46 + cmsg_data={scm_sec=0,scm_nsec=20000000}}, 47 + {cmsg_level=CMSG_LEVEL_IP, 48 + cmsg_type=CMSG_TYPE_RECVERR, 49 + cmsg_data={ee_errno=ENOMSG, 50 + ee_origin=SO_EE_ORIGIN_TIMESTAMPING, 51 + ee_type=0, 52 + ee_code=0, 53 + ee_info=SCM_TSTAMP_SCHED, 54 + ee_data=2963}} 55 + ]}, MSG_ERRQUEUE) = 0 56 + // SCM_TSTAMP_SND for the first chunk should be received almost immediately 57 + // after the first ack at t=20ms. 58 + +0 recvmsg(3, {msg_name(...)=..., 59 + msg_iov(1)=[{...,0}], 60 + msg_flags=MSG_ERRQUEUE|MSG_TRUNC, 61 + msg_control=[ 62 + {cmsg_level=SOL_SOCKET, 63 + cmsg_type=SCM_TIMESTAMPING, 64 + cmsg_data={scm_sec=0,scm_nsec=20000000}}, 65 + {cmsg_level=CMSG_LEVEL_IP, 66 + cmsg_type=CMSG_TYPE_RECVERR, 67 + cmsg_data={ee_errno=ENOMSG, 68 + ee_origin=SO_EE_ORIGIN_TIMESTAMPING, 69 + ee_type=0, 70 + ee_code=0, 71 + ee_info=SCM_TSTAMP_SND, 72 + ee_data=2963}} 73 + ]}, MSG_ERRQUEUE) = 0 74 + // SCM_TSTAMP_ACK for the first chunk should be received after the last ack at 75 + // t=30ms. 76 + +0 recvmsg(3, {msg_name(...)=..., 77 + msg_iov(1)=[{...,0}], 78 + msg_flags=MSG_ERRQUEUE|MSG_TRUNC, 79 + msg_control=[ 80 + {cmsg_level=SOL_SOCKET, 81 + cmsg_type=SCM_TIMESTAMPING, 82 + cmsg_data={scm_sec=0,scm_nsec=30000000}}, 83 + {cmsg_level=CMSG_LEVEL_IP, 84 + cmsg_type=CMSG_TYPE_RECVERR, 85 + cmsg_data={ee_errno=ENOMSG, 86 + ee_origin=SO_EE_ORIGIN_TIMESTAMPING, 87 + ee_type=0, 88 + ee_code=0, 89 + ee_info=SCM_TSTAMP_ACK, 90 + ee_data=2963}} 91 + ]}, MSG_ERRQUEUE) = 0
+145
tools/testing/selftests/net/packetdrill/tcp_timestamping_server.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test tx timestamping for server-side (IPv4). 3 + `./defaults.sh 4 + ` 5 + 6 + // Initialize connection 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 + +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 + +.01 < . 1:1(0) ack 1 win 514 15 + 16 + +0 accept(3, ..., ...) = 4 17 + +0 setsockopt(4, SOL_SOCKET, SO_TIMESTAMPING, 18 + [SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_SOFTWARE | 19 + SOF_TIMESTAMPING_TX_ACK | SOF_TIMESTAMPING_SOFTWARE | 20 + SOF_TIMESTAMPING_OPT_ID], 4) = 0 21 + 22 + // Write two 2KB chunks. 23 + // setsockopt(..., [SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_OPT_ID], ...) 24 + // is called after when SYN is acked. So, we expect the last byte of the first 25 + // and the second chunks to have timestamp keys of 1999 (i.e., 2000 - 1) and 26 + // 3999 (i.e., 4000 - 1) respectively. 27 + +0 write(4, ..., 2000) = 2000 28 + +0 write(4, ..., 2000) = 2000 29 + +0 > P. 1:2001(2000) ack 1 30 + +0 > P. 2001:4001(2000) ack 1 31 + +.01 < . 1:1(0) ack 2001 win 514 32 + +.01 < . 1:1(0) ack 4001 win 514 33 + 34 + // Make sure that internal TCP timestamps are not overwritten and we have sane 35 + // RTT measurement. 36 + +0 %{ 37 + assert 5000 <= tcpi_rtt <= 20000, 'srtt=%d us' % tcpi_rtt 38 + }% 39 + 40 + // SCM_TSTAMP_SCHED for the first chunk should be received almost immediately 41 + // after write at t=10ms. 42 + +0 recvmsg(4, {msg_name(...)=..., 43 + msg_iov(1)=[{...,0}], 44 + msg_flags=MSG_ERRQUEUE|MSG_TRUNC, 45 + msg_control=[ 46 + {cmsg_level=SOL_SOCKET, 47 + cmsg_type=SCM_TIMESTAMPING, 48 + cmsg_data={scm_sec=0,scm_nsec=10000000}}, 49 + {cmsg_level=CMSG_LEVEL_IP, 50 + cmsg_type=CMSG_TYPE_RECVERR, 51 + cmsg_data={ee_errno=ENOMSG, 52 + ee_origin=SO_EE_ORIGIN_TIMESTAMPING, 53 + ee_type=0, 54 + ee_code=0, 55 + ee_info=SCM_TSTAMP_SCHED, 56 + ee_data=1999}} 57 + ]}, MSG_ERRQUEUE) = 0 58 + // SCM_TSTAMP_SND for the first chunk should be received almost immediately 59 + // after write at t=10ms. 60 + +0 recvmsg(4, {msg_name(...)=..., 61 + msg_iov(1)=[{...,0}], 62 + msg_flags=MSG_ERRQUEUE|MSG_TRUNC, 63 + msg_control=[ 64 + {cmsg_level=SOL_SOCKET, 65 + cmsg_type=SCM_TIMESTAMPING, 66 + cmsg_data={scm_sec=0,scm_nsec=10000000}}, 67 + {cmsg_level=CMSG_LEVEL_IP, 68 + cmsg_type=CMSG_TYPE_RECVERR, 69 + cmsg_data={ee_errno=ENOMSG, 70 + ee_origin=SO_EE_ORIGIN_TIMESTAMPING, 71 + ee_type=0, 72 + ee_code=0, 73 + ee_info=SCM_TSTAMP_SND, 74 + ee_data=1999}} 75 + ]}, MSG_ERRQUEUE) = 0 76 + // SCM_TSTAMP_SCHED for the second chunk should be received almost immediately 77 + // after that at t=10ms. 78 + +0 recvmsg(4, {msg_name(...)=..., 79 + msg_iov(1)=[{...,0}], 80 + msg_flags=MSG_ERRQUEUE|MSG_TRUNC, 81 + msg_control=[ 82 + {cmsg_level=SOL_SOCKET, 83 + cmsg_type=SCM_TIMESTAMPING, 84 + cmsg_data={scm_sec=0,scm_nsec=10000000}}, 85 + {cmsg_level=CMSG_LEVEL_IP, 86 + cmsg_type=CMSG_TYPE_RECVERR, 87 + cmsg_data={ee_errno=ENOMSG, 88 + ee_origin=SO_EE_ORIGIN_TIMESTAMPING, 89 + ee_type=0, 90 + ee_code=0, 91 + ee_info=SCM_TSTAMP_SCHED, 92 + ee_data=3999}} 93 + ]}, MSG_ERRQUEUE) = 0 94 + // SCM_TSTAMP_SND for the second chunk should be received almost immediately 95 + // after that at t=10ms. 96 + +0 recvmsg(4, {msg_name(...)=..., 97 + msg_iov(1)=[{...,0}], 98 + msg_flags=MSG_ERRQUEUE|MSG_TRUNC, 99 + msg_control=[ 100 + {cmsg_level=SOL_SOCKET, 101 + cmsg_type=SCM_TIMESTAMPING, 102 + cmsg_data={scm_sec=0,scm_nsec=10000000}}, 103 + {cmsg_level=CMSG_LEVEL_IP, 104 + cmsg_type=CMSG_TYPE_RECVERR, 105 + cmsg_data={ee_errno=ENOMSG, 106 + ee_origin=SO_EE_ORIGIN_TIMESTAMPING, 107 + ee_type=0, 108 + ee_code=0, 109 + ee_info=SCM_TSTAMP_SND, 110 + ee_data=3999}} 111 + ]}, MSG_ERRQUEUE) = 0 112 + // SCM_TSTAMP_ACK for the first chunk should be received at t=20ms. 113 + +0 recvmsg(4, {msg_name(...)=..., 114 + msg_iov(1)=[{...,0}], 115 + msg_flags=MSG_ERRQUEUE|MSG_TRUNC, 116 + msg_control=[ 117 + {cmsg_level=SOL_SOCKET, 118 + cmsg_type=SCM_TIMESTAMPING, 119 + cmsg_data={scm_sec=0,scm_nsec=20000000}}, 120 + {cmsg_level=CMSG_LEVEL_IP, 121 + cmsg_type=CMSG_TYPE_RECVERR, 122 + cmsg_data={ee_errno=ENOMSG, 123 + ee_origin=SO_EE_ORIGIN_TIMESTAMPING, 124 + ee_type=0, 125 + ee_code=0, 126 + ee_info=SCM_TSTAMP_ACK, 127 + ee_data=1999}} 128 + ]}, MSG_ERRQUEUE) = 0 129 + // SCM_TSTAMP_ACK for the second chunk should be received at t=30ms. 130 + +0 recvmsg(4, {msg_name(...)=..., 131 + msg_iov(1)=[{...,0}], 132 + msg_flags=MSG_ERRQUEUE|MSG_TRUNC, 133 + msg_control=[ 134 + {cmsg_level=SOL_SOCKET, 135 + cmsg_type=SCM_TIMESTAMPING, 136 + cmsg_data={scm_sec=0,scm_nsec=30000000}}, 137 + {cmsg_level=CMSG_LEVEL_IP, 138 + cmsg_type=CMSG_TYPE_RECVERR, 139 + cmsg_data={ee_errno=ENOMSG, 140 + ee_origin=SO_EE_ORIGIN_TIMESTAMPING, 141 + ee_type=0, 142 + ee_code=0, 143 + ee_info=SCM_TSTAMP_ACK, 144 + ee_data=3999}} 145 + ]}, MSG_ERRQUEUE) = 0
+23
tools/testing/selftests/net/packetdrill/tcp_ts_recent_fin_tsval.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test that we send FIN packet with correct TSval 3 + --tcp_ts_tick_usecs=1000 4 + --tolerance_usecs=7000 5 + 6 + `./defaults.sh` 7 + 8 + // Create a socket. 9 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 10 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 11 + 12 + +0 bind(3, ..., ...) = 0 13 + +0 listen(3, 1) = 0 14 + 15 + // Establish a connection. 16 + +0 < S 0:0(0) win 20000 <mss 1000,sackOK,TS val 100 ecr 0> 17 + +0 > S. 0:0(0) ack 1 <mss 1460,sackOK,TS val 100 ecr 100> 18 + +.1 < . 1:1(0) ack 1 win 20000 <nop,nop,TS val 200 ecr 100> 19 + +0 accept(3, ..., ...) = 4 20 + 21 + +1 close(4) = 0 22 + // Check that FIN TSval is updated properly, one second has passed since last sent packet. 23 + +0 > F. 1:1(0) ack 1 <nop,nop,TS val 1200 ecr 200>
+25
tools/testing/selftests/net/packetdrill/tcp_ts_recent_invalid_ack.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test that we reject TS val updates on a packet with invalid ACK sequence 3 + 4 + `./defaults.sh 5 + ` 6 + 7 + // Create a socket. 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 9 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 10 + 11 + +0 bind(3, ..., ...) = 0 12 + +0 listen(3, 1) = 0 13 + 14 + // Establish a connection. 15 + +.1 < S 0:0(0) win 20000 <mss 1000,sackOK,TS val 100 ecr 0> 16 + +0 > S. 0:0(0) ack 1 <mss 1460,sackOK,TS val 100 ecr 100> 17 + +.1 < . 1:1(0) ack 1 win 20000 <nop,nop,TS val 200 ecr 100> 18 + +0 accept(3, ..., ...) = 4 19 + 20 + // bad packet with high tsval (its ACK sequence is above our sndnxt) 21 + +0 < F. 1:1(0) ack 9999 win 20000 <nop,nop,TS val 200000 ecr 100> 22 + 23 + 24 + +0 < . 1:1001(1000) ack 1 win 20000 <nop,nop,TS val 201 ecr 100> 25 + +0 > . 1:1(0) ack 1001 <nop,nop,TS val 200 ecr 201>
+25
tools/testing/selftests/net/packetdrill/tcp_ts_recent_reset_tsval.pkt
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Test that we send RST packet with correct TSval 3 + --tcp_ts_tick_usecs=1000 4 + 5 + `./defaults.sh` 6 + 7 + // Create a socket. 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 9 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 10 + 11 + +0 bind(3, ..., ...) = 0 12 + +0 listen(3, 1) = 0 13 + 14 + // Establish a connection. 15 + +0 < S 0:0(0) win 20000 <mss 1000,sackOK,TS val 100 ecr 0> 16 + +0 > S. 0:0(0) ack 1 <mss 1460,sackOK,TS val 100 ecr 100> 17 + +.1 < . 1:1(0) ack 1 win 20000 <nop,nop,TS val 200 ecr 100> 18 + +0 accept(3, ..., ...) = 4 19 + 20 + +0 < . 1:1001(1000) ack 1 win 20000 <nop,nop,TS val 201 ecr 100> 21 + +0 > . 1:1(0) ack 1001 <nop,nop,TS val 200 ecr 201> 22 + 23 + +1 close(4) = 0 24 + // Check that RST TSval is updated properly, one second has passed since last sent packet. 25 + +0 > R. 1:1(0) ack 1001 <nop,nop,TS val 1200 ecr 201>
+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