* [dts] [PATCH v4]tests,test_plans: add checksum offload and tso
@ 2016-03-08 7:31 Lijuan Tu
2016-03-10 7:18 ` Pei, Yulong
0 siblings, 1 reply; 3+ messages in thread
From: Lijuan Tu @ 2016-03-08 7:31 UTC (permalink / raw)
To: dts, yulong.pei
Add checksum offload and tso test scripts, test plan, config file
Signed-off-by: Lijuan Tu <lijuanx.a.tu@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(sport=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
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [dts] [PATCH v4]tests,test_plans: add checksum offload and tso
2016-03-08 7:31 [dts] [PATCH v4]tests,test_plans: add checksum offload and tso Lijuan Tu
@ 2016-03-10 7:18 ` Pei, Yulong
2016-03-11 4:20 ` Liu, Yong
0 siblings, 1 reply; 3+ messages in thread
From: Pei, Yulong @ 2016-03-10 7:18 UTC (permalink / raw)
To: Tu, LijuanX A, dts
Ack+
-----Original Message-----
From: Tu, LijuanX A
Sent: Tuesday, March 8, 2016 3:31 PM
To: dts@dpdk.org; Pei, Yulong <yulong.pei@intel.com>
Cc: Tu, LijuanX A <lijuanx.a.tu@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@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
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [dts] [PATCH v4]tests,test_plans: add checksum offload and tso
2016-03-10 7:18 ` Pei, Yulong
@ 2016-03-11 4:20 ` Liu, Yong
0 siblings, 0 replies; 3+ messages in thread
From: Liu, Yong @ 2016-03-11 4:20 UTC (permalink / raw)
To: Pei, Yulong, Tu, LijuanX A, dts
Thanks all, applied into master branch.
> -----Original Message-----
> From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of Pei, Yulong
> Sent: Thursday, March 10, 2016 3:18 PM
> To: Tu, LijuanX A; dts@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@dpdk.org; Pei, Yulong <yulong.pei@intel.com>
> Cc: Tu, LijuanX A <lijuanx.a.tu@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@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
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-03-11 4:20 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-08 7:31 [dts] [PATCH v4]tests,test_plans: add checksum offload and tso Lijuan Tu
2016-03-10 7:18 ` Pei, Yulong
2016-03-11 4:20 ` Liu, Yong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).