A concise user manual for Packetdrill

  • 2020-12-19 21:25:15
  • OfStack

1. Compilation and installation of Packetdrill

Source link https: / / github com/google/packetdrill git Source code compilation annotation netdev. c

/* Set the offload flags to be like a typical ethernet device */
static void set_device_offload_flags(struct local_netdev *netdev)
{
#ifdef linux
// const u32 offload =
//   TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | TUN_F_TSO_ECN | TUN_F_UFO;
// if (ioctl(netdev->tun_fd, TUNSETOFFLOAD, offload) != 0)
//   die_perror("TUNSETOFFLOAD");
#endif
}

./configure & & make

Method of use


./packetdrill test.pkt

test.pkt for test scripts written according to Packetdrill syntax.

Success: No output, indicating that the script is correct, 1 cut is as expected.

Failure: Indicate where the script went wrong, and why.

2. Packetdrill executes its own test cases

Open tcpdump-ES34en any tcp port port 8080 grab bag for easy analysis Here is the test for fast retransmission, test environment es38EN7.2. Simple instructions < Representing input, packetdrill constructs a real packet. > Represents a packet that the protocol stack is expected to respond to. (This package is not constructed by packetdrill but is issued by the protocol stack.)

// Test fast retransmit with 4 packets outstanding, receiver sending SACKs.
// In this variant the receiver supports SACK.
// 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
//3 handshake 
+0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7>
+0 > S. 0:0(0) ack 1 <...>
+.1 < . 1:1(0) ack 1 win 257
+0 accept(3, ..., ...) = 4
// System call, which sends out the protocol stack 100 bytes 
// Send 1 data segment and get an ACK, so cwnd is now 4.
+0 write(4, ..., 1000) = 1000
// The stack is expected to issue psh,ack It's actually sent out ack1
//+0 > P. 1:1001(1000) ack 2
// Injection into the protocol stack  ack
+.1 < . 1:1(0) ack 1001 win 257
// Write 4 data segments.
// System call, which sends out the protocol stack 4000 bytes 
+0 write(4, ..., 4000) = 4000
// The stack is expected to issue psh . ack It's actually sent out seq 1001:2001, ack 1 ; seq 2001:3001, ack 1 ; seq 3001:4001, ack 1 ; [P.], seq 4001:5001, ack 1
//+0 > P. 1001:5001(4000) ack 1
// Get 3 SACKs.
// Issue continuously to the protocol stack 3 a ack
+.1 < . 1:1(0) ack 1001 win 257 <sack 2001:3001,nop,nop>
+0 < . 1:1(0) ack 1001 win 257 <sack 2001:4001,nop,nop>
+0 < . 1:1(0) ack 1001 win 257 <sack 2001:5001,nop,nop>
// We've received 3 duplicate ACKs, so we do a fast retransmit.
// The stack is expected to issue 1 Secondary fast retransmission  Seq 1001 : 2001 . ack 1
//+0 > . 1001:2001(1000) ack 1
// Receiver ACKs all data.
// To the protocol stack ack , in response to all messages ack . 
+.1 < . 1:1(0) ack 6001 win 257
4.  will fr-4pkt-sack-linux.pkt  The modifications are as follows. 
+0 > P. 1:1001(1000) ack 2    +0 > P. 1:1001(1000) ack 1
//+0 > P. 1001:5001(4000) ack 1  
+0 > . 1001:2001(1000) ack 1
+0 > . 2001:3001(1000) ack 1
+0 > . 3001:4001(1000) ack 1
+0 > P. 4001:5001(1000) ack 1

[Note: If the use case for packetdrill is not executed correctly, it is usually the packet issued by the stack that does not meet the expected packet > That part is eliminated, then the test case is executed, and the expected results are analyzed by capturing the package. Usually because of the 3-handshake mss limit]

Execution:.. /.. /.. /packetdrill ES50en-4ES51en-ES52en-ES53en. pkt, no error. The grab packet can see 1 result: 3 repetitions of ack and fast retransmission. Achieve the desired effect.

