Ejemplo n.º 1
0
 def get_stats(self, portid):
     """
     Get packets number from port statistic.
     @param: stop -- stop forward before get stats
     """
     output = PmdOutput(self.dut)
     stats = output.get_pmd_stats(portid)
     return stats
Ejemplo n.º 2
0
class TestVF2VFBridge(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
        self.vm1 = 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, "Unspported 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', '#')


    def set_up(self):
        self.set_up_vf_to_vf_env()

    def set_up_vf_to_vf_env(self, driver='default'):
        self.pf_port_for_vfs = self.dut_ports[0]
        self.dut.restore_interfaces()
        self.dut.generate_sriov_vfs_by_port(
            self.pf_port_for_vfs, VF_NUMS_ON_ONE_PF, driver=driver)
        self.sriov_vfs_ports = self.dut.ports_info[
            self.pf_port_for_vfs]['vfs_port']
        self.host_port_intf = self.dut.ports_info[self.pf_port_for_vfs]['intf']
        for i in range(VF_NUMS_ON_ONE_PF):
            self.dut.send_expect('ip link set dev %s vf %d mac %s' %
                                 (self.host_port_intf, i, VF_TEMP_MAC % i), '#', 10)
        try:
            for port in self.sriov_vfs_ports:
                port.bind_driver(self.vf_driver)
            time.sleep(1)
        except Exception as e:
            raise Exception(e)

        vf0_prop = {'opt_host': self.sriov_vfs_ports[0].pci}
        vf1_prop = {'opt_host': self.sriov_vfs_ports[1].pci}
        time.sleep(1)
        self.vm0 = VM(self.dut, 'vm0', 'vf_to_vf_bridge')
        self.vm0.set_vm_device(driver=self.vf_assign_method, **vf0_prop)
        try:
            self.vm0_dut = self.vm0.start()
            if self.vm0_dut is None:
                raise Exception('Set up VM0 failed')
        except Exception as e:
            print utils.RED(str(e))

        self.vm1 = VM(self.dut, 'vm1', 'vf_to_vf_bridge')
        self.vm1.set_vm_device(driver=self.vf_assign_method, **vf1_prop)
        try:
            self.vm1_dut = self.vm1.start()
            if self.vm1_dut is None:
                raise Exception('Set up VM1 failed')
        except Exception as e:
            print utils.RED(str(e))

    def clear_vf_to_vf_env(self):
        if self.vm0 is not None:
            self.vm0.stop()
            self.vm0 = None
        if self.vm1 is not None:
            self.vm1.stop()
            self.vm1 = None
        self.dut.virt_exit()
        if self.pf_port_for_vfs is not None:
            self.dut.destroy_sriov_vfs_by_port(self.pf_port_for_vfs)
            port = self.dut.ports_info[self.pf_port_for_vfs]['port']
            port.bind_driver()
            self.pf_port_for_vfs = 0

    def generate_pcap_pkt(self, dst, src, load, pktname='flow.pcap'):
        """
        dst:
            server: dst server object
             ether: dst mac
                ip: dst ip
               udp: dst udp protocol
               tcp: dst tcp protocal
        src:
            server: src server object
             ether: src mac
                ip: src ip
               udp: src udp protocol
               tcp: src tcp protocal
        load:
           content: pay load
            length: content length
        """
        context = '[Ether(dst="%s", src="%s")/IP()/Raw(load=%s)]' % \
            (str(dst['ether']), str(src['ether']), load['content'])
        src['server'].send_expect('scapy', '>>> ', 10)
        src['server'].send_expect(
            'wrpcap("%s", %s)' % (pktname, context), '>>> ', 10)
        src['server'].send_expect('quit()', '#', 10)

    def prepare_pktgen(self, vm):
        vm.session.copy_file_to('./dep/tgen.tgz')
        vm.send_expect("cd /root", "#", 10)
        vm.send_expect("tar xvf tgen.tgz", '#', 20)

    def send_stream_pktgen(self, vm, pktname='flow.pcap'):
        vm.send_expect(
            "echo 2048 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages", "#", 10)
        vm.send_expect(" mount -t hugetlbfs nodedev /mnt/huge/", "#", 10)
        vm.send_expect(
            "./pktgen -c 0xf -n 2 --proc-type auto -- -P -T -m '1.0' -s 0:%s" %
                       pktname, "", 100)
        time.sleep(60)
        vm.send_expect("set 0 rate 50", "", 20)
        time.sleep(5)
        vm.send_expect("set 0 count %d" % SEND_PACKET, "", 20)
        time.sleep(5)
        vm.send_expect("start all", "", 20)
        time.sleep(20)

    def stop_stream_pktgen(self, vm):
        vm.send_expect("stop all", "", 20)
        time.sleep(5)
        vm.send_expect("quit", "#", 20)

    def test_2vf_d2d_pktgen_stream(self):
        self.vm0_ports = self.vm0_dut.get_ports('any')
        self.vm0_pmd = PmdOutput(self.vm0_dut)
        self.vm0_pmd.start_testpmd('all')
        self.vm0_pmd.execute_cmd('set fwd rxonly')
        self.vm0_pmd.execute_cmd("set promisc all off")
        self.vm0_pmd.execute_cmd('start')

        self.vm1_ports = self.vm1_dut.get_ports('any')
        self.prepare_pktgen(self.vm1_dut)

        dst = {}
        dst['server'] = self.vm0_dut
        dst['ether'] = self.vm0_dut.ports_info[self.vm0_ports[0]]['mac']
        src = {}
        src['server'] = self.vm1_dut
        src['ether'] = self.vm1_dut.ports_info[self.vm1_ports[0]]['mac']
        load = {}
        load['content'] = "'X'*46"
        self.generate_pcap_pkt(dst, src, load)
        self.vm0_pmd.execute_cmd('clear port stats all')
        self.send_stream_pktgen(self.vm1_dut)
        recv_num = self.vm0_pmd.get_pmd_stats(0)['RX-packets']
        time.sleep(1)
        self.stop_stream_pktgen(self.vm1_dut)
        self.vm0_pmd.execute_cmd('stop')
        self.vm0_pmd.execute_cmd('quit', '# ')

        self.verify(recv_num is SEND_PACKET,
                    'Rx port recv error: %d' % recv_num)

    def test_2vf_d2k_pktgen_stream(self):
        self.vm0_dut.restore_interfaces()
        self.vm0_ports = self.vm0_dut.get_ports('any')
        vf0_intf = self.vm0_dut.ports_info[self.vm0_ports[0]]['intf']

        self.vm1_ports = self.vm1_dut.get_ports('any')
        self.prepare_pktgen(self.vm1_dut)

        dst = {}
        dst['server'] = self.vm0_dut
        dst['ether'] = self.vm0_dut.ports_info[self.vm0_ports[0]]['mac']
        src = {}
        src['server'] = self.vm1_dut
        src['ether'] = self.vm1_dut.ports_info[self.vm1_ports[0]]['mac']
        load = {}
        load['content'] = "'X'*46"
        self.generate_pcap_pkt(dst, src, load)
        self.vm0_dut.send_expect(
            'tcpdump -i %s -s 1000 "ether src %s and ether dst %s"' %
                                 (vf0_intf, src['ether'], dst['ether']), 'tcpdump', 30)
        self.send_stream_pktgen(self.vm1_dut)
        self.stop_stream_pktgen(self.vm1_dut)

        recv_tcpdump = self.vm0_dut.send_expect('^C', '#', 30)
        time.sleep(5)
        recv_pattern = re.compile("(\d+) packets captured")
        recv_info = recv_pattern.search(recv_tcpdump)
        recv_str = recv_info.group(0).split(' ')[0]
        recv_number = int(recv_str, 10)
        self.vm0_dut.bind_interfaces_linux(self.drivername)

        self.verify(recv_number is SEND_PACKET,
                    'Rx port recv error: %d' % recv_number)

    def test_2vf_k2d_scapy_stream(self):
        self.vm0_ports = self.vm0_dut.get_ports('any')
        self.vm0_pmd = PmdOutput(self.vm0_dut)
        self.vm0_pmd.start_testpmd('all')

        self.vm1_ports = self.vm1_dut.get_ports('any')
        self.vm1_dut.restore_interfaces()
        vf1_intf = self.vm1_dut.ports_info[self.vm1_ports[0]]['intf']

        dst_mac = self.vm0_dut.ports_info[self.vm0_ports[0]]['mac']
        src_mac = self.vm1_dut.ports_info[self.vm1_ports[0]]['mac']
        pkt_content = 'Ether(dst="%s", src="%s")/IP()/Raw(load="X"*46)' % \
                      (dst_mac, src_mac)
        self.vm1_dut.send_expect('scapy', '>>> ', 10)

        self.vm0_pmd.execute_cmd('set promisc all off')
        self.vm0_pmd.execute_cmd('set fwd rxonly')
        self.vm0_pmd.execute_cmd('set verbose 1')
        self.vm0_pmd.execute_cmd('start')

        self.vm1_dut.send_expect('sendp([%s], iface="%s", count=%d)' %
                                 (pkt_content, vf1_intf, SEND_PACKET), '>>> ', 30)

        out = self.vm0_dut.get_session_output(timeout=60)
        rx_packets = re.findall("src=%s - dst=%s" % (src_mac, dst_mac), out)
        recv_num = len(rx_packets)

        self.vm1_dut.send_expect('quit()', '# ', 10)
        self.vm1_dut.bind_interfaces_linux(self.drivername)
        self.vm0_pmd.execute_cmd('stop')
        self.vm0_pmd.execute_cmd('quit', '# ')

        self.verify(recv_num is SEND_PACKET,
                    'Rx port recv error: %d' % recv_num)

    def tear_down(self):
        self.clear_vf_to_vf_env()

    def tear_down_all(self):
        pass
Ejemplo n.º 3
0
class TestVfJumboFrame(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
        self.env_done = False

        self.port = self.dut_ports[0]
        self.vm_port = 0
        cores = self.dut.get_core_list("1S/1C/1T")
        self.port_mask = utils.create_mask([self.port])

        # set vf assign method and vf driver
        self.dut.send_expect('modprobe vfio-pci', '#')
        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,
                    "Unspported 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', '#')

        # enable tester mtu
        tester_port = self.tester.get_local_port(self.port)
        self.netobj = self.tester.ports_info[tester_port]['port']
        self.netobj.enable_jumbo(framesize=ETHER_JUMBO_FRAME_MTU + 100)

    def set_up(self):
        self.setup_vm_env()

    def bind_nic_driver(self, ports, driver=""):
        # modprobe vfio driver
        if driver == "vfio-pci":
            for port in ports:
                netdev = self.dut.ports_info[port]['port']
                driver = netdev.get_nic_driver()
                if driver != 'vfio-pci':
                    netdev.bind_driver(driver='vfio-pci')

        elif driver == "igb_uio":
            # igb_uio should insmod as default, no need to check
            for port in ports:
                netdev = self.dut.ports_info[port]['port']
                driver = netdev.get_nic_driver()
                if driver != 'igb_uio':
                    netdev.bind_driver(driver='igb_uio')
        else:
            for port in ports:
                netdev = self.dut.ports_info[port]['port']
                driver_now = netdev.get_nic_driver()
                if driver == None:
                    driver = netdev.default_driver
                if driver != driver_now:
                    netdev.bind_driver(driver=driver)

    def setup_vm_env(self, driver='default'):
        """
        Create testing environment with 1VF generated from 1PF
        """
        if self.env_done:
            return

        # bind to default driver
        self.bind_nic_driver(self.dut_ports[:1], driver="")

        self.used_dut_port = self.dut_ports[0]
        self.host_intf = self.dut.ports_info[self.used_dut_port]['intf']
        tester_port = self.tester.get_local_port(self.used_dut_port)
        self.tester_intf = self.tester.get_interface(tester_port)

        self.dut.generate_sriov_vfs_by_port(self.used_dut_port,
                                            1,
                                            driver=driver)
        self.sriov_vfs_port = self.dut.ports_info[
            self.used_dut_port]['vfs_port']
        self.vf_mac = "00:10:00:00:00:00"
        self.dut.send_expect(
            "ip link set %s vf 0 mac %s" % (self.host_intf, self.vf_mac), "# ")

        try:

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

            time.sleep(1)
            vf_popt = {'opt_host': self.sriov_vfs_port[0].pci}

            # set up VM ENV
            self.vm = QEMUKvm(self.dut, 'vm0', 'vf_jumboframe')
            self.vm.set_vm_device(driver=self.vf_assign_method, **vf_popt)
            self.vm_dut = self.vm.start()
            if self.vm_dut is None:
                raise Exception("Set up VM ENV failed!")

            TESTPMD_MAIN = "app/test-pmd/testpmd.c"
            if self.kdriver == "ixgbe":
                self.vm_dut.send_expect(
                    "sed -i -e 's/.jumbo_frame    = .*$/.jumbo_frame = 1,/g' %s"
                    % TESTPMD_MAIN, "# ")
                self.vm_dut.build_install_dpdk(self.target)

            self.vm_testpmd = PmdOutput(self.vm_dut)

        except Exception as e:
            self.destroy_vm_env()
            raise Exception(e)

        self.env_done = True

    def destroy_vm_env(self):
        if getattr(self, 'vm', None):
            if getattr(self, 'vm_dut', None):
                self.vm_dut.kill_all()
            self.vm_testpmd = None
            self.vm_dut_ports = None
            # destroy vm0
            self.vm.stop()
            self.dut.virt_exit()
            time.sleep(3)
            self.vm = None

        if getattr(self, 'used_dut_port', None) != None:
            self.dut.destroy_sriov_vfs_by_port(self.used_dut_port)
            self.used_dut_port = None
        self.bind_nic_driver(self.dut_ports[:1], driver='default')

        self.env_done = False

    def jumboframes_get_stat(self, portid, rx_tx):
        """
        Get packets number from port statistic
        """
        stats = self.vm_testpmd.get_pmd_stats(portid)
        if rx_tx == "rx":
            return [stats['RX-packets'], stats['RX-errors'], stats['RX-bytes']]
        elif rx_tx == "tx":
            return [stats['TX-packets'], stats['TX-errors'], stats['TX-bytes']]
        else:
            return None

    def jumboframes_send_packet(self, pktsize, received=True):
        """
        Send 1 packet to portid
        """
        tx_pkts_ori, _, tx_bytes_ori = [
            int(_) for _ in self.jumboframes_get_stat(self.vm_port, "tx")
        ]
        rx_pkts_ori, rx_err_ori, rx_bytes_ori = [
            int(_) for _ in self.jumboframes_get_stat(self.vm_port, "rx")
        ]

        mac = self.vm_dut.get_mac_address(self.vm_port)

        pkt = Packet(pkt_type='UDP', pkt_len=pktsize)
        pkt.config_layer('ether', {'dst': mac})
        pkt.send_pkt(tx_port=self.tester_intf)

        time.sleep(1)

        tx_pkts, _, tx_bytes = [
            int(_) for _ in self.jumboframes_get_stat(self.port, "tx")
        ]
        rx_pkts, rx_err, rx_bytes = [
            int(_) for _ in self.jumboframes_get_stat(self.vm_port, "rx")
        ]

        tx_pkts -= tx_pkts_ori
        tx_bytes -= tx_bytes_ori
        rx_pkts -= rx_pkts_ori
        rx_bytes -= rx_bytes_ori
        rx_err -= rx_err_ori

        if received:
            self.verify((rx_pkts == 1) and (tx_pkts == 1),
                        "Packet forward assert error")

            if self.kdriver == "ixgbe":
                self.verify((rx_bytes + 4) == pktsize,
                            "Rx packet size should be packet size - 4")
            else:
                self.verify(rx_bytes == pktsize,
                            "Tx packet size should be equal to packet size")

            if self.kdriver == "igb":
                self.verify(tx_bytes == pktsize,
                            "Tx packet size should be packet size")
            else:
                self.verify((tx_bytes + 4) == pktsize,
                            "Tx packet size should be packet size - 4")
        else:
            self.verify(rx_err == 1 or tx_pkts == 0,
                        "Packet drop assert error")

    def test_vf_normal_nojumbo(self):
        """
        This case aims to test transmitting normal size packet without jumbo enable
        """
        # should enable jumbo on host
        self.dutobj = self.dut.ports_info[self.port]['port']
        self.dutobj.enable_jumbo(framesize=ETHER_STANDARD_MTU)

        self.vm_testpmd.start_testpmd(
            "Default", "--max-pkt-len=%d --port-topology=loop --txqflags=0x0" %
            (ETHER_STANDARD_MTU))

        self.vm_testpmd.execute_cmd("set fwd mac")
        self.vm_testpmd.execute_cmd("start")

        self.jumboframes_send_packet(ETHER_STANDARD_MTU - 1)
        self.jumboframes_send_packet(ETHER_STANDARD_MTU)

        self.vm_testpmd.execute_cmd("stop")
        self.vm_testpmd.quit()

    def test_vf_normal_withjumbo(self):
        """
        When jumbo frame supported, this case is to verify that the normal size
        packet forwrding should be support correct.
        """
        # should enable jumbo on host
        self.dutobj = self.dut.ports_info[self.port]['port']
        self.dutobj.enable_jumbo(framesize=ETHER_JUMBO_FRAME_MTU)

        self.vm_testpmd.start_testpmd(
            "Default", "--max-pkt-len=%d --port-topology=loop --txqflags=0x0" %
            (ETHER_JUMBO_FRAME_MTU))

        self.vm_testpmd.execute_cmd("set fwd mac")
        self.vm_testpmd.execute_cmd("start")

        self.jumboframes_send_packet(ETHER_STANDARD_MTU - 1)
        self.jumboframes_send_packet(ETHER_STANDARD_MTU)

        self.vm_testpmd.execute_cmd("stop")
        self.vm_testpmd.quit()

    def test_vf_jumbo_nojumbo(self):
        """
        This case aims to test transmitting jumbo frame packet on testpmd without
        jumbo frame support.
        """
        # should enable jumbo on host
        self.dutobj = self.dut.ports_info[self.port]['port']
        self.dutobj.enable_jumbo(framesize=ETHER_STANDARD_MTU)

        self.vm_testpmd.start_testpmd("Default",
                                      "--port-topology=loop --txqflags=0x0")

        self.vm_testpmd.execute_cmd("set fwd mac")
        self.vm_testpmd.execute_cmd("start")

        # On igb, for example i350, refer to :DPDK-1117
        # For PF, the max-pkt-len = mtu + 18 + 4(VLAN header len).
        # For VF, the real max-pkt-len = the given max-pkt-len + 4(VLAN header len).
        # This behavior is levelraged from kernel driver.
        # And it means max-pkt-len is always 4 bytes longer than assumed.

        if self.kdriver == "igb":
            self.jumboframes_send_packet(ETHER_STANDARD_MTU + 1 + 4, False)
        else:
            self.jumboframes_send_packet(ETHER_STANDARD_MTU + 1, False)

        self.vm_testpmd.execute_cmd("stop")
        self.vm_testpmd.quit()

    def test_vf_jumbo_withjumbo(self):
        """
        When jumbo frame supported, this case is to verify that jumbo frame
        packet can be forwarded correct.
        """
        # should enable jumbo on host
        self.dutobj = self.dut.ports_info[self.port]['port']
        self.dutobj.enable_jumbo(framesize=ETHER_JUMBO_FRAME_MTU)

        self.vm_testpmd.start_testpmd(
            "Default", "--max-pkt-len=%d --port-topology=loop --txqflags=0x0" %
            (ETHER_JUMBO_FRAME_MTU))

        self.vm_testpmd.execute_cmd("set fwd mac")
        self.vm_testpmd.execute_cmd("start")

        self.jumboframes_send_packet(ETHER_STANDARD_MTU + 1)
        self.jumboframes_send_packet(ETHER_JUMBO_FRAME_MTU - 1)
        self.jumboframes_send_packet(ETHER_JUMBO_FRAME_MTU)

        self.vm_testpmd.execute_cmd("stop")
        self.vm_testpmd.quit()

    def test_vf_jumbo_overjumbo(self):
        """
        When the jubmo frame MTU set as 9000, this case is to verify that the
        packet which the length bigger than MTU can not be forwarded.
        """
        # should enable jumbo on host
        self.dutobj = self.dut.ports_info[self.port]['port']
        self.dutobj.enable_jumbo(framesize=ETHER_JUMBO_FRAME_MTU)

        self.vm_testpmd.start_testpmd(
            "Default", "--max-pkt-len=%d --port-topology=loop --txqflags=0x0" %
            (ETHER_JUMBO_FRAME_MTU))

        self.vm_testpmd.execute_cmd("set fwd mac")
        self.vm_testpmd.execute_cmd("start")

        # On 1G NICs, when the jubmo frame MTU set as 9000, the software adjust it to 9004.
        if self.kdriver == "igb":
            self.jumboframes_send_packet(ETHER_JUMBO_FRAME_MTU + 4 + 1, False)
        else:
            self.jumboframes_send_packet(ETHER_JUMBO_FRAME_MTU + 1, False)

        self.vm_testpmd.execute_cmd("stop")
        self.vm_testpmd.quit()

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

    def tear_down_all(self):
        """
        When the case of this test suite finished, the enviroment should
        clear up.
        """
        self.destroy_vm_env()
        self.netobj.enable_jumbo(framesize=ETHER_STANDARD_MTU)
Ejemplo n.º 4
0
class TestVfPacketRxtx(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
        self.vm1 = 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,
                    "Unspported vf driver")
        if self.vf_driver == 'pci-stub':
            self.vf_assign_method = 'pci-assign'
        else:
            self.vf_assign_method = 'vfio-pci'
            self.tester.send_expect('modprobe vfio-pci', '#')

    def set_up(self):

        self.setup_2pf_2vf_1vm_env_flag = 0
        self.setup_3vf_2vm_env_flag = 0

    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
                }
                if (self.nic in ["niantic", "sageville", "sagepond"]):
                    self.host_testpmd.start_testpmd("1S/9C/1T",
                                                    "--txq=4 --rxq=4 ",
                                                    eal_param=eal_param)
                else:
                    self.host_testpmd.start_testpmd("1S/5C/1T",
                                                    "",
                                                    eal_param=eal_param)

            # set up VM0 ENV
            self.vm0 = QEMUKvm(self.dut, 'vm0', 'vf_packet_rxtx')
            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
            if getattr(self, 'vm0_testpmd', None):
                self.vm0_testpmd.execute_cmd('stop')
                self.vm0_testpmd.execute_cmd('quit', '# ')
                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

        self.dut.virt_exit()

        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 packet_rx_tx(self, driver='default'):

        if driver == 'igb_uio':
            self.setup_2pf_2vf_1vm_env(driver='igb_uio')
        else:
            self.setup_2pf_2vf_1vm_env(driver='')

        self.vm0_dut_ports = self.vm_dut_0.get_ports('any')
        port_id_0 = 0
        self.vm0_testpmd = PmdOutput(self.vm_dut_0)
        out = self.vm0_testpmd.start_testpmd(VM_CORES_MASK)
        pmd_vf0_mac = self.vm0_testpmd.get_port_mac(port_id_0)
        self.vm0_testpmd.execute_cmd('set fwd mac')
        self.vm0_testpmd.execute_cmd('start')

        time.sleep(2)

        tgen_ports = []
        tx_port = self.tester.get_local_port(self.dut_ports[0])
        rx_port = self.tester.get_local_port(self.dut_ports[1])
        tgen_ports.append((tx_port, rx_port))

        dst_mac = pmd_vf0_mac
        src_mac = self.tester.get_mac(tx_port)

        pkt_param = [("ether", {'dst': dst_mac, 'src': src_mac})]

        result = self.tester.check_random_pkts(tgen_ports,
                                               allow_miss=False,
                                               params=pkt_param)
        print self.vm0_testpmd.execute_cmd('show port stats all')
        self.verify(result != False, "VF0 failed to forward packets to VF1")

######1. test case for kernel pf and dpdk vf 2pf_2vf_1vm scenario packet rx tx.

    def test_kernel_2pf_2vf_1vm(self):

        self.packet_rx_tx(driver='')

######2. test case for dpdk pf and dpdk vf 2pf_2vf_1vm scenario packet rx tx.

    def test_dpdk_2pf_2vf_1vm(self):

        self.packet_rx_tx(driver='igb_uio')

    def setup_3vf_2vm_env(self, driver='default'):

        self.used_dut_port = self.dut_ports[0]
        self.dut.generate_sriov_vfs_by_port(self.used_dut_port,
                                            3,
                                            driver=driver)
        self.sriov_vfs_port = self.dut.ports_info[
            self.used_dut_port]['vfs_port']

        try:

            for port in self.sriov_vfs_port:
                print port.pci
                port.bind_driver(self.vf_driver)

            time.sleep(1)
            vf0_prop = {'opt_host': self.sriov_vfs_port[0].pci}
            vf1_prop = {'opt_host': self.sriov_vfs_port[1].pci}
            vf2_prop = {'opt_host': self.sriov_vfs_port[2].pci}

            for port_id in self.dut_ports:
                if port_id == self.used_dut_port:
                    continue
                port = self.dut.ports_info[port_id]['port']
                port.bind_driver()

            if driver == 'igb_uio':
                self.host_testpmd = PmdOutput(self.dut)
                eal_param = '-b %(vf0)s -b %(vf1)s -b %(vf2)s' % {
                    'vf0': self.sriov_vfs_port[0].pci,
                    'vf1': self.sriov_vfs_port[1].pci,
                    'vf2': self.sriov_vfs_port[2].pci
                }
                self.host_testpmd.start_testpmd("1S/2C/2T",
                                                eal_param=eal_param)

            # set up VM0 ENV
            self.vm0 = QEMUKvm(self.dut, 'vm0', 'vf_packet_rxtx')
            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!")
            # set up VM1 ENV
            self.vm1 = QEMUKvm(self.dut, 'vm1', 'vf_packet_rxtx')
            self.vm1.set_vm_device(driver=self.vf_assign_method, **vf2_prop)
            self.vm_dut_1 = self.vm1.start()
            if self.vm_dut_1 is None:
                raise Exception("Set up VM1 ENV failed!")

            self.setup_3vf_2vm_env_flag = 1
        except Exception as e:
            self.destroy_3vf_2vm_env()
            raise Exception(e)

    def destroy_3vf_2vm_env(self):
        if getattr(self, 'vm0', None):
            if getattr(self, 'vm0_testpmd', None):
                self.vm0_testpmd.execute_cmd('stop')
                self.vm0_testpmd.execute_cmd('quit', '# ')
            self.vm0_testpmd = None
            self.vm0_dut_ports = None
            self.vm_dut_0 = None
            self.vm0.stop()
            self.vm0 = None

        if getattr(self, 'vm1', None):
            if getattr(self, 'vm1_testpmd', None):
                self.vm1_testpmd.execute_cmd('stop')
                self.vm1_testpmd.execute_cmd('quit', '# ')
            self.vm1_testpmd = None
            self.vm1_dut_ports = None
            self.vm_dut_1 = None
            self.vm1.stop()
            self.vm1 = None

        self.dut.virt_exit()

        if getattr(self, 'host_testpmd', None) != None:
            self.host_testpmd.execute_cmd('quit', '# ')
            self.host_testpmd = None

        if getattr(self, 'used_dut_port', None) != None:
            self.dut.destroy_sriov_vfs_by_port(self.used_dut_port)
            port = self.dut.ports_info[self.used_dut_port]['port']
            port.bind_driver()
            self.used_dut_port = None

        for port_id in self.dut_ports:
            port = self.dut.ports_info[port_id]['port']
            port.bind_driver()

        self.setup_3vf_2vm_env_flag = 0

    def test_vf_reset(self):

        self.setup_3vf_2vm_env(driver='')

        self.vm0_dut_ports = self.vm_dut_0.get_ports('any')
        self.vm1_dut_ports = self.vm_dut_1.get_ports('any')

        port_id_0 = 0
        port_id_1 = 1

        self.vm0_testpmd = PmdOutput(self.vm_dut_0)
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK)
        self.vm0_testpmd.execute_cmd('show port info all')
        pmd0_vf0_mac = self.vm0_testpmd.get_port_mac(port_id_0)
        self.vm0_testpmd.execute_cmd('set fwd mac')
        self.vm0_testpmd.execute_cmd('start')

        time.sleep(2)

        self.vm1_testpmd = PmdOutput(self.vm_dut_1)
        self.vm1_testpmd.start_testpmd(VM_CORES_MASK)
        self.vm1_testpmd.execute_cmd('show port info all')

        tx_port = self.tester.get_local_port(self.dut_ports[0])
        rx_port = tx_port

        dst_mac = pmd0_vf0_mac
        self.tester.sendpkt_bg(tx_port, dst_mac)

        #vf port stop/start can trigger reset action
        for num in range(1000):
            self.vm1_testpmd.execute_cmd('port stop all')
            time.sleep(0.1)
            self.vm1_testpmd.execute_cmd('port start all')
            time.sleep(0.1)

        self.tester.stop_sendpkt_bg()

        pmd0_vf0_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
        pmd0_vf1_stats = self.vm0_testpmd.get_pmd_stats(port_id_1)

        vf0_rx_cnt = pmd0_vf0_stats['RX-packets']
        self.verify(vf0_rx_cnt != 0, "no packet was received by vm0_VF0")

        vf0_rx_err = pmd0_vf0_stats['RX-errors']
        self.verify(vf0_rx_err == 0, "vm0_VF0 rx-errors")

        vf1_tx_cnt = pmd0_vf1_stats['TX-packets']
        self.verify(vf1_tx_cnt != 0, "no packet was transmitted by vm0_VF1")

        vf1_tx_err = pmd0_vf1_stats['TX-errors']
        self.verify(vf1_tx_err == 0, "vm0_VF0 tx-errors")

        self.verify(
            vf0_rx_cnt == vf1_tx_cnt,
            "vm0_VF0 failed to forward packets to vm0_VF1 when reset vm1_VF0 frequently"
        )

    def tear_down(self):

        if self.setup_2pf_2vf_1vm_env_flag == 1:
            self.destroy_2pf_2vf_1vm_env()
        if self.setup_3vf_2vm_env_flag == 1:
            self.destroy_3vf_2vm_env()

        if getattr(self, 'vm0', None):
            self.vm0.stop()

        if getattr(self, 'vm1', None):
            self.vm1.stop()

        self.dut.virt_exit()

        for port_id in self.dut_ports:
            self.dut.destroy_sriov_vfs_by_port(port_id)
            # DPDK-1754
            intf = self.dut.ports_info[port_id]['intf']
            self.dut.send_expect("ethtool -s %s autoneg on" % intf, "# ")

    def tear_down_all(self):
        pass
