[dts] [PATCH V1 2/2] Packet capture: upload automation testing script/test plan

Mo, YufengX yufengx.mo at intel.com
Fri Aug 19 03:05:10 CEST 2016


hi, Marvin



a replay about your comment.



And please review my ipgre patch.



> -----Original Message-----

> From: Liu, Yong

> Sent: August 18, 2016 5:11 PM

> To: Mo, YufengX; dts at dpdk.org

> Subject: RE: [dts] [PATCH V1 2/2] Packet capture: upload automation testing script/test plan

>

> Hi Yufen, some concerns about this patch.

>

> > -----Original Message-----

> > From: dts [mailto:dts-bounces at dpdk.org] On Behalf Of Mo, YufengX

> > Sent: Thursday, August 18, 2016 2:33 PM

> > To: dts at dpdk.org<mailto:dts at dpdk.org>

> > Cc: Mo, YufengX

> > Subject: [dts] [PATCH V1 2/2] Packet capture: upload automation testing

> > script/test plan

> >

> > From: yufengmx <yufengx.mo at intel.com<mailto:yufengx.mo at intel.com>>

> >

> >

> > 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  tool is a Data Plane Development Kit (DPDK) tool that runs as

> > a DPDK secondary process and is capable of enabling packet capture on dpdk

> > ports.

> >   * The  tool depends on libpcap based PMD which is disabled

> >     by default in the build configuration files,

> >     owing to an external dependency on the libpcap development files

> >     which must be installed on the board.

> >     Once the libpcap development files are installed, the libpcap based

> > PMD

> >     can be enabled by setting CONFIG_RTE_LIBRTE_PMD_PCAP=y and recompiling

> > the DPDK.

> >

> > Signed-off-by: yufengmx <yufengx.mo at intel.com<mailto:yufengx.mo at intel.com>>

> > ---

> >  test_plans/packet_capture_test_plan.rst | 376 ++++++++++++++++

> >  tests/TestSuite_packet_capture.py       | 756

> > ++++++++++++++++++++++++++++++++

> >  2 files changed, 1132 insertions(+)

> >  create mode 100644 test_plans/packet_capture_test_plan.rst

> >  create mode 100644 tests/TestSuite_packet_capture.py

> >

> > diff --git a/test_plans/packet_capture_test_plan.rst

> > b/test_plans/packet_capture_test_plan.rst

> > new file mode 100644

> > index 0000000..6a51cf9

> > --- /dev/null

> > +++ b/test_plans/packet_capture_test_plan.rst

> > @@ -0,0 +1,376 @@

> > +.. Copyright (c) <2016> Intel Corporation

> > +   All rights reserved.

> > +

> > +   Redistribution and use in source and binary forms, with or without

> > +   modification, are permitted provided that the following conditions

> > +   are met:

> > +

> > +   - Redistributions of source code must retain the above copyright

> > +     notice, this list of conditions and the following disclaimer.

> > +

> > +   - Redistributions in binary form must reproduce the above copyright

> > +     notice, this list of conditions and the following disclaimer in

> > +     the documentation and/or other materials provided with the

> > +     distribution.

> > +

> > +   - Neither the name of Intel Corporation nor the names of its

> > +     contributors may be used to endorse or promote products derived

> > +     from this software without specific prior written permission.

> > +

> > +   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

> > +   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

> > +   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS

> > +   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

> > +   COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,

> > +   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

> > +   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR

> > +   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

> > +   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,

> > +   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

> > +   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED

> > +   OF THE POSSIBILITY OF SUCH DAMAGE.

> > +

> > +==================

> > +  packet capture framework feature

> > +==================

> > +

> > +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.

> > +

> > +Prerequisites

> > +=============

> > +* 2x NICs (2 full duplex ports per NIC) plugged into the available slots

> > on a platform, another

> > +two nic ports are linked with cables.

> > +

> > +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 files' content dumped by scapy and tcpdump to confirm

> > testpmd working correctly,

> > +check pcap files' content dumped by tcpdump and dpdk-pdump to confirm

> > dpdk-pdump working correctly.

> > +

> > +dpdk-pdump command format

> > +--------------------------

> > +* packet capture framework tool dpdk-pdump command format, parameters

> > inside the parenthesis

> > +represents the mandatory parametersm parameters inside the square

> > brackets represents optional

> > +parameters::

> > +./x86_64-native-linuxapp-gcc/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>]'

> > +

> > +transmission packets' format

> > +--------------------------

> > +* IP_RAW

> > +  [Ether()/IP()/Raw('\0'*60)]

> > +* TCP

> > +  [Ether()/IP()/TCP()/Raw('\0'*60)]

> > +* UDP

> > +  [Ether()/IP()/UDP()/Raw('\0'*60)]

> > +* SCTP

> > +  [Ether()/IP()/SCTP()/Raw('\0'*40)]

> > +* IPv6_TCP

> > +  [Ether()/IPv6()/TCP()/Raw('\0'*60)]

> > +* IPv6_UDP

> > +  [Ether()/IPv6()/UDP()/Raw('\0'*60)]

> > +* IPv6_SCTP

> > +  [Ether()/IP()/IPv6()/SCTP()/Raw('\0'*40)]

> > +* VLAN_UDP

> > +  [Ether()/Dot1Q()/IP()/UDP()/Raw('\0'*40)]

> > +* TIMESYNC

> > +  [Ether(dst='FF:FF:FF:FF:FF:FF',type=0x88f7)/"\\x00\\x02<file:///\\x00\x02>"]

> > +* ARP

> > +  [Ether(dst='FF:FF:FF:FF:FF:FF')/ARP()]

> > +* LLDP

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

> > +  notice: LLDP()/LLDPManagementAddress() method are in dts/dep/lldp.py

> > +

> > +port configuration

> > +--------------------------

> > +* confirm two NICs physical link on a platform:

> > +  dut port 0 <---> tester port 0

> > +  dut port 1 <---> tester port 1

> > +

> > +* Bind two port on DUT::

> > + ./tools/dpdk_nic_bind.py --bind=igb_uio <dut port 0 pci address> <dut

> > port 1 pci address>

> > +

> > +* 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.

> > +

> > +* 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

> > +

> > +Test Case 1: test pdump port

> > +=================================

> > +test different port options::

> > +* port=<dut port id>

> > +* device_id=<dut pci address>

> > +

> > +Boot up dpdk's testpmd with chained option::

