From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id D5D562B9F for ; Tue, 8 Mar 2016 02:49:55 +0100 (CET) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga101.jf.intel.com with ESMTP; 07 Mar 2016 17:49:55 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,554,1449561600"; d="scan'208";a="931799830" Received: from fmsmsx104.amr.corp.intel.com ([10.18.124.202]) by fmsmga002.fm.intel.com with ESMTP; 07 Mar 2016 17:49:55 -0800 Received: from fmsmsx116.amr.corp.intel.com (10.18.116.20) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.248.2; Mon, 7 Mar 2016 17:49:54 -0800 Received: from shsmsx104.ccr.corp.intel.com (10.239.110.15) by fmsmsx116.amr.corp.intel.com (10.18.116.20) with Microsoft SMTP Server (TLS) id 14.3.248.2; Mon, 7 Mar 2016 17:49:54 -0800 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.232]) by SHSMSX104.ccr.corp.intel.com ([169.254.5.132]) with mapi id 14.03.0248.002; Tue, 8 Mar 2016 09:49:48 +0800 From: "Tu, LijuanX A" To: "Pei, Yulong" , "dts@dpdk.org" Thread-Topic: [dts][PATCH v3]tests,test_plans: add checksum offload and tso Thread-Index: AQHRc4E5eBQCi8bTrUaPo4zPIkwW3p9OyI5ggAAJO9A= Date: Tue, 8 Mar 2016 01:49:47 +0000 Message-ID: <38D041F150D4184C8114E499040E623407282559@shsmsx102.ccr.corp.intel.com> References: <1456812437-16857-1-git-send-email-lijuanx.a.tu@intel.com> <188971FCDA171749BED5DA74ABF3E6F00353CF0A@shsmsx102.ccr.corp.intel.com> In-Reply-To: <188971FCDA171749BED5DA74ABF3E6F00353CF0A@shsmsx102.ccr.corp.intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: 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 v3]tests,test_plans: add checksum offload and tso 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: Tue, 08 Mar 2016 01:49:56 -0000 Hi ,yulong, I use scapy to send packets and check checksum.=20 IXIA is an example as an tester packet generator=09 > -----Original Message----- > From: Pei, Yulong > Sent: Tuesday, March 08, 2016 9:45 AM > To: Tu, LijuanX A; dts@dpdk.org > Subject: RE: [dts][PATCH v3]tests,test_plans: add checksum offload and > tso >=20 > Hi Lijuan, >=20 > Please see my comment's below, >=20 >=20 > -----Original Message----- > From: Tu, LijuanX A > Sent: Tuesday, March 1, 2016 2:07 PM > To: dts@dpdk.org; Pei, Yulong > Cc: Tu, LijuanX A > Subject: [dts][PATCH v3]tests,test_plans: add checksum offload and tso >=20 > Add checksum offload and tso test scripts, test plan, config file >=20 > Signed-off-by: Lijuan Tu > --- > conf/vf_offload.cfg | 107 ++++++++++ > test_plans/vf_offload_test_plan.rst | 175 +++++++++++++++++ > tests/TestSuite_vf_offload.py | 380 > ++++++++++++++++++++++++++++++++++++ > 3 files changed, 662 insertions(+) > create mode 100644 conf/vf_offload.cfg > create mode 100644 test_plans/vf_offload_test_plan.rst > create mode 100644 tests/TestSuite_vf_offload.py >=20 > diff --git a/conf/vf_offload.cfg b/conf/vf_offload.cfg new file mode > 100644 index 0000000..ab1c0c7 > --- /dev/null > +++ b/conf/vf_offload.cfg > @@ -0,0 +1,107 @@ > +# QEMU options > +# name > +# name: vm0 > +# > +# enable_kvm > +# enable: [yes | no] > +# > +# cpu > +# model: [host | core2duo | ...] > +# usage: > +# choose model value from the command > +# qemu-system-x86_64 -cpu help > +# number: '4' #number of vcpus > +# cpupin: '3 4 5 6' # host cpu list > +# > +# mem > +# size: 1024 > +# > +# disk > +# file: /path/to/image/test.img > +# > +# net > +# type: [nic | user | tap | bridge | ...] > +# nic > +# opt_vlan: 0 > +# note: Default is 0. > +# opt_macaddr: 00:00:00:00:01:01 > +# note: if creating a nic, it`s better to specify a > MAC, > +# else it will get a random number. > +# opt_model:["e1000" | "virtio" | "i82551" | ...] > +# note: Default is e1000. > +# opt_name: 'nic1' > +# opt_addr: '' > +# note: PCI cards only. > +# opt_vectors: > +# note: This option currently only affects virtio > cards. > +# user > +# opt_vlan: 0 > +# note: default is 0. > +# opt_hostfwd: [tcp|udp]:[hostaddr]:hostport- > [guestaddr]:guestport > +# note: If not specified, it will be setted > automatically. > +# tap > +# opt_vlan: 0 > +# note: default is 0. > +# opt_br: br0 > +# note: if choosing tap, need to specify bridge name, > +# else it will be br0. > +# opt_script: QEMU_IFUP_PATH > +# note: if not specified, default is > self.QEMU_IFUP_PATH. > +# opt_downscript: QEMU_IFDOWN_PATH > +# note: if not specified, default is > self.QEMU_IFDOWN_PATH. > +# > +# device > +# driver: [pci-assign | virtio-net-pci | ...] > +# pci-assign > +# prop_host: 08:00.0 > +# prop_addr: 00:00:00:00:01:02 > +# virtio-net-pci > +# prop_netdev: mynet1 > +# prop_id: net1 > +# prop_mac: 00:00:00:00:01:03 > +# prop_bus: pci.0 > +# prop_addr: 0x3 > +# > +# monitor > +# port: 6061 > +# note: if adding monitor to vm, need to specicy > +# this port, else it will get a free port > +# on the host machine. > +# > +# qga > +# enable: [yes | no] > +# > +# serial_port > +# enable: [yes | no] > +# > +# vnc > +# displayNum: 1 > +# note: you can choose a number not used on the host. > +# > +# daemon > +# enable: 'yes' > +# note: > +# By default VM will start with the daemonize status. > +# Not support starting it on the stdin now. > + > +# vm configuration for pmd sriov case > +[vm0] > +cpu =3D > + model=3Dhost,number=3D4,cpupin=3D5 6 7 8 9; disk =3D >=20 > Number=3D4, and cpupin is 5, right ? >=20 >=20 > + file=3D/home/image/fedora23.img; > +mem =3D > + size=3D8196 > +login =3D > + user=3Droot,password=3Dtester; > +net =3D > + type=3Dnic,opt_vlan=3D0; > + type=3Duser,opt_vlan=3D0; > +monitor =3D > + port=3D; > +qga =3D > + enable=3Dyes; > +vnc =3D > + displayNum=3D11; > +daemon =3D > + enable=3Dyes; > diff --git a/test_plans/vf_offload_test_plan.rst > b/test_plans/vf_offload_test_plan.rst > new file mode 100644 > index 0000000..1c0b914 > --- /dev/null > +++ b/test_plans/vf_offload_test_plan.rst > @@ -0,0 +1,175 @@ > +Prerequisites for checksum offload > +=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=3D > + > +Support igb_uio and vfio driver, if used vfio, kernel need 3.6+ and > enable vt-d in bios. > +When used vfio , used "modprobe vfio" and "modprobe vfio-pci" insmod > +vfiod driver, then used "./tools/dpdk_nic_bind.py --bind=3Dvfio-pci > device_bus_id" to bind vfio driver to test driver. > + > +Assuming that ports ``0`` and ``2`` are connected to a traffic > +generator, launch the ``testpmd`` with the following arguments:: > + > + ./build/app/testpmd -cffffff -n 1 -- -i --burst=3D1 --txpt=3D32 \ > + --txht=3D8 --txwt=3D0 --txfreet=3D0 --rxfreet=3D64 --mbcache=3D250 > + --portmask=3D0x5 enable-rx-checksum > + > +Set the verbose level to 1 to display informations for each received > packet:: > + > + testpmd> set verbose 1 > + > +Setup the ``csum`` forwarding mode:: > + > + testpmd> set fwd csum > + Set csum packet forwarding mode > + > +Start the packet forwarding:: > + > + testpmd> start > + csum packet forwarding - CRC stripping disabled - packets/burst=3D32 > + nb forwarding cores=3D1 - nb forwarding ports=3D10 > + RX queues=3D1 - RX desc=3D128 - RX free threshold=3D64 > + RX threshold registers: pthresh=3D8 hthresh=3D8 wthresh=3D4 > + TX queues=3D1 - TX desc=3D512 - TX free threshold=3D0 > + TX threshold registers: pthresh=3D32 hthresh=3D8 wthresh=3D8 > + > +Verify that how many packets found with Bad-ipcsum or Bad-l4csum:: > + > + testpmd> stop > + ---------------------- Forward statistics for port 0 -------------- > -------- > + RX-packets: 0 RX-dropped: 0 RX-total: 0 > + Bad-ipcsum: 0 Bad-l4csum: 0 > + TX-packets: 0 TX-dropped: 0 TX-total: 0 > + > + --------------------------------------------------------------------- > - > + ------ > + > + > +Test Case: HW checksum offload check > +=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=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=3D=3D=3D=3D > =3D > +=3D Start testpmd and enable checksum offload on tx port. > +Send packet with incorrect checksum, can rx it and reported the > +checksum error, and verify forwarded packets have correct checksum. > + > +Setup the ``csum`` forwarding mode:: > + > + testpmd> set fwd csum > + Set csum packet forwarding mode > + > +Enable the IPv4/UDP/TCP/SCTP checksum offload on port 0:: > + > + testpmd> > + testpmd> tx_checksum set ip hw 0 > + testpmd> tx_checksum set udp hw 0 > + testpmd> tx_checksum set tcp hw 0 > + testpmd> tx_checksum set sctp hw 0 > + testpmd> start > + csum packet forwarding - CRC stripping disabled - packets/burst=3D32 > + nb forwarding cores=3D1 - nb forwarding ports=3D10 > + RX queues=3D1 - RX desc=3D128 - RX free threshold=3D64 > + RX threshold registers: pthresh=3D8 hthresh=3D8 wthresh=3D4 > + TX queues=3D1 - TX desc=3D512 - TX free threshold=3D0 > + TX threshold registers: pthresh=3D32 hthresh=3D8 wthresh=3D8 > + > +Configure the traffic generator to send the multiple packets for the > +following > +combination: IPv4/UDP, IPv4/TCP, IPv4/SCTP, IPv6/UDP, IPv6/TCP. > + > +Except that SCTP header + payload length must be a multiple of 4 bytes. > +IPv4 + UDP/TCP packet length can range from the minimum length to 1518 > bytes. > + > +Then verify that the same number of packet are correctly received on > +the traffic generator side. And IPv4 checksum, TCP checksum, UDP > +checksum, SCTP CRC32c need be validated as pass by the IXIA. > + >=20 > Does your cases need IXIA ? >=20 >=20 > +The IPv4 source address will not be changed by testpmd. > + > + > +Test Case: SW checksum offload check > +=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=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=3D=3D=3D=3D > =3D > +=3D=3D=3D disable HW checksum offload on tx port, SW Checksum check. > +Send same packet with incorrect checksum and verify checksum is valid. > + > +Setup the ``csum`` forwarding mode:: > + > + testpmd> set fwd csum > + Set csum packet forwarding mode > + > +Disable the IPv4/UDP/TCP/SCTP checksum offload on port 0:: > + > + testpmd> tx_checksum set 0x0 0 > + testpmd> start > + csum packet forwarding - CRC stripping disabled - packets/burst=3D32 > + nb forwarding cores=3D1 - nb forwarding ports=3D10 > + RX queues=3D1 - RX desc=3D128 - RX free threshold=3D64 > + RX threshold registers: pthresh=3D8 hthresh=3D8 wthresh=3D4 > + TX queues=3D1 - TX desc=3D512 - TX free threshold=3D0 > + TX threshold registers: pthresh=3D32 hthresh=3D8 wthresh=3D8 > + > +Configure the traffic generator to send the multiple packets for the > +follwing > +combination: IPv4/UDP, IPv4/TCP, IPv6/UDP, IPv6/TCP. > + > +IPv4 + UDP/TCP packet length can range from the minimum length to 1518 > bytes. > + > +Then verify that the same number of packet are correctly received on > +the traffic generator side. And IPv4 checksum, TCP checksum, UDP > +checksum need be validated as pass by the IXIA. > + >=20 > Does your cases need IXIA ? >=20 >=20 > Best Regards > Yulong Pei >=20 >=20 > +The first byte of source IPv4 address will be increment by testpmd. > The > +checksum is indeed recalculated by software algorithms. > + > +Prerequisites for TSO > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > + > +The DUT must take one of the Ethernet controller ports connected to a > +port on another device that is controlled by the Scapy packet > generator. > + > +The Ethernet interface identifier of the port that Scapy will use must > be known. > +On tester, all offload feature should be disabled on tx port, and > start rx port capture:: > + ethtool -K rx off tx off tso off gso off gro off lro off > + ip l set up > + tcpdump -n -e -i -s 0 -w /tmp/cap > + > + > +On DUT, run pmd with parameter "--enable-rx-cksum". Then enable TSO on > +tx port and checksum on rx port. The test commands is below:: > + #enable hw checksum on rx port > + tx_checksum set ip hw 0 > + tx_checksum set udp hw 0 > + tx_checksum set tcp hw 0 > + tx_checksum set sctp hw 0 > + set fwd csum > + > + # enable TSO on tx port > + *tso set 800 1 > + > + > +Test case: csum fwd engine, use TSO > +=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=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D > + > +This test uses ``Scapy`` to send out one large TCP package. The dut > +forwards package with TSO enable on tx port while rx port turns > +checksum on. After package send out by TSO on tx port, the tester > receives multiple small TCP package. > + > +Turn off tx port by ethtool on tester:: > + ethtool -K rx off tx off tso off gso off gro off lro off > + ip l set up > +capture package rx port on tester:: > + tcpdump -n -e -i -s 0 -w /tmp/cap > + > +Launch the userland ``testpmd`` application on DUT as follows:: > + > + testpmd> set verbose 1 > + > + # enable hw checksum on rx port > + testpmd> tx_checksum set ip hw 0 > + testpmd> tx_checksum set udp hw 0 > + testpmd> tx_checksum set tcp hw 0 > + testpmd> tx_checksum set sctp hw 0 > + # enable TSO on tx port > + testpmd> tso set 800 1 > + # set fwd engine and start > + testpmd> set fwd csum > + testpmd> start > + > +Test IPv4() in scapy: > + sendp([Ether(dst=3D"%s", > +src=3D"52:00:00:00:00:00")/IP(src=3D"192.168.1.1",dst=3D"192.168.1.2")/U= DP(s > p > +ort=3D1021,dport=3D1021)/Raw(load=3D"\x50"*%s)], iface=3D"%s") > + > +Test IPv6() in scapy: > + sendp([Ether(dst=3D"%s", > src=3D"52:00:00:00:00:00")/IPv6(src=3D"FE80:0:0:0:200:1FF:FE00:200", > dst=3D"3555:5555:6666:6666:7777:7777:8888:8888")/UDP(sport=3D1021,dport= =3D102 > 1)/Raw(load=3D"\x50"*%s)], iface=3D"%s" > + > diff --git a/tests/TestSuite_vf_offload.py > b/tests/TestSuite_vf_offload.py new file mode 100644 index > 0000000..78fa5a6 > --- /dev/null > +++ b/tests/TestSuite_vf_offload.py > @@ -0,0 +1,380 @@ > +# > + > +import re > +import time > + > +import dts > +from qemu_kvm import QEMUKvm > +from test_case import TestCase > +from pmd_output import PmdOutput > +from utils import RED, GREEN > +from net_device import NetDevice > +from crb import Crb > +from scapy.all import * > +from settings import HEADER_SIZE > +VM_CORES_MASK =3D 'all' > + > +class TestVfOffload(TestCase): > + > + def set_up_all(self): > + self.dut_ports =3D self.dut.get_ports(self.nic) > + self.verify(len(self.dut_ports) > 1, "Insufficient ports") > + self.vm0 =3D None > + self.setup_2pf_2vf_1vm_env_flag =3D 0 > + self.setup_2pf_2vf_1vm_env(driver=3D'') > + self.vm0_dut_ports =3D self.vm_dut_0.get_ports('any') > + self.portMask =3D dts.create_mask([self.vm0_dut_ports[0]]) > + self.vm0_testpmd =3D PmdOutput(self.vm_dut_0) > + > + def set_up(self): > + pass > + > + def setup_2pf_2vf_1vm_env(self, driver=3D'default'): > + > + self.used_dut_port_0 =3D self.dut_ports[0] > + self.dut.generate_sriov_vfs_by_port(self.used_dut_port_0, 1, > driver=3Ddriver) > + self.sriov_vfs_port_0 =3D > self.dut.ports_info[self.used_dut_port_0]['vfs_port'] > + self.used_dut_port_1 =3D self.dut_ports[1] > + self.dut.generate_sriov_vfs_by_port(self.used_dut_port_1, 1, > driver=3Ddriver) > + self.sriov_vfs_port_1 =3D > + self.dut.ports_info[self.used_dut_port_1]['vfs_port'] > + > + try: > + > + for port in self.sriov_vfs_port_0: > + port.bind_driver('pci-stub') > + > + for port in self.sriov_vfs_port_1: > + port.bind_driver('pci-stub') > + > + time.sleep(1) > + vf0_prop =3D {'opt_host': self.sriov_vfs_port_0[0].pci} > + vf1_prop =3D {'opt_host': self.sriov_vfs_port_1[0].pci} > + > + if driver =3D=3D 'igb_uio': > + # start testpmd without the two VFs on the host > + self.host_testpmd =3D PmdOutput(self.dut) > + eal_param =3D '-b %(vf0)s -b %(vf1)s' % {'vf0': > self.sriov_vfs_port_0[0].pci, > + 'vf1': > self.sriov_vfs_port_1[0].pci} > + self.host_testpmd.start_testpmd("1S/2C/2T", > + eal_param=3Deal_param) > + > + # set up VM0 ENV > + self.vm0 =3D QEMUKvm(self.dut, 'vm0', 'vf_offload') > + self.vm0.set_vm_device(driver=3D'pci-assign', **vf0_prop) > + self.vm0.set_vm_device(driver=3D'pci-assign', **vf1_prop) > + self.vm_dut_0 =3D self.vm0.start() > + if self.vm_dut_0 is None: > + raise Exception("Set up VM0 ENV failed!") > + > + self.setup_2pf_2vf_1vm_env_flag =3D 1 > + except Exception as e: > + self.destroy_2pf_2vf_1vm_env() > + raise Exception(e) > + > + def destroy_2pf_2vf_1vm_env(self): > + if getattr(self, 'vm0', None): > + #destroy testpmd in vm0 > + self.vm0_testpmd =3D None > + self.vm0_dut_ports =3D None > + #destroy vm0 > + self.vm0.stop() > + self.vm0 =3D None > + > + if getattr(self, 'host_testpmd', None): > + self.host_testpmd.execute_cmd('quit', '# ') > + self.host_testpmd =3D None > + > + if getattr(self, 'used_dut_port_0', None): > + self.dut.destroy_sriov_vfs_by_port(self.used_dut_port_0) > + port =3D self.dut.ports_info[self.used_dut_port_0]['port'] > + port.bind_driver() > + self.used_dut_port_0 =3D None > + > + if getattr(self, 'used_dut_port_1', None): > + self.dut.destroy_sriov_vfs_by_port(self.used_dut_port_1) > + port =3D self.dut.ports_info[self.used_dut_port_1]['port'] > + port.bind_driver() > + self.used_dut_port_1 =3D None > + > + for port_id in self.dut_ports: > + port =3D self.dut.ports_info[port_id]['port'] > + port.bind_driver() > + > + self.setup_2pf_2vf_1vm_env_flag =3D 0 > + > + def checksum_enablehw(self, port, dut): > + dut.send_expect("csum set ip hw %d" % port, "testpmd>") > + dut.send_expect("csum set udp hw %d" % port, "testpmd>") > + dut.send_expect("csum set tcp hw %d" % port, "testpmd>") > + dut.send_expect("csum set sctp hw %d" % port, "testpmd>") > + > + def checksum_enablesw(self, port, dut): > + dut.send_expect("csum set ip sw %d" % port, "testpmd>") > + dut.send_expect("csum set udp sw %d" % port, "testpmd>") > + dut.send_expect("csum set tcp sw %d" % port, "testpmd>") > + dut.send_expect("csum set sctp sw %d" % port, "testpmd>") > + > + def checksum_validate(self, packets_sent, packets_expected): > + """ > + Validate the checksum. > + """ > + tx_interface =3D > self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0])) > + rx_interface =3D > + self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0] > + )) > + > + sniff_src =3D self.vm0_testpmd.get_port_mac(0) > + checksum_pattern =3D re.compile("chksum.*=3D.*(0x[0-9a-z]+)") > + > + chksum =3D dict() > + result =3D dict() > + > + self.tester.send_expect("scapy", ">>> ") > + > + for packet_type in packets_expected.keys(): > + self.tester.send_expect("p =3D %s" % > packets_expected[packet_type], ">>>") > + out =3D self.tester.send_expect("p.show2()", ">>>") > + chksums =3D checksum_pattern.findall(out) > + chksum[packet_type] =3D chksums > + print packet_type, ": ", chksums > + > + self.tester.send_expect("exit()", "#") > + > + self.tester.scapy_background() > + self.tester.scapy_append('p =3D sniff(filter=3D"ether src %s", > iface=3D"%s", count=3D%d)' % (sniff_src, rx_interface, len(packets_sent))= ) > + self.tester.scapy_append('nr_packets=3Dlen(p)') > + self.tester.scapy_append('reslist =3D > [p[i].sprintf("%IP.chksum%;%TCP.chksum%;%UDP.chksum%;%SCTP.chksum%") > for i in range(nr_packets)]') > + self.tester.scapy_append('import string') > + self.tester.scapy_append('RESULT =3D string.join(reslist, ",")') > + > + # Send packet. > + self.tester.scapy_foreground() > + > + for packet_type in packets_sent.keys(): > + self.tester.scapy_append('sendp([%s], iface=3D"%s")' % > + (packets_sent[packet_type], tx_interface)) > + > + self.tester.scapy_execute() > + out =3D self.tester.scapy_get_result() > + packets_received =3D out.split(',') > + self.verify(len(packets_sent) =3D=3D len(packets_received), > + "Unexpected Packets Drop") > + > + for packet_received in packets_received: > + ip_checksum, tcp_checksum, udp_checksup, sctp_checksum =3D > packet_received.split(';') > + print "ip_checksum: ", ip_checksum, "tcp_checksum:, ", > + tcp_checksum, "udp_checksup: ", udp_checksup, "sctp_checksum: ", > + sctp_checksum > + > + packet_type =3D '' > + l4_checksum =3D '' > + if tcp_checksum !=3D '??': > + packet_type =3D 'TCP' > + l4_checksum =3D tcp_checksum > + elif udp_checksup !=3D '??': > + packet_type =3D 'UDP' > + l4_checksum =3D udp_checksup > + elif sctp_checksum !=3D '??': > + packet_type =3D 'SCTP' > + l4_checksum =3D sctp_checksum > + > + if ip_checksum !=3D '??': > + packet_type =3D 'IP/' + packet_type > + if chksum[packet_type] !=3D [ip_checksum, l4_checksum]: > + result[packet_type] =3D packet_type + " checksum > error" > + else: > + packet_type =3D 'IPv6/' + packet_type > + if chksum[packet_type] !=3D [l4_checksum]: > + result[packet_type] =3D packet_type + " checksum > error" > + > + return result > + > + def test_checksum_offload_enable(self): > + """ > + Enable HW Checksum offload. > + Send packet with incorrect checksum, > + can rx it and reported the checksum error, > + verify forwarded packets have correct checksum > + """ > + self.vm0_testpmd.start_testpmd(VM_CORES_MASK, "--portmask=3D%s > " % > + (self.portMask) + "--disable-hw- > vlan --enable-rx-cksum " + "--txqflags=3D0 " + > + "--crc-strip --port- > topology=3Dloop") > + self.vm0_testpmd.execute_cmd('set fwd csum') > + > + time.sleep(2) > + port_id_0 =3D 0 > + mac =3D self.vm0_testpmd.get_port_mac(0) > + > + sndIP =3D '10.0.0.1' > + sndIPv6 =3D '::1' > + pkts =3D {'IP/UDP': 'Ether(dst=3D"%s", > src=3D"52:00:00:00:00:00")/IP(src=3D"%s", > chksum=3D0xf)/UDP(chksum=3D0xf)/("X"*46)' % (mac, sndIP), > + 'IP/TCP': 'Ether(dst=3D"%s", > src=3D"52:00:00:00:00:00")/IP(src=3D"%s", > chksum=3D0xf)/TCP(chksum=3D0xf)/("X"*46)' % (mac, sndIP), > + 'IP/SCTP': 'Ether(dst=3D"%s", > src=3D"52:00:00:00:00:00")/IP(src=3D"%s", > chksum=3D0xf)/SCTP(chksum=3D0xf)/("X"*48)' % (mac, sndIP), > + 'IPv6/UDP': 'Ether(dst=3D"%s", > src=3D"52:00:00:00:00:00")/IPv6(src=3D"%s")/UDP(chksum=3D0xf)/("X"*46)' % > (mac, sndIPv6), > + 'IPv6/TCP': 'Ether(dst=3D"%s", > + src=3D"52:00:00:00:00:00")/IPv6(src=3D"%s")/TCP(chksum=3D0xf)/("X"*46)'= % > + (mac, sndIPv6)} > + > + expIP =3D "10.0.0.2" > + expIPv6 =3D '::2' > + pkts_ref =3D {'IP/UDP': 'Ether(dst=3D"02:00:00:00:00:00", > src=3D"%s")/IP(src=3D"%s")/UDP()/("X"*46)' % (mac, expIP), > + 'IP/TCP': 'Ether(dst=3D"02:00:00:00:00:00", > src=3D"%s")/IP(src=3D"%s")/TCP()/("X"*46)' % (mac, expIP), > + 'IP/SCTP': 'Ether(dst=3D"02:00:00:00:00:00", > src=3D"%s")/IP(src=3D"%s")/SCTP()/("X"*48)' % (mac, expIP), > + 'IPv6/UDP': 'Ether(dst=3D"02:00:00:00:00:00", > src=3D"%s")/IPv6(src=3D"%s")/UDP()/("X"*46)' % (mac, expIPv6), > + 'IPv6/TCP': 'Ether(dst=3D"02:00:00:00:00:00", > + src=3D"%s")/IPv6(src=3D"%s")/TCP()/("X"*46)' % (mac, expIPv6)} > + > + if self.nic in ['redrockcanyou', 'atwood']: > + del pkts['IP/SCTP'] > + del pkts_ref['IP/SCTP'] > + > + self.checksum_enablehw(0,self.vm_dut_0) > + > + self.vm0_testpmd.execute_cmd('start') > + result =3D self.checksum_validate(pkts, pkts_ref) > + > + # Validate checksum on the receive packet > + out =3D self.vm0_testpmd.execute_cmd('stop') > + bad_ipcsum =3D self.vm0_testpmd.get_pmd_value("Bad-ipcsum:", out= ) > + bad_l4csum =3D self.vm0_testpmd.get_pmd_value("Bad-l4csum:", out= ) > + self.verify(bad_ipcsum =3D=3D 3, "Bad-ipcsum check error") > + self.verify(bad_l4csum =3D=3D 5, "Bad-l4csum check error") > + > + self.verify(len(result) =3D=3D 0, string.join(result.values(), > + ",")) > + > + def test_checksum_offload_disable(self): > + """ > + disable HW checksum offload on tx port, SW Checksum check. > + SW Checksum on by default. > + Send same packet with incorrect checksum and verify checksum > is valid. > + """ > + > + self.vm0_testpmd.start_testpmd(VM_CORES_MASK, "--portmask=3D%s > " % > + (self.portMask) + "--disable-hw- > vlan --enable-rx-cksum " + > + "--crc-strip --port- > topology=3Dloop") > + self.vm0_testpmd.execute_cmd('set fwd csum') > + > + time.sleep(2) > + > + mac =3D self.vm0_testpmd.get_port_mac(0) > + sndIP =3D '10.0.0.1' > + sndIPv6 =3D '::1' > + sndPkts =3D {'IP/UDP': 'Ether(dst=3D"%s", > src=3D"52:00:00:00:00:00")/IP(src=3D"%s",chksum=3D0xf)/UDP(chksum=3D0xf)/= ("X"*4 > 6)' % (mac, sndIP), > + 'IP/TCP': 'Ether(dst=3D"%s", > src=3D"52:00:00:00:00:00")/IP(src=3D"%s",chksum=3D0xf)/TCP(chksum=3D0xf)/= ("X"*4 > 6)' % (mac, sndIP), > + 'IPv6/UDP': 'Ether(dst=3D"%s", > src=3D"52:00:00:00:00:00")/IPv6(src=3D"%s")/UDP(chksum=3D0xf)/("X"*46)' % > (mac, sndIPv6), > + 'IPv6/TCP': 'Ether(dst=3D"%s", > + src=3D"52:00:00:00:00:00")/IPv6(src=3D"%s")/TCP(chksum=3D0xf)/("X"*46)'= % > + (mac, sndIPv6)} > + > + expIP =3D "10.0.0.2" > + expIPv6 =3D '::2' > + expPkts =3D {'IP/UDP': 'Ether(dst=3D"02:00:00:00:00:00", > src=3D"%s")/IP(src=3D"%s")/UDP()/("X"*46)' % (mac, expIP), > + 'IP/TCP': 'Ether(dst=3D"02:00:00:00:00:00", > src=3D"%s")/IP(src=3D"%s")/TCP()/("X"*46)' % (mac, expIP), > + 'IPv6/UDP': 'Ether(dst=3D"02:00:00:00:00:00", > src=3D"%s")/IPv6(src=3D"%s")/UDP()/("X"*46)' % (mac, expIPv6), > + 'IPv6/TCP': 'Ether(dst=3D"02:00:00:00:00:00", > + src=3D"%s")/IPv6(src=3D"%s")/TCP()/("X"*46)' % (mac, expIPv6)} > + > + self.vm0_testpmd.execute_cmd('start') > + result =3D self.checksum_validate(sndPkts, expPkts) > + > + # Validate checksum on the receive packet > + out =3D self.vm0_testpmd.execute_cmd('stop') > + bad_ipcsum =3D self.vm0_testpmd.get_pmd_value("Bad-ipcsum:", out= ) > + bad_l4csum =3D self.vm0_testpmd.get_pmd_value("Bad-l4csum:", out= ) > + self.verify(bad_ipcsum =3D=3D 2, "Bad-ipcsum check error") > + self.verify(bad_l4csum =3D=3D 4, "Bad-l4csum check error") > + > + self.verify(len(result) =3D=3D 0, string.join(result.values(), > + ",")) > + > + def tcpdump_start_sniffing(self, ifaces=3D[]): > + """ > + Starts tcpdump in the background to sniff the tester interface > where > + the packets are transmitted to and from the self.dut. > + All the captured packets are going to be stored in a file for > a > + post-analysis. > + """ > + > + for iface in ifaces: > + command =3D ('tcpdump -w tcpdump_{0}.pcap -i {0} > 2>tcpdump_{0}.out &').format(iface) > + self.tester.send_expect('rm -f tcpdump_{0}.pcap', > '#').format(iface) > + self.tester.send_expect(command, '#') > + > + def tcpdump_stop_sniff(self): > + """ > + Stops the tcpdump process running in the background. > + """ > + self.tester.send_expect('killall tcpdump', '#') > + time.sleep(1) > + self.tester.send_expect('echo "Cleaning buffer"', '#') > + time.sleep(1) > + > + def tcpdump_command(self, command): > + """ > + Sends a tcpdump related command and returns an integer from > the output > + """ > + > + result =3D self.tester.send_expect(command, '#') > + print result > + return int(result.strip()) > + > + def number_of_packets(self, iface): > + """ > + By reading the file generated by tcpdump it counts how many > packets were > + forwarded by the sample app and received in the self.tester. > The sample app > + will add a known MAC address for the test to look for. > + """ > + > + command =3D ('tcpdump -A -nn -e -v -r tcpdump_{iface}.pcap > 2>/dev/null | ' + > + 'grep -c "seq"') > + return self.tcpdump_command(command.format(**locals())) > + > + def test_tso(self): > + """ > + TSO IPv4 TCP, IPv6 TCP, VXLan testing > + """ > + tx_interface =3D > self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0])) > + rx_interface =3D > + self.tester.get_interface(self.tester.get_local_port(self.dut_ports[1] > + )) > + > + self.frame_sizes =3D [128, 1458] > + self.headers_size =3D HEADER_SIZE['eth'] + HEADER_SIZE['ip'] + > HEADER_SIZE['tcp'] > + padding =3D self.frame_sizes[0] - self.headers_size > + > + self.tester.send_expect("ethtool -K %s rx off tx off tso off > gso off gro off lro off" % tx_interface, "# ") > + self.tester.send_expect("ip l set %s up" % tx_interface, "# ") > + > + self.portMask =3D dts.create_mask([self.vm0_dut_ports[0]]) > + self.vm0_testpmd.start_testpmd(VM_CORES_MASK, "--portmask=3D%s > " % > + (self.portMask) + "--enable-rx- > cksum " + > + "--txqflags=3D0 " + > + "--crc-strip > + --port-topology=3Dloop") > + > + mac =3D self.vm0_testpmd.get_port_mac(0) > + > + self.checksum_enablehw(0,self.vm_dut_0) > + self.vm0_testpmd.execute_cmd("tso set 800 %d" % > self.vm0_dut_ports[1]) > + self.vm0_testpmd.execute_cmd("set fwd csum") > + self.vm0_testpmd.execute_cmd("start") > + > + self.tester.scapy_foreground() > + time.sleep(5) > + > + # IPv4 tcp test > + > + self.tcpdump_start_sniffing([tx_interface, rx_interface]) > + > self.tester.scapy_append('sendp([Ether(dst=3D"%s",src=3D"52:00:00:00:00:0= 0" > )/IP(src=3D"192.168.1.1",dst=3D"192.168.1.2")/TCP(sport=3D1021,dport=3D10= 21)/(" > X"*%s)], iface=3D"%s")' % (mac, padding, tx_interface)) > + out =3D self.tester.scapy_execute() > + out =3D self.vm0_testpmd.execute_cmd("show port stats all") > + print out > + self.tcpdump_stop_sniff() > + rx_stats =3D self.number_of_packets(rx_interface) > + if (rx_stats =3D=3D 2): > + self.verify(1, "Pass") > + > + # IPv6 tcp test > + > + self.tcpdump_start_sniffing([tx_interface, rx_interface]) > + self.tester.scapy_append('sendp([Ether(dst=3D"%s", > src=3D"52:00:00:00:00:00")/IPv6(src=3D"FE80:0:0:0:200:1FF:FE00:200", > dst=3D"3555:5555:6666:6666:7777:7777:8888:8888")/TCP(sport=3D1021,dport= =3D102 > 1)/("X"*%s)], iface=3D"%s")' % (mac, padding, tx_interface)) > + out =3D self.tester.scapy_execute() > + out =3D self.vm0_testpmd.execute_cmd("show port stats all") > + print out > + self.tcpdump_stop_sniff() > + rx_stats =3D self.number_of_packets(rx_interface) > + if (rx_stats =3D=3D 2): > + self.verify(1, "Pass") > + > + > + def tear_down(self): > + self.vm0_testpmd.execute_cmd('quit', '# ') > + pass > + > + def tear_down_all(self): > + print "tear_down_all" > + if self.setup_2pf_2vf_1vm_env_flag =3D=3D 1: > + self.destroy_2pf_2vf_1vm_env() > -- > 2.5.0