Ejemplo n.º 5
0
class TestPmd(TestCase, IxiaPacketGenerator):
    def set_up_all(self):
        """
        Run at the start of each test suite.

        PMD prerequisites.
        """
        self.tester.extend_external_packet_generator(TestPmd, self)

        self.frame_sizes = [64, 72, 128, 256, 512, 1024, 1280, 1518]

        self.rxfreet_values = [0, 8, 16, 32, 64, 128]

        self.test_cycles = [{'cores': '1S/2C/1T', 'Mpps': {}, 'pct': {}}]

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

        self.perf_results = {'header': [], 'data': []}

        self.blacklist = ""

        # Update config file and rebuild to get best perf on FVL
        self.dut.send_expect(
            "sed -i -e 's/CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n/CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=y/' ./config/common_base",
            "#", 20)
        self.dut.build_install_dpdk(self.target)

        # Based on h/w type, choose how many ports to use
        self.dut_ports = self.dut.get_ports()
        if self.dut.get_os_type() == 'linux':
            # Get dut system information
            port_num = self.dut_ports[0]
            pci_device_id = self.dut.ports_info[port_num]['pci']
            ori_driver = self.dut.ports_info[port_num]['port'].get_nic_driver()
            self.dut.ports_info[port_num]['port'].bind_driver()

            sut = SystemInfo(self.dut, pci_device_id)
            self.system_info = sut.get_system_info()
            self.nic_info = sut.get_nic_info()

            self.dut.ports_info[port_num]['port'].bind_driver(ori_driver)
        ######

        self.headers_size = HEADER_SIZE['eth'] + HEADER_SIZE[
            'ip'] + HEADER_SIZE['tcp']

        self.ports_socket = self.dut.get_numa_id(self.dut_ports[0])

        self.pmdout = PmdOutput(self.dut)

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

    def test_perf_single_core_performance(self):
        """
        Run single core performance
        """
        self.perf_results['header'] = []
        self.perf_results['data'] = []

        if len(self.dut_ports) >= 4:
            self.pmd_performance_4ports()
        else:
            self.verify(
                len(self.dut_ports) >= 2,
                "Insufficient ports for 2 ports performance test")
            self.pmd_performance_2ports()

        #To replace False to True for if condition to send the result by email.
        if False:
            #it need place dpdk source git repo under dep directory.
            repo_dir = FOLDERS["Depends"] + r'/dpdk'
            git_info = perf_report.get_dpdk_git_info(repo_dir)
            self.verify(git_info is not None, "get dpdk git repo error")

            tpl_path = FOLDERS["NicDriver"] + r'/perf_report.jinja'
            file_tpl = os.path.abspath(tpl_path)
            html_msg = perf_report.generate_html_report(file_tpl, \
                                                        perf_data = self.perf_results['data'], \
                                                        git_info = git_info, \
                                                        nic_info = self.nic_info, \
                                                        system_info = self.system_info)
            self.verify(html_msg is not None, "generate html report error")

            subject = "Single core performance test with %d ports %s -- %s" % \
                      (len(self.dut_ports), self.nic, datetime.now().strftime('%Y-%m-%d %H:%M'))
            sender = '*****@*****.**'
            mailto = ['*****@*****.**']
            smtp_server = 'smtp.intel.com'
            perf_report.send_html_report(sender, mailto, subject, html_msg,
                                         smtp_server)

    def pmd_performance_4ports(self):
        """
        PMD Performance Benchmarking with 4 ports.
        """
        all_cores_mask = utils.create_mask(self.dut.get_core_list("all"))

        # prepare traffic generator input
        tgen_input = []

        tgen_input.append(
            (self.tester.get_local_port(self.dut_ports[0]),
             self.tester.get_local_port(self.dut_ports[1]), "test.pcap"))
        tgen_input.append(
            (self.tester.get_local_port(self.dut_ports[2]),
             self.tester.get_local_port(self.dut_ports[3]), "test.pcap"))
        tgen_input.append(
            (self.tester.get_local_port(self.dut_ports[1]),
             self.tester.get_local_port(self.dut_ports[0]), "test.pcap"))
        tgen_input.append(
            (self.tester.get_local_port(self.dut_ports[3]),
             self.tester.get_local_port(self.dut_ports[2]), "test.pcap"))

        # run testpmd for each core config
        for test_cycle in self.test_cycles:
            core_config = test_cycle['cores']

            core_list = self.dut.get_core_list(core_config,
                                               socket=self.ports_socket)

            if len(core_list) > 4:
                queues = len(core_list) / 4
            else:
                queues = 1

            core_mask = utils.create_mask(core_list)
            port_mask = utils.create_mask(self.dut.get_ports())

            self.pmdout.start_testpmd(
                core_config,
                " --rxq=%d --txq=%d --portmask=%s --rss-ip --txrst=32 --txfreet=32 --txd=128 --tx-offloads=0"
                % (queues, queues, port_mask),
                socket=self.ports_socket)
            command_line = self.pmdout.get_pmd_cmd()

            info = "Executing PMD using %s\n" % test_cycle['cores']
            self.rst_report(info, annex=True)
            self.logger.info(info)
            self.rst_report(command_line + "\n\n", frame=True, annex=True)

            # self.dut.send_expect("set fwd mac", "testpmd> ", 100)
            self.dut.send_expect("start", "testpmd> ", 100)
            for frame_size in self.frame_sizes:
                wirespeed = self.wirespeed(self.nic, frame_size, 4)

                # create pcap file
                self.logger.info("Running with frame size %d " % frame_size)
                payload_size = frame_size - self.headers_size
                self.tester.scapy_append(
                    'wrpcap("test.pcap", [Ether(src="52:00:00:00:00:00")/IP(src="1.2.3.4",dst="1.1.1.1")/TCP()/("X"*%d)])'
                    % payload_size)
                self.tester.scapy_execute()

                # run traffic generator
                _, pps = self.tester.traffic_generator_throughput(
                    tgen_input, rate_percent=100, delay=60)

                pps /= 1000000.0
                pct = pps * 100 / wirespeed
                test_cycle['Mpps'][frame_size] = float('%.3f' % pps)
                test_cycle['pct'][frame_size] = float('%.3f' % pct)

            self.dut.send_expect("stop", "testpmd> ")
            self.dut.send_expect("quit", "# ", 30)
            sleep(5)

        for n in range(len(self.test_cycles)):
            for frame_size in self.frame_sizes:
                self.verify(self.test_cycles[n]['Mpps'][frame_size] is not 0,
                            "No traffic detected")

        # Print results
        self.result_table_create(self.table_header)
        self.perf_results['header'] = self.table_header

        for frame_size in self.frame_sizes:
            table_row = [frame_size]
            for test_cycle in self.test_cycles:
                table_row.append(test_cycle['Mpps'][frame_size])
                table_row.append(test_cycle['pct'][frame_size])

            self.result_table_add(table_row)
            self.perf_results['data'].append(table_row)

        self.result_table_print()

    def pmd_performance_2ports(self):
        """
        PMD Performance Benchmarking with 2 ports.
        """

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

        # prepare traffic generator input
        tgen_input = []
        tgen_input.append(
            (self.tester.get_local_port(self.dut_ports[0]),
             self.tester.get_local_port(self.dut_ports[1]), "test.pcap"))
        tgen_input.append(
            (self.tester.get_local_port(self.dut_ports[1]),
             self.tester.get_local_port(self.dut_ports[0]), "test.pcap"))

        # run testpmd for each core config
        for test_cycle in self.test_cycles:
            core_config = test_cycle['cores']

            core_list = self.dut.get_core_list(core_config,
                                               socket=self.ports_socket)

            if len(core_list) > 2:
                queues = len(core_list) / 2
            else:
                queues = 1

            core_mask = utils.create_mask(core_list)
            port_mask = utils.create_mask(
                [self.dut_ports[0], self.dut_ports[1]])

            #self.pmdout.start_testpmd("all", "--coremask=%s --rxq=%d --txq=%d --portmask=%s" % (core_mask, queues, queues, port_mask))
            self.pmdout.start_testpmd(
                core_config,
                " --rxq=%d --txq=%d --portmask=%s --rss-ip --txrst=32 --txfreet=32 --txd=128"
                % (queues, queues, port_mask),
                socket=self.ports_socket)
            command_line = self.pmdout.get_pmd_cmd()

            info = "Executing PMD using %s\n" % test_cycle['cores']
            self.logger.info(info)
            self.rst_report(info, annex=True)
            self.rst_report(command_line + "\n\n", frame=True, annex=True)

            self.dut.send_expect("start", "testpmd> ", 100)

            for frame_size in self.frame_sizes:
                wirespeed = self.wirespeed(self.nic, frame_size, 2)

                # create pcap file
                self.logger.info("Running with frame size %d " % frame_size)
                payload_size = frame_size - self.headers_size
                self.tester.scapy_append(
                    'wrpcap("test.pcap", [Ether(src="52:00:00:00:00:00")/IP(src="1.2.3.4",dst="1.1.1.1")/TCP()/("X"*%d)])'
                    % payload_size)
                self.tester.scapy_execute()

                # run traffic generator
                _, pps = self.tester.traffic_generator_throughput(
                    tgen_input, rate_percent=100, delay=60)

                pps /= 1000000.0
                pct = pps * 100 / wirespeed
                test_cycle['Mpps'][frame_size] = float('%.3f' % pps)
                test_cycle['pct'][frame_size] = float('%.3f' % pct)

            self.dut.send_expect("stop", "testpmd> ")
            self.dut.send_expect("quit", "# ", 30)
            sleep(5)

        for n in range(len(self.test_cycles)):
            for frame_size in self.frame_sizes:
                self.verify(self.test_cycles[n]['Mpps'][frame_size] > 0,
                            "No traffic detected")

        # Print results
        self.result_table_create(self.table_header)
        self.perf_results['header'] = self.table_header
        for frame_size in self.frame_sizes:
            table_row = [frame_size]
            for test_cycle in self.test_cycles:
                table_row.append(test_cycle['Mpps'][frame_size])
                table_row.append(test_cycle['pct'][frame_size])

            self.result_table_add(table_row)
            self.perf_results['data'].append(table_row)

        self.result_table_print()

    def test_checksum_checking(self):
        """
        Packet forwarding checking test
        """

        self.dut.kill_all()

        port_mask = utils.create_mask([self.dut_ports[0], self.dut_ports[1]])

        for rxfreet_value in self.rxfreet_values:

            self.pmdout.start_testpmd(
                "1S/2C/1T",
                "--portmask=%s --enable-rx-cksum --disable-rss --rxd=1024 --txd=1024 --rxfreet=%d"
                % (port_mask, rxfreet_value),
                socket=self.ports_socket)
            self.dut.send_expect("set fwd csum", "testpmd> ")
            self.dut.send_expect("start", "testpmd> ")

            self.send_packet(self.frame_sizes[0], checksum_test=True)

            l4csum_error = self.stop_and_get_l4csum_errors()

            # Check the l4 checksum errors reported for Rx port
            self.verify(
                1 == int(l4csum_error[1]),
                "Wrong l4 checksum error count using rxfreet=%d (expected 1, reported %s)"
                % (rxfreet_value, l4csum_error[1]))

            self.dut.send_expect("quit", "# ", 30)
            sleep(5)

    def test_packet_checking(self):
        """
        Packet forwarding checking test
        """

        self.dut.kill_all()

        port_mask = utils.create_mask([self.dut_ports[0], self.dut_ports[1]])

        self.pmdout.start_testpmd("1S/2C/1T",
                                  "--portmask=%s" % port_mask,
                                  socket=self.ports_socket)
        self.dut.send_expect("start", "testpmd> ")
        for size in self.frame_sizes:
            self.send_packet(size)

        self.dut.send_expect("stop", "testpmd> ")
        self.dut.send_expect("quit", "# ", 30)
        sleep(5)

    def stop_and_get_l4csum_errors(self):
        """
        Stop forwarding and get Bad-l4csum number from stop statistic
        """

        out = self.dut.send_expect("stop", "testpmd> ")
        result_scanner = r"Bad-l4csum: ([0-9]+) \s*"
        scanner = re.compile(result_scanner, re.DOTALL)
        m = scanner.findall(out)

        return m

    def get_stats(self, portid):
        """
        Get packets number from port statistic
        """

        stats = self.pmdout.get_pmd_stats(portid)
        return stats

    def send_packet(self, frame_size, checksum_test=False):
        """
        Send 1 packet to portid
        """

        port0_stats = self.get_stats(self.dut_ports[0])
        gp0tx_pkts, gp0tx_bytes = [
            port0_stats['TX-packets'], port0_stats['TX-bytes']
        ]
        port1_stats = self.get_stats(self.dut_ports[1])
        gp1rx_pkts, gp1rx_err, gp1rx_bytes = [
            port1_stats['RX-packets'], port1_stats['RX-errors'],
            port1_stats['RX-bytes']
        ]

        interface = self.tester.get_interface(
            self.tester.get_local_port(self.dut_ports[1]))
        mac = self.dut.get_mac_address(self.dut_ports[1])

        load_size = frame_size - HEADER_SIZE['eth']
        padding = frame_size - HEADER_SIZE['eth'] - HEADER_SIZE['ip'] - \
            HEADER_SIZE['udp']

        checksum = ''
        if checksum_test:
            checksum = 'chksum=0x1'

        self.tester.scapy_foreground()
        self.tester.scapy_append('nutmac="%s"' % mac)
        self.tester.scapy_append(
            'sendp([Ether(dst=nutmac, src="52:00:00:00:00:00")/IP(len=%s)/UDP(%s)/Raw(load="\x50"*%s)], iface="%s")'
            % (load_size, checksum, padding, interface))

        out = self.tester.scapy_execute()
        time.sleep(.5)

        port0_stats = self.get_stats(self.dut_ports[0])
        p0tx_pkts, p0tx_bytes = [
            port0_stats['TX-packets'], port0_stats['TX-bytes']
        ]
        port1_stats = self.get_stats(self.dut_ports[1])
        p1rx_pkts, p1rx_err, p1rx_bytes = [
            port1_stats['RX-packets'], port1_stats['RX-errors'],
            port1_stats['RX-bytes']
        ]

        p0tx_pkts -= gp0tx_pkts
        p0tx_bytes -= gp0tx_bytes
        p1rx_pkts -= gp1rx_pkts
        p1rx_bytes -= gp1rx_bytes
        p1rx_err -= gp1rx_err

        time.sleep(5)

        self.verify(
            self.pmdout.check_tx_bytes(p0tx_pkts, p1rx_pkts),
            "packet pass assert error, %d RX packets, %d TX packets" %
            (p1rx_pkts, p0tx_pkts))

        self.verify(
            p1rx_bytes == frame_size - 4,
            "packet pass assert error, expected %d RX bytes, actual %d" %
            (frame_size - 4, p1rx_bytes))

        self.verify(
            self.pmdout.check_tx_bytes(p0tx_bytes, frame_size - 4),
            "packet pass assert error, expected %d TX bytes, actual %d" %
            (frame_size - 4, p0tx_bytes))

        return out

    def ip(self, port, frag, src, proto, tos, dst, chksum, len, options,
           version, flags, ihl, ttl, id):
        self.add_tcl_cmd("protocol config -name ip")
        self.add_tcl_cmd('ip config -sourceIpAddr "%s"' % src)
        self.add_tcl_cmd("ip config -sourceIpAddrMode ipRandom")
        self.add_tcl_cmd('ip config -destIpAddr "%s"' % dst)
        self.add_tcl_cmd("ip config -destIpAddrMode ipIdle")
        self.add_tcl_cmd("ip config -ttl %d" % ttl)
        self.add_tcl_cmd("ip config -totalLength %d" % len)
        self.add_tcl_cmd("ip config -fragment %d" % frag)
        self.add_tcl_cmd("ip config -ipProtocol ipV4ProtocolReserved255")
        self.add_tcl_cmd("ip config -identifier %d" % id)
        self.add_tcl_cmd("stream config -framesize %d" % (len + 18))
        self.add_tcl_cmd("ip set %d %d %d" %
                         (self.chasId, port['card'], port['port']))

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

    def tear_down_all(self):
        """
        Run after each test suite.
        """
        self.dut.kill_all()
