From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 084295A4D for ; Thu, 18 Aug 2016 11:11:21 +0200 (CEST) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP; 18 Aug 2016 02:11:20 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.28,538,1464678000"; d="scan'208";a="157667831" Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by fmsmga004.fm.intel.com with ESMTP; 18 Aug 2016 02:11:21 -0700 Received: from fmsmsx101.amr.corp.intel.com (10.18.124.199) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.248.2; Thu, 18 Aug 2016 02:10:42 -0700 Received: from shsmsx152.ccr.corp.intel.com (10.239.6.52) by fmsmsx101.amr.corp.intel.com (10.18.124.199) with Microsoft SMTP Server (TLS) id 14.3.248.2; Thu, 18 Aug 2016 02:10:42 -0700 Received: from shsmsx103.ccr.corp.intel.com ([169.254.4.181]) by SHSMSX152.ccr.corp.intel.com ([169.254.6.107]) with mapi id 14.03.0248.002; Thu, 18 Aug 2016 17:10:40 +0800 From: "Liu, Yong" To: "Mo, YufengX" , "dts@dpdk.org" Thread-Topic: [dts] [PATCH V1 2/2] Packet capture: upload automation testing script/test plan Thread-Index: AQHR+SRpAurfWpFU30e+myr56YcL46BOWxYA Date: Thu, 18 Aug 2016 09:10:39 +0000 Message-ID: <86228AFD5BCD8E4EBFD2B90117B5E81E222708BA@SHSMSX103.ccr.corp.intel.com> References: <1471502003-25292-1-git-send-email-yufengx.mo@intel.com> <1471502003-25292-3-git-send-email-yufengx.mo@intel.com> In-Reply-To: <1471502003-25292-3-git-send-email-yufengx.mo@intel.com> Accept-Language: zh-CN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiMmZhM2I5N2EtZGZlMi00YmM3LWEwNjAtYzI1YjU0MjRiZTE4IiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX0lDIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE1LjkuNi42IiwiVHJ1c3RlZExhYmVsSGFzaCI6IlI2TVFLNVBoS3BicGpHdWx0YytweGZYNkFIZUk5N2FRY2NRTERXWHVncXM9In0= x-ctpclassification: CTP_IC x-originating-ip: [10.239.127.40] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dts] [PATCH V1 2/2] Packet capture: upload automation testing script/test plan X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 18 Aug 2016 09:11:23 -0000 Hi Yufen, some concerns about this patch. > -----Original Message----- > From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of Mo, YufengX > Sent: Thursday, August 18, 2016 2:33 PM > To: dts@dpdk.org > Cc: Mo, YufengX > Subject: [dts] [PATCH V1 2/2] Packet capture: upload automation testing > script/test plan >=20 > From: yufengmx >=20 >=20 > Packet capture framework feature support packet capturing on dpdk etherne= t > devices. > DPDK provides dpdk-pdump tool under app/pdump directory for packet > capturing on dpdk. >=20 > 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 dpd= k > 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=3Dy and recompil= ing > the DPDK. >=20 > Signed-off-by: yufengmx > --- > 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 >=20 > 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. > + > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > + packet capture framework feature > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > + > +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 o= n > socket.If packet > +matches, reference count of packet will be incremented and enqueued to > second rte_ring for > +the secondary process to use. > + > +Prerequisites > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > +* 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 > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > +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=3D > +'(port =3D |device_id =3D ), > +(queue=3D), > +(rx-dev=3D | tx-dev=3D= ), > +[ring-size=3D], > +[mbuf-size=3D], > +[total-num-mbufs=3D]' > + > +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=3D'FF:FF:FF:FF:FF:FF',type=3D0x88f7)/"\\x00\\x02"] > +* ARP > + [Ether(dst=3D'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=3Digb_uio 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, whic= h > haven't been binded > + to dpdk and have been in linked status > + > +Test Case 1: test pdump port > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D > +test different port options:: > +* port=3D > +* device_id=3D > + > +Boot up dpdk's testpmd with chained option:: > + ./x86_64-native-linuxapp-gcc/app/testpmd -c 0x6 -n 4 -- -i --port- > topology=3Dchained > + 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 ' option>,queue=3D*,\ > + tx-dev=3D/tmp/pdump-tx.pcap,rx-dev=3D/tmp/pdump-rx.pcap' > + > +Set up linux's tcpdump to receiver packet on tester:: > + tcpdump -i -w /tmp/sniff-.pcap > + tcpdump -i -w /tmp/sniff-.pcap > + > +Send packet on tester by port 0:: > + sendp(, iface=3D) > + > +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(, iface=3D) > + > +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 > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D > +test different queue options:: > +* first queue: > + queue=3D0 > +* all: > + queue=3D* > + > +Boot up dpdk's testpmd with chained option:: > + ./x86_64-native-linuxapp-gcc/app/testpmd -c 0x6 -n 4 -- -i --port- > topology=3Dchained > + 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=3D0,,\ > + tx-dev=3D/tmp/pdump-tx.pcap,rx-dev=3D/tmp/pdump-rx.pcap' > + > +Set up linux's tcpdump to receiver packet on tester:: > + tcpdump -i -w /tmp/sniff-.pcap > + tcpdump -i -w /tmp/sniff-.pcap > + > +Send packet on tester by port 0:: > + sendp(, iface=3D) > + > +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(, iface=3D) > + > +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 > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D > +test different dump options:: > +* tx-dev=3D/tmp/pdump-tx.pcap,rx-dev=3D/tmp/pdump-rx.pcap > +* rx-dev=3D/tmp/pdump-rx.pcap > +* tx-dev=3D/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=3Dchained > + 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=3D0,queue=3D*,' > + > +Set up linux's tcpdump to receiver packet on tester:: > + tcpdump -i -w /tmp/sniff-.pcap > + tcpdump -i -w /tmp/sniff-.pcap > + > +Send packet on tester by port 0:: > + sendp(, iface=3D) > + > +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(, iface=3D) > + > +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 > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D > +test different dump options:: > +* tx-dev=3D,rx-dev=3D > +* rx-dev=3D > +* tx-dev=3D > + > +Boot up dpdk's testpmd with chained option:: > + ./x86_64-native-linuxapp-gcc/app/testpmd -c 0x6 -n 4 -- -i --port- > topology=3Dchained > + 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=3D0,queue=3D*,' > + > +Set up linux's tcpdump to receiver packet on tester:: > + tcpdump -i -w /tmp/sniff-.pcap > + tcpdump -i -w /tmp/sniff-.pcap > + > +Set up linux's tcpdump to receiver packet of dpdk-pdump on Dut:: > + when rx-dev is set > + tcpdump -i -w /tmp/pdump-rx.pcap > + > + when tx-dev is set > + tcpdump -i -w /tmp/pdump-tx.pcap > + > +Send packet on tester by port 0:: > + sendp(, iface=3D) > + > +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(, iface=3D) > + > +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 > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D > +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=3Dchained > + 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=3D0,queue=3D*,\ > + tx-dev=3D/tmp/pdump-tx.pcap,rx-dev=3D/tmp/pdump-rx.pcap,ring-size=3D= 1024' > + > +Set up linux's tcpdump to receiver packet on tester:: > + tcpdump -i -w /tmp/sniff-.pcap > + tcpdump -i -w /tmp/sniff-.pcap > + > +Send packet on tester by port 0:: > + sendp(, iface=3D) > + > +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(, iface=3D) > + > +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 > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D > +test mbuf size option, set value within [252~59520]. min value is decide= d > 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=3Dchained > + 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=3D0,queue=3D*,\ > + tx-dev=3D/tmp/pdump-tx.pcap,rx-dev=3D/tmp/pdump-rx.pcap,mbuf-size=3D= 2048' > + > +Set up linux's tcpdump to receiver packet on tester:: > + tcpdump -i -w /tmp/sniff-.pcap > + tcpdump -i -w /tmp/sniff-.pcap > + > +Send packet on tester by port 0:: > + sendp(, iface=3D) > + > +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(, iface=3D) > + > +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 > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D > +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=3Dchained > + 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=3D0,queue=3D*,\ > + tx-dev=3D/tmp/pdump-tx.pcap,rx-dev=3D/tmp/pdump-rx.pcap,total-num- > mbufs=3D8191' > + > +Set up linux's tcpdump to receiver packet on tester:: > + tcpdump -i -w /tmp/sniff-.pcap > + tcpdump -i -w /tmp/sniff-.pcap > + > +Send packet on tester by port 0:: > + sendp(, iface=3D) > + > +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(, iface=3D) > + > +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 o= n it. > +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 =3D dts.debug_mode > + > +class parsePacket(object): > + ''' > + this class is used to parse pcap files' packets' layer content > + ''' > + def __init__(self, filename, skip_flag=3DFalse): > + self.pcapFile =3D filename > + self.scapy_conf =3D scapy_conf() > + self.packetLayers =3D dict() > + self.skip =3D skip_flag > + > + def parse_packet_layer(self, pkt, indent=3D3, lvl=3D"", label_lvl=3D= ""): > + ''' > + parse one packet every layers' fields and value > + ''' > + if pkt =3D=3D None: > + return > + ct =3D 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 pac= ket information in self.packetLayers.=20 This function look like scapy internal function, let discuss about it later= . > + self.packetLayers[ct.layer_name(pkt.name)] =3D 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 =3D ct.emph_field_name > + vcol =3D ct.emph_field_value > + else: > + ncol =3D ct.field_name > + vcol =3D ct.field_value > + fvalue =3D 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\\" % (label_lvl+lvl, > ncol(field.name)) > + print "%s \\%-10s\\" % (label_lvl+lvl, > ncol(field.name)) > + fvalue_gen =3D SetGen(fvalue,_iterpacket=3D0) > + for fvalue in fvalue_gen: > + fvalue.show(indent=3Dindent, label_lvl=3Dlabel_lvl+l= vl+" > |") > + else: > + if print_flag: > + begn =3D "%s %-10s%s " % (label_lvl+lvl, > + ncol(field.name), > + ct.punct("=3D"),) > + reprval =3D field.i2repr(pkt,fvalue) > + if type(reprval) is str: > + reprval =3D 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] = =3D > vcol(reprval) > + > + if isinstance(pkt.payload, NoPayload): > + return > + else: > + self.parse_packet_layer(pkt.payload, indent=3Dindent, > lvl=3Dlvl+(" "*indent*pkt.show_indent), label_lvl=3Dlabel_lvl) > + > + def get_valid_packet(self, pcap_pkts_origin, number): > + cnt =3D 0 > + for packet in pcap_pkts_origin: > + self.parse_packet_layer(packet) > + if self.skip: > + flag =3D 'LLDP' not in self.packetLayers.keys() > + else: > + flag =3D True > + if self.packetLayers["Ethernet"]['dst'] =3D=3D > 'ff:ff:ff:ff:ff:ff' and flag: > + if number =3D=3D cnt: > + break > + cnt +=3D 1 > + self.packetLayers.clear() > + > + def parse_pcap(self, number=3D0): > + ''' > + parse one packet content > + ''' > + pcap_pkts =3D [] > + try: > + if os.path.exists(self.pcapFile) =3D=3D False: > + warning =3D "{0} is not exist !".format(self.pcapFile) > + print warning > + return warning > + > + if print_flag: > + print "open pcap <{0}>".format(self.pcapFile) > + pcap_pkts =3D rdpcap(self.pcapFile) > + # parse packets' every layers and fields > + if len(pcap_pkts) =3D=3D 0: > + warning =3D "{0} is empty".format(self.pcapFile) > + print warning > + return warning > + elif number>=3D len(pcap_pkts): > + warning =3D "{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 =3D self.dut.get_ports() > + self.verify(self.target =3D=3D "x86_64-native-linuxapp-gcc", > + "only support x86_64-native-linuxapp-gcc") > + self.verify(len(self.ports) >=3D 2, "Insufficient ports for > testing") > + self.test_port0_id =3D 0 > + self.test_port1_id =3D 1 > + # compile dpdk app with SW CONFIG_RTE_LIBRTE_PMD_PCAP open > + self.dut_skip_compile =3D self.dut.skip_setup > + if not (self.dut_skip_compile and self.check_pcap_lib()): > + self.pcap_SW =3D "CONFIG_RTE_LIBRTE_PMD_PCAP" > + self.dut.send_expect("sed -i -e 's/{0}=3Dn$/{0}=3Dy/' > config/common_base".format(self.pcap_SW), "# ", 30) > + self.dut.skip_setup =3D False > + self.dut.build_install_dpdk(self.target) > + self.dut.session_ex =3D self.dut.new_session() > + # secondary process (dpdk-pdump) > + self.pdump_dir =3D self.dut.base_dir + os.sep + > "%s/build/app/pdump/" % self.target > + exe_files =3D os.popen("ls {0} -F | grep > '*'".format(self.pdump_dir)).readlines() > + if len(exe_files) =3D=3D 1: > + self.tool_name =3D exe_files[0][:-2] > + else: > + self.verify(False, "tool name exception !") > + self.dut_dpdk_pdump_dir =3D self.dut.base_dir + os.sep + > "%s/app/%s" % (self.target, self.tool_name) > + self.dpdk_pdump =3D self.dut_dpdk_pdump_dir + " -- --pdump " > + self.send_pcap =3D "/tmp/scapy_%s_%s_%d.pcap" > + self.src_mac =3D "11:22:33:44:55:66" > + self.rx_pcap =3D "/tmp/pdump-rx.pcap" > + self.tx_pcap =3D "/tmp/pdump-tx.pcap" > + self.rxtx_pcap =3D "/tmp/pdump-rxtx.pcap" > + self.rx_iface =3D None > + self.tx_iface =3D None > + self.rxtx_iface =3D None > + self.rx_packet_pos =3D 0 > + self.tx_packet_pos =3D 0 > + self.dev_iface_flag =3D False > + # primary process > + self.pmdout =3D 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 =3D True > + > + def check_pcap_lib(self): > + pcap_lib_dir =3D 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 $?", "# ") =3D=3D "0": > + return True > + else: > + return False > + > + def get_packet_types(self): > + ''' > + ''' > + packet_types =3D ["TCP", > + "UDP", > + "SCTP", > + "TIMESYNC", > + "ARP", > + "LLDP", > + "IP_RAW", > + "IPv6_TCP", > + "IPv6_UDP", > + "IPv6_SCTP", > + "VLAN_UDP"] > + > + if self.full_test: > + test_packet_types =3D packet_types > + else: > + test_packet_types =3D ["TCP", "IPv6_TCP"] > + > + return test_packet_types > + > + def generate_options(self, port_id, pci, intf, types): > + port_types =3D ["port=3D%d,"%port_id, > + "device_id=3D%s,"%pci] > + dump_pcap_types =3D [["tx-dev=3D{0},rx-dev=3D{1},".format(self.t= x_pcap, > self.rx_pcap), > + {"rx": [self.rx_pcap, 1], > + "tx": [self.tx_pcap, 1]}], > + ["rx-dev=3D{0},".format(self.rx_pcap), > + {"rx": [self.rx_pcap, 1], > + "tx": [None, 0]}], > + ["tx-dev=3D{0},".format(self.tx_pcap), > + {"rx": [None, 0], > + "tx": [self.tx_pcap, 1]}], > + ] > + dump_iface_types =3D [["tx-dev=3D{0},rx- > dev=3D{1},".format(self.tx_iface, self.rx_iface), > + {"rx": [self.rx_pcap, 1], > + "tx": [self.tx_pcap, 1]}], > + ["rx-dev=3D{0},".format(self.rx_iface), > + {"rx": [self.rx_pcap, 1], > + "tx": [None, 0]}], > + ["tx-dev=3D{0},".format(self.tx_iface), > + {"rx": [None, 0], > + "tx": [self.tx_pcap, 1]}] > + ] > + > + queue_types =3D ["queue=3D*,", "queue=3D0,"] > + # ring size > + maxPower =3D 27 > + minPower =3D 1 > + ring_size_types =3D ["ring-size=3D%d,"%(2**minPower), > + "ring-size=3D%d,"% (2**random.randint(minPowe= r+1, > maxPower)), > + "ring-size=3D%d,"%(2**maxPower)] > + # mbuf size > + max_mbuf_size =3D 59520 > + min_mbuf_size =3D 252 > + mbuf_size_types =3D ["mbuf-size=3D%d,"%min_mbuf_size, > + "mbuf-size=3D%d,"%random.randint(min_mbuf_siz= e+1, > max_mbuf_size), > + "mbuf-size=3D%d,"%max_mbuf_size] > + # total number mbuf > + max_total_num_mbufs =3D 65535 > + min_total_num_mbufs =3D 1025 > + total_num_mbufs_types =3D ["total-num- > mbufs=3D%d,"%min_total_num_mbufs, > + "total-num- > mbufs=3D%d,"%random.randint(min_total_num_mbufs+1, max_total_num_mbufs), > + "total-num- > mbufs=3D%d,"%max_total_num_mbufs] > + > + if "port" in types: > + port_num =3D len(port_types) > + else: > + port_num =3D 1 > + > + if "dev-pcap" in types: > + dump_types =3D dump_pcap_types > + elif "dev-iface" in types: > + dump_types =3D dump_iface_types > + else: > + dump_types =3D dump_pcap_types[:1] > + > + if "queue" in types: > + queue_num =3D len(queue_types) > + else: > + queue_num =3D 1 > + > + option_exds =3D [""] > + if "ring_size" in types: > + option_exds =3D ring_size_types[:] > + > + if "mbuf_size" in types: > + option_exds =3D mbuf_size_types[:] > + > + if "total_num_mbufs" in types: > + option_exds =3D total_num_mbufs_types[:] > + > + options =3D 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 =3D False > + > + def compare_pkts(self, refPkt=3DNone, targetPkt=3DNone, pkt_type=3DN= one, > refPacketNo=3D0, targetPacketNo=3D0): > + ''' > + 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 =3D None > + refObj =3D parsePacket(refPkt) > + warning =3D refObj.parse_pcap(number=3DrefPacketNo) > + if warning: > + return warning > + if pkt_type =3D=3D 'VLAN_UDP' and '802.1Q' in > refObj.packetLayers.keys(): > + refObj.packetLayers['Ethernet']['type'] =3D > refObj.packetLayers['802.1Q']['type'] > + refObj.packetLayers.pop('802.1Q') > + targetObj =3D parsePacket(targetPkt) > + warning =3D targetObj.parse_pcap(number=3DtargetPacketNo) > + if warning: > + return warning > + if "Padding" in targetObj.packetLayers.keys(): > + targetObj.packetLayers.pop("Padding") > + if len(refObj.packetLayers) !=3D len(targetObj.packetLayers): > + print "refObj: %s"%refObj.packetLayers > + print "targetObj: %s"%targetObj.packetLayers > + warning =3D "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 =3D "{0} has no [{1}] layer".format(targetPkt, > layer) > + #print warning > + return warning > + > + if (pkt_type in ['TIMESYNC', 'VLAN_UDP']) and layer =3D=3D '= Raw': > + continue > + > + refLayerFields =3D refObj.packetLayers[layer] > + targetLayerFields =3D targetObj.packetLayers[layer] > + if len(refLayerFields) !=3D len(targetLayerFields): > + warning =3D "{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 =3D "{0} layer [{1}] has no [{2}] > field".format(targetPkt, layer, field) > + #print warning > + return warning > + if refLayerFields[field] !=3D targetLayerFields[field]: > + warning =3D "{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=3Dchained"= ) > + 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 $?", "#") =3D=3D "0": > + return True > + else: > + return False > + > + def start_tcpdump_pdump_iface(self, option): > + if option["rx"][0] !=3D None and option["tx"][0] !=3D None and > option["rx"][0] =3D=3D option["tx"][0]: > + if self.check_dut_file_exist(self.rxtx_pcap): > + self.dut.session_ex.send_expect("rm -f %s"%self.rxtx_pca= p, > "#") > + 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] !=3D 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] !=3D 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 =3D time.localtime() > + microTime =3D "%04d%02d%02d-%02d_%02d_%02d"%( curTime.tm_y= ear, > + curTime.tm_mon, > + curTime.tm_mday, > + curTime.tm_hour, > + curTime.tm_min, > + curTime.tm_sec) > + if self.check_dut_file_exist("/root/pdump/") =3D=3D 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 =3D 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 =3D 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 =3D=3D '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 =3D self.ports[self.test_port0_id] > + port_1 =3D 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 =3D > self.tester.get_interface(self.tester.get_local_port(port_1)) > + # prepare to catch replay packet in out port > + recPaket =3D "/tmp/sniff_%s.pcap" % intf > + if os.path.exists(recPaket): > + os.remove(recPaket) > + inst =3D sniff_packets(intf, count=3D1, timeout=3D15) > + pkt =3D Packet(pkt_type=3Dpkt_type) > + if pkt_type =3D=3D 'VLAN_UDP': > + pkt.config_layer('dot1q', {'vlan': 20}) > + pkt.config_layer('ether', {'src': self.src_mac}) > + # save send packet in a pcap file > + refPaket =3D 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 =3D self.tester.get_local_port(port_0) > + intf =3D self.tester.get_interface(tester_port) > + pkt.send_pkt(tx_port=3Dintf) > + # 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 =3D self.compare_pkts(refPaket, recPaket, pkt_type) > + self.verify(warning =3D=3D None, "tcpdump rx Receive Packet erro= r: > {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 =3D > self.tester.get_interface(self.tester.get_local_port(port_0)) > + # prepare to catch replay packet in out port > + recPaket =3D "/tmp/sniff_%s.pcap" % intf > + if os.path.exists(recPaket): > + os.remove(recPaket) > + inst =3D sniff_packets(intf, count=3D1, timeout=3D15) > + pkt =3D Packet(pkt_type=3Dpkt_type) > + if pkt_type =3D=3D 'VLAN_UDP': > + pkt.config_layer('dot1q', {'vlan': 20}) > + pkt.config_layer('ether', {'src': self.src_mac}) > + # save send packet in a pcap file > + refPaket =3D 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 =3D self.tester.get_local_port(port_1) > + intf =3D self.tester.get_interface(tester_port) > + pkt.send_pkt(tx_port=3Dintf) > + # 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 =3D self.compare_pkts(refPaket, recPaket, pkt_type) > + self.verify(warning =3D=3D None, "tcpdump tx Receive Packet erro= r: > {0}".format(warning)) > + > + def packet_capture_check_pdump_pcaps(self, pkt_type, number, > **kwargs): > + ################################################ > + rx_dump_pcap =3D 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 =3D 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 referenc= e > packet pcap file > + warning =3D self.compare_pkts(refPaket, rx_dump_pcap, pkt_ty= pe, > targetPacketNo=3Dself.rx_packet_pos) > + if kwargs["rx"][1] =3D=3D 2: > + self.rx_packet_pos +=3D kwargs["rx"][1] > + else: > + self.rx_packet_pos +=3D 1 > + self.verify(warning =3D=3D 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 =3D 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 =3D 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 referenc= e > packet pcap file > + if kwargs["tx"][1] =3D=3D 2 and self.tx_packet_pos =3D=3D 0: > + self.tx_packet_pos =3D 1 > + warning =3D self.compare_pkts(refPaket, tx_dump_pcap, pkt_ty= pe, > targetPacketNo=3Dself.tx_packet_pos) > + if kwargs["tx"][1] =3D=3D 2: > + self.tx_packet_pos +=3D kwargs["tx"][1] > + else: > + self.tx_packet_pos +=3D 1 > + self.verify(warning =3D=3D 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 =3D=3D True: > + self.start_tcpdump_pdump_iface(option[1]) > + self.check_pdump_ready(option[1]) > + number =3D 0 > + for packet_type in self.get_packet_types(): > + self.packet_capture_dump_packets(packet_type, number, > **option[1]) > + number +=3D 1 > + time.sleep(2) > + if self.dev_iface_flag =3D=3D True: > + self.stop_tcpdump_pdump_iface() > + self.stop_dpdk_pdump() > + self.stop_testpmd() > + > + number =3D 0 > + self.rx_packet_pos =3D 0 > + self.tx_packet_pos =3D 0 > + for packet_type in self.get_packet_types(): > + self.packet_capture_check_pdump_pcaps(packet_type, number, > **option[1]) > + number +=3D 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 =3D True > + except Exception as e: > + print e > + raise Exception(e) > + > + def test_pdump_port(self): > + ''' > + test different port options:: > + * port=3D > + * device_id=3D > + ''' > + port_id =3D self.test_port0_id > + port_name =3D self.dut.ports_info[port_id]['intf'] > + port_pci =3D self.dut.ports_info[port_id]['pci'] > + test_types =3D ["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=3D/tmp/pdump-tx.pcap,rx-dev=3D/tmp/pdump-rx.pcap > + * rx-dev=3D/tmp/pdump-rx.pcap > + * tx-dev=3D/tmp/pdump-tx.pcap > + ''' > + port_id =3D self.test_port0_id > + port_name =3D self.dut.ports_info[port_id]['intf'] > + port_pci =3D self.dut.ports_info[port_id]['pci'] > + test_types =3D ["dev-pcap"] > + self.packet_capture_test_options(self.generate_options( port_id, > port_pci, port_name, test_types)) > + > + def get_dut_iface(self): > + out =3D self.dut.send_expect("ip link show | grep LOWER_UP | awk > {'print $2'}", "#") > + pat =3D "(.*):" > + ifaces =3D re.findall(pat, out, re.M) > + # get dut/tester ip to check if they are in a platform > + tester_ip =3D self.tester.get_ip_address() > + dut_ip =3D 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 =3D=3D dut_ip: > + tester_port =3D self.tester.get_local_port(link_port) > + intf =3D self.tester.get_interface(tester_port) > + if intf in ifaces: > + ifaces.remove(intf) > + # ignore interface used by dut > + intf =3D self.dut.ports_info[link_port]['intf'] > + if intf in ifaces: > + ifaces.remove(intf) > + tmp_ifaces =3D ifaces[:] > + for iface in tmp_ifaces: > + # ignore current interface used by system > + if self.dut.send_expect("ifconfig %s | grep 'inet ' "%iface, > "#") !=3D "": > + ifaces.remove(iface) > + > + self.verify(len(ifaces) >=3D 2, "Insufficient ports for iface > testing") > + # set iface port for pdump tool output dump packets > + self.rx_iface =3D ifaces[0] > + self.tx_iface =3D ifaces[1] > + self.rxtx_iface =3D ifaces[0] > + > + def test_pdump_dev_iface(self): > + ''' > + test different dump options with interfaces as output:: > + * tx-dev=3D,rx-dev=3D > + * rx-dev=3D > + * tx-dev=3D > + ''' > + self.get_dut_iface() > + port_id =3D self.test_port0_id > + port_name =3D self.dut.ports_info[port_id]['intf'] > + port_pci =3D self.dut.ports_info[port_id]['pci'] > + test_types =3D ["dev-iface"] > + self.dev_iface_flag =3D 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=3D0 > + * all: > + queue=3D* > + ''' > + port_id =3D self.test_port0_id > + port_name =3D self.dut.ports_info[port_id]['intf'] > + port_pci =3D self.dut.ports_info[port_id]['pci'] > + test_types =3D ["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 =3D self.test_port0_id > + port_name =3D self.dut.ports_info[port_id]['intf'] > + port_pci =3D self.dut.ports_info[port_id]['pci'] > + test_types =3D ["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 i= s > decided by single packet size, > + max value is decided by test platform memery size. > + ''' > + port_id =3D self.test_port0_id > + port_name =3D self.dut.ports_info[port_id]['intf'] > + port_pci =3D self.dut.ports_info[port_id]['pci'] > + test_types =3D ["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 =3D self.test_port0_id > + port_name =3D self.dut.ports_info[port_id]['intf'] > + port_pci =3D self.dut.ports_info[port_id]['pci'] > + test_types =3D ["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 =3D=3D 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 =3D 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}=3Dy$/{0}=3Dn/' > config/common_base".format(self.pcap_SW), "# ", 120) > + # temporary disable skip_setup > + skip_setup =3D self.dut.skip_setup > + self.dut.skip_setup =3D True > + self.dut.build_install_dpdk(self.target) > + self.dut.skip_setup =3D skip_setup > -- > 1.9.3 >=20