> > +      ./x86_64-native-linuxapp-gcc/app/testpmd -c 0x6 -n 4 -- -i --port-

> > topology=chained

> > +      testpmd> set fwd io

> > +      testpmd> start

> > +

> > +When test VLAN_UDP type packet transmission, set vlan:

> > +    testpmd> vlan set filter off 1

> > +    testpmd> start

> > +

> > +Boot up dpdk-pdump::

> > +    ./x86_64-native-linuxapp-gcc/app/dpdk-pdump -- --pdump  '<port

> > option>,queue=*,\

> > +    tx-dev=/tmp/pdump-tx.pcap,rx-dev=/tmp/pdump-rx.pcap'

> > +

> > +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

> > +

> > +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.

> > +

> > +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.

> > +

> > +Test Case 2: test pdump queue

> > +=================================

> > +test different queue options::

> > +* first queue:

> > +  queue=0

> > +* all:

> > +  queue=*

> > +

> > +Boot up dpdk's testpmd with chained option::

> > +      ./x86_64-native-linuxapp-gcc/app/testpmd -c 0x6 -n 4 -- -i --port-

> > topology=chained

> > +      testpmd> set fwd io

> > +      testpmd> start

> > +

> > +When test VLAN_UDP type packet transmission, set vlan:

> > +    testpmd> vlan set filter off 1

> > +    testpmd> start

> > +

> > +Boot up dpdk-pdump::

> > +    ./x86_64-native-linuxapp-gcc/app/dpdk-pdump -- --pdump

> > 'port=0,<queue option>,\

> > +    tx-dev=/tmp/pdump-tx.pcap,rx-dev=/tmp/pdump-rx.pcap'

> > +

> > +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

> > +

> > +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.

> > +

> > +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.

> > +

> > +Test Case 3: test pdump dev pcap

> > +=================================

> > +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

> > +

> > +Boot up dpdk's testpmd with chained option::

> > +      ./x86_64-native-linuxapp-gcc/app/testpmd -c 0x6 -n 4 -- -i --port-

> > topology=chained

> > +      testpmd> set fwd io

> > +      testpmd> start

> > +

> > +When test VLAN_UDP type packet transmission, set vlan:

> > +    testpmd> vlan set filter off 1

> > +    testpmd> start

> > +

> > +Boot up dpdk-pdump with pdump options::

> > +    ./x86_64-native-linuxapp-gcc/app/dpdk-pdump -- --pdump

> > 'port=0,queue=*,<dump object>'

> > +

> > +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

> > +

> > +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(ignore when only set tx-

> > dev).

> > +

> > +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(ignore when only set rx-

> > dev).

> > +

> > +Test Case 4: test pdump dev iface

> > +=================================

> > +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>

> > +

> > +Boot up dpdk's testpmd with chained option::

> > +      ./x86_64-native-linuxapp-gcc/app/testpmd -c 0x6 -n 4 -- -i --port-

> > topology=chained

> > +      testpmd> set fwd io

> > +      testpmd> start

> > +

> > +When test VLAN_UDP type packet transmission, set vlan:

> > +    testpmd> vlan set filter off 1

> > +    testpmd> start

> > +

> > +Boot up dpdk-pdump with pdump options::

> > +    ./x86_64-native-linuxapp-gcc/app/dpdk-pdump -- --pdump

> > 'port=0,queue=*,<dump object>'

> > +

> > +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

> > +

> > +Set up linux's tcpdump to receiver packet of dpdk-pdump on Dut::

> > +      when rx-dev is set

> > +      tcpdump -i <dut rx port name> -w /tmp/pdump-rx.pcap

> > +

> > +      when tx-dev is set

> > +      tcpdump -i <dut tx port name> -w /tmp/pdump-tx.pcap

> > +

> > +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(ignore when only set tx-

> > dev).

> > +

> > +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(ignore when only set rx-

> > dev).

> > +

> > +Test Case 5: test pdump ring size

> > +=================================

> > +test ring size option, set value within 2^[1~27]

> > +

> > +Boot up dpdk's testpmd with chained option::

> > +      ./x86_64-native-linuxapp-gcc/app/testpmd -c 0x6 -n 4 -- -i --port-

> > topology=chained

> > +      testpmd> set fwd io

> > +      testpmd> start

> > +

> > +When test VLAN_UDP type packet transmission, set vlan:

> > +    testpmd> vlan set filter off 1

> > +    testpmd> start

> > +

> > +Boot up dpdk-pdump with pdump options::

> > +    ./x86_64-native-linuxapp-gcc/app/dpdk-pdump -- --pdump

> > 'port=0,queue=*,\

> > +    tx-dev=/tmp/pdump-tx.pcap,rx-dev=/tmp/pdump-rx.pcap,ring-size=1024'

> > +

> > +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

> > +

> > +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.

> > +

> > +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.

> > +

> > +Test Case 6: test pdump mbuf size

> > +=================================

> > +test mbuf size option, set value within [252~59520]. min value is decided

> > by single packet size,

> > +max value is decided by test platform memery size.

> > +

> > +

> > +Boot up dpdk's testpmd with chained option::

> > +      ./x86_64-native-linuxapp-gcc/app/testpmd -c 0x6 -n 4 -- -i --port-

> > topology=chained

> > +      testpmd> set fwd io

> > +      testpmd> start

> > +

> > +When test VLAN_UDP type packet transmission, set vlan:

> > +    testpmd> vlan set filter off 1

> > +    testpmd> start

> > +

> > +Boot up dpdk-pdump with pdump options::

> > +    ./x86_64-native-linuxapp-gcc/app/dpdk-pdump -- --pdump

> > 'port=0,queue=*,\

> > +    tx-dev=/tmp/pdump-tx.pcap,rx-dev=/tmp/pdump-rx.pcap,mbuf-size=2048'

> > +

> > +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

> > +

> > +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.

> > +

> > +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.

> > +

> > +Test Case 7: test pdump total num mbufs

> > +=================================

> > +test total-num-mbufs option, set value within [1025~65535]

> > +

> > +Boot up dpdk's testpmd with chained option::

> > +      ./x86_64-native-linuxapp-gcc/app/testpmd -c 0x6 -n 4 -- -i --port-

> > topology=chained

> > +      testpmd> set fwd io

> > +      testpmd> start

> > +

> > +When test VLAN_UDP type packet transmission, set vlan:

> > +    testpmd> vlan set filter off 1