Ejemplo n.º 6
0
class TestPmd(TestCase):
    def plot_results(self, number_ports):

        cores_configs = []
        percent_values = []

        # Append the percentage results for the all the cores configs
        for test_cycle in self.test_cycles:
            cores_configs.append(test_cycle['cores'])
            config_results = []
            for frame_size in self.frame_sizes:
                config_results.append(test_cycle['pct'][frame_size])

            percent_values.append(config_results)

        image_path = self.plotting.create_bars_plot(
            'test_perf_pmd_%sports' % number_ports,
            'PMD, %d ports' % number_ports,
            self.frame_sizes,
            percent_values,
            ylabel='% linerate',
            legend=cores_configs)

        dts.results_plot_print(image_path)

    def set_up_all(self):
        """
        Run at the start of each test suite.

        PMD prerequisites.
        """
        self.frame_sizes = [64, 65, 128, 256, 512, 1024, 1280, 1518]

        self.rxfreet_values = [0, 8, 16, 32, 64, 128]

        self.test_cycles = [{
            'cores': '1S/1C/1T',
            'Mpps': {},
            'pct': {}
        }, {
            'cores': '1S/1C/2T',
            'Mpps': {},
            'pct': {}
        }, {
            'cores': '1S/2C/1T',
            'Mpps': {},
            'pct': {}
        }, {
            'cores': '1S/2C/2T',
            'Mpps': {},
            'pct': {}
        }, {
            'cores': '1S/4C/2T',
            'Mpps': {},
            'pct': {}
        }]

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

        self.blacklist = ""

        # Based on h/w type, choose how many ports to use
        self.dut_ports = self.dut.get_ports()

        self.headers_size = HEADER_SIZE['eth'] + HEADER_SIZE[
            'ip'] + HEADER_SIZE['udp']

        self.ports_socket = self.dut.get_numa_id(self.dut_ports[0])

        self.plotting = Plotting(self.dut.crb['name'], self.target, self.nic)

        self.pmdout = PmdOutput(self.dut)

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

    def test_perf_pmd_performance_4ports(self):
        """
        PMD Performance Benchmarking with 4 ports.
        """
        all_cores_mask = dts.create_mask(self.dut.get_core_list("all"))

        # prepare traffic generator input
        self.verify(
            len(self.dut_ports) >= 4,
            "Insufficient ports for 4 ports performance")
        tgen_input = []

        tgen_input.append(
            (self.tester.get_local_port(self.dut_ports[0]),
             self.tester.get_local_port(self.dut_ports[1]), "test.pcap"))
        tgen_input.append(
            (self.tester.get_local_port(self.dut_ports[2]),
             self.tester.get_local_port(self.dut_ports[3]), "test.pcap"))
        tgen_input.append(
            (self.tester.get_local_port(self.dut_ports[1]),
             self.tester.get_local_port(self.dut_ports[0]), "test.pcap"))
        tgen_input.append(
            (self.tester.get_local_port(self.dut_ports[3]),
             self.tester.get_local_port(self.dut_ports[2]), "test.pcap"))

        # run testpmd for each core config
        for test_cycle in self.test_cycles:
            core_config = test_cycle['cores']

            core_list = self.dut.get_core_list(core_config,
                                               socket=self.ports_socket)

            if len(core_list) > 4:
                queues = len(core_list) / 4
            else:
                queues = 1

            core_mask = dts.create_mask(core_list)
            port_mask = dts.create_mask(self.dut.get_ports())

            self.pmdout.start_testpmd(
                "all", "--coremask=%s --rxq=%d --txq=%d --portmask=%s" %
                (core_mask, queues, queues, port_mask))

            info = "Executing PMD (mac fwd) using %s\n" % test_cycle['cores']
            dts.report(info, annex=True)
            self.logger.info(info)

            dts.report(commandLine + "\n\n", frame=True, annex=True)

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

            for frame_size in self.frame_sizes:
                wirespeed = self.wirespeed(self.nic, frame_size, 4)

                # create pcap file
                self.logger.info("Running with frame size %d " % frame_size)
                payload_size = frame_size - self.headers_size
                self.tester.scapy_append(
                    'wrpcap("test.pcap", [Ether(src="52:00:00:00:00:00")/IP()/UDP()/("X"*%d)])'
                    % payload_size)
                self.tester.scapy_execute()

                # run traffic generator
                _, pps = self.tester.traffic_generator_throughput(tgen_input)

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

            self.dut.send_expect("stop", "testpmd> ")
            self.dut.send_expect("quit", "# ", 30)
            sleep(5)

        for n in range(len(self.test_cycles)):
            for frame_size in self.frame_sizes:
                self.verify(self.test_cycles[n]['Mpps'][frame_size] is not 0,
                            "No traffic detected")

        # Print results
        dts.results_table_add_header(self.table_header)

        for frame_size in self.frame_sizes:
            table_row = [frame_size]

            for test_cycle in self.test_cycles:
                table_row.append(test_cycle['Mpps'][frame_size])
                table_row.append(test_cycle['pct'][frame_size])

            dts.results_table_add_row(table_row)

        self.plot_results(number_ports=4)
        dts.results_table_print()

    def test_perf_pmd_performance_2ports(self):
        """
        PMD Performance Benchmarking with 2 ports.
        """

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

        # prepare traffic generator input
        tgen_input = []
        tgen_input.append(
            (self.tester.get_local_port(self.dut_ports[0]),
             self.tester.get_local_port(self.dut_ports[1]), "test.pcap"))
        tgen_input.append(
            (self.tester.get_local_port(self.dut_ports[1]),
             self.tester.get_local_port(self.dut_ports[0]), "test.pcap"))

        # run testpmd for each core config
        for test_cycle in self.test_cycles:
            core_config = test_cycle['cores']

            core_list = self.dut.get_core_list(core_config,
                                               socket=self.ports_socket)

            if len(core_list) > 2:
                queues = len(core_list) / 2
            else:
                queues = 1

            core_mask = dts.create_mask(core_list)
            port_mask = dts.create_mask([self.dut_ports[0], self.dut_ports[1]])

            self.pmdout.start_testpmd(
                "all", "--coremask=%s --rxq=%d --txq=%d --portmask=%s" %
                (core_mask, queues, queues, port_mask))
            command_line = self.pmdout.get_pmd_cmd()

            info = "Executing PMD using %s\n" % test_cycle['cores']
            self.logger.info(info)
            dts.report(info, annex=True)
            dts.report(command_line + "\n\n", frame=True, annex=True)

            self.dut.send_expect("start", "testpmd> ")
            for frame_size in self.frame_sizes:
                wirespeed = self.wirespeed(self.nic, frame_size, 2)

                # create pcap file
                self.logger.info("Running with frame size %d " % frame_size)
                payload_size = frame_size - self.headers_size
                self.tester.scapy_append(
                    'wrpcap("test.pcap", [Ether(src="52:00:00:00:00:00")/IP()/UDP()/("X"*%d)])'
                    % payload_size)
                self.tester.scapy_execute()

                # run traffic generator
                _, pps = self.tester.traffic_generator_throughput(tgen_input)

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

            self.dut.send_expect("stop", "testpmd> ")
            self.dut.send_expect("quit", "# ", 30)
            sleep(5)

        for n in range(len(self.test_cycles)):
            for frame_size in self.frame_sizes:
                self.verify(self.test_cycles[n]['Mpps'][frame_size] > 0,
                            "No traffic detected")

        # Print results
        dts.results_table_add_header(self.table_header)
        for frame_size in self.frame_sizes:
            table_row = [frame_size]
            for test_cycle in self.test_cycles:
                table_row.append(test_cycle['Mpps'][frame_size])
                table_row.append(test_cycle['pct'][frame_size])

            dts.results_table_add_row(table_row)

        self.plot_results(number_ports=2)
        dts.results_table_print()

    def test_checksum_checking(self):
        """
        Packet forwarding checking test
        """

        self.dut.kill_all()

        all_cores_mask = dts.create_mask(self.dut.get_core_list("all"))
        core_mask = dts.create_mask(
            self.dut.get_core_list('1S/1C/1T', socket=self.ports_socket))
        port_mask = dts.create_mask([self.dut_ports[0], self.dut_ports[1]])

        for rxfreet_value in self.rxfreet_values:

            self.pmdout.start_testpmd(
                "all",
                "--coremask=%s --portmask=%s --nb-cores=2 --enable-rx-cksum --disable-hw-vlan --disable-rss --crc-strip --rxd=1024 --txd=1024 --rxfreet=%d"
                % (core_mask, port_mask, rxfreet_value))
            self.dut.send_expect("set fwd csum", "testpmd> ")
            self.dut.send_expect("start", "testpmd> ")

            self.send_packet(self.frame_sizes[0], checksum_test=True)

            l4csum_error = self.stop_and_get_l4csum_errors()

            # Check the l4 checksum errors reported for Rx port
            self.verify(
                1 == int(l4csum_error[1]),
                "Wrong l4 checksum error count using rxfreet=%d (expected 1, reported %s)"
                % (rxfreet_value, l4csum_error[1]))

            self.dut.send_expect("quit", "# ", 30)
            sleep(5)

    def test_packet_checking(self):
        """
        Packet forwarding checking test
        """

        self.dut.kill_all()

        all_cores_mask = dts.create_mask(self.dut.get_core_list("all"))
        core_mask = dts.create_mask(
            self.dut.get_core_list('1S/1C/1T', socket=self.ports_socket))
        port_mask = dts.create_mask([self.dut_ports[0], self.dut_ports[1]])

        self.pmdout.start_testpmd(
            "all", "--coremask=%s --portmask=%s" % (core_mask, port_mask))
        self.dut.send_expect("start", "testpmd> ")
        for size in self.frame_sizes:
            self.send_packet(size)

        self.dut.send_expect("stop", "testpmd> ")
        self.dut.send_expect("quit", "# ", 30)
        sleep(5)

    def stop_and_get_l4csum_errors(self):
        """
        Stop forwarding and get Bad-l4csum number from stop statistic
        """

        out = self.dut.send_expect("stop", "testpmd> ")
        result_scanner = r"Bad-l4csum: ([0-9]+) \s*"
        scanner = re.compile(result_scanner, re.DOTALL)
        m = scanner.findall(out)

        return m

    def get_stats(self, portid):
        """
        Get packets number from port statistic
        """

        stats = self.pmdout.get_pmd_stats(portid)
        return stats

    def send_packet(self, frame_size, checksum_test=False):
        """
        Send 1 packet to portid
        """

        port0_stats = self.get_stats(self.dut_ports[0])
        gp0tx_pkts, gp0tx_bytes = [
            port0_stats['TX-packets'], port0_stats['TX-bytes']
        ]
        port1_stats = self.get_stats(self.dut_ports[1])
        gp1rx_pkts, gp1rx_err, gp1rx_bytes = [
            port1_stats['RX-packets'], port1_stats['RX-errors'],
            port1_stats['RX-bytes']
        ]

        interface = self.tester.get_interface(
            self.tester.get_local_port(self.dut_ports[1]))
        mac = self.dut.get_mac_address(self.dut_ports[1])

        load_size = frame_size - HEADER_SIZE['eth']
        padding = frame_size - HEADER_SIZE['eth'] - HEADER_SIZE['ip'] - \
            HEADER_SIZE['udp']

        checksum = ''
        if checksum_test:
            checksum = 'chksum=0x0'

        self.tester.scapy_foreground()
        self.tester.scapy_append('nutmac="%s"' % mac)
        self.tester.scapy_append(
            'sendp([Ether(dst=nutmac, src="52:00:00:00:00:00")/IP(len=%s)/UDP(%s)/Raw(load="\x50"*%s)], iface="%s")'
            % (load_size, checksum, padding, interface))

        out = self.tester.scapy_execute()
        time.sleep(.5)

        port0_stats = self.get_stats(self.dut_ports[0])
        p0tx_pkts, p0tx_bytes = [
            port0_stats['TX-packets'], port0_stats['TX-bytes']
        ]
        port1_stats = self.get_stats(self.dut_ports[1])
        p1rx_pkts, p1rx_err, p1rx_bytes = [
            port1_stats['RX-packets'], port1_stats['RX-errors'],
            port1_stats['RX-bytes']
        ]

        p0tx_pkts -= gp0tx_pkts
        p0tx_bytes -= gp0tx_bytes
        p1rx_pkts -= gp1rx_pkts
        p1rx_bytes -= gp1rx_bytes
        p1rx_err -= gp1rx_err

        time.sleep(5)

        self.verify(
            p0tx_pkts == p1rx_pkts,
            "packet pass assert error, %d RX packets, %d TX packets" %
            (p1rx_pkts, p0tx_pkts))

        if checksum_test:
            self.verify(
                p1rx_bytes == frame_size - 4,
                "packet pass assert error, expected %d RX bytes, actual %d" %
                (frame_size - 4, p1rx_bytes))
        else:
            self.verify(
                p1rx_bytes == frame_size,
                "packet pass assert error, expected %d RX bytes, actual %d" %
                (frame_size, p1rx_bytes))

        self.verify(
            p0tx_bytes == frame_size,
            "packet pass assert error, expected %d TX bytes, actual %d" %
            (frame_size, p0tx_bytes))

        return out

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

    def tear_down_all(self):
        """
        Run after each test suite.
        """
        self.dut.kill_all()
Ejemplo n.º 7
0
class TestPmd(TestCase):

    def plot_results(self, number_ports):

        cores_configs = []
        percent_values = []

        # Append the percentage results for the all the cores configs
        for test_cycle in self.test_cycles:
            cores_configs.append(test_cycle['cores'])
            config_results = []
            for frame_size in self.frame_sizes:
                config_results.append(test_cycle['pct'][frame_size])

            percent_values.append(config_results)

        image_path = self.plotting.create_bars_plot(
            'test_perf_pmd_%sports' % number_ports,
            'PMD, %d ports' % number_ports,
            self.frame_sizes,
            percent_values,
            ylabel='% linerate',
            legend=cores_configs)

        dts.results_plot_print(image_path)

    def set_up_all(self):
        """
        Run at the start of each test suite.

        PMD prerequisites.
        """
        self.frame_sizes = [64, 65, 128, 256, 512, 1024, 1280, 1518]

        self.rxfreet_values = [0, 8, 16, 32, 64, 128]

        self.test_cycles = [{'cores': '1S/1C/1T', 'Mpps': {}, 'pct': {}},
                            {'cores': '1S/1C/2T', 'Mpps': {}, 'pct': {}},
                            {'cores': '1S/2C/1T', 'Mpps': {}, 'pct': {}},
                            {'cores': '1S/2C/2T', 'Mpps': {}, 'pct': {}},
                            {'cores': '1S/4C/2T', 'Mpps': {}, 'pct': {}}
                            ]

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

        self.blacklist = ""

        # Based on h/w type, choose how many ports to use
        self.dut_ports = self.dut.get_ports()

        self.headers_size = HEADER_SIZE['eth'] + HEADER_SIZE[
            'ip'] + HEADER_SIZE['udp']

        self.ports_socket = self.dut.get_numa_id(self.dut_ports[0])

        self.plotting = Plotting(self.dut.crb['name'], self.target, self.nic)

        self.pmdout = PmdOutput(self.dut)

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

    def test_perf_pmd_performance_4ports(self):
        """
        PMD Performance Benchmarking with 4 ports.
        """
        all_cores_mask = dts.create_mask(self.dut.get_core_list("all"))

        # prepare traffic generator input
        self.verify(len(self.dut_ports) >= 4,
                    "Insufficient ports for 4 ports performance")
        tgen_input = []

        tgen_input.append((self.tester.get_local_port(self.dut_ports[0]),
                           self.tester.get_local_port(self.dut_ports[1]),
                           "test.pcap"))
        tgen_input.append((self.tester.get_local_port(self.dut_ports[2]),
                           self.tester.get_local_port(self.dut_ports[3]),
                           "test.pcap"))
        tgen_input.append((self.tester.get_local_port(self.dut_ports[1]),
                           self.tester.get_local_port(self.dut_ports[0]),
                           "test.pcap"))
        tgen_input.append((self.tester.get_local_port(self.dut_ports[3]),
                           self.tester.get_local_port(self.dut_ports[2]),
                           "test.pcap"))

        # run testpmd for each core config
        for test_cycle in self.test_cycles:
            core_config = test_cycle['cores']

            core_list = self.dut.get_core_list(core_config,
                                               socket=self.ports_socket)

            if len(core_list) > 4:
                queues = len(core_list) / 4
            else:
                queues = 1

            core_mask = dts.create_mask(core_list)
            port_mask = dts.create_mask(self.dut.get_ports())

            self.pmdout.start_testpmd("all", "--coremask=%s --rxq=%d --txq=%d --portmask=%s" % (core_mask, queues, queues, port_mask))

            info = "Executing PMD (mac fwd) using %s\n" % test_cycle['cores']
            dts.report(info, annex=True)
            self.logger.info(info)

            dts.report(commandLine + "\n\n", frame=True, annex=True)

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

            for frame_size in self.frame_sizes:
                wirespeed = self.wirespeed(self.nic, frame_size, 4)

                # create pcap file
                self.logger.info("Running with frame size %d " % frame_size)
                payload_size = frame_size - self.headers_size
                self.tester.scapy_append(
                    'wrpcap("test.pcap", [Ether(src="52:00:00:00:00:00")/IP()/UDP()/("X"*%d)])' % payload_size)
                self.tester.scapy_execute()

                # run traffic generator
                _, pps = self.tester.traffic_generator_throughput(tgen_input)

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

            self.dut.send_expect("stop", "testpmd> ")
            self.dut.send_expect("quit", "# ", 30)
            sleep(5)

        for n in range(len(self.test_cycles)):
            for frame_size in self.frame_sizes:
                self.verify(self.test_cycles[n]['Mpps'][
                            frame_size] is not 0, "No traffic detected")

        # Print results
        dts.results_table_add_header(self.table_header)

        for frame_size in self.frame_sizes:
            table_row = [frame_size]

            for test_cycle in self.test_cycles:
                table_row.append(test_cycle['Mpps'][frame_size])
                table_row.append(test_cycle['pct'][frame_size])

            dts.results_table_add_row(table_row)

        self.plot_results(number_ports=4)
        dts.results_table_print()

    def test_perf_pmd_performance_2ports(self):
        """
        PMD Performance Benchmarking with 2 ports.
        """

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

        # prepare traffic generator input
        tgen_input = []
        tgen_input.append((self.tester.get_local_port(self.dut_ports[0]),
                           self.tester.get_local_port(self.dut_ports[1]),
                           "test.pcap"))
        tgen_input.append((self.tester.get_local_port(self.dut_ports[1]),
                           self.tester.get_local_port(self.dut_ports[0]),
                           "test.pcap"))

        # run testpmd for each core config
        for test_cycle in self.test_cycles:
            core_config = test_cycle['cores']

            core_list = self.dut.get_core_list(core_config,
                                               socket=self.ports_socket)

            if len(core_list) > 2:
                queues = len(core_list) / 2
            else:
                queues = 1

            core_mask = dts.create_mask(core_list)
            port_mask = dts.create_mask([self.dut_ports[0], self.dut_ports[1]])

            self.pmdout.start_testpmd("all", "--coremask=%s --rxq=%d --txq=%d --portmask=%s" % (core_mask, queues, queues, port_mask))
            command_line = self.pmdout.get_pmd_cmd()

            info = "Executing PMD using %s\n" % test_cycle['cores']
            self.logger.info(info)
            dts.report(info, annex=True)
            dts.report(command_line + "\n\n", frame=True, annex=True)

            self.dut.send_expect("start", "testpmd> ")
            for frame_size in self.frame_sizes:
                wirespeed = self.wirespeed(self.nic, frame_size, 2)

                # create pcap file
                self.logger.info("Running with frame size %d " % frame_size)
                payload_size = frame_size - self.headers_size
                self.tester.scapy_append(
                    'wrpcap("test.pcap", [Ether(src="52:00:00:00:00:00")/IP()/UDP()/("X"*%d)])' % payload_size)
                self.tester.scapy_execute()

                # run traffic generator
                _, pps = self.tester.traffic_generator_throughput(tgen_input)

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

            self.dut.send_expect("stop", "testpmd> ")
            self.dut.send_expect("quit", "# ", 30)
            sleep(5)

        for n in range(len(self.test_cycles)):
            for frame_size in self.frame_sizes:
                self.verify(self.test_cycles[n]['Mpps'][
                            frame_size] > 0, "No traffic detected")

        # Print results
        dts.results_table_add_header(self.table_header)
        for frame_size in self.frame_sizes:
            table_row = [frame_size]
            for test_cycle in self.test_cycles:
                table_row.append(test_cycle['Mpps'][frame_size])
                table_row.append(test_cycle['pct'][frame_size])

            dts.results_table_add_row(table_row)

        self.plot_results(number_ports=2)
        dts.results_table_print()

    def test_checksum_checking(self):
        """
        Packet forwarding checking test
        """

        self.dut.kill_all()

        all_cores_mask = dts.create_mask(self.dut.get_core_list("all"))
        core_mask = dts.create_mask(self.dut.get_core_list('1S/1C/1T',
                                                           socket=self.ports_socket))
        port_mask = dts.create_mask([self.dut_ports[0], self.dut_ports[1]])

        for rxfreet_value in self.rxfreet_values:

            self.pmdout.start_testpmd("all", "--coremask=%s --portmask=%s --nb-cores=2 --enable-rx-cksum --disable-hw-vlan --disable-rss --crc-strip --rxd=1024 --txd=1024 --rxfreet=%d" % (core_mask, port_mask, rxfreet_value))
            self.dut.send_expect("set fwd csum", "testpmd> ")
            self.dut.send_expect("start", "testpmd> ")

            self.send_packet(self.frame_sizes[0], checksum_test=True)

            l4csum_error = self.stop_and_get_l4csum_errors()

            # Check the l4 checksum errors reported for Rx port
            self.verify(1 == int(l4csum_error[1]),
                        "Wrong l4 checksum error count using rxfreet=%d (expected 1, reported %s)" %
                        (rxfreet_value, l4csum_error[1]))

            self.dut.send_expect("quit", "# ", 30)
            sleep(5)

    def test_packet_checking(self):
        """
        Packet forwarding checking test
        """

        self.dut.kill_all()

        all_cores_mask = dts.create_mask(self.dut.get_core_list("all"))
        core_mask = dts.create_mask(self.dut.get_core_list('1S/1C/1T',
                                                           socket=self.ports_socket))
        port_mask = dts.create_mask([self.dut_ports[0], self.dut_ports[1]])

        self.pmdout.start_testpmd("all", "--coremask=%s --portmask=%s" % (core_mask, port_mask))
        self.dut.send_expect("start", "testpmd> ")
        for size in self.frame_sizes:
            self.send_packet(size)

        self.dut.send_expect("stop", "testpmd> ")
        self.dut.send_expect("quit", "# ", 30)
        sleep(5)

    def stop_and_get_l4csum_errors(self):
        """
        Stop forwarding and get Bad-l4csum number from stop statistic
        """

        out = self.dut.send_expect("stop", "testpmd> ")
        result_scanner = r"Bad-l4csum: ([0-9]+) \s*"
        scanner = re.compile(result_scanner, re.DOTALL)
        m = scanner.findall(out)

        return m

    def get_stats(self, portid):
        """
        Get packets number from port statistic
        """

        stats = self.pmdout.get_pmd_stats(portid)
        return stats

    def send_packet(self, frame_size, checksum_test=False):
        """
        Send 1 packet to portid
        """

        port0_stats = self.get_stats(self.dut_ports[0])
        gp0tx_pkts, gp0tx_bytes = [port0_stats['TX-packets'], port0_stats['TX-bytes']]
        port1_stats = self.get_stats(self.dut_ports[1])
        gp1rx_pkts, gp1rx_err, gp1rx_bytes = [port1_stats['RX-packets'], port1_stats['RX-errors'], port1_stats['RX-bytes']]

        interface = self.tester.get_interface(
            self.tester.get_local_port(self.dut_ports[1]))
        mac = self.dut.get_mac_address(self.dut_ports[1])

        load_size = frame_size - HEADER_SIZE['eth']
        padding = frame_size - HEADER_SIZE['eth'] - HEADER_SIZE['ip'] - \
            HEADER_SIZE['udp']

        checksum = ''
        if checksum_test:
            checksum = 'chksum=0x0'

        self.tester.scapy_foreground()
        self.tester.scapy_append('nutmac="%s"' % mac)
        self.tester.scapy_append('sendp([Ether(dst=nutmac, src="52:00:00:00:00:00")/IP(len=%s)/UDP(%s)/Raw(load="\x50"*%s)], iface="%s")' % (
            load_size, checksum, padding, interface))

        out = self.tester.scapy_execute()
        time.sleep(.5)

        port0_stats = self.get_stats(self.dut_ports[0])
        p0tx_pkts, p0tx_bytes = [port0_stats['TX-packets'], port0_stats['TX-bytes']]
        port1_stats = self.get_stats(self.dut_ports[1])
        p1rx_pkts, p1rx_err, p1rx_bytes = [port1_stats['RX-packets'], port1_stats['RX-errors'], port1_stats['RX-bytes']]

        p0tx_pkts -= gp0tx_pkts
        p0tx_bytes -= gp0tx_bytes
        p1rx_pkts -= gp1rx_pkts
        p1rx_bytes -= gp1rx_bytes
        p1rx_err -= gp1rx_err

        time.sleep(5)

        self.verify(p0tx_pkts == p1rx_pkts,
                    "packet pass assert error, %d RX packets, %d TX packets" % (p1rx_pkts, p0tx_pkts))

        if checksum_test:
            self.verify(p1rx_bytes == frame_size - 4,
                        "packet pass assert error, expected %d RX bytes, actual %d" % (frame_size - 4, p1rx_bytes))
        else:
            self.verify(p1rx_bytes == frame_size,
                        "packet pass assert error, expected %d RX bytes, actual %d" % (frame_size, p1rx_bytes))

        self.verify(p0tx_bytes == frame_size,
                    "packet pass assert error, expected %d TX bytes, actual %d" % (frame_size, p0tx_bytes))

        return out

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

    def tear_down_all(self):
        """
        Run after each test suite.
        """
        self.dut.kill_all()