//  Build your own package implementation 3 Repetitions of ack 1001.
07:57:36.469280 IP 192.0.2.1.36840 > TENCENT64.site.webcache: Flags [.], ack 1001, win 257, options [sack 1 {2001:3001},nop,nop], length 0
07:57:36.469836 IP 192.0.2.1.36840 > TENCENT64.site.webcache: Flags [.], ack 1001, win 257, options [sack 1 {2001:4001},nop,nop], length 0
07:57:36.470349 IP 192.0.2.1.36840 > TENCENT64.site.webcache: Flags [.], ack 1001, win 257, options [sack 1 {2001:5001},nop,nop], length 0
//  The stack initiates fast retransmission. Seq 1001 : 2001 . ack 1,1000
07:57:36.470376 IP TENCENT64.site.webcache > 192.0.2.1.36840: Flags [.], seq 1001:2001, ack 1, win 229, length 1000

3. Packetdrill interprets the built-in test case instructions

The basic syntax of packetdrill is explained here.

The script can contain four types of statements: packet, system call, shell command, python statement.
Each statement must begin with a timestamp indicating when it was executed.

Packets

Data packets are divided into: input data packets, output data packets, with a format similar to tcpdump,
Support for TCP, UDP, ICMP, and most of the TCP options.

Input packet ( < packetdrill will construct a real packet and inject it into the stack.

Example:


0.100 < S 0:0(0) win 32792 <mss 1000, nop, nop, sackOK, nop, wscale 7>
0.250 < [1:1461(1460)] icmp unreachable frag_needed mtu 1200

Output packet ( > packetdrill checks to see if the stack actually issued such a package.


+0 > udp (1472)
System Calls

The system call format is similar to strace.
For each system call, packetdrill executes at a specified time and checks that the return value is exactly the same as expected. The system call is mainly applied to the construction of the scene, has not been the test side of the data sent and received.

Common examples of system calls:
The system calls


connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)  // The client connects to the server 
getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0  // To obtain scoketopt
fcntl(3, F_SETFL, O_RDWR) = 0  //Fcntl Set up the 
ioctl(4, SIOCINQ, [1000]) = 0  //Ioctl Set up the 
read(3, ..., 1024) = 785  // Read the data 
write(3, ..., 57) = 57 // Write data 
close(3) = 0  // Close the connection 
socket(..., SOCK_STREAM, IPPROTO_TCP) = 3  //Tcp socket
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 // Set address multiplexing 
bind(3, ..., ...) = 0  // Binding port 
listen(3, 1) = 0  // Listen on port 
accept(3, ..., ...) = 4 // Accept connections 
shell script usage

Common usage is to set kernel parameters with the shell script or call the shell command to count tcp information. Set up the

Example:


+0 `sysctl -q net.ipv4.tcp_timestamps=0`
+0 `ss -4 -n state SYN-RECV | grep 192.168.0.1:8080 > /dev/null`
Usage of the python script

The common usage is to use assert of python to assert that the information in tcp_info is as expected.

Example:


0.310 %{
assert tcpi_reordering == 3
assert tcpi_unacked == 10
assert tcpi_sacked == 6
assert tcpi_ca_state == TCP_CA_Recovery
}%
The time stamp

Each statement must begin with a timestamp indicating when it was executed or when the expected event occurred. Test case It is possible that there was a problem with timing that caused test case to fail.

Timestamps can be in a variety of formats:


Absolute (Absolute time) : 0.75
Relative (Relative time ) : +0.2
Wildcard (Any time ) : *
Range (Absolute time interval ) : 0.750~0.900
Relative Range (Relative time interval) : +0.1~+0.2
Loose (Allowable error value) : --tolerance_usecs=800
Blocking (Block time interval) : 0.750...0.900

If the corresponding event did not occur at the specified timestamp, an error is reported and the actual time of the event is notified.


./packetdrill test.pkt
0

It is expected that TCP should send 1 SYNACK packet after 1s.

In practical use, tolerance_usecs=405000 is generally specified, which allows the time error of 4ms.

4. Packetdrill implements the basic scenario construction test

The scenario construction of a scenario is either a client scenario or a server scenario. How the package is constructed depends on the test case that comes with packetdrill.

1. Server-side scenario

Construct the server-side scenario: the packet input side is the client side. The packet output is a system call that acts as a server.


./packetdrill test.pkt
1

1. Client scene construction

Construct the server-side scenario: the packet input side is the server side. The packet output is a system call that acts as a client.


./packetdrill test.pkt
2

conclusion


Related articles: