266. packet capture

Packet capture framework feature support packet capturing on dpdk ethernet devices. DPDK provides dpdk-pdump tool under app/pdump directory for packet capturing on dpdk.

The dpdk-pdump application will act as the secondary process. The EAL thread polls for packet capture fd. If fd polled matches packet capture fd, it will initiate packet capture processing.

The testpmd application will act as the primary process. The primary process create socket for packet capture connection with the secondary process and registers socket with packet capture epoll event. Packet capture event will be polled as part of interrupt thread.

The primary process creates mempool and two rte_rings for packets duplication and sharing packet info with the secondary process respectively.

Upon receiving packet capture event, the primary process receive either register RX/TX callbacks or remove RX/TX callbacks message from the secondary process on socket.If packet matches, reference count of packet will be incremented and enqueued to second rte_ring for the secondary process to use.

DPDK technical doc refer to:

dpdk/doc/guides/tools/pdump.rst

266.1. Test configuration

2x NICs (2 full duplex ports per NIC) plugged into the available slots on a platform, another two nic ports are linked with cables.

Connections ports between TESTER and DUT:

  TESTER                                DUT
               physical link
.--------.                          .--------.
| portA0 | <----------------------> | portB0 |
|        |                          |        |
| portA1 | <----------------------> | portB1 |
'--------'                          |        |
                            ------> | portB2 |
                           |        |        |
                            ------> | portB3 |
                                    '--------'
note: portB0/portB1 are the binded ports.
portB2/portB3 keep link up status and don’t bind to dpdk driver. Except portB0/portB1, DUT should have other two ports on link up status

266.2. Prerequisites

Enable pcap lib in dpdk code and recompile:

--- a/config/common_base
+++ b/config/common_base
@@ -492,7 +492,7 @@ CONFIG_RTE_LIBRTE_PMD_NULL=y
 #
 # Compile software PMD backed by PCAP files
 #
-CONFIG_RTE_LIBRTE_PMD_PCAP=n
+CONFIG_RTE_LIBRTE_PMD_PCAP=y

266.3. Test cases

The testpmd application act as server process with port-topology chained mode, the dpdk-pdump act as client process to dump capture packet with different options setting. Select one port of tester as tx port, another port of tester as rx port, send different type packets from two ports, check pcap file content dumped by scapy and tcpdump to confirm testpmd working correctly, check pcap file content dumped by tcpdump and dpdk-pdump to confirm dpdk-pdump working correctly.

266.3.1. dpdk-pdump command format

#. packet capture framework tool dpdk-pdump command format, parameters inside the parenthesis represents the mandatory parameters, parameters inside the square brackets represents optional

parameters:

./app/dpdk-pdump -- --pdump=
'(port = <port_id> |device_id = <pci address>),
(queue=<queue number>),
(rx-dev=<iface/path to pcap file> | tx-dev=<iface/path to pcap file>),
[ring-size=<size>],
[mbuf-size=<size>],
[total-num-mbufs=<size>]'

266.3.2. transmission packet format

  1. IP_RAW:

    [Ether()/IP()/Raw('\0'*60)]
    
  2. TCP:

    [Ether()/IP()/TCP()/Raw('\0'*60)]
    
  3. UDP:

    [Ether()/IP()/UDP()/Raw('\0'*60)]
    
  4. SCTP:

    [Ether()/IP()/SCTP()/Raw('\0'*40)]
    
  5. IPv6_TCP:

    [Ether()/IPv6()/TCP()/Raw('\0'*60)]
    
  6. IPv6_UDP:

    [Ether()/IPv6()/UDP()/Raw('\0'*60)]
    
  7. IPv6_SCTP:

    [Ether()/IP()/IPv6()/SCTP()/Raw('\0'*40)]
    
  8. VLAN_UDP:

    [Ether()/Dot1Q()/IP()/UDP()/Raw('\0'*40)]
    
  9. TIMESYNC:

    [Ether(dst='FF:FF:FF:FF:FF:FF',type=0x88f7)/"\\x00\\x02"]
    
  10. ARP:

    [Ether(dst='FF:FF:FF:FF:FF:FF')/ARP()]
    
  11. LLDP(LLDP()/LLDPManagementAddress() method are in dts/dep/lldp.py):

    [Ether()/LLDP()/LLDPManagementAddress()]
    

266.3.3. port configuration

  1. confirm two NICs physical link on a platform:

    dut port 0 <---> tester port 0
    dut port 1 <---> tester port 1
    
  2. Bind two port on DUT:

    ./usertools/dpdk_nic_bind.py --bind=igb_uio <dut port 0 pci address> <dut port 1 pci address>
    
  3. On dut, use port 0 as rx/tx port. If dut port 0 rx dump is set, scapy send packet from tester port 0 and tcpdump dumps tester port 1’s packet. If dut port 0 tx dump is set, scapy send packet from tester port 1 and tcpdump dumps tester port 0’s packet.

  4. If using interfaces as dpdk-pdump vdev, prepare two ports on DUT, which haven’t been binded to dpdk and have been in linked status

266.4. Test Case: test pdump port

Test different port type definition options:

port=<dut port id>
device_id=<dut pci address>

steps:

  1. Boot up dpdk’s testpmd with chained option:

    ./app/testpmd -c 0x6 -n 4 -- -i --port-topology=chained
    testpmd> set fwd io
    testpmd> start
    
  2. When test VLAN_UDP type packet transmission, set vlan:

    testpmd> vlan set filter off 1
    testpmd> start
    
  3. Boot up dpdk-pdump:

    ./app/dpdk-pdump -- --pdump  '<port option>,queue=*,\
    tx-dev=/tmp/pdump-tx.pcap,rx-dev=/tmp/pdump-rx.pcap'
    
  4. Set up linux’s tcpdump to receiver packet on tester:

    tcpdump -i <rx port name> -w /tmp/sniff-<rx port name>.pcap
    tcpdump -i <tx port name> -w /tmp/sniff-<tx port name>.pcap
    
  5. Send packet on tester by port 0:

    sendp(<packet format>, iface=<port 0 name>)
    

#. Compare pcap file of scapy with the pcap file dumped by tcpdump. Compare pcap file dumped by dpdk-pdump with pcap files dumped by tcpdump.

  1. Send packet on tester by port 1:

    sendp(<packet format>, iface=<port 1 name>)
    

#. Compare pcap file of scapy with the pcap file dumped by tcpdump. Compare pcap file dumped by dpdk-pdump with pcap files dumped by tcpdump:

pkt=rdpcap('xxxx1.pcap')
pkt[0].show2()
pkt=rdpcap('xxxx2.pcap')
pkt[0].show2()

266.5. Test Case: test pdump queue

Capture first queue traffic.

test different queue options:

first queue 'queue=0'
all queue 'queue=*'

steps:

  1. Boot up dpdk’s testpmd with chained option:

    ./app/testpmd -c 0x6 -n 4 -- -i --port-topology=chained
    testpmd> set fwd io
    testpmd> start
    
  2. When test VLAN_UDP type packet transmission, set vlan:

    testpmd> vlan set filter off 1
    testpmd> start
    
  3. Boot up dpdk-pdump:

    ./app/dpdk-pdump -- --pdump  'port=0,<queue option>,\
    tx-dev=/tmp/pdump-tx.pcap,rx-dev=/tmp/pdump-rx.pcap'
    
  4. Set up linux’s tcpdump to receiver packet on tester:

    tcpdump -i <rx port name> -w /tmp/sniff-<rx port name>.pcap
    tcpdump -i <tx port name> -w /tmp/sniff-<tx port name>.pcap
    
  5. Send packet on tester by port 0:

    sendp(<packet format>, iface=<port 0 name>)
    
  6. Compare pcap file of scapy with the pcap file dumped by tcpdump. Compare pcap file dumped by dpdk-pdump with pcap files dumped by tcpdump.

  7. Send packet on tester by port 1:

    sendp(<packet format>, iface=<port 1 name>)
    
  8. Compare pcap file of scapy with the pcap file dumped by tcpdump. Compare pcap file dumped by dpdk-pdump with pcap files dumped by tcpdump:

    pkt=rdpcap('xxxx1.pcap')
    pkt[0].show2()
    pkt=rdpcap('xxxx2.pcap')
    pkt[0].show2()
    

266.6. Test Case: test pdump dev pcap

Dump rx/tx transmission packets into a specified pcap files.

test different dump options:

tx-dev=/tmp/pdump-tx.pcap,rx-dev=/tmp/pdump-rx.pcap
rx-dev=/tmp/pdump-rx.pcap
tx-dev=/tmp/pdump-tx.pcap

steps:

  1. Boot up dpdk’s testpmd with chained option:

    ./app/testpmd -c 0x6 -n 4 -- -i --port-topology=chained
    testpmd> set fwd io
    testpmd> start
    
  2. When test VLAN_UDP type packet transmission, set vlan(other packet ignore this step):

    testpmd> vlan set filter off 1
    testpmd> start
    
  3. Boot up dpdk-pdump with pdump options:

    ./app/dpdk-pdump -- --pdump  'port=0,queue=*,<dump object>'
    
  4. Set up linux’s tcpdump to receiver packet on tester:

    tcpdump -i <rx port name> -w /tmp/sniff-<rx port name>.pcap
    tcpdump -i <tx port name> -w /tmp/sniff-<tx port name>.pcap
    
  5. Send packet on tester by port 0:

    sendp(<packet format>, iface=<port 0 name>)
    
  6. Compare pcap file of scapy with the pcap file dumped by tcpdump. Compare pcap file dumped by dpdk-pdump with pcap files dumped by tcpdump(ignore when only set tx-dev).

  7. Send packet on tester by port 1:

    sendp(<packet format>, iface=<port 1 name>)
    
  8. Compare pcap file of scapy with the pcap file dumped by tcpdump. Compare pcap file dumped by dpdk-pdump with pcap files dumped by tcpdump(ignore when only set rx-dev):

    pkt=rdpcap('xxxx1.pcap')
    pkt[0].show2()
    pkt=rdpcap('xxxx2.pcap')
    pkt[0].show2()
    

266.7. Test Case: test pdump dev iface

Dump rx/tx transmission packets to a specified port, which is on link status.

test different dump options:

tx-dev=<dut tx port name>,rx-dev=<dut rx port name>
rx-dev=<dut rx port name>
tx-dev=<dut tx port name>

steps:

  1. Boot up dpdk’s testpmd with chained option:

    ./app/testpmd -c 0x6 -n 4 -- -i --port-topology=chained
    testpmd> set fwd io
    testpmd> start
    
  2. When test VLAN_UDP type packet transmission, set vlan(other packet ignore this step):

    testpmd> vlan set filter off 1
    testpmd> start
    
  3. Boot up dpdk-pdump with pdump options:

    ./app/dpdk-pdump -- --pdump  'port=0,queue=*,<dump object>'
    
  4. Set up linux’s tcpdump to receiver packet on tester:

    tcpdump -i <rx port name> -w /tmp/sniff-<rx port name>.pcap
    tcpdump -i <tx port name> -w /tmp/sniff-<tx port name>.pcap
    
  5. Set up linux’s tcpdump to receiver packet of dpdk-pdump on Dut:

    when rx-dev is set, use 'tcpdump -i <dut rx port name> -w /tmp/pdump-rx.pcap'
    when tx-dev is set, use 'tcpdump -i <dut tx port name> -w /tmp/pdump-tx.pcap'
    
  6. Send packet on tester by port 0:

    sendp(<packet format>, iface=<port 0 name>)
    
  7. Compare pcap file of scapy with the pcap file dumped by tcpdump. Compare pcap file dumped by dpdk-pdump with pcap files dumped by tcpdump(ignore when only set tx-dev).

  8. Send packet on tester by port 1:

    sendp(<packet format>, iface=<port 1 name>)
    
  9. Compare pcap file of scapy with the pcap file dumped by tcpdump. Compare pcap file dumped by dpdk-pdump with pcap files dumped by tcpdump(ignore when only set rx-dev):

    pkt=rdpcap('xxxx1.pcap')
    pkt[0].show2()
    pkt=rdpcap('xxxx2.pcap')
    pkt[0].show2()
    

266.8. Test Case: test pdump ring size

Test ring size option, set value within 2^[1~27].