> > +    testpmd> start

> > +

> > +Boot up dpdk-pdump with pdump options::

> > +    ./x86_64-native-linuxapp-gcc/app/dpdk-pdump -- --pdump

> > 'port=0,queue=*,\

> > +    tx-dev=/tmp/pdump-tx.pcap,rx-dev=/tmp/pdump-rx.pcap,total-num-

> > mbufs=8191'

> > +

> > +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

> > +

> > +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.

> > +

> > +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.

> > +

> > diff --git a/tests/TestSuite_packet_capture.py

> > b/tests/TestSuite_packet_capture.py

> > new file mode 100644

> > index 0000000..b6722ae

> > --- /dev/null

> > +++ b/tests/TestSuite_packet_capture.py

> > @@ -0,0 +1,756 @@

> > +# BSD LICENSE

> > +#

> > +# Copyright(c) 2010-2016 Intel Corporation. All rights reserved.

> > +# All rights reserved.

> > +#

> > +# Redistribution and use in source and binary forms, with or without

> > +# modification, are permitted provided that the following conditions

> > +# are met:

> > +#

> > +#   * Redistributions of source code must retain the above copyright

> > +#     notice, this list of conditions and the following disclaimer.

> > +#   * Redistributions in binary form must reproduce the above copyright

> > +#     notice, this list of conditions and the following disclaimer in

> > +#     the documentation and/or other materials provided with the

> > +#     distribution.

> > +#   * Neither the name of Intel Corporation nor the names of its

> > +#     contributors may be used to endorse or promote products derived

> > +#     from this software without specific prior written permission.

> > +#

> > +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

> > +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

> > +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR

> > +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT

> > +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

> > +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

> > +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

> > +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY

> > +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

> > +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

> > +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

> > +

> > +'''

> > +DPDK Test suite.

> > +Test support packet_capture features of dpdk-pdump tool

> > +'''

> > +

> > +import os

> > +

> > +import dts

> > +import time

> > +import re

> > +import types

> > +import random

> > +

> > +try:

> > +    from scapy.all import Conf as scapy_conf

> > +except ImportError:

> > +    from scapy.config import Conf as scapy_conf

> > +

> Not sure why need to include scapy config object, suite should not depend on it.

[Mo, YufengX] you haven't notice that scapy config is used in parse_packet_layer() to do layer parsing

>

> > +from scapy.utils import rdpcap

> > +from scapy.packet import NoPayload

> > +from scapy.packet import Packet as scapyPacket

> > +from scapy.fields import ConditionalField,Emph

> > +from scapy.base_classes import SetGen

> > +

> > +from test_case import TestCase

> > +from pmd_output import PmdOutput

> > +from packet import Packet, sniff_packets, load_sniff_packets

> > +

> > +print_flag = dts.debug_mode

> > +

> > +class parsePacket(object):

> > +    '''

> > +    this class is used to parse pcap files' packets' layer content

> > +    '''

> > +    def __init__(self, filename, skip_flag=False):

> > +        self.pcapFile = filename

> > +        self.scapy_conf = scapy_conf()

> > +        self.packetLayers = dict()

> > +        self.skip = skip_flag

> > +

> > +    def parse_packet_layer(self, pkt, indent=3, lvl="", label_lvl=""):

> > +        '''

> > +        parse one packet every layers' fields and value

> > +        '''

> > +        if pkt == None:

> > +            return

> > +        ct = self.scapy_conf.color_theme

> > +        if print_flag:

> > +            print "%s%s %s %s" % (label_lvl,

> > +                                  ct.punct("###["),

> > +                                  ct.layer_name(pkt.name),

> > +                                  ct.punct("]###"))

>

> This function contain much of useless code, look like only need to save packet information in self.packetLayers.

> This function look like scapy internal function, let discuss about it later.

>

> > +        self.packetLayers[ct.layer_name(pkt.name)] = dict()

> > +        for field in pkt.fields_desc:

> > +            if isinstance(field, ConditionalField) and not

> > field._evalcond(pkt):

> > +                continue

> > +

> > +            if isinstance(field, Emph) or field in self.scapy_conf.emph:

> > +                ncol = ct.emph_field_name

> > +                vcol = ct.emph_field_value

> > +            else:

> > +                ncol = ct.field_name

> > +                vcol = ct.field_value

> > +            fvalue = pkt.getfieldval(field.name)

> > +            if isinstance(fvalue, scapyPacket) or (field.islist and

> > field.holds_packets and type(fvalue) is list):

> > +                if print_flag:

> > +                    print "%s  \\%-10s\\<file:///\\%25-10s\>" % (label_lvl+lvl,

> > ncol(field.name))

> > +                    print "%s  \\%-10s\\<file:///\\%25-10s\>" % (label_lvl+lvl,

> > ncol(field.name))

> > +                fvalue_gen = SetGen(fvalue,_iterpacket=0)

> > +                for fvalue in fvalue_gen:

> > +                    fvalue.show(indent=indent, label_lvl=label_lvl+lvl+"

> > |")

> > +            else:

> > +                if print_flag:

> > +                    begn = "%s  %-10s%s " % (label_lvl+lvl,

> > +                                           ncol(field.name),

> > +                                            ct.punct("="),)

> > +                reprval = field.i2repr(pkt,fvalue)

> > +                if type(reprval) is str:

> > +                    reprval = reprval.replace("\n", "\n"+"

> > "*(len(label_lvl)

> > +                                                              +len(lvl)

> > +

> > +len(field.name)

> > +                                                              +4))

> > +                if print_flag:

> > +                    print "%s%s" % (begn,vcol(reprval))

> > +                self.packetLayers[ct.layer_name(pkt.name)][field.name] =

> > vcol(reprval)

> > +

> > +        if isinstance(pkt.payload, NoPayload):

> > +            return

> > +        else:

> > +            self.parse_packet_layer(pkt.payload, indent=indent,

> > lvl=lvl+(" "*indent*pkt.show_indent), label_lvl=label_lvl)

> > +

> > +    def get_valid_packet(self, pcap_pkts_origin, number):

> > +        cnt = 0

> > +        for packet in pcap_pkts_origin:

> > +            self.parse_packet_layer(packet)

> > +            if self.skip:

> > +                flag = 'LLDP' not in self.packetLayers.keys()

> > +            else:

> > +                flag = True

> > +            if self.packetLayers["Ethernet"]['dst'] ==

> > 'ff:ff:ff:ff:ff:ff' and flag:

> > +                if number == cnt:

> > +                    break

> > +                cnt += 1

> > +            self.packetLayers.clear()

> > +

> > +    def parse_pcap(self, number=0):

> > +        '''

> > +        parse one packet content

> > +        '''

> > +        pcap_pkts = []

> > +        try:

> > +            if os.path.exists(self.pcapFile) == False:

> > +                warning = "{0} is not exist !".format(self.pcapFile)

> > +                print warning

> > +                return warning

> > +

> > +            if print_flag:

> > +                print "open pcap <{0}>".format(self.pcapFile)

> > +            pcap_pkts = rdpcap(self.pcapFile)

> > +            # parse packets' every layers and fields

> > +            if len(pcap_pkts) == 0:

> > +                warning = "{0} is empty".format(self.pcapFile)

> > +                print warning

> > +                return warning

> > +            elif number>= len(pcap_pkts):

> > +                warning = "{0} is missing No.{1}

> > packet".format(self.pcapFile, number)

> > +                return warning

> > +

> > +            self.get_valid_packet(pcap_pkts, number)

> > +

> > +            if print_flag:

> > +                print self.packetLayers

> > +        except Exception,e:

> > +            print(Exception)

> > +            print(e)

> > +        finally:

> > +            pass

> > +

> > +        return None

> > +

> > +class TestPacketCapture(TestCase):

> > +    def set_up_all(self):

> > +        '''

> > +        Run at the start of each test suite.

> > +        '''

> > +        self.ports = self.dut.get_ports()

> > +        self.verify(self.target == "x86_64-native-linuxapp-gcc",

> > +                    "only support x86_64-native-linuxapp-gcc")

> > +        self.verify(len(self.ports) >= 2, "Insufficient ports for

> > testing")

> > +        self.test_port0_id = 0

> > +        self.test_port1_id = 1

> > +        # compile dpdk app with SW CONFIG_RTE_LIBRTE_PMD_PCAP open

> > +        self.dut_skip_compile = self.dut.skip_setup

> > +        if not (self.dut_skip_compile and self.check_pcap_lib()):

> > +            self.pcap_SW = "CONFIG_RTE_LIBRTE_PMD_PCAP"

> > +            self.dut.send_expect("sed -i -e 's/{0}=n$/{0}=y/'

> > config/common_base".format(self.pcap_SW), "# ", 30)

> > +            self.dut.skip_setup = False

> > +            self.dut.build_install_dpdk(self.target)

> > +        self.dut.session_ex = self.dut.new_session()

> > +        # secondary process (dpdk-pdump)

> > +        self.pdump_dir = self.dut.base_dir + os.sep +

> > "%s/build/app/pdump/" % self.target

> > +        exe_files = os.popen("ls {0} -F | grep

> > '*'".format(self.pdump_dir)).readlines()

> > +        if len(exe_files) == 1:

> > +            self.tool_name = exe_files[0][:-2]

> > +        else:

> > +            self.verify(False, "tool name exception !")

> > +        self.dut_dpdk_pdump_dir = self.dut.base_dir + os.sep +

> > "%s/app/%s" % (self.target, self.tool_name)

> > +        self.dpdk_pdump = self.dut_dpdk_pdump_dir + " -- --pdump "

> > +        self.send_pcap = "/tmp/scapy_%s_%s_%d.pcap"

> > +        self.src_mac = "11:22:33:44:55:66"

> > +        self.rx_pcap = "/tmp/pdump-rx.pcap"

> > +        self.tx_pcap = "/tmp/pdump-tx.pcap"

> > +        self.rxtx_pcap = "/tmp/pdump-rxtx.pcap"

> > +        self.rx_iface = None

> > +        self.tx_iface = None

> > +        self.rxtx_iface = None

> > +        self.rx_packet_pos = 0

> > +        self.tx_packet_pos = 0

> > +        self.dev_iface_flag = False

> > +        # primary process

> > +        self.pmdout = PmdOutput(self.dut)

> > +

> > +        # False: reduce test items for regression testing,

> > +        #        shut off base test environment checking

> > +        # True: make a full range testing

> > +        self.full_test = True

> > +

> > +    def check_pcap_lib(self):

> > +        pcap_lib_dir = self.dut.base_dir + os.sep +

> > "%s/lib/librte_pmd_pcap.a" % self.target

> > +        self.dut.send_expect("ll %s"%pcap_lib_dir, "# ")

> > +        if self.dut.send_expect("echo $?", "# ") == "0":

> > +            return True

> > +        else:

> > +            return False

> > +

> > +    def get_packet_types(self):

> > +        '''

> > +        '''

> > +        packet_types = ["TCP",

> > +                        "UDP",

> > +                        "SCTP",

> > +                        "TIMESYNC",

> > +                        "ARP",

> > +                        "LLDP",

> > +                        "IP_RAW",

> > +                        "IPv6_TCP",

> > +                        "IPv6_UDP",

> > +                        "IPv6_SCTP",

> > +                        "VLAN_UDP"]

> > +

> > +        if self.full_test:

> > +            test_packet_types = packet_types

> > +        else:

> > +            test_packet_types = ["TCP", "IPv6_TCP"]

> > +

> > +        return test_packet_types

> > +

> > +    def generate_options(self, port_id, pci, intf, types):

> > +        port_types = ["port=%d,"%port_id,

> > +                      "device_id=%s,"%pci]

> > +        dump_pcap_types = [["tx-dev={0},rx-dev={1},".format(self.tx_pcap,

> > self.rx_pcap),

> > +                       {"rx": [self.rx_pcap, 1],

> > +                        "tx": [self.tx_pcap, 1]}],

> > +                      ["rx-dev={0},".format(self.rx_pcap),

> > +                       {"rx": [self.rx_pcap, 1],

> > +                        "tx": [None, 0]}],

> > +                      ["tx-dev={0},".format(self.tx_pcap),

> > +                       {"rx": [None, 0],

> > +                        "tx": [self.tx_pcap, 1]}],

> > +                    ]

> > +        dump_iface_types = [["tx-dev={0},rx-

> > dev={1},".format(self.tx_iface, self.rx_iface),

> > +                       {"rx": [self.rx_pcap, 1],

> > +                        "tx": [self.tx_pcap, 1]}],

> > +                      ["rx-dev={0},".format(self.rx_iface),

> > +                       {"rx": [self.rx_pcap, 1],

> > +                        "tx": [None, 0]}],

> > +                      ["tx-dev={0},".format(self.tx_iface),

> > +                       {"rx": [None, 0],

> > +                        "tx": [self.tx_pcap, 1]}]

> > +                    ]

> > +

> > +        queue_types = ["queue=*,", "queue=0,"]

> > +        # ring size

> > +        maxPower = 27

> > +        minPower = 1

> > +        ring_size_types = ["ring-size=%d,"%(2**minPower),

> > +                           "ring-size=%d,"% (2**random.randint(minPower+1,

> > maxPower)),

> > +                           "ring-size=%d,"%(2**maxPower)]

> > +        # mbuf size

> > +        max_mbuf_size = 59520

> > +        min_mbuf_size = 252

> > +        mbuf_size_types = ["mbuf-size=%d,"%min_mbuf_size,

> > +                           "mbuf-size=%d,"%random.randint(min_mbuf_size+1,

> > max_mbuf_size),

> > +                           "mbuf-size=%d,"%max_mbuf_size]

> > +        # total number mbuf

> > +        max_total_num_mbufs = 65535

> > +        min_total_num_mbufs = 1025

> > +        total_num_mbufs_types = ["total-num-

> > mbufs=%d,"%min_total_num_mbufs,

> > +                                 "total-num-

> > mbufs=%d,"%random.randint(min_total_num_mbufs+1, max_total_num_mbufs),

> > +                                 "total-num-

> > mbufs=%d,"%max_total_num_mbufs]

> > +

> > +        if "port" in types:

> > +            port_num = len(port_types)

> > +        else:

> > +            port_num = 1

> > +

> > +        if "dev-pcap" in types:

> > +            dump_types = dump_pcap_types

> > +        elif  "dev-iface" in types:

> > +            dump_types = dump_iface_types

> > +        else:

> > +            dump_types = dump_pcap_types[:1]

> > +

> > +        if "queue" in types:

> > +            queue_num = len(queue_types)

> > +        else:

> > +            queue_num = 1

> > +

> > +        option_exds = [""]

> > +        if "ring_size" in types:

> > +            option_exds = ring_size_types[:]

> > +

> > +        if "mbuf_size" in types:

> > +            option_exds =  mbuf_size_types[:]

> > +

> > +        if "total_num_mbufs" in types:

> > +            option_exds = total_num_mbufs_types[:]

> > +

> > +        options = list()

> > +        for port in port_types[:port_num]:

> > +            for queue in queue_types[:queue_num]:

> > +                for dump in dump_types:

> > +                    for option_exd in option_exds:

> > +                        options.append([((port + queue+ dump[0]) +

> > option_exd)[:-1], dump[1]])

> > +

> > +        return options

> > +

> > +    def set_up(self):

> > +        '''

> > +        Run before each test case.

> > +        '''

> > +        self.exit_flag = False

> > +

> > +    def compare_pkts(self, refPkt=None, targetPkt=None, pkt_type=None,

> > refPacketNo=0, targetPacketNo=0):

> > +        '''

> > +        compare two pcap files' specified packet content

> > +        '''

> > +        if print_flag:

> > +            print "   " + "*"*50

> > +            print "   <%s> No.%d packet is the reference packet"%(refPkt,

> > refPacketNo)

> > +            print "   <%s> No.%d packet is the target packet"%(targetPkt,

> > targetPacketNo)

> > +            print "   " + "*"*50

> > +        warning = None

> > +        refObj = parsePacket(refPkt)

> > +        warning = refObj.parse_pcap(number=refPacketNo)

> > +        if warning:

> > +            return warning

> > +        if pkt_type == 'VLAN_UDP' and '802.1Q' in

> > refObj.packetLayers.keys():

> > +            refObj.packetLayers['Ethernet']['type'] =

> > refObj.packetLayers['802.1Q']['type']

> > +            refObj.packetLayers.pop('802.1Q')

> > +        targetObj = parsePacket(targetPkt)

> > +        warning = targetObj.parse_pcap(number=targetPacketNo)

> > +        if warning:

> > +            return warning

> > +        if "Padding" in  targetObj.packetLayers.keys():

> > +            targetObj.packetLayers.pop("Padding")

> > +        if len(refObj.packetLayers) != len(targetObj.packetLayers):

> > +            print "refObj:    %s"%refObj.packetLayers

> > +            print "targetObj: %s"%targetObj.packetLayers

> > +            warning = "packet {0} layers are not as

> > expected".format(targetPkt)

> > +            #print warning

> > +            return warning

> > +

> > +        for layer in refObj.packetLayers.keys():

> > +            if layer not in targetObj.packetLayers.keys():

> > +                warning = "{0} has no [{1}] layer".format(targetPkt,

> > layer)

> > +                #print warning

> > +                return warning

> > +

> > +            if (pkt_type in ['TIMESYNC', 'VLAN_UDP']) and layer == 'Raw':

> > +                continue

> > +

> > +            refLayerFields = refObj.packetLayers[layer]

> > +            targetLayerFields = targetObj.packetLayers[layer]

> > +            if len(refLayerFields) != len(targetLayerFields):

> > +                warning = "{0} [{1}] layer has no expected

> > fields".format(targetPkt, layer)

> > +                #print warning

> > +                return warning

> > +

> > +            for field in refLayerFields.keys():

> > +                if field not in targetLayerFields.keys():

> > +                    warning = "{0} layer [{1}] has no [{2}]

> > field".format(targetPkt, layer, field)

> > +                    #print warning

> > +                    return warning

> > +                if refLayerFields[field] != targetLayerFields[field]:

> > +                    warning = "{0} [{1}] layer [{2}] field has no

> > expected value".format(targetPkt, layer, field)

> > +                    #print warning

> > +                    return warning

> > +

> > +        return warning

> > +

> > +    def clear_ASLR(self):

> > +        self.dut.session_ex.send_expect("echo 0 >

> > /proc/sys/kernel/randomize_va_space", "#")

> > +        time.sleep(2)

> > +

> > +    def reset_ASLR(self):

> > +        self.dut.session_ex.send_expect("echo 2 >

> > /proc/sys/kernel/randomize_va_space", "#")

> > +        time.sleep(4)

> > +

> > +    def start_testpmd(self):

> > +        self.dut.send_expect("rm -fr /tmp/*", "# ")

> > +        # boot up testpmd

> > +        self.pmdout.start_testpmd("Default", "--port-topology=chained")

> > +        self.pmdout.execute_cmd("set fwd io")

> > +        self.pmdout.execute_cmd("start")

> > +        time.sleep(2)

> > +

> > +    def stop_testpmd(self):

> > +        # quit testpmd

> > +        self.pmdout.execute_cmd("stop")

> > +        self.pmdout.quit()

> > +        time.sleep(2)

> > +

> > +    def check_dut_file_exist(self, file_path):

> > +        self.dut.session_ex.send_expect("ll %s"%file_path, "#")

> > +        if self.dut.session_ex.send_expect("echo $?", "#") == "0":

> > +            return True

> > +        else:

> > +            return False

> > +

> > +    def start_tcpdump_pdump_iface(self, option):

> > +        if option["rx"][0] != None and option["tx"][0] != None and

> > option["rx"][0] == option["tx"][0]:

> > +            if self.check_dut_file_exist(self.rxtx_pcap):

> > +                self.dut.session_ex.send_expect("rm -f %s"%self.rxtx_pcap,

> > "#")

> > +            self.dut.session_ex.send_expect("tcpdump -i %s -P out -

> > w %s >/dev/null 2>&1 &" % (self.rxtx_iface, self.rxtx_pcap), "#")

> > +        else:

> > +            if option["rx"][0] != None:

> > +                if self.check_dut_file_exist(self.rx_pcap):

> > +                    self.dut.session_ex.send_expect("rm -

> > f %s"%self.rx_pcap, "#")

> > +                self.dut.session_ex.send_expect("tcpdump -i %s -P out -

> > w %s >/dev/null 2>&1 &" % (self.rx_iface, self.rx_pcap), "#")

> > +

> > +            if option["tx"][0] != None:

> > +                if self.check_dut_file_exist(self.tx_pcap):

> > +                    self.dut.session_ex.send_expect("rm -

> > f %s"%self.tx_pcap, "#")

> > +                self.dut.session_ex.send_expect("tcpdump -i %s -P out -

> > w %s >/dev/null 2>&1 &" % (self.tx_iface, self.tx_pcap), "#")

> > +        time.sleep(4)

> > +

> > +    def stop_tcpdump_pdump_iface(self):

> > +        self.dut.session_ex.send_expect("killall tcpdump", "# ", 5)

> > +        time.sleep(2)

> > +

> > +    def start_dpdk_pdump(self, option):

> > +        # boot up dpdk-pdump tool with packet_capture feature set

> > +        # delete last time dumped files

> > +        self.dut.session_ex.send_expect("rm -fr /tmp/*", "# ")

> > +        self.dut.session_ex.send_expect("cd %s"%self.dut.base_dir, "# ")

> > +        if print_flag: # for debugging

> > +            curTime = time.localtime()

> > +            microTime = "%04d%02d%02d-%02d_%02d_%02d"%(   curTime.tm_year,

> > +                                                     curTime.tm_mon,

> > +                                                     curTime.tm_mday,

> > +                                                     curTime.tm_hour,

> > +                                                     curTime.tm_min,

> > +                                                     curTime.tm_sec)

> > +            if self.check_dut_file_exist("/root/pdump/") == False:

> > +                self.dut.session_ex.send_expect("mkdir /root/pdump", "# ")

> > +            self.dut.session_ex.send_expect("echo %s "%self.dpdk_pdump +

> > " '%s' > /root/pdump/pdump_%s.log &"%(option[0], microTime), "# ")

> > +            self.dut.session_ex.send_expect(self.dpdk_pdump + " '%s' >>

> > /root/pdump/pdump_%s.log &"%(option[0], microTime), "# ", 15)

> > +        else:

> > +            self.dut.session_ex.send_expect(self.dpdk_pdump + "

> > '%s' >/dev/null 2>&1 &"%(option[0]), "# ")

> > +        time.sleep(6)

> > +

> > +    def check_pdump_ready(self, option):

> > +        rx_dump_pcap = option["rx"][0]

> > +        if rx_dump_pcap:

> > +            self.verify(self.check_dut_file_exist(rx_dump_pcap), "{1} {0}

> > is not ready".format(rx_dump_pcap, self.tool_name))

> > +        tx_dump_pcap = option["tx"][0]

> > +        if tx_dump_pcap:

> > +            self.verify(self.check_dut_file_exist(tx_dump_pcap), "{1} {0}

> > is not ready".format(tx_dump_pcap, self.tool_name))

> > +

> > +    def stop_dpdk_pdump(self):

> > +        # quit dpdk-pdump

> > +        self.dut.session_ex.send_expect("killall %s"%self.tool_name, "# ",

> > 5)

> > +        time.sleep(3)

> > +

> > +    def packet_capture_dump_packets(self, pkt_type, number, **kwargs):

> > +        if pkt_type == 'VLAN_UDP':

> > +            self.pmdout.execute_cmd("vlan set filter off 0")

> > +            self.pmdout.execute_cmd("vlan set filter off 1")

> > +            self.pmdout.execute_cmd("start")

> > +        # tester's port 0 and port 1 work under chained mode.

> > +        port_0 = self.ports[self.test_port0_id]

> > +        port_1 = self.ports[self.test_port1_id]

> > +        ################################################

> > +        # check send tx packet by port 0

> > +        # send packet to dut and compare dpdk-pdump dump pcap with scapy

> > pcap file

> > +        intf =

> > self.tester.get_interface(self.tester.get_local_port(port_1))

> > +        # prepare to catch replay packet in out port

> > +        recPaket = "/tmp/sniff_%s.pcap" % intf

> > +        if os.path.exists(recPaket):

> > +            os.remove(recPaket)

> > +        inst = sniff_packets(intf, count=1, timeout=15)

> > +        pkt = Packet(pkt_type=pkt_type)

> > +        if pkt_type == 'VLAN_UDP':

> > +            pkt.config_layer('dot1q', {'vlan': 20})

> > +        pkt.config_layer('ether', {'src': self.src_mac})

> > +        # save send packet in a pcap file

> > +        refPaket = self.send_pcap % (pkt_type, "rx", number)

> > +        if os.path.exists(refPaket):

> > +            os.remove(refPaket)

> > +        pkt.pktgen.write_pcap(refPaket)

> > +        # send out test packet

> > +        tester_port = self.tester.get_local_port(port_0)

> > +        intf = self.tester.get_interface(tester_port)

> > +        pkt.send_pkt(tx_port=intf)

> > +        # load pcap file catched by out port

> > +        time.sleep(1)

> > +        load_sniff_packets(inst)

> > +        # compare pcap file received by out port with scapy reference

> > packet pcap file

> > +        warning = self.compare_pkts(refPaket, recPaket, pkt_type)

> > +        self.verify(warning == None, "tcpdump rx Receive Packet error:

> > {0}".format(warning))

> > +        ################################################

> > +        # check send tx packet by port 1

> > +        # send packet to dut and compare dpdk-pdump dump pcap with scapy

> > pcap file

> > +        intf =

> > self.tester.get_interface(self.tester.get_local_port(port_0))

> > +        # prepare to catch replay packet in out port

> > +        recPaket = "/tmp/sniff_%s.pcap" % intf

> > +        if os.path.exists(recPaket):

> > +            os.remove(recPaket)

> > +        inst = sniff_packets(intf, count=1, timeout=15)

> > +        pkt = Packet(pkt_type=pkt_type)

> > +        if pkt_type == 'VLAN_UDP':

> > +            pkt.config_layer('dot1q', {'vlan': 20})

> > +        pkt.config_layer('ether', {'src': self.src_mac})

> > +        # save send packet in a pcap file

> > +        refPaket = self.send_pcap % (pkt_type, "tx", number)

> > +        if os.path.exists(refPaket):

> > +            os.remove(refPaket)

> > +        pkt.pktgen.write_pcap(refPaket)

> > +        # send out test packet

> > +        tester_port = self.tester.get_local_port(port_1)

> > +        intf = self.tester.get_interface(tester_port)

> > +        pkt.send_pkt(tx_port=intf)

> > +        # load pcap file catched by out port

> > +        time.sleep(1)

> > +        load_sniff_packets(inst)

> > +        # compare pcap file received by out port with scapy reference

> > packet pcap file

> > +        warning = self.compare_pkts(refPaket, recPaket, pkt_type)

> > +        self.verify(warning == None, "tcpdump tx Receive Packet error:

> > {0}".format(warning))

> > +

> > +    def packet_capture_check_pdump_pcaps(self, pkt_type, number,

> > **kwargs):

> > +        ################################################

> > +        rx_dump_pcap = kwargs["rx"][0]

> > +        if rx_dump_pcap:

> > +            self.verify(os.path.exists(rx_dump_pcap), "{0} doesn't

> > exist".format(rx_dump_pcap))

> > +            # save send packet in a pcap file

> > +            refPaket = self.send_pcap % (pkt_type, "rx", number)

> > +            self.verify(os.path.exists(refPaket), "{0} doesn't

> > exist".format(refPaket))

> > +            # compare pcap file dumped by dpdk-pdump with scapy reference

> > packet pcap file

> > +            warning = self.compare_pkts(refPaket, rx_dump_pcap, pkt_type,

> > targetPacketNo=self.rx_packet_pos)

> > +            if kwargs["rx"][1] == 2:

> > +                self.rx_packet_pos += kwargs["rx"][1]

> > +            else:

> > +                self.rx_packet_pos += 1

> > +            self.verify(warning == None, "dpdk-pdump rx dump packet error:

> > {0}".format(warning))

> > +            print "*"*36

> > +            print "pdump rx {0} packet content is

> > correct".format(pkt_type)

> > +            print "-"*36

> > +        ################################################

> > +        tx_dump_pcap = kwargs["tx"][0]

> > +        if tx_dump_pcap:

> > +            self.verify(os.path.exists(tx_dump_pcap), "{0} doesn't

> > exist".format(tx_dump_pcap))

> > +            # set send packet

> > +            refPaket = self.send_pcap % (pkt_type, "tx", number)

> > +            self.verify(os.path.exists(refPaket), "{0} doesn't

> > exist".format(refPaket))

> > +            # compare pcap file dumped by dpdk-pdump with scapy reference

> > packet pcap file

> > +            if kwargs["tx"][1] == 2 and self.tx_packet_pos == 0:

> > +                self.tx_packet_pos = 1

> > +            warning = self.compare_pkts(refPaket, tx_dump_pcap, pkt_type,

> > targetPacketNo=self.tx_packet_pos)

> > +            if kwargs["tx"][1] == 2:

> > +                self.tx_packet_pos += kwargs["tx"][1]

> > +            else:

> > +                self.tx_packet_pos += 1

> > +            self.verify(warning == None, "dpdk-pdump tx dump packet error:

> > {0}".format(warning))

> > +            print "*"*36

> > +            print "pdump tx {0} packet content is

> > correct".format(pkt_type)

> > +            print "-"*36

> > +

> > +    def packet_capture_test_packets(self, option):

> > +        self.clear_ASLR()

> > +        self.start_testpmd()

> > +        self.start_dpdk_pdump(option)

> > +        if self.dev_iface_flag == True:

> > +            self.start_tcpdump_pdump_iface(option[1])

> > +        self.check_pdump_ready(option[1])

> > +        number = 0

> > +        for packet_type in self.get_packet_types():

> > +            self.packet_capture_dump_packets(packet_type, number,

> > **option[1])

> > +            number += 1

> > +            time.sleep(2)

> > +        if self.dev_iface_flag == True:

> > +            self.stop_tcpdump_pdump_iface()

> > +        self.stop_dpdk_pdump()

> > +        self.stop_testpmd()

> > +

> > +        number = 0

> > +        self.rx_packet_pos = 0

> > +        self.tx_packet_pos = 0

> > +        for packet_type in self.get_packet_types():

> > +            self.packet_capture_check_pdump_pcaps(packet_type, number,

> > **option[1])

> > +            number += 1

> > +            time.sleep(2)

> > +        self.reset_ASLR()

> > +

> > +    def packet_capture_test_options(self, pdump_options):

> > +        try:

> > +            for option in pdump_options:

> > +                self.packet_capture_test_packets(option)

> > +

> > +            self.exit_flag = True

> > +        except Exception as e:

> > +            print e

> > +            raise Exception(e)

> > +

> > +    def test_pdump_port(self):

> > +        '''

> > +        test different port options::

> > +        * port=<dut port id>

> > +        * device_id=<dut pci address>

> > +        '''

> > +        port_id = self.test_port0_id

> > +        port_name = self.dut.ports_info[port_id]['intf']

> > +        port_pci = self.dut.ports_info[port_id]['pci']

> > +        test_types = ["port"]

> > +        self.packet_capture_test_options(self.generate_options( port_id,

> > port_pci, port_name, test_types))

> > +

> > +    def test_pdump_dev_pcap(self):

> > +        '''

> > +        test different dump options with pcap files as output::

> > +        * tx-dev=/tmp/pdump-tx.pcap,rx-dev=/tmp/pdump-rx.pcap

> > +        * rx-dev=/tmp/pdump-rx.pcap

> > +        * tx-dev=/tmp/pdump-tx.pcap

> > +        '''

> > +        port_id = self.test_port0_id

> > +        port_name = self.dut.ports_info[port_id]['intf']

> > +        port_pci = self.dut.ports_info[port_id]['pci']

> > +        test_types = ["dev-pcap"]

> > +        self.packet_capture_test_options(self.generate_options( port_id,

> > port_pci, port_name, test_types))

> > +

> > +    def get_dut_iface(self):

> > +        out = self.dut.send_expect("ip link show | grep LOWER_UP | awk

> > {'print $2'}", "#")

> > +        pat = "(.*):"

> > +        ifaces = re.findall(pat, out, re.M)

> > +        # get dut/tester ip to check if they are in a platform

> > +        tester_ip = self.tester.get_ip_address()

> > +        dut_ip = self.dut.get_ip_address()

> > +        for link_port in range(len(self.ports)):

> > +            # if they are in a platform, ignore interface used by tester

> > +            if tester_ip == dut_ip:

> > +                tester_port = self.tester.get_local_port(link_port)

> > +                intf = self.tester.get_interface(tester_port)

> > +                if intf in ifaces:

> > +                    ifaces.remove(intf)

> > +            # ignore interface used by dut

> > +            intf = self.dut.ports_info[link_port]['intf']

> > +            if intf in ifaces:

> > +                ifaces.remove(intf)

> > +        tmp_ifaces = ifaces[:]

> > +        for iface in tmp_ifaces:

> > +            # ignore current interface used by system

> > +            if self.dut.send_expect("ifconfig %s | grep 'inet ' "%iface,

> > "#") != "":

> > +                ifaces.remove(iface)

> > +

> > +        self.verify(len(ifaces) >= 2, "Insufficient ports for iface

> > testing")

> > +        # set iface port for pdump tool output dump packets

> > +        self.rx_iface = ifaces[0]

> > +        self.tx_iface = ifaces[1]

> > +        self.rxtx_iface = ifaces[0]

> > +

> > +    def test_pdump_dev_iface(self):

> > +        '''

> > +        test different dump options with interfaces as output::

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

> > +        * rx-dev=<dut rx port name>

> > +        * tx-dev=<dut tx port name>

> > +        '''

> > +        self.get_dut_iface()

> > +        port_id = self.test_port0_id

> > +        port_name = self.dut.ports_info[port_id]['intf']

> > +        port_pci = self.dut.ports_info[port_id]['pci']

> > +        test_types = ["dev-iface"]

> > +        self.dev_iface_flag = True

> > +        self.packet_capture_test_options(self.generate_options( port_id,

> > port_pci, port_name, test_types))

> > +

> > +    def test_pdump_queue(self):

> > +        '''

> > +        test different queue options::

> > +        * first queue:

> > +          queue=0

> > +        * all:

> > +          queue=*

> > +        '''

> > +        port_id = self.test_port0_id

> > +        port_name = self.dut.ports_info[port_id]['intf']

> > +        port_pci = self.dut.ports_info[port_id]['pci']

> > +        test_types = ["queue"]

> > +        self.packet_capture_test_options(self.generate_options( port_id,

> > port_pci, port_name, test_types))

> > +

> > +    def test_pdump_ring_size(self):

> > +        '''

> > +        test ring size option, set value within 2^[1~27]

> > +        '''

> > +        port_id = self.test_port0_id

> > +        port_name = self.dut.ports_info[port_id]['intf']

> > +        port_pci = self.dut.ports_info[port_id]['pci']

> > +        test_types = ["ring_size"]

> > +        self.packet_capture_test_options(self.generate_options( port_id,

> > port_pci, port_name, test_types))

> > +

> > +    def test_pdump_mbuf_size(self):

> > +        '''

> > +        test mbuf size option, set value within [252~59520]. min value is

> > decided by single packet size,

> > +        max value is decided by test platform memery size.

> > +        '''

> > +        port_id = self.test_port0_id

> > +        port_name = self.dut.ports_info[port_id]['intf']

> > +        port_pci = self.dut.ports_info[port_id]['pci']

> > +        test_types = ["mbuf_size"]

> > +        self.packet_capture_test_options(self.generate_options( port_id,

> > port_pci, port_name, test_types))

> > +

> > +    def test_pdump_total_num_mbufs(self):

> > +        '''

> > +        test total-num-mbufs option, set value within [1025~65535]

> > +        '''

> > +        port_id = self.test_port0_id

> > +        port_name = self.dut.ports_info[port_id]['intf']

> > +        port_pci = self.dut.ports_info[port_id]['pci']

> > +        test_types = ["total_num_mbufs"]

> > +        self.packet_capture_test_options(self.generate_options( port_id,

> > port_pci, port_name, test_types))

> > +

> > +    def tear_down(self):

> > +        '''

> > +        Run after each test case.

> > +        '''

> > +        if self.exit_flag == False:

> > +            self.stop_dpdk_pdump()

> > +            self.tester.send_expect("killall testpmd", "#")

> > +            self.tester.send_expect("killall tcpdump", "#")

> > +        if self.dev_iface_flag:

> > +            self.stop_tcpdump_pdump_iface()

> > +            self.dev_iface_flag = False

> > +

> > +    def tear_down_all(self):

> > +        '''

> > +        Run after each test suite.

> > +        '''

> > +        self.dut.kill_all()

> > +        # Restore the config file and recompile the package.

> > +        if not (self.dut_skip_compile and self.check_pcap_lib()):

> > +            self.reset_ASLR()

> > +            self.dut.send_expect("sed -i -e 's/{0}=y$/{0}=n/'

> > config/common_base".format(self.pcap_SW), "# ", 120)

> > +            # temporary disable skip_setup

> > +            skip_setup = self.dut.skip_setup

> > +            self.dut.skip_setup = True

> > +            self.dut.build_install_dpdk(self.target)

> > +            self.dut.skip_setup = skip_setup

> > --

> > 1.9.3

> >




More information about the dts mailing list