mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
selftests/net: packetdrill: import tcp/fast_recovery, tcp/nagle, tcp/timestamping
Use the standard import and testing method, as described in the import of tcp/ecn , 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-3-sohamch.kernel@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
88395c071f
commit
eab35989cc
10 changed files with 683 additions and 0 deletions
|
@ -0,0 +1,72 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Test PRR-slowstart implementation.
|
||||
// In this variant we test a simple case where in-flight == ssthresh
|
||||
// all the way through recovery, so during fast recovery we send one segment
|
||||
// for each segment SACKed/ACKed.
|
||||
|
||||
// Set up config.
|
||||
`./defaults.sh`
|
||||
|
||||
// Establish a connection.
|
||||
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
|
||||
+.1 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7>
|
||||
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8>
|
||||
// RTT 100ms
|
||||
+.1 < . 1:1(0) ack 1 win 320
|
||||
+0 accept(3, ..., ...) = 4
|
||||
|
||||
// Send 10 data segments.
|
||||
+0 write(4, ..., 10000) = 10000
|
||||
+0 > P. 1:10001(10000) ack 1
|
||||
|
||||
// Lost packet 1:1001.
|
||||
+.11 < . 1:1(0) ack 1 win 320 <sack 1001:2001,nop,nop>
|
||||
+.01 < . 1:1(0) ack 1 win 320 <sack 1001:3001,nop,nop>
|
||||
+.01 < . 1:1(0) ack 1 win 320 <sack 1001:4001,nop,nop>
|
||||
// Enter fast recovery.
|
||||
+0 > . 1:1001(1000) ack 1
|
||||
+.01 %{
|
||||
assert tcpi_ca_state == TCP_CA_Recovery, tcpi_ca_state
|
||||
assert tcpi_snd_cwnd == 7, tcpi_snd_cwnd
|
||||
assert tcpi_snd_ssthresh == 7, tcpi_snd_ssthresh
|
||||
}%
|
||||
|
||||
// Write some more, which we will send 1 MSS at a time,
|
||||
// as in-flight segments are SACKed or ACKed.
|
||||
+.01 write(4, ..., 7000) = 7000
|
||||
|
||||
+.01 < . 1:1(0) ack 1 win 320 <sack 1001:5001,nop,nop>
|
||||
+0 > . 10001:11001(1000) ack 1
|
||||
|
||||
+.01 < . 1:1(0) ack 1 win 320 <sack 1001:6001,nop,nop>
|
||||
+0 > . 11001:12001(1000) ack 1
|
||||
|
||||
+.01 < . 1:1(0) ack 1 win 320 <sack 1001:7001,nop,nop>
|
||||
+0 > . 12001:13001(1000) ack 1
|
||||
|
||||
+.01 < . 1:1(0) ack 1 win 320 <sack 1001:8001,nop,nop>
|
||||
+0 > . 13001:14001(1000) ack 1
|
||||
|
||||
+.01 < . 1:1(0) ack 1 win 320 <sack 1001:9001,nop,nop>
|
||||
+0 > . 14001:15001(1000) ack 1
|
||||
|
||||
+.01 < . 1:1(0) ack 1 win 320 <sack 1001:10001,nop,nop>
|
||||
+0 > . 15001:16001(1000) ack 1
|
||||
|
||||
+.02 < . 1:1(0) ack 10001 win 320
|
||||
+0 > P. 16001:17001(1000) ack 1
|
||||
// Leave fast recovery.
|
||||
+.01 %{
|
||||
assert tcpi_ca_state == TCP_CA_Open, tcpi_ca_state
|
||||
assert tcpi_snd_cwnd == 7, tcpi_snd_cwnd
|
||||
assert tcpi_snd_ssthresh == 7, tcpi_snd_ssthresh
|
||||
}%
|
||||
|
||||
+.03 < . 1:1(0) ack 12001 win 320
|
||||
+.02 < . 1:1(0) ack 14001 win 320
|
||||
+.02 < . 1:1(0) ack 16001 win 320
|
||||
+.02 < . 1:1(0) ack 17001 win 320
|
|
@ -0,0 +1,50 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Test PRR-slowstart implementation. The sender sends 20 packets. Packet
|
||||
// 1 to 4, and 11 to 16 are dropped.
|
||||
`./defaults.sh`
|
||||
|
||||
// Establish a connection.
|
||||
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
|
||||
+0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7>
|
||||
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8>
|
||||
|
||||
+.01 < . 1:1(0) ack 1 win 320
|
||||
+0 accept(3, ..., ...) = 4
|
||||
|
||||
// Write 20 data segments.
|
||||
+0 write(4, ..., 20000) = 20000
|
||||
+0 > P. 1:10001(10000) ack 1
|
||||
|
||||
// Receive first DUPACK, entering PRR part
|
||||
+.01 < . 1:1(0) ack 1 win 320 <sack 4001:5001,nop,nop>
|
||||
+0 > . 10001:11001(1000) ack 1
|
||||
+.002 < . 1:1(0) ack 1 win 320 <sack 4001:6001,nop,nop>
|
||||
+0 > . 11001:12001(1000) ack 1
|
||||
+.002 < . 1:1(0) ack 1 win 320 <sack 4001:7001,nop,nop>
|
||||
+0 > . 1:1001(1000) ack 1
|
||||
+.002 < . 1:1(0) ack 1 win 320 <sack 4001:8001,nop,nop>
|
||||
+0 > . 1001:2001(1000) ack 1
|
||||
+.002 < . 1:1(0) ack 1 win 320 <sack 4001:9001,nop,nop>
|
||||
+0 > . 2001:3001(1000) ack 1
|
||||
+.002 < . 1:1(0) ack 1 win 320 <sack 4001:10001,nop,nop>
|
||||
+0 > . 3001:4001(1000) ack 1
|
||||
// Enter PRR CRB
|
||||
+.002 < . 1:1(0) ack 1 win 320 <sack 4001:11001,nop,nop>
|
||||
+0 > . 12001:13001(1000) ack 1
|
||||
+.002 < . 1:1(0) ack 1 win 320 <sack 4001:12001,nop,nop>
|
||||
+0 > . 13001:14001(1000) ack 1
|
||||
// Enter PRR slow start
|
||||
+.01 < . 1:1(0) ack 1001 win 320 <sack 4001:12001,nop,nop>
|
||||
+0 > P. 14001:16001(2000) ack 1
|
||||
+.002 < . 1:1(0) ack 1001 win 320 <sack 2001:12001,nop,nop>
|
||||
+0 > . 1001:2001(1000) ack 1
|
||||
+0 > . 16001:17001(1000) ack 1
|
||||
// inflight reaches ssthresh, goes into packet conservation mode
|
||||
+.002 < . 1:1(0) ack 1001 win 320 <sack 2001:13001,nop,nop>
|
||||
+0 > . 17001:18001(1000) ack 1
|
||||
+.002 < . 1:1(0) ack 1001 win 320 <sack 2001:14001,nop,nop>
|
||||
+0 > . 18001:19001(1000) ack 1
|
|
@ -0,0 +1,43 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Test PRR-slowstart implementation. The sender sends 20 packets. Packet
|
||||
// 1 to 4 are lost. The sender writes another 10 packets.
|
||||
`./defaults.sh`
|
||||
|
||||
// Establish a connection.
|
||||
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
|
||||
+0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7>
|
||||
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8>
|
||||
|
||||
+.01 < . 1:1(0) ack 1 win 320
|
||||
+0 accept(3, ..., ...) = 4
|
||||
|
||||
// Send 20 data segments.
|
||||
+0 write(4, ..., 10000) = 10000
|
||||
+0 > P. 1:10001(10000) ack 1
|
||||
|
||||
// Lost packet 1,2,3,4
|
||||
+.01 < . 1:1(0) ack 1 win 320 <sack 4001:5001,nop,nop>
|
||||
+.002 < . 1:1(0) ack 1 win 320 <sack 4001:6001,nop,nop>
|
||||
+0 < . 1:1(0) ack 1 win 320 <sack 4001:7001,nop,nop>
|
||||
+0 > . 1:1001(1000) ack 1
|
||||
+0 < . 1:1(0) ack 1 win 320 <sack 4001:8001,nop,nop>
|
||||
+0 > . 1001:2001(1000) ack 1
|
||||
+0 < . 1:1(0) ack 1 win 320 <sack 4001:9001,nop,nop>
|
||||
+0 > . 2001:3001(1000) ack 1
|
||||
+0 < . 1:1(0) ack 1 win 320 <sack 4001:10001,nop,nop>
|
||||
+0 > . 3001:4001(1000) ack 1
|
||||
|
||||
// Receiver ACKs all data.
|
||||
+.01 < . 1:1(0) ack 1001 win 320 <sack 4001:10001,nop,nop>
|
||||
+0 < . 1:1(0) ack 2001 win 320 <sack 4001:10001,nop,nop>
|
||||
+0 < . 1:1(0) ack 3001 win 320 <sack 4001:10001,nop,nop>
|
||||
+0 < . 1:1(0) ack 10001 win 320
|
||||
|
||||
// Writes another 10 packets, which the ssthresh*mss amount
|
||||
// should be sent right away
|
||||
+.01 write(4, ..., 10000) = 10000
|
||||
+0 > . 10001:17001(7000) ack 1
|
|
@ -0,0 +1,41 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Test PRR-slowstart implementation.
|
||||
// In this variant we verify that the sender uses SACK info on an ACK
|
||||
// below snd_una.
|
||||
|
||||
// Set up config.
|
||||
`./defaults.sh`
|
||||
|
||||
// Establish a connection.
|
||||
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
|
||||
+0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 8>
|
||||
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8>
|
||||
// RTT 10ms
|
||||
+.01 < . 1:1(0) ack 1 win 320
|
||||
+0 accept(3, ..., ...) = 4
|
||||
|
||||
// Send 10 data segments.
|
||||
+0 write(4, ..., 10000) = 10000
|
||||
+0 > P. 1:10001(10000) ack 1
|
||||
|
||||
// Lost packet 1:1001,4001:5001,7001:8001.
|
||||
+.01 < . 1:1(0) ack 1 win 320 <sack 1001:2001,nop,nop>
|
||||
+0 < . 1:1(0) ack 1 win 320 <sack 1001:3001,nop,nop>
|
||||
+0 < . 1:1(0) ack 1 win 320 <sack 1001:3001 8001:9001,nop,nop>
|
||||
+0 > . 1:1001(1000) ack 1
|
||||
|
||||
+.012 < . 1:1(0) ack 4001 win 320 <sack 8001:9001,nop,nop>
|
||||
+0 > . 4001:7001(3000) ack 1
|
||||
|
||||
+0 write(4, ..., 10000) = 10000
|
||||
|
||||
// The following ACK was reordered - delayed so that it arrives with
|
||||
// an ACK field below snd_una. Here we check that the newly-SACKed
|
||||
// 2MSS at 5001:7001 cause us to send out 2 more MSS.
|
||||
+.002 < . 1:1(0) ack 3001 win 320 <sack 5001:7001,nop,nop>
|
||||
+0 > . 7001:8001(1000) ack 1
|
||||
+0 > . 10001:11001(1000) ack 1
|
|
@ -0,0 +1,40 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// This is a test inspired by an Android client app using SSL. This
|
||||
// test verifies using TCP_NODELAY would save application latency
|
||||
// (Perhaps even better with TCP_NAGLE).
|
||||
//
|
||||
`./defaults.sh
|
||||
ethtool -K tun0 tso off gso off
|
||||
./set_sysctls.py /proc/sys/net/ipv4/tcp_timestamps=0`
|
||||
|
||||
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4
|
||||
+0 fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0
|
||||
+0 setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0
|
||||
|
||||
+0 connect(4, ..., ...) = -1 EINPROGRESS (Operation now in progress)
|
||||
+0 > S 0:0(0) <mss 1460,nop,nop,sackOK,nop,wscale 8>
|
||||
+.1 < S. 0:0(0) ack 1 win 5792 <mss 974,nop,nop,sackOK,nop,wscale 7>
|
||||
+0 > . 1:1(0) ack 1
|
||||
|
||||
// SSL handshake (resumed session)
|
||||
+0 write(4, ..., 517) = 517
|
||||
+0 > P. 1:518(517) ack 1
|
||||
+.1 < . 1:1(0) ack 518 win 229
|
||||
|
||||
+0 < P. 1:144(143) ack 1 win 229
|
||||
+0 > . 518:518(0) ack 144
|
||||
+0 read(4, ..., 1000) = 143
|
||||
|
||||
// Application POST header (51B) and body (2002B)
|
||||
+0 write(4, ..., 51) = 51
|
||||
+0 > P. 518:569(51) ack 144
|
||||
+.03 write(4, ..., 2002) = 2002
|
||||
+0 > . 569:1543(974) ack 144
|
||||
+0 > P. 1543:2517(974) ack 144
|
||||
// Without disabling Nagle, this packet will not happen until the remote ACK.
|
||||
+0 > P. 2517:2571(54) ack 144
|
||||
|
||||
+.1 < . 1:1(0) ack 2571 win 229
|
||||
|
||||
// Reset sysctls
|
||||
`/tmp/sysctl_restore_${PPID}.sh`
|
|
@ -0,0 +1,66 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Test the MSG_MORE flag will correctly corks the tiny writes
|
||||
`./defaults.sh`
|
||||
|
||||
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
|
||||
+0 < S 0:0(0) win 32792 <mss 1000,nop,wscale 7>
|
||||
+0 > S. 0:0(0) ack 1 <mss 1460,nop,wscale 8>
|
||||
+.01 < . 1:1(0) ack 1 win 257
|
||||
+0 accept(3, ..., ...) = 4
|
||||
// Disable Nagle by default on this socket.
|
||||
+0 setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0
|
||||
|
||||
// Test the basic case: MSG_MORE overwrites TCP_NODELAY and enables Nagle.
|
||||
+0 sendmsg(4, {msg_name(...)=...,
|
||||
msg_iov(1)=[{..., 40}], msg_flags=0}, MSG_MORE) = 40
|
||||
+.21~+.215 > P. 1:41(40) ack 1
|
||||
+.01 < . 1:1(0) ack 41 win 257
|
||||
|
||||
// Test unsetting MSG_MORE releases the packet
|
||||
+0 sendmsg(4, {msg_name(...)=...,
|
||||
msg_iov(1)=[{..., 100}], msg_flags=0}, MSG_MORE) = 100
|
||||
+.005 sendmsg(4, {msg_name(...)=...,
|
||||
msg_iov(1)=[{..., 160}], msg_flags=0}, MSG_MORE) = 160
|
||||
+.01 sendmsg(4, {msg_name(...)=...,
|
||||
msg_iov(3)=[{..., 100}, {..., 200}, {..., 195}],
|
||||
msg_flags=0}, MSG_MORE) = 495
|
||||
+.008 sendmsg(4, {msg_name(...)=...,
|
||||
msg_iov(1)=[{..., 5}], msg_flags=0}, 0) = 5
|
||||
+0 > P. 41:801(760) ack 1
|
||||
+.02 < . 1:1(0) ack 801 win 257
|
||||
|
||||
|
||||
// Test >MSS write will unleash MSS packets but hold on the remaining data.
|
||||
+.1 sendmsg(4, {msg_name(...)=...,
|
||||
msg_iov(1)=[{..., 3100}], msg_flags=0}, MSG_MORE) = 3100
|
||||
+0 > . 801:3801(3000) ack 1
|
||||
+.003 sendmsg(4, {msg_name(...)=...,
|
||||
msg_iov(1)=[{..., 50}], msg_flags=0}, MSG_MORE) = 50
|
||||
|
||||
+.01 < . 1:1(0) ack 2801 win 257
|
||||
// Err... we relase the remaining right after the ACK? note that PUSH is reset
|
||||
+0 > . 3801:3951(150) ack 1
|
||||
|
||||
// Test we'll hold on the subsequent writes when inflight (3801:3951) > 0
|
||||
+.001 sendmsg(4, {msg_name(...)=...,
|
||||
msg_iov(1)=[{..., 1}], msg_flags=0}, MSG_MORE) = 1
|
||||
+.002 sendmsg(4, {msg_name(...)=...,
|
||||
msg_iov(1)=[{..., 2}], msg_flags=0}, MSG_MORE) = 2
|
||||
+.003 sendmsg(4, {msg_name(...)=...,
|
||||
msg_iov(1)=[{..., 3}], msg_flags=0}, MSG_MORE) = 3
|
||||
+.004 sendmsg(4, {msg_name(...)=...,
|
||||
msg_iov(1)=[{..., 4}], msg_flags=0}, MSG_MORE) = 4
|
||||
+.02 < . 1:1(0) ack 3951 win 257
|
||||
+0 > . 3951:3961(10) ack 1
|
||||
+.02 < . 1:1(0) ack 3961 win 257
|
||||
|
||||
|
||||
// Test the case a MSG_MORE send followed by a write flushes the data
|
||||
+0 sendmsg(4, {msg_name(...)=...,
|
||||
msg_iov(1)=[{..., 20}], msg_flags=0}, MSG_MORE) = 20
|
||||
+.05 write(4, ..., 20) = 20
|
||||
+0 > P. 3961:4001(40) ack 1
|
|
@ -0,0 +1,43 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Test TCP_CORK and TCP_NODELAY sockopt behavior
|
||||
`./defaults.sh`
|
||||
|
||||
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
|
||||
+0 < S 0:0(0) win 32792 <mss 1000,nop,wscale 7>
|
||||
+0 > S. 0:0(0) ack 1 <mss 1460,nop,wscale 8>
|
||||
+.01 < . 1:1(0) ack 1 win 257
|
||||
+0 accept(3, ..., ...) = 4
|
||||
// Set TCP_CORK sockopt to hold small packets
|
||||
+0 setsockopt(4, SOL_TCP, TCP_CORK, [1], 4) = 0
|
||||
|
||||
+0 write(4, ..., 40) = 40
|
||||
+.05 write(4, ..., 40) = 40
|
||||
|
||||
// Unset TCP_CORK should push pending bytes out
|
||||
+.01 setsockopt(4, SOL_TCP, TCP_CORK, [0], 4) = 0
|
||||
+0 > P. 1:81(80) ack 1
|
||||
+.01 < . 1:1(0) ack 81 win 257
|
||||
|
||||
// Set TCP_CORK sockopt to hold small packets
|
||||
+0 setsockopt(4, SOL_TCP, TCP_CORK, [1], 4) = 0
|
||||
|
||||
+0 write(4, ..., 40) = 40
|
||||
+.05 write(4, ..., 40) = 40
|
||||
|
||||
// Set TCP_NODELAY sockopt should push pending bytes out
|
||||
+0 setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0
|
||||
+0 > P. 81:161(80) ack 1
|
||||
+.01 < . 1:1(0) ack 161 win 257
|
||||
|
||||
// Set MSG_MORE to hold small packets
|
||||
+0 send(4, ..., 40, MSG_MORE) = 40
|
||||
+.05 send(4, ..., 40, MSG_MORE) = 40
|
||||
|
||||
// Set TCP_NODELAY sockopt should push pending bytes out
|
||||
+.01 setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0
|
||||
+0 > . 161:241(80) ack 1
|
||||
+.01 < . 1:1(0) ack 241 win 257
|
|
@ -0,0 +1,92 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Test that tx timestamping sends timestamps only for
|
||||
// the last byte of each sendmsg.
|
||||
`./defaults.sh
|
||||
`
|
||||
|
||||
// Create a socket and set it to non-blocking.
|
||||
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
|
||||
+0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
|
||||
+0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
|
||||
|
||||
// Establish connection and verify that there was no error.
|
||||
+0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)
|
||||
+0 > S 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8>
|
||||
+.01 < S. 0:0(0) ack 1 win 20000 <mss 1000,nop,nop,sackOK>
|
||||
+0 > . 1:1(0) ack 1
|
||||
+0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
|
||||
+0 fcntl(3, F_SETFL, O_RDWR) = 0 // set back to blocking
|
||||
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_TIMESTAMPING,
|
||||
[SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_SOFTWARE |
|
||||
SOF_TIMESTAMPING_TX_ACK | SOF_TIMESTAMPING_SOFTWARE |
|
||||
SOF_TIMESTAMPING_OPT_ID], 4) = 0
|
||||
|
||||
+0 write(3, ..., 11000) = 11000
|
||||
+0 > P. 1:10001(10000) ack 1
|
||||
+.01 < . 1:1(0) ack 10001 win 4000
|
||||
+0 > P. 10001:11001(1000) ack 1
|
||||
+.01 < . 1:1(0) ack 11001 win 4000
|
||||
|
||||
// Make sure that internal TCP timestamps are not overwritten and we have sane
|
||||
// RTT measurement.
|
||||
+0 %{
|
||||
assert 5000 <= tcpi_rtt <= 20000, 'srtt=%d us' % tcpi_rtt
|
||||
}%
|
||||
|
||||
// SCM_TSTAMP_SCHED for the last byte should be received almost immediately
|
||||
// once 10001 is acked at t=20ms.
|
||||
// setsockopt(..., [SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_OPT_ID], ...)
|
||||
// is called after when SYN is acked. So, we expect the last byte of the first
|
||||
// chunk to have a timestamp key of 10999 (i.e., 11000 - 1).
|
||||
+0 recvmsg(3, {msg_name(...)=...,
|
||||
msg_iov(1)=[{...,0}],
|
||||
msg_flags=MSG_ERRQUEUE|MSG_TRUNC,
|
||||
msg_control=[
|
||||
{cmsg_level=SOL_SOCKET,
|
||||
cmsg_type=SCM_TIMESTAMPING,
|
||||
cmsg_data={scm_sec=0,scm_nsec=20000000}},
|
||||
{cmsg_level=CMSG_LEVEL_IP,
|
||||
cmsg_type=CMSG_TYPE_RECVERR,
|
||||
cmsg_data={ee_errno=ENOMSG,
|
||||
ee_origin=SO_EE_ORIGIN_TIMESTAMPING,
|
||||
ee_type=0,
|
||||
ee_code=0,
|
||||
ee_info=SCM_TSTAMP_SCHED,
|
||||
ee_data=10999}}
|
||||
]}, MSG_ERRQUEUE) = 0
|
||||
// SCM_TSTAMP_SND for the last byte should be received almost immediately
|
||||
// once 10001 is acked at t=20ms.
|
||||
+0 recvmsg(3, {msg_name(...)=...,
|
||||
msg_iov(1)=[{...,0}],
|
||||
msg_flags=MSG_ERRQUEUE|MSG_TRUNC,
|
||||
msg_control=[
|
||||
{cmsg_level=SOL_SOCKET,
|
||||
cmsg_type=SCM_TIMESTAMPING,
|
||||
cmsg_data={scm_sec=0,scm_nsec=20000000}},
|
||||
{cmsg_level=CMSG_LEVEL_IP,
|
||||
cmsg_type=CMSG_TYPE_RECVERR,
|
||||
cmsg_data={ee_errno=ENOMSG,
|
||||
ee_origin=SO_EE_ORIGIN_TIMESTAMPING,
|
||||
ee_type=0,
|
||||
ee_code=0,
|
||||
ee_info=SCM_TSTAMP_SND,
|
||||
ee_data=10999}}
|
||||
]}, MSG_ERRQUEUE) = 0
|
||||
// SCM_TSTAMP_ACK for the last byte should be received at t=30ms.
|
||||
+0 recvmsg(3, {msg_name(...)=...,
|
||||
msg_iov(1)=[{...,0}],
|
||||
msg_flags=MSG_ERRQUEUE|MSG_TRUNC,
|
||||
msg_control=[
|
||||
{cmsg_level=SOL_SOCKET,
|
||||
cmsg_type=SCM_TIMESTAMPING,
|
||||
cmsg_data={scm_sec=0,scm_nsec=30000000}},
|
||||
{cmsg_level=CMSG_LEVEL_IP,
|
||||
cmsg_type=CMSG_TYPE_RECVERR,
|
||||
cmsg_data={ee_errno=ENOMSG,
|
||||
ee_origin=SO_EE_ORIGIN_TIMESTAMPING,
|
||||
ee_type=0,
|
||||
ee_code=0,
|
||||
ee_info=SCM_TSTAMP_ACK,
|
||||
ee_data=10999}}
|
||||
]}, MSG_ERRQUEUE) = 0
|
|
@ -0,0 +1,91 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Test tx timestamping for partial writes (IPv4).
|
||||
`./defaults.sh
|
||||
`
|
||||
|
||||
// Create a socket and set it to non-blocking.
|
||||
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
|
||||
+0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
|
||||
+0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
|
||||
|
||||
// Establish connection and verify that there was no error.
|
||||
+0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)
|
||||
+0 > S 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8>
|
||||
+.01 < S. 0:0(0) ack 1 win 2000 <mss 1000,sackOK,TS val 700 ecr 100,nop,wscale 7>
|
||||
+0 > . 1:1(0) ack 1 <nop,nop,TS val 200 ecr 700>
|
||||
+0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
|
||||
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_SNDBUF, [1000], 4) = 0
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_TIMESTAMPING,
|
||||
[SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_SOFTWARE |
|
||||
SOF_TIMESTAMPING_TX_ACK | SOF_TIMESTAMPING_SOFTWARE |
|
||||
SOF_TIMESTAMPING_OPT_ID], 4) = 0
|
||||
|
||||
// We have a partial write.
|
||||
+0 write(3, ..., 10000) = 2964
|
||||
+0 > . 1:989(988) ack 1 <nop,nop,TS val 110 ecr 700>
|
||||
+0 > P. 989:1977(988) ack 1 <nop,nop,TS val 110 ecr 700>
|
||||
+.01 < . 1:1(0) ack 1977 win 92 <nop,nop,TS val 800 ecr 200>
|
||||
+0 > P. 1977:2965(988) ack 1 <nop,nop,TS val 114 ecr 800>
|
||||
+.01 < . 1:1(0) ack 2965 win 92 <nop,nop,TS val 800 ecr 200>
|
||||
|
||||
// Make sure that internal TCP timestamps are not overwritten and we have sane
|
||||
// RTT measurement.
|
||||
+0 %{
|
||||
assert 5000 <= tcpi_rtt <= 20000, 'srtt=%d us' % tcpi_rtt
|
||||
}%
|
||||
|
||||
// SCM_TSTAMP_SCHED for the first chunk should be received almost immediately
|
||||
// after the first ack at t=20ms.
|
||||
+0 recvmsg(3, {msg_name(...)=...,
|
||||
msg_iov(1)=[{...,0}],
|
||||
msg_flags=MSG_ERRQUEUE|MSG_TRUNC,
|
||||
msg_control=[
|
||||
{cmsg_level=SOL_SOCKET,
|
||||
cmsg_type=SCM_TIMESTAMPING,
|
||||
cmsg_data={scm_sec=0,scm_nsec=20000000}},
|
||||
{cmsg_level=CMSG_LEVEL_IP,
|
||||
cmsg_type=CMSG_TYPE_RECVERR,
|
||||
cmsg_data={ee_errno=ENOMSG,
|
||||
ee_origin=SO_EE_ORIGIN_TIMESTAMPING,
|
||||
ee_type=0,
|
||||
ee_code=0,
|
||||
ee_info=SCM_TSTAMP_SCHED,
|
||||
ee_data=2963}}
|
||||
]}, MSG_ERRQUEUE) = 0
|
||||
// SCM_TSTAMP_SND for the first chunk should be received almost immediately
|
||||
// after the first ack at t=20ms.
|
||||
+0 recvmsg(3, {msg_name(...)=...,
|
||||
msg_iov(1)=[{...,0}],
|
||||
msg_flags=MSG_ERRQUEUE|MSG_TRUNC,
|
||||
msg_control=[
|
||||
{cmsg_level=SOL_SOCKET,
|
||||
cmsg_type=SCM_TIMESTAMPING,
|
||||
cmsg_data={scm_sec=0,scm_nsec=20000000}},
|
||||
{cmsg_level=CMSG_LEVEL_IP,
|
||||
cmsg_type=CMSG_TYPE_RECVERR,
|
||||
cmsg_data={ee_errno=ENOMSG,
|
||||
ee_origin=SO_EE_ORIGIN_TIMESTAMPING,
|
||||
ee_type=0,
|
||||
ee_code=0,
|
||||
ee_info=SCM_TSTAMP_SND,
|
||||
ee_data=2963}}
|
||||
]}, MSG_ERRQUEUE) = 0
|
||||
// SCM_TSTAMP_ACK for the first chunk should be received after the last ack at
|
||||
// t=30ms.
|
||||
+0 recvmsg(3, {msg_name(...)=...,
|
||||
msg_iov(1)=[{...,0}],
|
||||
msg_flags=MSG_ERRQUEUE|MSG_TRUNC,
|
||||
msg_control=[
|
||||
{cmsg_level=SOL_SOCKET,
|
||||
cmsg_type=SCM_TIMESTAMPING,
|
||||
cmsg_data={scm_sec=0,scm_nsec=30000000}},
|
||||
{cmsg_level=CMSG_LEVEL_IP,
|
||||
cmsg_type=CMSG_TYPE_RECVERR,
|
||||
cmsg_data={ee_errno=ENOMSG,
|
||||
ee_origin=SO_EE_ORIGIN_TIMESTAMPING,
|
||||
ee_type=0,
|
||||
ee_code=0,
|
||||
ee_info=SCM_TSTAMP_ACK,
|
||||
ee_data=2963}}
|
||||
]}, MSG_ERRQUEUE) = 0
|
|
@ -0,0 +1,145 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Test tx timestamping for server-side (IPv4).
|
||||
`./defaults.sh
|
||||
`
|
||||
|
||||
// Initialize connection
|
||||
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
|
||||
+0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 10>
|
||||
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8>
|
||||
+.01 < . 1:1(0) ack 1 win 514
|
||||
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 setsockopt(4, SOL_SOCKET, SO_TIMESTAMPING,
|
||||
[SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_SOFTWARE |
|
||||
SOF_TIMESTAMPING_TX_ACK | SOF_TIMESTAMPING_SOFTWARE |
|
||||
SOF_TIMESTAMPING_OPT_ID], 4) = 0
|
||||
|
||||
// Write two 2KB chunks.
|
||||
// setsockopt(..., [SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_OPT_ID], ...)
|
||||
// is called after when SYN is acked. So, we expect the last byte of the first
|
||||
// and the second chunks to have timestamp keys of 1999 (i.e., 2000 - 1) and
|
||||
// 3999 (i.e., 4000 - 1) respectively.
|
||||
+0 write(4, ..., 2000) = 2000
|
||||
+0 write(4, ..., 2000) = 2000
|
||||
+0 > P. 1:2001(2000) ack 1
|
||||
+0 > P. 2001:4001(2000) ack 1
|
||||
+.01 < . 1:1(0) ack 2001 win 514
|
||||
+.01 < . 1:1(0) ack 4001 win 514
|
||||
|
||||
// Make sure that internal TCP timestamps are not overwritten and we have sane
|
||||
// RTT measurement.
|
||||
+0 %{
|
||||
assert 5000 <= tcpi_rtt <= 20000, 'srtt=%d us' % tcpi_rtt
|
||||
}%
|
||||
|
||||
// SCM_TSTAMP_SCHED for the first chunk should be received almost immediately
|
||||
// after write at t=10ms.
|
||||
+0 recvmsg(4, {msg_name(...)=...,
|
||||
msg_iov(1)=[{...,0}],
|
||||
msg_flags=MSG_ERRQUEUE|MSG_TRUNC,
|
||||
msg_control=[
|
||||
{cmsg_level=SOL_SOCKET,
|
||||
cmsg_type=SCM_TIMESTAMPING,
|
||||
cmsg_data={scm_sec=0,scm_nsec=10000000}},
|
||||
{cmsg_level=CMSG_LEVEL_IP,
|
||||
cmsg_type=CMSG_TYPE_RECVERR,
|
||||
cmsg_data={ee_errno=ENOMSG,
|
||||
ee_origin=SO_EE_ORIGIN_TIMESTAMPING,
|
||||
ee_type=0,
|
||||
ee_code=0,
|
||||
ee_info=SCM_TSTAMP_SCHED,
|
||||
ee_data=1999}}
|
||||
]}, MSG_ERRQUEUE) = 0
|
||||
// SCM_TSTAMP_SND for the first chunk should be received almost immediately
|
||||
// after write at t=10ms.
|
||||
+0 recvmsg(4, {msg_name(...)=...,
|
||||
msg_iov(1)=[{...,0}],
|
||||
msg_flags=MSG_ERRQUEUE|MSG_TRUNC,
|
||||
msg_control=[
|
||||
{cmsg_level=SOL_SOCKET,
|
||||
cmsg_type=SCM_TIMESTAMPING,
|
||||
cmsg_data={scm_sec=0,scm_nsec=10000000}},
|
||||
{cmsg_level=CMSG_LEVEL_IP,
|
||||
cmsg_type=CMSG_TYPE_RECVERR,
|
||||
cmsg_data={ee_errno=ENOMSG,
|
||||
ee_origin=SO_EE_ORIGIN_TIMESTAMPING,
|
||||
ee_type=0,
|
||||
ee_code=0,
|
||||
ee_info=SCM_TSTAMP_SND,
|
||||
ee_data=1999}}
|
||||
]}, MSG_ERRQUEUE) = 0
|
||||
// SCM_TSTAMP_SCHED for the second chunk should be received almost immediately
|
||||
// after that at t=10ms.
|
||||
+0 recvmsg(4, {msg_name(...)=...,
|
||||
msg_iov(1)=[{...,0}],
|
||||
msg_flags=MSG_ERRQUEUE|MSG_TRUNC,
|
||||
msg_control=[
|
||||
{cmsg_level=SOL_SOCKET,
|
||||
cmsg_type=SCM_TIMESTAMPING,
|
||||
cmsg_data={scm_sec=0,scm_nsec=10000000}},
|
||||
{cmsg_level=CMSG_LEVEL_IP,
|
||||
cmsg_type=CMSG_TYPE_RECVERR,
|
||||
cmsg_data={ee_errno=ENOMSG,
|
||||
ee_origin=SO_EE_ORIGIN_TIMESTAMPING,
|
||||
ee_type=0,
|
||||
ee_code=0,
|
||||
ee_info=SCM_TSTAMP_SCHED,
|
||||
ee_data=3999}}
|
||||
]}, MSG_ERRQUEUE) = 0
|
||||
// SCM_TSTAMP_SND for the second chunk should be received almost immediately
|
||||
// after that at t=10ms.
|
||||
+0 recvmsg(4, {msg_name(...)=...,
|
||||
msg_iov(1)=[{...,0}],
|
||||
msg_flags=MSG_ERRQUEUE|MSG_TRUNC,
|
||||
msg_control=[
|
||||
{cmsg_level=SOL_SOCKET,
|
||||
cmsg_type=SCM_TIMESTAMPING,
|
||||
cmsg_data={scm_sec=0,scm_nsec=10000000}},
|
||||
{cmsg_level=CMSG_LEVEL_IP,
|
||||
cmsg_type=CMSG_TYPE_RECVERR,
|
||||
cmsg_data={ee_errno=ENOMSG,
|
||||
ee_origin=SO_EE_ORIGIN_TIMESTAMPING,
|
||||
ee_type=0,
|
||||
ee_code=0,
|
||||
ee_info=SCM_TSTAMP_SND,
|
||||
ee_data=3999}}
|
||||
]}, MSG_ERRQUEUE) = 0
|
||||
// SCM_TSTAMP_ACK for the first chunk should be received at t=20ms.
|
||||
+0 recvmsg(4, {msg_name(...)=...,
|
||||
msg_iov(1)=[{...,0}],
|
||||
msg_flags=MSG_ERRQUEUE|MSG_TRUNC,
|
||||
msg_control=[
|
||||
{cmsg_level=SOL_SOCKET,
|
||||
cmsg_type=SCM_TIMESTAMPING,
|
||||
cmsg_data={scm_sec=0,scm_nsec=20000000}},
|
||||
{cmsg_level=CMSG_LEVEL_IP,
|
||||
cmsg_type=CMSG_TYPE_RECVERR,
|
||||
cmsg_data={ee_errno=ENOMSG,
|
||||
ee_origin=SO_EE_ORIGIN_TIMESTAMPING,
|
||||
ee_type=0,
|
||||
ee_code=0,
|
||||
ee_info=SCM_TSTAMP_ACK,
|
||||
ee_data=1999}}
|
||||
]}, MSG_ERRQUEUE) = 0
|
||||
// SCM_TSTAMP_ACK for the second chunk should be received at t=30ms.
|
||||
+0 recvmsg(4, {msg_name(...)=...,
|
||||
msg_iov(1)=[{...,0}],
|
||||
msg_flags=MSG_ERRQUEUE|MSG_TRUNC,
|
||||
msg_control=[
|
||||
{cmsg_level=SOL_SOCKET,
|
||||
cmsg_type=SCM_TIMESTAMPING,
|
||||
cmsg_data={scm_sec=0,scm_nsec=30000000}},
|
||||
{cmsg_level=CMSG_LEVEL_IP,
|
||||
cmsg_type=CMSG_TYPE_RECVERR,
|
||||
cmsg_data={ee_errno=ENOMSG,
|
||||
ee_origin=SO_EE_ORIGIN_TIMESTAMPING,
|
||||
ee_type=0,
|
||||
ee_code=0,
|
||||
ee_info=SCM_TSTAMP_ACK,
|
||||
ee_data=3999}}
|
||||
]}, MSG_ERRQUEUE) = 0
|
Loading…
Add table
Reference in a new issue