steps:

  1. Boot up dpdk’s testpmd with chained option:

    ./app/testpmd -c 0x6 -n 4 -- -i --port-topology=chained
    testpmd> set fwd io
    testpmd> start
    
  2. When test VLAN_UDP type packet transmission, set vlan:

    testpmd> vlan set filter off 1
    testpmd> start
    
  3. Boot up dpdk-pdump with pdump options:

    ./app/dpdk-pdump -- --pdump  'port=0,queue=*,\
    tx-dev=/tmp/pdump-tx.pcap,rx-dev=/tmp/pdump-rx.pcap,ring-size=1024'
    
  4. Set up linux’s tcpdump to receiver packet on tester:

    tcpdump -i <rx port name> -w /tmp/sniff-<rx port name>.pcap
    tcpdump -i <tx port name> -w /tmp/sniff-<tx port name>.pcap
    
  5. Send packet on tester by port 0:

    sendp(<packet format>, iface=<port 0 name>)
    
  6. Compare pcap file of scapy with the pcap file dumped by tcpdump. Compare pcap file dumped by dpdk-pdump with pcap files dumped by tcpdump.

  7. Send packet on tester by port 1:

    sendp(<packet format>, iface=<port 1 name>)
    
  8. Compare pcap file of scapy with the pcap file dumped by tcpdump. Compare pcap file dumped by dpdk-pdump with pcap files dumped by tcpdump:

    pkt=rdpcap('xxxx1.pcap')
    pkt[0].show2()
    pkt=rdpcap('xxxx2.pcap')
    pkt[0].show2()
    

266.9. Test Case: test pdump mbuf size

Test mbuf size option, set value within [252~50000]. min value is decided by single packet size, max value is decided by test platform memory size.

steps:

  1. Boot up dpdk’s testpmd with chained option:

    ./app/testpmd -c 0x6 -n 4 -- -i --port-topology=chained
    testpmd> set fwd io
    testpmd> start
    
  2. When test VLAN_UDP type packet transmission, set vlan:

    testpmd> vlan set filter off 1
    testpmd> start
    
  3. Boot up dpdk-pdump with pdump options:

    ./app/dpdk-pdump -- --pdump  'port=0,queue=*,\
    tx-dev=/tmp/pdump-tx.pcap,rx-dev=/tmp/pdump-rx.pcap,mbuf-size=2048'
    
  4. Set up linux’s tcpdump to receiver packet on tester:

    tcpdump -i <rx port name> -w /tmp/sniff-<rx port name>.pcap
    tcpdump -i <tx port name> -w /tmp/sniff-<tx port name>.pcap
    
  5. Send packet on tester by port 0:

    sendp(<packet format>, iface=<port 0 name>)
    
  6. Compare pcap file of scapy with the pcap file dumped by tcpdump. Compare pcap file dumped by dpdk-pdump with pcap files dumped by tcpdump.

  7. Send packet on tester by port 1:

    sendp(<packet format>, iface=<port 1 name>)
    
  8. Compare pcap file of scapy with the pcap file dumped by tcpdump. Compare pcap file dumped by dpdk-pdump with pcap files dumped by tcpdump:

    pkt=rdpcap('xxxx1.pcap')
    pkt[0].show2()
    pkt=rdpcap('xxxx2.pcap')
    pkt[0].show2()
    

266.10. Test Case: test pdump total num mbufs

Test total-num-mbufs option, set value within [1025~65535]

steps:

  1. Boot up dpdk’s testpmd with chained option:

    ./app/testpmd -c 0x6 -n 4 -- -i --port-topology=chained
    testpmd> set fwd io
    testpmd> start
    
  2. When test VLAN_UDP type packet transmission, set vlan:

    testpmd> vlan set filter off 1
    testpmd> start
    
  3. Boot up dpdk-pdump with pdump options:

    ./app/dpdk-pdump -- --pdump  'port=0,queue=*,\
    tx-dev=/tmp/pdump-tx.pcap,rx-dev=/tmp/pdump-rx.pcap,total-num-mbufs=8191'
    
  4. Set up linux’s tcpdump to receiver packet on tester:

    tcpdump -i <rx port name> -w /tmp/sniff-<rx port name>.pcap
    tcpdump -i <tx port name> -w /tmp/sniff-<tx port name>.pcap
    
  5. Send packet on tester by port 0:

    sendp(<packet format>, iface=<port 0 name>)
    
  6. Compare pcap file of scapy with the pcap file dumped by tcpdump. Compare pcap file dumped by dpdk-pdump with pcap files dumped by tcpdump.

  7. Send packet on tester by port 1:

    sendp(<packet format>, iface=<port 1 name>)
    
  8. Compare pcap file of scapy with the pcap file dumped by tcpdump. Compare pcap file dumped by dpdk-pdump with pcap files dumped by tcpdump:

    pkt=rdpcap('xxxx1.pcap')
    pkt[0].show2()
    pkt=rdpcap('xxxx2.pcap')
    pkt[0].show2()