[dts] [PATCH v4]tests,test_plans: add checksum offload and tso

Liu, Yong yong.liu at intel.com
Fri Mar 11 05:20:09 CET 2016


Thanks all, applied into master branch.

> -----Original Message-----
> From: dts [mailto:dts-bounces at dpdk.org] On Behalf Of Pei, Yulong
> Sent: Thursday, March 10, 2016 3:18 PM
> To: Tu, LijuanX A; dts at dpdk.org
> Subject: Re: [dts] [PATCH v4]tests,test_plans: add checksum offload and
> tso
> 
> Ack+
> 
> -----Original Message-----
> From: Tu, LijuanX A
> Sent: Tuesday, March 8, 2016 3:31 PM
> To: dts at dpdk.org; Pei, Yulong <yulong.pei at intel.com>
> Cc: Tu, LijuanX A <lijuanx.a.tu at intel.com>
> Subject: [dts][PATCH v4]tests,test_plans: add checksum offload and tso
> 
> Add checksum offload and tso test scripts, test plan, config file
> 
> Signed-off-by: Lijuan Tu <lijuanx.a.tu at intel.com>
> ---
>  conf/vf_offload.cfg                 | 107 ++++++++++
>  test_plans/vf_offload_test_plan.rst | 172 ++++++++++++++++
>  tests/TestSuite_vf_offload.py       | 380
> ++++++++++++++++++++++++++++++++++++
>  3 files changed, 659 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
> 
> diff --git a/conf/vf_offload.cfg b/conf/vf_offload.cfg new file mode
> 100644 index 0000000..4ecbe0f
> --- /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 =
> +    model=host,number=4,cpupin=4 5 6 7; disk =
> +    file=/home/image/sriov-fc23-1.img;
> +mem =
> +    size=4096;
> +login =
> +    user=root,password=tester;
> +net =
> +   type=nic,opt_vlan=0;
> +   type=user,opt_vlan=0;
> +monitor =
> +    port=;
> +qga =
> +    enable=yes;
> +vnc =
> +    displayNum=11;
> +daemon =
> +    enable=yes;
> diff --git a/test_plans/vf_offload_test_plan.rst
> b/test_plans/vf_offload_test_plan.rst
> new file mode 100644
> index 0000000..36beaaa
> --- /dev/null
> +++ b/test_plans/vf_offload_test_plan.rst
> @@ -0,0 +1,172 @@
> +Prerequisites for checksum offload
> +==================================
> +
> +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=vfio-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=1 --txpt=32 \
> +  --txht=8 --txwt=0 --txfreet=0 --rxfreet=64 --mbcache=250
> + --portmask=0x5  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=32
> +    nb forwarding cores=1 - nb forwarding ports=10
> +    RX queues=1 - RX desc=128 - RX free threshold=64
> +    RX threshold registers: pthresh=8 hthresh=8 wthresh=4
> +    TX queues=1 - TX desc=512 - TX free threshold=0
> +    TX threshold registers: pthresh=32 hthresh=8 wthresh=8
> +
> +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
> +=======================================================================
> += Start testpmd and enable checksum offload on tx port.
> +
> +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=32
> +    nb forwarding cores=1 - nb forwarding ports=10
> +    RX queues=1 - RX desc=128 - RX free threshold=64
> +    RX threshold registers: pthresh=8 hthresh=8 wthresh=4
> +    TX queues=1 - TX desc=512 - TX free threshold=0
> +    TX threshold registers: pthresh=32 hthresh=8 wthresh=8
> +
> +Configure the traffic generator to send the multiple packets for the
> +following
> +combination: IPv4/UDP, IPv4/TCP, IPv4/SCTP, IPv6/UDP, IPv6/TCP.
> +
> +Send packets with incorrect checksum,
> +Verify dpdk can rx it and reported the checksum error, 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 tester.
> +
> +The IPv4 source address will not be changed by testpmd.
> +
> +
> +Test Case: SW checksum offload check
> +=======================================================================
> +=== 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=32
> +    nb forwarding cores=1 - nb forwarding ports=10
> +    RX queues=1 - RX desc=128 - RX free threshold=64
> +    RX threshold registers: pthresh=8 hthresh=8 wthresh=4
> +    TX queues=1 - TX desc=512 - TX free threshold=0
> +    TX threshold registers: pthresh=32 hthresh=8 wthresh=8
> +
> +Configure the traffic generator to send the multiple packets for the
> +follwing
> +combination: IPv4/UDP, IPv4/TCP, IPv6/UDP, IPv6/TCP.
> +
> +Send packets with incorrect checksum,
> +Verify dpdk can rx it and reported the checksum error, 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.
> +
> +The first byte of source IPv4 address will be increment by testpmd. The
> +checksum is indeed recalculated by software algorithms.
> +
> +Prerequisites for TSO
> +=====================
> +
> +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 <tx port> rx off tx off tso off gso off gro off lro off
> +  ip l set <tx port> up
> +  tcpdump -n -e -i <rx port> -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
> +====================================================
> +
> +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 <tx port> rx off tx off tso off gso off gro off lro off
> +  ip l set <tx port> up
> +capture package rx port on tester::
> +  tcpdump -n -e -i <rx port> -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="%s",
> +src="52:00:00:00:00:00")/IP(src="192.168.1.1",dst="192.168.1.2")/UDP(sp
> +ort=1021,dport=1021)/Raw(load="\x50"*%s)], iface="%s")
> +
> +Test IPv6() in scapy:
> +    sendp([Ether(dst="%s",
> src="52:00:00:00:00:00")/IPv6(src="FE80:0:0:0:200:1FF:FE00:200",
> dst="3555:5555:6666:6666:7777:7777:8888:8888")/UDP(sport=1021,dport=1021)
> /Raw(load="\x50"*%s)], iface="%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 @@
> +# <COPYRIGHT_TAG>
> +
> +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 = 'all'
> +
> +class TestVfOffload(TestCase):
> +
> +    def set_up_all(self):
> +        self.dut_ports = self.dut.get_ports(self.nic)
> +        self.verify(len(self.dut_ports) > 1, "Insufficient ports")
> +        self.vm0 = None
> +        self.setup_2pf_2vf_1vm_env_flag = 0
> +        self.setup_2pf_2vf_1vm_env(driver='')
> +        self.vm0_dut_ports = self.vm_dut_0.get_ports('any')
> +        self.portMask = dts.create_mask([self.vm0_dut_ports[0]])
> +        self.vm0_testpmd = PmdOutput(self.vm_dut_0)
> +
> +    def set_up(self):
> +        pass
> +
> +    def setup_2pf_2vf_1vm_env(self, driver='default'):
> +
> +        self.used_dut_port_0 = self.dut_ports[0]
> +        self.dut.generate_sriov_vfs_by_port(self.used_dut_port_0, 1,
> driver=driver)
> +        self.sriov_vfs_port_0 =
> self.dut.ports_info[self.used_dut_port_0]['vfs_port']
> +        self.used_dut_port_1 = self.dut_ports[1]
> +        self.dut.generate_sriov_vfs_by_port(self.used_dut_port_1, 1,
> driver=driver)
> +        self.sriov_vfs_port_1 =
> + 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 = {'opt_host': self.sriov_vfs_port_0[0].pci}
> +            vf1_prop = {'opt_host': self.sriov_vfs_port_1[0].pci}
> +
> +            if driver == 'igb_uio':
> +                # start testpmd without the two VFs on the host
> +                self.host_testpmd = PmdOutput(self.dut)
> +                eal_param = '-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=eal_param)
> +
> +            # set up VM0 ENV
> +            self.vm0 = QEMUKvm(self.dut, 'vm0', 'vf_offload')
> +            self.vm0.set_vm_device(driver='pci-assign', **vf0_prop)
> +            self.vm0.set_vm_device(driver='pci-assign', **vf1_prop)
> +            self.vm_dut_0 = self.vm0.start()
> +            if self.vm_dut_0 is None:
> +                raise Exception("Set up VM0 ENV failed!")
> +
> +            self.setup_2pf_2vf_1vm_env_flag = 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 = None
> +            self.vm0_dut_ports = None
> +            #destroy vm0
> +            self.vm0.stop()
> +            self.vm0 = None
> +
> +        if getattr(self, 'host_testpmd', None):
> +            self.host_testpmd.execute_cmd('quit', '# ')
> +            self.host_testpmd = None
> +
> +        if getattr(self, 'used_dut_port_0', None):
> +            self.dut.destroy_sriov_vfs_by_port(self.used_dut_port_0)
> +            port = self.dut.ports_info[self.used_dut_port_0]['port']
> +            port.bind_driver()
> +            self.used_dut_port_0 = None
> +
> +        if getattr(self, 'used_dut_port_1', None):
> +            self.dut.destroy_sriov_vfs_by_port(self.used_dut_port_1)
> +            port = self.dut.ports_info[self.used_dut_port_1]['port']
> +            port.bind_driver()
> +            self.used_dut_port_1 = None
> +
> +        for port_id in self.dut_ports:
> +            port = self.dut.ports_info[port_id]['port']
> +            port.bind_driver()
> +
> +        self.setup_2pf_2vf_1vm_env_flag = 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 =
> self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0]))
> +        rx_interface =
> + self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0]
> + ))
> +
> +        sniff_src = self.vm0_testpmd.get_port_mac(0)
> +        checksum_pattern = re.compile("chksum.*=.*(0x[0-9a-z]+)")
> +
> +        chksum = dict()
> +        result = dict()
> +
> +        self.tester.send_expect("scapy", ">>> ")
> +
> +        for packet_type in packets_expected.keys():
> +            self.tester.send_expect("p = %s" %
> packets_expected[packet_type], ">>>")
> +            out = self.tester.send_expect("p.show2()", ">>>")
> +            chksums = checksum_pattern.findall(out)
> +            chksum[packet_type] = chksums
> +            print packet_type, ": ", chksums
> +
> +        self.tester.send_expect("exit()", "#")
> +
> +        self.tester.scapy_background()
> +        self.tester.scapy_append('p = sniff(filter="ether src %s",
> iface="%s", count=%d)' % (sniff_src, rx_interface, len(packets_sent)))
> +        self.tester.scapy_append('nr_packets=len(p)')
> +        self.tester.scapy_append('reslist =
> [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 = string.join(reslist, ",")')
> +
> +        # Send packet.
> +        self.tester.scapy_foreground()
> +
> +        for packet_type in packets_sent.keys():
> +            self.tester.scapy_append('sendp([%s], iface="%s")' %
> + (packets_sent[packet_type], tx_interface))
> +
> +        self.tester.scapy_execute()
> +        out = self.tester.scapy_get_result()
> +        packets_received = out.split(',')
> +        self.verify(len(packets_sent) == len(packets_received),
> + "Unexpected Packets Drop")
> +
> +        for packet_received in packets_received:
> +            ip_checksum, tcp_checksum, udp_checksup, sctp_checksum =
> packet_received.split(';')
> +            print "ip_checksum: ", ip_checksum, "tcp_checksum:, ",
> + tcp_checksum, "udp_checksup: ", udp_checksup, "sctp_checksum: ",
> + sctp_checksum
> +
> +            packet_type = ''
> +            l4_checksum = ''
> +            if tcp_checksum != '??':
> +                packet_type = 'TCP'
> +                l4_checksum = tcp_checksum
> +            elif udp_checksup != '??':
> +                packet_type = 'UDP'
> +                l4_checksum = udp_checksup
> +            elif sctp_checksum != '??':
> +                packet_type = 'SCTP'
> +                l4_checksum = sctp_checksum
> +
> +            if ip_checksum != '??':
> +                packet_type = 'IP/' + packet_type
> +                if chksum[packet_type] != [ip_checksum, l4_checksum]:
> +                    result[packet_type] = packet_type + " checksum
> error"
> +            else:
> +                packet_type = 'IPv6/' + packet_type
> +                if chksum[packet_type] != [l4_checksum]:
> +                    result[packet_type] = 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=%s " %
> +                                      (self.portMask) + "--disable-hw-
> vlan --enable-rx-cksum " + "--txqflags=0 " +
> +                                      "--crc-strip --port-topology=loop")
> +        self.vm0_testpmd.execute_cmd('set fwd csum')
> +
> +        time.sleep(2)
> +        port_id_0 = 0
> +        mac = self.vm0_testpmd.get_port_mac(0)
> +
> +        sndIP = '10.0.0.1'
> +        sndIPv6 = '::1'
> +        pkts = {'IP/UDP': 'Ether(dst="%s",
> src="52:00:00:00:00:00")/IP(src="%s",
> chksum=0xf)/UDP(chksum=0xf)/("X"*46)' % (mac, sndIP),
> +                'IP/TCP': 'Ether(dst="%s",
> src="52:00:00:00:00:00")/IP(src="%s",
> chksum=0xf)/TCP(chksum=0xf)/("X"*46)' % (mac, sndIP),
> +                'IP/SCTP': 'Ether(dst="%s",
> src="52:00:00:00:00:00")/IP(src="%s",
> chksum=0xf)/SCTP(chksum=0xf)/("X"*48)' % (mac, sndIP),
> +                'IPv6/UDP': 'Ether(dst="%s",
> src="52:00:00:00:00:00")/IPv6(src="%s")/UDP(chksum=0xf)/("X"*46)' % (mac,
> sndIPv6),
> +                'IPv6/TCP': 'Ether(dst="%s",
> + src="52:00:00:00:00:00")/IPv6(src="%s")/TCP(chksum=0xf)/("X"*46)' %
> + (mac, sndIPv6)}
> +
> +        expIP = "10.0.0.2"
> +        expIPv6 = '::2'
> +        pkts_ref = {'IP/UDP': 'Ether(dst="02:00:00:00:00:00",
> src="%s")/IP(src="%s")/UDP()/("X"*46)' % (mac, expIP),
> +                    'IP/TCP': 'Ether(dst="02:00:00:00:00:00",
> src="%s")/IP(src="%s")/TCP()/("X"*46)' % (mac, expIP),
> +                    'IP/SCTP': 'Ether(dst="02:00:00:00:00:00",
> src="%s")/IP(src="%s")/SCTP()/("X"*48)' % (mac, expIP),
> +                    'IPv6/UDP': 'Ether(dst="02:00:00:00:00:00",
> src="%s")/IPv6(src="%s")/UDP()/("X"*46)' % (mac, expIPv6),
> +                    'IPv6/TCP': 'Ether(dst="02:00:00:00:00:00",
> + src="%s")/IPv6(src="%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 = self.checksum_validate(pkts, pkts_ref)
> +
> +        # Validate checksum on the receive packet
> +        out = self.vm0_testpmd.execute_cmd('stop')
> +        bad_ipcsum = self.vm0_testpmd.get_pmd_value("Bad-ipcsum:", out)
> +        bad_l4csum = self.vm0_testpmd.get_pmd_value("Bad-l4csum:", out)
> +        self.verify(bad_ipcsum == 3, "Bad-ipcsum check error")
> +        self.verify(bad_l4csum == 5, "Bad-l4csum check error")
> +
> +        self.verify(len(result) == 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=%s " %
> +                                      (self.portMask) + "--disable-hw-
> vlan --enable-rx-cksum " +
> +                                      "--crc-strip --port-topology=loop")
> +        self.vm0_testpmd.execute_cmd('set fwd csum')
> +
> +        time.sleep(2)
> +
> +        mac = self.vm0_testpmd.get_port_mac(0)
> +        sndIP = '10.0.0.1'
> +        sndIPv6 = '::1'
> +        sndPkts = {'IP/UDP': 'Ether(dst="%s",
> src="52:00:00:00:00:00")/IP(src="%s",chksum=0xf)/UDP(chksum=0xf)/("X"*46)
> ' % (mac, sndIP),
> +                   'IP/TCP': 'Ether(dst="%s",
> src="52:00:00:00:00:00")/IP(src="%s",chksum=0xf)/TCP(chksum=0xf)/("X"*46)
> ' % (mac, sndIP),
> +                   'IPv6/UDP': 'Ether(dst="%s",
> src="52:00:00:00:00:00")/IPv6(src="%s")/UDP(chksum=0xf)/("X"*46)' % (mac,
> sndIPv6),
> +                   'IPv6/TCP': 'Ether(dst="%s",
> + src="52:00:00:00:00:00")/IPv6(src="%s")/TCP(chksum=0xf)/("X"*46)' %
> + (mac, sndIPv6)}
> +
> +        expIP = "10.0.0.2"
> +        expIPv6 = '::2'
> +        expPkts = {'IP/UDP': 'Ether(dst="02:00:00:00:00:00",
> src="%s")/IP(src="%s")/UDP()/("X"*46)' % (mac, expIP),
> +                   'IP/TCP': 'Ether(dst="02:00:00:00:00:00",
> src="%s")/IP(src="%s")/TCP()/("X"*46)' % (mac, expIP),
> +                   'IPv6/UDP': 'Ether(dst="02:00:00:00:00:00",
> src="%s")/IPv6(src="%s")/UDP()/("X"*46)' % (mac, expIPv6),
> +                   'IPv6/TCP': 'Ether(dst="02:00:00:00:00:00",
> + src="%s")/IPv6(src="%s")/TCP()/("X"*46)' % (mac, expIPv6)}
> +
> +        self.vm0_testpmd.execute_cmd('start')
> +        result = self.checksum_validate(sndPkts, expPkts)
> +
> +        # Validate checksum on the receive packet
> +        out = self.vm0_testpmd.execute_cmd('stop')
> +        bad_ipcsum = self.vm0_testpmd.get_pmd_value("Bad-ipcsum:", out)
> +        bad_l4csum = self.vm0_testpmd.get_pmd_value("Bad-l4csum:", out)
> +        self.verify(bad_ipcsum == 2, "Bad-ipcsum check error")
> +        self.verify(bad_l4csum == 4, "Bad-l4csum check error")
> +
> +        self.verify(len(result) == 0, string.join(result.values(),
> + ","))
> +
> +    def tcpdump_start_sniffing(self, ifaces=[]):
> +        """
> +        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 = ('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 = 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 = ('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 =
> self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0]))
> +        rx_interface =
> + self.tester.get_interface(self.tester.get_local_port(self.dut_ports[1]
> + ))
> +
> +        self.frame_sizes = [128, 1458]
> +        self.headers_size = HEADER_SIZE['eth'] + HEADER_SIZE['ip'] +
> HEADER_SIZE['tcp']
> +        padding = 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 = dts.create_mask([self.vm0_dut_ports[0]])
> +        self.vm0_testpmd.start_testpmd(VM_CORES_MASK, "--portmask=%s " %
> +                                      (self.portMask) + "--enable-rx-
> cksum " +
> +                                      "--txqflags=0 " +
> +                                      "--crc-strip
> + --port-topology=loop")
> +
> +        mac = 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="%s",src="52:00:00:00:00:00")/
> IP(src="192.168.1.1",dst="192.168.1.2")/TCP(sport=1021,dport=1021)/("X"*%
> s)], iface="%s")' % (mac, padding, tx_interface))
> +        out = self.tester.scapy_execute()
> +        out = self.vm0_testpmd.execute_cmd("show port stats all")
> +        print out
> +        self.tcpdump_stop_sniff()
> +        rx_stats = self.number_of_packets(rx_interface)
> +        if (rx_stats == 2):
> +            self.verify(1, "Pass")
> +
> +        # IPv6 tcp test
> +
> +        self.tcpdump_start_sniffing([tx_interface, rx_interface])
> +        self.tester.scapy_append('sendp([Ether(dst="%s",
> src="52:00:00:00:00:00")/IPv6(src="FE80:0:0:0:200:1FF:FE00:200",
> dst="3555:5555:6666:6666:7777:7777:8888:8888")/TCP(sport=1021,dport=1021)
> /("X"*%s)], iface="%s")' % (mac, padding, tx_interface))
> +        out = self.tester.scapy_execute()
> +        out = self.vm0_testpmd.execute_cmd("show port stats all")
> +        print out
> +        self.tcpdump_stop_sniff()
> +        rx_stats = self.number_of_packets(rx_interface)
> +        if (rx_stats == 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 == 1:
> +            self.destroy_2pf_2vf_1vm_env()
> --
> 2.5.0



More information about the dts mailing list