Ejemplo n.º 8
0
class PmdBonding(object):
    ''' common methods for testpmd bonding '''

    def __init__(self, **kwargs):
        # set parent instance
        self.parent = kwargs.get('parent')
        # set target source code directory
        self.target_source = self.parent.dut.base_dir
        # set logger
        self.logger = self.parent.logger
        self.verify = self.parent.verify
        # select packet generator
        self.pktgen_name = 'ixia' if self.is_perf else 'scapy'
        # traffic default config
        self.default_pkt_size = kwargs.get('pkt_size') or FRAME_SIZE_64
        self.default_src_mac = kwargs.get('src_mac')
        self.default_src_ip = kwargs.get('src_ip')
        self.default_src_port = kwargs.get('src_port')
        self.default_dst_ip = kwargs.get('dst_ip')
        self.default_dst_port = kwargs.get('dst_port')
        self.default_pkt_name = kwargs.get('pkt_name')
        # testpmd
        self.testpmd = PmdOutput(self.parent.dut)
        self.testpmd_status = 'close'
    #
    # On tester platform, packet transmission
    #
    def mac_str_to_int(self, mac_str):
        """ convert the MAC type from the string into the int. """
        mac_hex = '0x'
        for mac_part in mac_str.split(':'):
            mac_hex += mac_part
        return int(mac_hex, 16)

    def mac_int_to_str(self, mac_int):
        """ Translate the MAC type from the string into the int. """
        temp = hex(mac_int)[2:]
        b = []
        [b.append(temp[n:n+2]) for n in range(len(temp)) if n % 2 == 0]
        new_mac = ":".join(b)
        return new_mac

    def ip_str_to_int(self, ip_str):
        """
        convert the IP type from the string into the int.
        """
        ip_int = socket.ntohl(struct.unpack(
                                "I", socket.inet_aton(str(ip_str)))[0])
        return ip_int

    def ip_int_to_str(self, ip_int):
        """
        convert the IP type from the int into the string.
        """
        ip_str = socket.inet_ntoa(struct.pack('I', socket.htonl(ip_int)))
        return ip_str

    def increase_ip(self, ip, step=1):
        ''' ip: string format '''
        _ip_int = self.ip_str_to_int(ip)
        new_ip = self.ip_int_to_str(_ip_int + step)
        return new_ip

    def increase_mac(self, mac, step=1):
        ''' mac: string format '''
        _mac_int = self.mac_str_to_int(mac)
        new_mac = self.mac_int_to_str(_mac_int+step)
        return new_mac

    def increase_port(self, port, step=1):
        ''' port: int format '''
        new_port = port + step
        return new_port

    def increase_mac_ip_port(self, step=1):
        # get source port setting
        mac, ip, port = (self.default_src_mac,
                         self.default_src_ip,
                         self.default_src_port)
        return (self.increase_mac(mac, step),
                self.increase_ip(ip, step),
                self.increase_port(port, step))

    def get_pkt_len(self, pkt_type):
        ''' get packet payload size '''
        frame_size = self.default_pkt_size
        headers_size = sum(map(lambda x: HEADER_SIZE[x],
                               ['eth', 'ip', pkt_type]))
        pktlen = frame_size - headers_size
        return pktlen

    def set_stream_to_slave_port(self, dut_port_id):
        '''
        use framework/packet.py module to create one stream, send stream to
        slave port
        '''
        # get dst port mac address
        pkt_name = self.default_pkt_name
        destport = self.default_dst_port
        destip = self.default_dst_ip
        dst_mac = self.get_port_info(dut_port_id, 'mac')
        # packet size
        pktlen = self.get_pkt_len(pkt_name)
        # set stream configuration
        srcmac, srcip, srcport = self.increase_mac_ip_port(0)
        pkt_config = {
        'type': pkt_name.upper(),
        'pkt_layers': {
            # Ether(dst=nutmac, src=srcmac)
            'ether': {'src': srcmac, 'dst': dst_mac},
            # IP(dst=destip, src=srcip, len=%s)
            'ipv4': {'src': srcip, 'dst': destip},
            # pkt_name(sport=srcport, dport=destport)
            pkt_name: {'src': srcport, 'dst': destport},
            # Raw(load='\x50'*%s)
            'raw': {'payload': ['58'] * self.get_pkt_len(pkt_name)}}}
        # create packet
        streams = []
        # keep a copy of pcap for debug
        savePath = os.sep.join([self.target_source,
                                "pkt_{0}.pcap".format(pkt_name)])
        pkt_type = pkt_config.get('type')
        pkt_layers = pkt_config.get('pkt_layers')
        pkt = Packet(pkt_type=pkt_type.upper())
        for layer in pkt_layers.keys():
            pkt.config_layer(layer, pkt_layers[layer])
        pkt.pktgen.write_pcap(savePath)
        streams.append(pkt.pktgen.pkt)

        return streams

    def set_stream_to_bond_port(self, bond_port, slaves):
        '''
        : use framework/packet.py module to create multiple streams
          send streams from bond port to slaves
        :param bond_port:
            bonded device port id
        :param slaves: 
            slaves port id
        '''
        pkt_configs = []
        # get dst port mac address
        pkt_name = self.default_pkt_name
        destport = self.default_dst_port
        destip = self.default_dst_ip
        dst_mac = self.get_port_info(bond_port, 'mac')
        # packet size
        pktlen = self.get_pkt_len(pkt_type)
        # set stream configuration
        for packet_id in range(len(slaves['active'])):
            srcmac, srcip, srcport = self.increase_mac_ip_port(packet_id)
            pkt_configs.append({
            'type': pkt_name.upper(),
            'pkt_layers': {
                # Ether(dst=nutmac, src=srcmac)
                'ether': {'src': srcmac, 'dst': dst_mac},
                # IP(dst=destip, src=srcip, len=%s)
                'ipv4': {'src': srcip, 'dst': destip},
                # pkt_name(sport=srcport, dport=destport)
                pkt_name: {'src': srcport, 'dst': destport},
                # Raw(load='\x50'*%s)
                'raw': {'payload': ['58'] * self.get_pkt_len(pkt_name)}}})
        # create packet
        streams = []
        for values in pkt_configs:
            # keep a copy of pcap for debug
            savePath = os.sep.join([self.target_source,
                                    "pkt_{0}.pcap".format(stm_name)])
            pkt_type = values.get('type')
            pkt_layers = values.get('pkt_layers')
            pkt = Packet(pkt_type=pkt_type.upper())
            for layer in pkt_layers.keys():
                pkt.config_layer(layer, pkt_layers[layer])
            pkt.pktgen.write_pcap(savePath)
            streams.append(pkt.pktgen.pkt)

        return streams

    def send_packets_by_scapy(self, **kwargs):
        tx_iface = kwargs.get('port topo')[0]
        # set interface ready to send packet
        cmd = "ifconfig {0} up".format(tx_iface)
        self.parent.tester.send_expect(cmd, '# ', 30)
        send_pkts = kwargs.get('stream')
        # stream config
        stream_configs = kwargs.get('traffic configs')
        count = stream_configs.get('count')
        interval = stream_configs.get('interval', 0.01)
        # run traffic
        sendp(send_pkts, iface=tx_iface, inter=interval, verbose=False,
              count=count)

    def send_packets_by_ixia(self, **kwargs):
        tester_port = kwargs.get('tx_intf')
        count = kwargs.get('count', 1)
        traffic_type = kwargs.get('traffic_type', 'normal')
        traffic_time = kwargs.get('traffic_time', 0)
        rate_percent = kwargs.get('rate_percent', float(100)) 
        #---------------------------------------------------------------
        send_pkts = []
        self.tgen_input = []
        tgen_input = self.tgen_input
        # generate packet contain multi stream
        for pkt in self.packet_types.values():
            send_pkts.append(pkt.pktgen.pkt)
        ixia_pkt = os.sep.join([self.target_source, 'bonding_ixia.pcap'])
        wrpcap(ixia_pkt, send_pkts)
        #----------------------------------------------------------------
        # set packet for send
        # pause frame basic configuration
        pause_time = 65535
        pause_rate = 0.50
        # run ixia testing 
        frame_size = self.default_pkt_size
        # calculate number of packets
        expect_pps = self.parent.wirespeed(self.parent.nic, frame_size, 1) * \
                                                                    1000000.0
        # get line rate
        linerate = expect_pps * (frame_size + 20) * 8
        # calculate default sleep time for one pause frame
        sleep = (1 / linerate) * pause_time * 512
        # calculate packets dropped in sleep time
        self.n_pkts = int((sleep / (1 / expect_pps)) * (1 / pause_rate))
        #----------------------------------------------------------------
        tester_port = self.parent.tester.get_local_port(self.parent.dut_ports[0])
        tgen_input.append((tester_port, tester_port,ixia_pkt))
        # run latency stat statistics
        self.parent.tester.loop_traffic_generator_throughput(tgen_input,
                                                      self.rate_percent)

    def stop_ixia(self, data_types='packets'):
        tester_inst = self.parent.tester
        # get ixia statistics
        line_rate = tester_inst.get_port_line_rate()
        rx_bps, rx_pps = \
            tester_inst.stop_traffic_generator_throughput_loop(self.tgen_input)
        output = tester_inst.traffic_get_port_stats(self.tgen_input)
        self.cur_data['ixia statistics'] = []
        append = self.cur_data['ixia statistics'].append
        append('send packets: {0}'.format(output[0]))
        append('line_rate: {0}'.format(line_rate[0]))
        append('rate_percent: {0}%'.format(self.rate_percent))

    def get_pktgen(self, name):
        pkt_gens = {
            'ixia':     self.send_packets_by_ixia,
            'scapy':    self.send_packets_by_scapy,}
        pkt_generator = pkt_gens.get(name)
        
        return pkt_generator
    
    def send_packet(self, traffic_config):
        """
        stream transmission on specified link topology
        """
        time.sleep(2)
        # start traffic
        self.logger.info("begin transmission ...")
        pktgen = self.get_pktgen(self.pktgen_name)
        result = pktgen(**traffic_config)
        # end traffic
        self.logger.info("complete transmission")

        return result
    #
    # On dut, dpdk testpmd common methods
    #
    def check_process_status(self, process_name='testpmd'):
        cmd = "ps aux | grep -i %s | grep -v grep | awk {'print $2'}"%(
                                                                process_name)
        out = self.parent.dut.alt_session.send_expect(cmd, "# ", 10)
        status = True if out != "" else False
        return status

    def check_process_exist(self, process_name='testpmd'):
        status = self.check_process_status(process_name)
        if not status:
            msg = "{0} process exceptional quit".format(process_name)
            out = self.parent.dut.session.session.get_output_all()
            self.logger.info(out)
            raise VerifyFailure(msg)

    def d_console(self, cmds):
        ''' wrap up testpmd command interactive console '''
        if len(cmds) == 0:
            return
        # check if cmds is string
        if isinstance(cmds, str):
            timeout = 10
            cmds = [[cmds, '', timeout]]
        # check if cmds is only one command
        if not isinstance(cmds[0], list):
            cmds = [cmds]
        outputs = [] if len(cmds) > 1 else ''
        for item in cmds:
            expected_items = item[1]
            if expected_items and isinstance(expected_items, (list, tuple)):
                check_output = True
                expected_str = expected_items[0] or 'testpmd> '
            else:
                check_output = False
                expected_str = expected_items or 'testpmd> '
            timeout = int(item[2]) if len(item) == 3 else 5
            #----------------------------------------------------------------
            # run command on session
            try:
                console = self.testpmd.execute_cmd
                msg_pipe = self.testpmd.get_output
                output = console(item[0], expected_str, timeout)
                output = msg_pipe(timeout) if not output else output
            except TimeoutException:
                try:
                    # check if testpmd quit
                    self.check_process_exist()
                except Exception as e:
                    self.testpmd_status = 'close'
                msg = "execute '{0}' timeout".format(item[0])
                output = out = self.parent.dut.session.session.get_output_all()
                self.logger.error(output)
                raise Exception(msg)
            
            if len(cmds) > 1:
                outputs.append(output)
            else:
                outputs = output
            if check_output and len(expected_items) >= 2:
                self.logger.info(output)
                expected_output = expected_items[1]
                check_type = True if len(expected_items) == 2 \
                                  else expected_items[2]
                if check_type and expected_output in output:
                    msg = "expected '{0}' is in output".format(expected_output)
                    self.logger.info(msg)
                elif not check_type and expected_output not in output:
                    fmt = "unexpected '{0}' is not in output"
                    msg = fmt.format(expected_output)
                    self.logger.info(msg)
                else:
                    status = "isn't in" if check_type else "is in"
                    msg = "[{0}] {1} output".format(expected_output, status)
                    self.logger.error(msg)
                    raise VerifyFailure(msg)

        time.sleep(2)
        return outputs

    def preset_testpmd(self, core_mask, options='', eal_param=''):
        try:
            self.testpmd.start_testpmd( core_mask,
                                        param=' '.join(options),
                                        eal_param=eal_param)
        except TimeoutException:
            # check if testpmd quit
            try:
                self.check_process_exist()
            except Exception as e:
                self.testpmd_status = 'close'
            msg = "execute '{0}' timeout".format(item[0])
            self.logger.error(msg_pipe(timeout))
            raise TimeoutException(msg)
        # wait lsc event udpate done
        time.sleep(10)
        # check if testpmd has bootep up
        if self.check_process_status():
            self.logger.info("testpmd boot up successful")
        else:
            raise VerifyFailure("testpmd boot up failed")
        self.d_console(self.preset_testpmd_cmds)
        self.preset_testpmd_cmds = []
        time.sleep(1)

    def start_testpmd(self, eal_option=''):
        if self.testpmd_status == 'running':
            return
        # boot up testpmd
        hw_mask = 'all'
        options = ''
        self.preset_testpmd_cmds = ['port stop all', '', 15]
        self.preset_testpmd(hw_mask, options, eal_param=eal_option)
        self.testpmd_status = 'running'

    def stop_testpmd(self):
        time.sleep(1)
        testpmd_cmds =[['port stop all', '', 15],
                       ['show port stats all', ''],
                       ['stop', ''],]
        output = self.d_console(testpmd_cmds)
        time.sleep(1)
        return output

    def close_testpmd(self):
        if self.testpmd_status == 'close':
            return None
        output = self.stop_testpmd()
        time.sleep(1)
        self.testpmd.quit()
        time.sleep(10)
        if self.check_process_status():
            raise VerifyFailure("testpmd close failed")
        else:
            self.logger.info("close testpmd successful")
        self.testpmd_status = 'close'
        return output

    def start_ports(self, port='all'):
        """
        Start a port which the testpmd can see.
        """
        timeout = 12 if port=='all' else 5
        cmds =[
           ["port start %s" % str(port), " ", timeout],
           # to avoid lsc event message interfere normal status
           [" ", '', timeout]]
        self.d_console(cmds)

    def get_stats(self, portid, flow=['rx', 'tx']):
        """
        get one port statistics of testpmd
        """
        _portid = int(portid) if isinstance(portid, (str, unicode)) else portid
        info = self.testpmd.get_pmd_stats(_portid)
        _kwd = ["-packets", "-errors", "-bytes"]
        stats = {}
        if isinstance(flow, list):
            for item in flow:
                for item2 in _kwd:
                    name = item.upper() + item2
                    stats[name] = int(info[name])
        elif isinstance(flow, (str, unicode)):
            for item in _kwd:
                name = flow.upper() + item
                stats[name] = int(info[name])
        else:
            msg = 'unknown data type'
            raise Exception(msg)

        return stats

    def get_all_stats(self, ports):
        """
        Get a group of ports statistics, which testpmd can display.
        """
        stats = {}
        attrs = ['tx', 'rx']
        for port_id in ports:
            stats[port_id] = self.get_stats(port_id, attrs)

        return stats

    def set_tester_port_status(self, port_name, status):
        """
        Do some operations to the network interface port,
        such as "up" or "down".
        """
        eth = self.parent.tester.get_interface(port_name)
        self.parent.tester.admin_ports_linux(eth, status)
        time.sleep(5)

    def set_dut_peer_port_by_id(self, port_id, status):
        # stop peer port on tester
        intf = self.parent.tester.get_local_port(self.parent.dut_ports[port_id])
        self.set_tester_port_status(intf, status)
        time.sleep(5)
        cur_status = self.get_port_info(port_id, 'link_status')
        self.logger.info("port {0} is [{1}]".format(port_id, cur_status))
        if cur_status != status:
            self.logger.warning("expected status is [{0}]".format(status))

    def set_dut_port_status(self, port_id, status):
        opt = 'link-up' if status == 'up' else 'link-down'
        # stop slave link by force 
        cmd = "set {0} port {1}".format(opt, port_id)
        self.d_console(cmd)
        time.sleep(5)
        cur_status = self.get_port_info(port_id, 'link_status')
        self.logger.info("port {0} is [{1}]".format(port_id, cur_status))
        if cur_status != status:
            self.logger.warning("expected status is [{0}]".format(status))
    # 
    # testpmd bonding commands
    #
    def get_value_from_str(self, key_str, regx_str, string):
        """
        Get some values from the given string by the regular expression.
        """
        if isinstance(key_str, (unicode, str)):
            pattern = r"(?<=%s)%s" % (key_str, regx_str)
            s = re.compile(pattern)
            res = s.search(string)
            if type(res).__name__ == 'NoneType':
                msg = "{0} hasn't match anything".format(key_str)
                self.logger.warning(msg)
                return ' '
            else:
                return res.group(0)
        elif isinstance(key_str, (list, tuple)):
            for key in key_str:
                pattern = r"(?<=%s)%s" % (key, regx_str)
                s = re.compile(pattern)
                res = s.search(string)
                if type(res).__name__ == 'NoneType':
                    continue
                else:
                    return res.group(0)
            else:
                self.logger.warning("all key_str hasn't match anything")
                return ' '

    def _get_detail_from_port_info(self, port_id, args):
        """
        Get the detail info from the output of pmd cmd 
            'show port info <port num>'.
        """
        key_str, regx_str = args
        out = self.d_console("show port info %d" % port_id)
        find_value = self.get_value_from_str(key_str, regx_str, out)
        return find_value

    def get_detail_from_port_info(self, port_id, args):
        if isinstance(args[0], (list, tuple)):
            return [self._get_detail_from_port_info(port_id, sub_args)
                        for sub_args in args]
        else:
            return self._get_detail_from_port_info(port_id, args)

    def get_port_info(self, port_id, info_type):
        '''
        Get the specified port information by its output message format
        '''
        info_set = {
        'mac':              ["MAC address: ", "([0-9A-F]{2}:){5}[0-9A-F]{2}"],
        'connect_socket':   ["Connect to socket: ", "\d+"],
        'memory_socket':    ["memory allocation on the socket: ", "\d+"],
        'link_status':      ["Link status: ", "\S+"],
        'link_speed':       ["Link speed: ", "\d+"],
        'link_duplex':      ["Link duplex: ", "\S+"],
        'promiscuous_mode': ["Promiscuous mode: ", "\S+"],
        'allmulticast_mode':["Allmulticast mode: ", "\S+"],
        'vlan_offload':     [
                        ["strip ", "\S+"],
                        ['filter', "\S+"],
                        ['qinq\(extend\) ', "\S+"]],
        'queue_config':     [
                        ["Max possible RX queues: ", "\d+"],
                        ['Max possible number of RXDs per queue: ', "\d+"],
                        ['Min possible number of RXDs per queue: ', "\d+"],
                        ["Max possible TX queues: ", "\d+"],
                        ['Max possible number of TXDs per queue: ', "\d+"],
                        ['Min possible number of TXDs per queue: ', "\d+"],]
        }

        if info_type in info_set.keys():
            return self.get_detail_from_port_info(port_id, info_set[info_type])
        else:
            msg = os.linesep.join([
                "support query items including::",
                os.linesep.join(info_set.keys())])
            self.logger.warning(msg)
            return None
    # 
    # On dut, dpdk testpmd common bonding methods
    #
    def get_bonding_config(self, config_content, args):
        """
        Get bonding info by command "show bonding config".
        """
        key_str, regx_str = args
        find_value = self.get_value_from_str(key_str, regx_str, config_content)
        return find_value

    def get_info_from_bond_config(self, config_content, args):
        """
        Get active slaves of the bonding device which you choose.
        """
        search_args = args if isinstance(args[0], (list, tuple)) else [args]
        for search_args in search_args:
            try:
                info = self.get_bonding_config(config_content, search_args)
                break
            except Exception as e:
                self.logger.info(e)
        else:
            info = None

        return info

    def get_bonding_info(self, bond_port, info_types):
        ''' Get the specified port information by its output message format '''
        info_set = {
            'mode':          ["Bonding mode: ", "\d*"],
            'agg_mode':      ["IEEE802.3AD Aggregator Mode: ", "\S*"],
            'balance_policy':["Balance Xmit Policy: ", "\S+"],
            'slaves':        [["Slaves \(\d\): \[", "\d*( \d*)*"],
                              ["Slaves: \[", "\d*( \d*)*"]],
            'active_slaves': [["Active Slaves \(\d\): \[", "\d*( \d*)*"],
                              ["Acitve Slaves: \[", "\d*( \d*)*"]],
            'primary':       ["Primary: \[", "\d*"]}
        # get all config information
        config_content = self.d_console("show bonding config %d" % bond_port)
        if isinstance(info_types, (list or tuple)):
            query_values = []
            for info_type in info_types:
                if info_type in info_set.keys():
                    find_value = self.get_info_from_bond_config(
                                            config_content, info_set[info_type])
                    if info_type in ['active_slaves', 'slaves']:
                        find_value = [value for value in find_value.split(' ')
                                        if value]
                else:
                    find_value = None
                query_values.append(find_value)
            return query_values
        else:
            info_type = info_types
            if info_type in info_set.keys():
                find_value = self.get_info_from_bond_config(
                                            config_content, info_set[info_type])
                if info_type in ['active_slaves', 'slaves']:
                    find_value = [value for value in find_value.split(' ') 
                                        if value]
                return find_value
            else:
                return None

    def get_active_slaves(self, bond_port):
        primary_port = int(self.get_bonding_info(bond_port, 'primary'))
        active_slaves = self.get_bonding_info(bond_port, 'active_slaves')

        return int(primary_port), [int(slave) for slave in active_slaves]

    def create_bonded_device(self, mode=0, socket=0, verify_detail=False):
        """
        Create a bonding device with the parameters you specified.
        """
        cmd = "create bonded device %d %d" % (mode, socket)
        out = self.d_console(cmd)
        err_fmt = "Create bonded device on mode [%d] socket [%d] failed"
        self.verify("Created new bonded device" in out, err_fmt% (mode, socket))
        fmts = [
             "Created new bonded device net_bond_testpmd_[\d] on \(port ",
             "Created new bonded device net_bonding_testpmd_[\d] on \(port ",
             "Created new bonded device eth_bond_testpmd_[\d] on \(port "]
        bond_port = self.get_value_from_str(fmts, "\d+", out)
        bond_port = int(bond_port)

        if verify_detail:
            out = self.d_console("show bonding config %d" % bond_port)
            self.verify("Bonding mode: %d" % mode in out,
                        "Bonding mode display error when create bonded device")
            self.verify("Slaves: []" in out,
                        "Slaves display error when create bonded device")
            self.verify("Active Slaves: []" in out,
                        "Active Slaves display error when create bonded device")
            self.verify("Primary: []" not in out,
                        "Primary display error when create bonded device")
            out = self.d_console("show port info %d" % bond_port)
            self.verify("Connect to socket: %d" % socket in out,
                        "Bonding port connect socket error")
            self.verify("Link status: down" in out,
                        "Bonding port default link status error")
            self.verify("Link speed: 0 Mbps" in out,
                        "Bonding port default link speed error")

        return bond_port

    def add_slave(self, bond_port, invert_verify=False, expected_str='',
                  *slave_ports):
        """
        Add ports into the bonding device as slaves.
        """
        if len(slave_ports) <= 0:
            utils.RED("No port exist when add slave to bonded device")
        for slave_id in slave_ports:
            cmd = "add bonding slave %d %d" % (slave_id, bond_port)
            out = self.d_console(cmd)
            if expected_str:
                self.verify(expected_str in out,
                            "message <{0}> is missing".format(expected_str))
            slaves = self.get_bonding_info(bond_port, 'slaves')
            if not invert_verify:
                self.verify(str(slave_id) in slaves,
                            "Add port as bonding slave failed")
            else:
                err = "Add port as bonding slave successfully,should fail"
                self.verify(str(slave_id) not in slaves, err)

    def remove_slaves(self, bond_port, invert_verify=False, *slave_port):
        """
        Remove the specified slave port from the bonding device.
        """
        if len(slave_port) <= 0:
            msg = "No port exist when remove slave from bonded device"
            self.logger.error(msg)
        for slave_id in slave_port:
            cmd = "remove bonding slave %d %d" % (int(slave_id), bond_port)
            self.d_console(cmd)
            slaves = self.get_bonding_info(bond_port, 'slaves')
            if not invert_verify:
                self.verify(str(slave_id) not in slaves,
                            "Remove slave to fail from bonding device")
            else:
                err = (
                    "Remove slave successfully from bonding device, "
                    "should be failed")
                self.verify(str(slave_id) in slaves, err)

    def remove_all_slaves(self, bond_port):
        """
        Remove all slaves of specified bound device.
        """
        all_slaves = self.get_bonding_info(bond_port, 'slaves')
        if not all_slaves:
            return
        all_slaves = all_slaves.split()
        if len(all_slaves) == 0:
            return
        self.remove_slaves(bond_port, False, *all_slaves)

    def set_primary_slave(self, bond_port, slave_port, invert_verify=False):
        """
        Set the primary slave for the bonding device.
        """
        cmd = "set bonding primary %d %d" % (slave_port, bond_port)
        self.d_console(cmd)
        out = self.get_bonding_info(bond_port, 'primary')
        if not invert_verify:
            self.verify(str(slave_port) in out,
                        "Set bonding primary port failed")
        else:
            err = "Set bonding primary port successfully, should not success"
            self.verify(str(slave_port) not in out, err)

    def set_bonding_mode(self, bond_port, mode):
        """
        Set the bonding mode for port_id.
        """
        cmd = "set bonding mode %d %d" % (mode, bond_port)
        self.d_console(cmd)
        mode_value = self.get_bonding_info(bond_port, 'mode')
        self.verify(str(mode) in mode_value, "Set bonding mode failed")

    def set_bonding_mac(self, bond_port, mac):
        """
        Set the MAC for the bonding device.
        """
        cmd = "set bonding mac_addr %s %s" % (bond_port, mac)
        self.d_console(cmd)
        new_mac = self.get_port_mac(bond_port)
        self.verify(new_mac == mac, "Set bonding mac failed")

    def get_port_mac(self, bond_port, query_type):
        bond_port_mac = self.get_port_info(bond_port, query_type)
        return bond_port_mac

    def set_bonding_balance_policy(self, bond_port, policy):
        """
        Set the balance transmit policy for the bonding device.
        """
        cmd = "set bonding balance_xmit_policy %d %s" % (bond_port, policy)
        self.d_console(cmd)
        new_policy = self.get_bonding_info(bond_port, 'balance_policy')
        policy = "BALANCE_XMIT_POLICY_LAYER" + policy.lstrip('l')
        self.verify(new_policy == policy, "Set bonding balance policy failed")

    @property
    def is_perf(self):
        return self.parent._enable_perf