Beispiel #1
0
class TestVfOffload(TestCase):

    supported_vf_driver = ['pci-stub', 'vfio-pci']

    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

        # set vf assign method and vf driver
        self.vf_driver = self.get_suite_cfg()['vf_driver']
        if self.vf_driver is None:
            self.vf_driver = 'pci-stub'
        self.verify(self.vf_driver in self.supported_vf_driver, "Unsupported vf driver")
        if self.vf_driver == 'pci-stub':
            self.vf_assign_method = 'pci-assign'
        else:
            self.vf_assign_method = 'vfio-pci'
            self.dut.send_expect('modprobe vfio-pci', '#')

        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 = utils.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(self.vf_driver)

            for port in self.sriov_vfs_port_1:
                port.bind_driver(self.vf_driver)

            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 = VM(self.dut, 'vm0', 'vf_offload')
            self.vm0.set_vm_device(driver=self.vf_assign_method, **vf0_prop)
            self.vm0.set_vm_device(driver=self.vf_assign_method, **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.dut.virt_exit()
            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) != 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) != 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("port stop all", "testpmd>")
        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>")
        dut.send_expect("port start all", "testpmd>")

    def checksum_enablesw(self, port, dut):
        dut.send_expect("port stop all", "testpmd>")
        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>")
        dut.send_expect("port start all", "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 report the checksum error,
        verify forwarded packets have correct checksum.
        """
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK, "--portmask=%s " %
                                      (self.portMask) + "--enable-rx-cksum " + "" +
                                      "--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 = sndIP
        expIPv6 = sndIPv6
        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):
        """
        Enable SW checksum offload.
        Send same packet with incorrect checksum and verify checksum is valid.
        """

        self.vm0_testpmd.start_testpmd(VM_CORES_MASK, "--portmask=%s " %
                                      (self.portMask) + "--enable-rx-cksum " +
                                      "--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 = sndIP
        expIPv6 = sndIPv6
        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.checksum_enablesw(0, self.vm_dut_0)

        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=[]):
        """
        Start 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):
        """
        Stop 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):
        """
        Send a tcpdump related command and return 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 are
        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 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 = utils.create_mask([self.vm0_dut_ports[0]])
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK, "--portmask=%s " %
                                      (self.portMask) + "--enable-rx-cksum " +
                                      "" + 
                                      "--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()
Beispiel #2
0
class TestNvgre(TestCase):

    #
    #
    # Utility methods and other non-test code.
    #
    # Insert or move non-test functions here.
    #
    #
    #
    # Test cases.
    #

    def set_up_all(self):
        """
        nvgre Prerequisites
        """
        # this feature only enable in FVL now
        if self.nic in [
                "fortville_eagle", "fortville_spirit",
                "fortville_spirit_single", "fortville_25g", "fortpark_TLV",
                "cavium_a063"
        ]:
            self.compile_switch = 'CONFIG_RTE_LIBRTE_I40E_INC_VECTOR'
        elif self.nic in ["sageville", "sagepond"]:
            self.compile_switch = 'CONFIG_RTE_IXGBE_INC_VECTOR'
        else:
            self.verify(False, "%s not support NVGRE case" % self.nic)
        # Based on h/w type, choose how many ports to use
        ports = self.dut.get_ports(self.nic)
        self.portmask = utils.create_mask(self.dut.get_ports(self.nic))

        # Verify that enough ports are available
        self.verify(len(ports) >= 2, "Insufficient ports for testing")

        # Verify that enough threads are available
        self.all_cores_mask = utils.create_mask(self.dut.get_core_list("all"))
        cores = self.dut.get_core_list("1S/5C/1T")
        self.verify(cores is not None, "Insufficient cores for speed testing")
        self.coremask = utils.create_mask(cores)

        # start testpmd
        self.pmdout = PmdOutput(self.dut)

        # init port
        self.dut_rx_port = ports[0]
        self.dut_tx_port = ports[1]
        self.dut_rx_port_mac = self.dut.get_mac_address(self.dut_rx_port)
        self.dut_tx_port_mac = self.dut.get_mac_address(self.dut_tx_port)

        self.tester_tx_port = self.tester.get_local_port(self.dut_rx_port)
        self.tester_tx_iface = self.tester.get_interface(self.tester_tx_port)
        self.tester_rx_port = self.tester.get_local_port(self.dut_tx_port)
        self.tester_rx_iface = self.tester.get_interface(self.tester_rx_port)

        # invalid parameter
        self.invalid_mac = "00:00:00:00:01"
        self.invalid_ip = "192.168.1.256"
        self.invalid_vlan = 4097
        self.invalid_queue = 64

        # performance test cycle
        self.test_cycles = [{
            'cores': '1S/1C/1T',
            'Mpps': {},
            'pct': {}
        }, {
            'cores': '1S/1C/2T',
            'Mpps': {},
            'pct': {}
        }, {
            'cores': '1S/2C/1T',
            'Mpps': {},
            'pct': {}
        }]
        """
        self.cal_type = [
            {'Type': 'SOFTWARE ALL', 'tx_checksum': '0x0'},
            {'Type': 'HW OUTER L3', 'tx_checksum': '0x1'},
            {'Type': 'HW OUTER L4', 'tx_checksum': '0x2'},
            {'Type': 'HW OUTER L3&L4', 'tx_checksum': '0x3'},
            {'Type': 'HW INNER L3', 'tx_checksum': '0x10'},
            {'Type': 'HW INNER L4', 'tx_checksum': '0x20'},
            {'Type': 'HW INNER L3&L4', 'tx_checksum': '0x30'},
            {'Type': 'HARDWARE ALL', 'tx_checksum': '0xff'}
        ]
        """

        self.table_header = ['Calculate Type']
        for test_cycle in self.test_cycles:
            self.table_header.append("%s Mpps" % test_cycle['cores'])
            self.table_header.append("% linerate")

        # tunnel filter performance test
        self.default_vlan = 1
        self.tunnel_multiqueue = 2
        self.tunnel_header = [
            'Packet', 'Filter', 'Queue', 'Mpps', '% linerate'
        ]
        self.tunnel_perf = [{
            'Packet': 'Normal',
            'tunnel_filter': 'None',
            'recvqueue': 'Single',
            'Mpps': {},
            'pct': {}
        }, {
            'Packet': 'NVGRE',
            'tunnel_filter': 'None',
            'recvqueue': 'Single',
            'Mpps': {},
            'pct': {}
        }, {
            'Packet': 'NVGRE',
            'tunnel_filter': 'imac-ivlan',
            'recvqueue': 'Single',
            'Mpps': {},
            'pct': {}
        }, {
            'Packet': 'NVGRE',
            'tunnel_filter': 'imac-ivlan-tenid',
            'recvqueue': 'Single',
            'Mpps': {},
            'pct': {}
        }, {
            'Packet': 'NVGRE',
            'tunnel_filter': 'imac-tenid',
            'recvqueue': 'Single',
            'Mpps': {},
            'pct': {}
        }, {
            'Packet': 'NVGRE',
            'tunnel_filter': 'imac',
            'recvqueue': 'Single',
            'Mpps': {},
            'pct': {}
        }, {
            'Packet': 'NVGRE',
            'tunnel_filter': 'omac-imac-tenid',
            'recvqueue': 'Single',
            'Mpps': {},
            'pct': {}
        }, {
            'Packet': 'NVGRE',
            'tunnel_filter': 'imac-ivlan',
            'recvqueue': 'Multi',
            'Mpps': {},
            'pct': {}
        }, {
            'Packet': 'NVGRE',
            'tunnel_filter': 'imac-ivlan-tenid',
            'recvqueue': 'Multi',
            'Mpps': {},
            'pct': {}
        }, {
            'Packet': 'NVGRE',
            'tunnel_filter': 'imac-tenid',
            'recvqueue': 'Multi',
            'Mpps': {},
            'pct': {}
        }, {
            'Packet': 'NVGRE',
            'tunnel_filter': 'imac',
            'recvqueue': 'Multi',
            'Mpps': {},
            'pct': {}
        }, {
            'Packet': 'NVGRE',
            'tunnel_filter': 'omac-imac-tenid',
            'recvqueue': 'Multi'
        }]

        self.ports_socket = self.dut.get_numa_id(self.dut_rx_port)

    def nvgre_detect(self, **kwargs):
        """
        send nvgre packet and check whether testpmd detect the correct packet type
        """
        out = self.dut.send_expect(
            "./%s/app/testpmd -c %s -n %d -- -i --disable-rss --rxq=4 --txq=4 --nb-cores=4 --portmask=%s"
            % (self.target, self.coremask, self.dut.get_memory_channels(),
               self.portmask), "testpmd>", 30)
        out = self.dut.send_expect("set fwd rxonly", "testpmd>", 10)
        self.dut.send_expect("set verbose 1", "testpmd>", 10)

        arg_str = ""
        for arg in kwargs:
            arg_str += "[%s = %s]" % (arg, kwargs[arg])

        # create pcap file with supplied arguments
        self.logger.info("send nvgre pkts %s" % arg_str)
        config = NvgreTestConfig(self, **kwargs)
        # now cloud filter will default enable L2 mac filter, so dst mac must be same
        config.outer_mac_dst = self.dut_rx_port_mac
        config.create_pcap()
        self.dut.send_expect("start", "testpmd>", 10)
        config.send_pcap()
        # check whether detect nvgre type
        out = self.dut.get_session_output()
        print out
        self.verify(
            config.packet_type(self.nic) in out, "Nvgre Packet not detected")
        self.dut.send_expect("show port stats all", "testpmd>", 10)
        self.dut.send_expect("stop", "testpmd>", 10)
        self.dut.send_expect("quit", "#", 10)

    def nvgre_filter(self,
                     filter_type="omac-imac-tenid",
                     queue_id=3,
                     vlan=False,
                     remove=False):
        """
        send nvgre packet and check whether receive packet in assigned queue
        """
        self.dut.send_expect(
            "./%s/app/testpmd -c %s -n %d -- -i --disable-rss --rxq=4 --txq=4 --nb-cores=4 --portmask=%s"
            % (self.target, self.coremask, self.dut.get_memory_channels(),
               self.portmask), "testpmd>", 30)
        self.dut.send_expect("set fwd rxonly", "testpmd>", 10)
        self.dut.send_expect("set verbose 1", "testpmd>", 10)

        if vlan is not False:
            config = NvgreTestConfig(self, inner_vlan=vlan)
            vlan_id = vlan
        else:
            config = NvgreTestConfig(self)
            vlan_id = 1

        # now cloud filter will default enable L2 mac filter, so dst mac must be same
        config.outer_mac_dst = self.dut_rx_port_mac

        # tunnel_filter add port_id outer_mac inner_mac ip_addr inner_vlan tunnel_type(vxlan|nvgre)
        #       filter_type (imac-ivlan|imac-ivlan-tenid|imac-tenid|imac|omac-imac-tenid|iip) tenant_id queue_num

        out = self.dut.send_expect(
            "tunnel_filter add %d %s %s %s %d nvgre %s %d %d" %
            (self.dut_rx_port, config.outer_mac_dst, config.inner_mac_dst,
             config.inner_ip_dst, vlan_id, filter_type, config.tni, queue_id),
            "testpmd>", 10)
        print out
        # invalid case request to remove tunnel filter
        if remove is True:
            queue_id = 0
            self.dut.send_expect(
                "tunnel_filter rm %d %s %s %s %d nvgre %s %d %d" %
                (self.dut_rx_port, config.outer_mac_dst, config.inner_mac_dst,
                 config.inner_ip_dst, vlan_id, filter_type, config.tni,
                 queue_id), "testpmd>", 10)

        # send nvgre packet
        config.create_pcap()
        self.dut.send_expect("start", "testpmd>", 10)
        config.send_pcap()
        out = self.dut.get_session_output()
        print out
        queue = -1
        pattern = re.compile("- Receive queue=0x(\d)")
        m = pattern.search(out)
        if m is not None:
            queue = m.group(1)

        # verify received in expected queue
        self.verify(queue_id == int(queue), "invalid receive queue")

        self.dut.send_expect("stop", "testpmd>", 10)
        self.dut.send_expect("quit", "#", 10)

    def nvgre_checksum(self, **kwargs):

        # create pcap file with correct arguments
        args = {}
        for arg in kwargs:
            if "invalid" not in arg:
                args[arg] = kwargs[arg]

        config = NvgreTestConfig(self, **args)
        # now cloud filter will default enable L2 mac filter, so dst mac must be same
        config.outer_mac_dst = self.dut_rx_port_mac
        # csum function will not change outer ipv src address already
        if config.outer_ip6_src != "N/A":
            config.outer_ip6_src = config.outer_ip6_src
        else:
            config.outer_ip_src = config.outer_ip_src

        # csum function will not auto change nvgre inner ipv src address already
        if config.inner_ip6_src != "N/A":
            config.inner_ip6_src = config.inner_ip6_src
        else:
            config.inner_ip_src = config.inner_ip_src

        # create abnormal package with wrong checksum
        config.create_pcap()
        chksums_default = config.get_chksums()
        self.logger.info("chksums_ref:" + str(chksums_default))

        # start testpmd with 2queue/1port
        out = self.dut.send_expect(
            "./%s/app/testpmd -c %s -n %d -- -i --disable-rss --rxq=4 --txq=4 --nb-cores=4 --portmask=%s --enable-rx-cksum"
            % (self.target, self.coremask, self.dut.get_memory_channels(),
               self.portmask), "testpmd>", 30)
        # disable vlan filter
        self.dut.send_expect('vlan set filter off %d' % self.dut_rx_port,
                             "testpmd")

        # enable tx checksum offload
        self.dut.send_expect("set verbose 1", "testpmd>", 10)
        self.dut.send_expect("set fwd csum", "testpmd>", 10)
        self.dut.send_expect("port stop all", "testpmd>")
        self.dut.send_expect("csum set ip hw %d" % (self.dut_tx_port),
                             "testpmd>", 10)
        self.dut.send_expect("csum set udp hw %d" % (self.dut_tx_port),
                             "testpmd>", 10)
        self.dut.send_expect("csum set tcp hw %d" % (self.dut_tx_port),
                             "testpmd>", 10)
        self.dut.send_expect("csum set sctp hw %d" % (self.dut_tx_port),
                             "testpmd>", 10)
        self.dut.send_expect("csum set outer-ip hw %d" % (self.dut_tx_port),
                             "testpmd>", 10)
        self.dut.send_expect("csum parse-tunnel on %d" % (self.dut_tx_port),
                             "testpmd>", 10)
        self.dut.send_expect("port start all", "testpmd>")

        # log the nvgre format
        arg_str = ""
        for arg in kwargs:
            arg_str += "[%s = %s]" % (arg, kwargs[arg])
        self.logger.info("nvgre packet %s" % arg_str)

        out = self.dut.send_expect("start", "testpmd>", 10)

        # create pcap file with supplied arguments
        config = NvgreTestConfig(self, **kwargs)
        config.outer_mac_dst = self.dut_rx_port_mac
        config.create_pcap()

        # remove temporary files
        self.tester.send_expect("rm -rf %s" % config.capture_file, "# ")
        # save the capture packet into pcap format
        self.tester.scapy_background()
        self.tester.scapy_append(
            'p=sniff(iface="%s",filter="ether[12:2]!=0x88cc",count=1,timeout=5)'
            % self.tester_rx_iface)
        self.tester.scapy_append('wrpcap(\"%s\", p)' % config.capture_file)
        self.tester.scapy_foreground()

        config.send_pcap()
        time.sleep(5)

        # extract the checksum offload from saved pcap file
        chksums = config.get_chksums(pcap=config.capture_file)
        os.remove(config.capture_file)
        self.logger.info("chksums_tx:" + str(chksums))

        out = self.dut.send_expect("stop", "testpmd>", 10)

        # verify detected l4 invalid checksum
        if "inner_l4_invalid" in kwargs and config.inner_l4_type is not 'UDP':
            self.verify(
                self.pmdout.get_pmd_value("Bad-l4csum:", out) == 1,
                "Failed to count inner l4 chksum error")

        # verify detected l3 invalid checksum
        if "inner_ip_invalid" in kwargs:
            self.verify(
                self.pmdout.get_pmd_value("Bad-ipcsum:", out) == 1,
                "Failed to count inner ip chksum error")

        self.dut.send_expect("quit", "#", 10)

        # verify saved pcap checksum same to expected checksum
        for key in chksums_default:
            self.verify(chksums[key] == chksums_default[key],
                        "%s not matched to %s" % (key, chksums_default[key]))

    def test_nvgre_ipv4(self):
        """
        verify nvgre packet with ipv4
        """
        # packet type detect must used without VECTOR pmd
        out = self.dut.send_expect("cat config/common_base", "]# ", 10)
        src_vec_model = re.findall("%s=." % self.compile_switch, out)[0][-1]
        if src_vec_model == 'y':
            self.dut.send_expect(
                "sed -i -e 's/%s=.*$/" % self.compile_switch +
                "%s=n/' config/common_base" % self.compile_switch, "# ", 30)
            self.dut.skip_setup = False
            self.dut.build_install_dpdk(self.target)

        # check no nvgre packet
        self.nvgre_detect(outer_ip_proto=0xFF)
        # check nvgre + IP inner packet
        self.nvgre_detect(inner_l3_type="IPv4", inner_l4_type='None')
        # check nvgre + udp inner packet
        self.nvgre_detect(inner_l4_type='TCP')
        # check nvgre + SCTP inner packet
        # self.nvgre_detect(inner_l4_type='SCTP')
        # check nvgre + vlan inner packet
        self.nvgre_detect(outer_vlan=1)
        # check vlan nvgre + vlan inner packet
        self.nvgre_detect(outer_vlan=1, inner_vlan=1)
        out = self.dut.send_expect("cat config/common_base", "]# ", 10)
        dst_vec_model = re.findall("%s=." % self.compile_switch, out)[0][-1]
        if src_vec_model != dst_vec_model:
            self.dut.send_expect(
                "sed -i -e 's/%s=.*$/" % self.compile_switch +
                "%s=%s/' config/common_base" %
                (self.compile_switch, src_vec_model), "# ", 30)
            self.dut.skip_setup = False
            self.dut.build_install_dpdk(self.target)

    def test_tunnel_filter(self):

        # verify tunnel filter feature
        # check outer mac
        self.nvgre_filter(filter_type="omac-imac-tenid")
        # check inner mac + inner vlan filter can work
        self.nvgre_filter(filter_type="imac-ivlan", vlan=1)
        # check inner mac + inner vlan + tunnel id filter can work
        self.nvgre_filter(filter_type="imac-ivlan-tenid", vlan=1)
        # check inner mac + tunnel id filter can work
        self.nvgre_filter(filter_type="imac-tenid")
        # check inner mac filter can work
        self.nvgre_filter(filter_type="imac")
        # check outer mac + inner mac + tunnel id filter can work
        self.nvgre_filter(filter_type="omac-imac-tenid")
        # check iip filter can work
        # self.nvgre_filter(filter_type="iip")

    def test_tunnel_filter_invalid(self):
        # verify tunnel filter parameter check function

        # invalid parameter
        vlan_id = 1
        filter_type = 'omac-imac-tenid'
        queue_id = 3

        self.nvgre_filter(filter_type="imac", remove=True)
        config = NvgreTestConfig(self)
        # config.outer_mac_dst = self.dut_port_mac
        self.dut.send_expect(
            "./%s/app/testpmd -c %s -n %d -- -i --disable-rss --rxq=4 --txq=4 --nb-cores=4 --portmask=%s"
            % (self.target, self.coremask, self.dut.get_memory_channels(),
               self.portmask), "testpmd>", 30)
        out = self.dut.send_expect(
            "tunnel_filter add %d %s %s %s %d nvgre %s %d %d" %
            (self.dut_rx_port, config.outer_mac_dst, self.invalid_mac,
             config.inner_ip_dst, vlan_id, filter_type, config.tni, queue_id),
            "testpmd>", 10)
        self.verify("Bad arguments" in out, "Failed to detect invalid mac")
        out = self.dut.send_expect(
            "tunnel_filter add %d %s %s %s %d nvgre %s %d %d" %
            (self.dut_rx_port, config.outer_mac_dst, config.inner_mac_dst,
             self.invalid_ip, vlan_id, filter_type, config.tni, queue_id),
            "testpmd>", 10)
        self.verify("Bad arguments" in out, "Failed to detect invalid ip")
        out = self.dut.send_expect(
            "tunnel_filter add %d %s %s %s %d nvgre %s %d %d" %
            (self.dut_rx_port, config.outer_mac_dst, config.inner_mac_dst,
             config.inner_ip_dst, self.invalid_vlan, filter_type, config.tni,
             queue_id), "testpmd>", 10)
        self.verify("Input/output error" in out,
                    "Failed to detect invalid vlan")
        out = self.dut.send_expect(
            "tunnel_filter add %d %s %s %s %d nvgre %s %d %d" %
            (self.dut_rx_port, config.outer_mac_dst, config.inner_mac_dst,
             config.inner_ip_dst, vlan_id, filter_type, config.tni,
             self.invalid_queue), "testpmd>", 10)
        self.verify("Input/output error" in out,
                    "Failed to detect invalid queue")

        self.dut.send_expect("stop", "testpmd>", 10)
        self.dut.send_expect("quit", "#", 10)

    def test_nvgre_ipv4_checksum_offload(self):
        # check normal packet
        self.nvgre_checksum()
        # check normal packet + ip checksum invalid
        self.nvgre_checksum(outer_ip_invalid=1)
        # check nvgre packet + inner ip checksum invalid
        self.nvgre_checksum(inner_ip_invalid=1)
        # check nvgre packet + outer ip checksum invalid
        self.nvgre_checksum(outer_ip_invalid=1)
        # check nvgre packet + outer ip + inner ip checksum invalid
        self.nvgre_checksum(outer_ip_invalid=1, inner_ip_invalid=1)
        # check nvgre packet + inner udp checksum invalid
        self.nvgre_checksum(inner_l4_invalid=1)
        # check nvgre packet + inner tcp checksum invalid
        self.nvgre_checksum(inner_l4_invalid=1, inner_l4_type='TCP')
        # check nvgre packet + inner sctp checksum invalid
        self.nvgre_checksum(inner_l4_invalid=1, inner_l4_type='SCTP')
        # check vlan nvgre packet + outer ip checksum invalid
        self.nvgre_checksum(outer_vlan=1, outer_ip_invalid=1)
        # check vlan nvgre packet + inner ip checksum invalid
        self.nvgre_checksum(outer_vlan=1, inner_ip_invalid=1)
        # check vlan nvgre packet + outer&inner ip checksum invalid
        self.nvgre_checksum(outer_vlan=1,
                            outer_ip_invalid=1,
                            inner_ip_invalid=1)
        # check vlan nvgre packet + inner vlan + outer ip checksum invalid
        self.nvgre_checksum(outer_vlan=1, inner_vlan=1, outer_ip_invalid=1)
        # check vlan nvgre packet + inner vlan + inner ip checksum invalid
        self.nvgre_checksum(outer_vlan=1, inner_vlan=1, inner_ip_invalid=1)
        # check vlan nvgre packet + inner vlan + outer&inner ip checksum invalid
        self.nvgre_checksum(outer_vlan=1,
                            inner_vlan=1,
                            outer_ip_invalid=1,
                            inner_ip_invalid=1)
        # check vlan nvgre packet + inner vlan + inner udp checksum invalid
        self.nvgre_checksum(outer_vlan=1,
                            inner_l4_invalid=1,
                            inner_l4_type='UDP')
        # check vlan nvgre packet + inner vlan + inner tcp checksum invalid
        self.nvgre_checksum(outer_vlan=1,
                            inner_l4_invalid=1,
                            inner_l4_type='TCP')
        # check vlan nvgre packet + inner vlan + inner sctp checksum invalid
        self.nvgre_checksum(outer_vlan=1,
                            inner_l4_invalid=1,
                            inner_l4_type='SCTP')

    def test_perf_nvgre_tunnelfilter_performance_2ports(self):
        self.result_table_create(self.tunnel_header)
        core_list = self.dut.get_core_list('1S/%dC/1T' %
                                           (self.tunnel_multiqueue * 2),
                                           socket=self.ports_socket)
        core_mask = utils.create_mask(core_list)

        command_line = "./%s/app/testpmd -c %s -n %d -- -i --disable-rss --coremask=%s --rxq=4 --txq=4 --portmask=%s" % (
            self.target, self.all_cores_mask, self.dut.get_memory_channels(),
            core_mask, self.portmask)
        for perf_config in self.tunnel_perf:
            pkts = []
            config = NvgreTestConfig(self)
            config.inner_vlan = self.default_vlan
            config.outer_mac_dst = self.dut.get_mac_address(self.dut_port)
            # get frame size
            config.create_pcap()
            frame_size = config.pcap_len()

            # restart testpmd in each performance config
            self.dut.send_expect(command_line, "testpmd> ", 100)
            if perf_config['tunnel_filter'] != 'None':
                self.dut.send_expect(
                    "tunnel_filter add %d %s %s %s %d vxlan %s %d %d" %
                    (self.dut_port, config.outer_mac_dst, config.inner_mac_dst,
                     config.inner_ip_dst, config.inner_vlan,
                     perf_config['tunnel_filter'], config.tni, 0), "testpmd>",
                    10)

            if perf_config['Packet'] == 'Normal':
                config.outer_udp_dst = 63
                config.outer_mac_dst = self.dut.get_mac_address(self.dut_port)
                config.payload_size = frame_size - HEADER_SIZE[
                    'eth'] - HEADER_SIZE['ip'] - HEADER_SIZE['udp']

            # add default pkt into pkt list
            pkt = config.create_pcap()
            pkts.append(pkt)

            # add other pkts into pkt list when enable multi receive queues
            if perf_config['recvqueue'] == 'Multi':
                for queue in range(self.tunnel_multiqueue - 1):
                    if 'imac' in perf_config['tunnel_filter']:
                        config.inner_mac_dst = "00:00:20:00:00:0%d" % (queue +
                                                                       2)
                    if 'ivlan' in perf_config['tunnel_filter']:
                        config.inner_vlan = (queue + 2)
                    if 'tenid' in perf_config['tunnel_filter']:
                        config.vni = (queue + 2)

                    # add tunnel filter the same as pkt
                    pkt = config.create_pcap()
                    pkts.append(pkt)
                    out = self.dut.send_expect(
                        "tunnel_filter add %d %s %s %s %d vxlan %s %d %d" %
                        (self.dut_port, config.outer_mac_dst,
                         config.inner_mac_dst, config.inner_ip_dst,
                         config.inner_vlan, perf_config['tunnel_filter'],
                         config.vni, (queue + 1)), "testpmd>", 10)

            # save pkt list into pcap file
            wrpcap(config.pcap_file, pkts)
            self.tester.session.copy_file_to(config.pcap_file)

            # config the flows
            tgen_input = []
            tgen_input.append(
                (self.tester.get_local_port(self.dut_port),
                 self.tester.get_local_port(self.recv_port), config.pcap_file))

            self.dut.send_expect("set fwd mac", "testpmd>", 10)
            self.dut.send_expect("start", "testpmd>", 10)

            frame_size = config.pcap_len()
            wirespeed = self.wirespeed(self.nic, frame_size, 2)
            # run traffic generator
            _, pps = self.tester.traffic_generator_throughput(tgen_input)

            pps /= 1000000.0
            perf_config['Mpps'] = pps
            perf_config['pct'] = pps * 100 / wirespeed

            out = self.dut.send_expect("stop", "testpmd>", 10)
            self.dut.send_expect("quit", "# ", 10)

            # verify every queue work fine
            if perf_config['recvqueue'] == 'Multi':
                for queue in range(self.tunnel_multiqueue):
                    self.verify(
                        "RX Port= 0/Queue= %d -> TX Port= 1/Queue= %d" %
                        (queue, queue) in out, "Queue %d no traffic" % queue)

            table_row = [
                perf_config['Packet'], perf_config['tunnel_filter'],
                perf_config['recvqueue'], perf_config['Mpps'],
                perf_config['pct']
            ]

            self.result_table_add(table_row)

        self.result_table_print()

    def test_perf_nvgre_checksum_performance_2ports(self):
        config = NvgreTestConfig(self)
        config.outer_mac_dst = self.dut.get_mac_address(self.dut_port)
        config.pcap_file = "nvgre1.pcap"
        config.create_pcap()
        config.outer_mac_dst = self.dut.get_mac_address(self.recv_port)
        config.pcap_file = "nvgre.pcap"
        config.create_pcap()

        # configure flows
        tgen_input = []
        tgen_input.append(
            (self.tester.get_local_port(self.dut_port),
             self.tester.get_local_port(self.recv_port), "nvgre.pcap"))
        tgen_input.append(
            (self.tester.get_local_port(self.recv_port),
             self.tester.get_local_port(self.dut_port), "nvgre.pcap"))

        all_cores_mask = utils.create_mask(self.dut.get_core_list("all"))

        # socket/core/thread
        for test_cycle in self.test_cycles:
            core_config = test_cycle['cores']

            # take care the corelist when enable numa
            if '2S' not in core_config:
                core_list = self.dut.get_core_list(core_config,
                                                   socket=self.ports_socket)
            else:
                core_list = self.dut.get_core_list(core_config)

            core_mask = utils.create_mask(core_list)

            command_line = "./%s/app/testpmd -c %s -n %d -- -i \
 --disable-rss --coremask=%s --portmask=%s" % (self.target, all_cores_mask,
                                               self.dut.get_memory_channels(),
                                               core_mask, self.portmask)

            self.dut.send_expect(command_line, "testpmd> ", 100)
            self.dut.send_expect("set fwd csum", "testpmd>", 10)

            # different calculate type
            for cal in self.cal_type:
                self.dut.send_expect(
                    "tx_checksum set %s %d" %
                    (cal['tx_checksum'], self.dut_port), "testpmd>", 10)
                self.dut.send_expect(
                    "tx_checksum set %s %d" %
                    (cal['tx_checksum'], self.recv_port), "testpmd>", 10)
                self.dut.send_expect("start", "testpmd>", 10)

                frame_size = config.pcap_len()
                wirespeed = self.wirespeed(self.nic, frame_size, 2)
                # run traffic generator
                _, pps = self.tester.traffic_generator_throughput(tgen_input)

                pps /= 1000000.0
                test_cycle['Mpps'][cal['Type']] = pps
                test_cycle['pct'][cal['Type']] = pps * 100 / wirespeed

                self.dut.send_expect("stop", "testpmd>", 10)

            self.dut.send_expect("quit", "# ", 10)

        self.result_table_create(self.table_header)

        # save the results
        for cal in self.cal_type:
            table_row = [cal['Type']]
            for test_cycle in self.test_cycles:
                table_row.append(test_cycle['Mpps'][cal['Type']])
                table_row.append(test_cycle['pct'][cal['Type']])

            self.result_table_add(table_row)

        self.result_table_print()

    def set_up(self):
        """
        Run before each test case.
        """
        pass

    def tear_down(self):
        """
        Run after each test case.
        """
        self.dut.kill_all()

    def tear_down_all(self):
        """
        Run after each test suite.
        """
        pass