Exemplo n.º 1
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)
Exemplo n.º 2
0
class TestVfRss(TestCase):

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

    def send_packet(self, itf, tran_type):
        """
        Sends packets.
        """
        global reta_lines
        reta_lines = []
        self.tester.scapy_foreground()
        self.tester.scapy_append('sys.path.append("./")')
        self.tester.scapy_append('from sctp import *')
        self.vm_dut_0.send_expect("start", "testpmd>")
        mac = self.vm0_testpmd.get_port_mac(0)
        # send packet with different source and dest ip
        if tran_type == "ipv4-other":
            for i in range(16):
                packet = r'sendp([Ether(dst="%s", src="02:00:00:00:00:00")/IP(src="192.168.0.%d", dst="192.168.0.%d")], iface="%s")' % (
                    mac, i + 1, i + 2, itf)
                self.tester.scapy_append(packet)
                self.tester.scapy_execute()
                time.sleep(.5)
        elif tran_type == "ipv4-tcp":
            for i in range(16):
                packet = r'sendp([Ether(dst="%s", src="02:00:00:00:00:00")/IP(src="192.168.0.%d", dst="192.168.0.%d")/TCP(sport=1024,dport=1024)], iface="%s")' % (
                    mac, i + 1, i + 2, itf)
                self.tester.scapy_append(packet)
                self.tester.scapy_execute()
                time.sleep(.5)
        elif tran_type == "ipv4-udp":
            for i in range(16):
                packet = r'sendp([Ether(dst="%s", src="02:00:00:00:00:00")/IP(src="192.168.0.%d", dst="192.168.0.%d")/UDP(sport=1024,dport=1024)], iface="%s")' % (
                    mac, i + 1, i + 2, itf)
                self.tester.scapy_append(packet)
                self.tester.scapy_execute()
                time.sleep(.5)
        elif tran_type == "ipv4-sctp":
            for i in range(16):
                packet = r'sendp([Ether(dst="%s")/IP(src="192.168.0.%d", dst="192.168.0.%d")/SCTP(sport=1024,dport=1025,tag=1)], iface="%s")' % (
                    mac, i + 1, i + 2, itf)
                self.tester.scapy_append(packet)
                self.tester.scapy_execute()
                time.sleep(.5)
                packet = r'sendp([Ether(dst="%s")/IP(src="192.168.0.%d", dst="192.168.0.%d")/SCTP(sport=1025,dport=1024,tag=1)], iface="%s")' % (
                    mac, i + 2, i + 1, itf)
                self.tester.scapy_append(packet)
                self.tester.scapy_execute()
                time.sleep(.5)
        elif tran_type == "l2_payload":
            for i in range(16):
                packet = r'sendp([Ether(src="00:00:00:00:00:%02d",dst="%s")], iface="%s")' % (
                    i + 1, mac, itf)
                self.tester.scapy_append(packet)
                self.tester.scapy_execute()
                time.sleep(.5)

        elif tran_type == "ipv6-other":
            for i in range(16):
                packet = r'sendp([Ether(dst="%s", src="02:00:00:00:00:00")/IPv6(src="3ffe:2501:200:1fff::%d", dst="3ffe:2501:200:3::%d")], iface="%s")' % (
                    mac, i + 1, i + 2, itf)
                self.tester.scapy_append(packet)
                self.tester.scapy_execute()
                time.sleep(.5)
        elif tran_type == "ipv6-tcp":
            for i in range(16):
                packet = r'sendp([Ether(dst="%s", src="02:00:00:00:00:00")/IPv6(src="3ffe:2501:200:1fff::%d", dst="3ffe:2501:200:3::%d")/TCP(sport=1024,dport=1024)], iface="%s")' % (
                    mac, i + 1, i + 2, itf)
                self.tester.scapy_append(packet)
                self.tester.scapy_execute()
                time.sleep(.5)
        elif tran_type == "ipv6-udp":
            for i in range(16):
                packet = r'sendp([Ether(dst="%s", src="02:00:00:00:00:00")/IPv6(src="3ffe:2501:200:1fff::%d", dst="3ffe:2501:200:3::%d")/UDP(sport=1024,dport=1024)], iface="%s")' % (
                    mac, i + 1, i + 2, itf)
                self.tester.scapy_append(packet)
                self.tester.scapy_execute()
                time.sleep(.5)
        elif tran_type == "ipv6-sctp":
            for i in range(16):
                packet = r'sendp([Ether(dst="%s")/IPv6(src="3ffe:2501:200:1fff::%d", dst="3ffe:2501:200:3::%d", nh=132)/SCTP(sport=1024,dport=1025,tag=1)], iface="%s")' % (
                    mac, i + 1, i + 2, itf)
                self.tester.scapy_append(packet)
                self.tester.scapy_execute()
                time.sleep(.5)
                packet = r'sendp([Ether(dst="%s")/IPv6(src="3ffe:2501:200:1fff::%d", dst="3ffe:2501:200:3::%d", nh=132)/SCTP(sport=1025,dport=1024,tag=1)], iface="%s")' % (
                    mac, i + 2, i + 1, itf)
                self.tester.scapy_append(packet)
                self.tester.scapy_execute()
                time.sleep(.5)

        else:
            print "\ntran_type error!\n"

        #out = self.vm_dut_0.send_expect("stop", "testpmd>")
        out = self.vm_dut_0.get_session_output()
        print '*******************************************'
        print out
        if not reta_entries:
            self.verify('RSS hash=' in out, 'rss faied')
            return
        lines = out.split("\r\n")
        out = ''
        reta_line = {}

        # collect the hash result of five tuple and the queue id
        for line in lines:
            line = line.strip()
            if len(line) != 0 and line.startswith(("src=", )):
                for item in line.split("-"):
                    item = item.strip()
                    if (item.startswith("RSS hash")):
                        name, value = item.split("=", 1)
                        print name + "-" + value

                reta_line[name.strip()] = value.strip()
                reta_lines.append(reta_line)
                reta_line = {}
            elif len(line) != 0 and line.strip().startswith("port "):
                rexp = r"port (\d)/queue (\d{1,2}): received (\d) packets"
                m = re.match(rexp, line.strip())
                if m:
                    reta_line["port"] = m.group(1)
                    reta_line["queue"] = m.group(2)
            elif len(line) != 0 and line.startswith("stop"):
                break
            else:
                pass
        self.verifyResult()

    def verifyResult(self):
        """
        Verify whether or not the result passes.
        """

        global reta_lines
        result = []
        self.result_table_create([
            'packet index', 'hash value', 'hash index', 'queue id',
            'actual queue id', 'pass '
        ])

        i = 0
        for tmp_reta_line in reta_lines:
            status = "false"
            if self.kdriver == "fm10k":
                # compute the hash result of five tuple into the 7 LSBs value.
                hash_index = int(tmp_reta_line["RSS hash"], 16) % 128
            else:
                # compute the hash result of five tuple into the 7 LSBs value.
                hash_index = int(tmp_reta_line["RSS hash"], 16) % 512
            if (reta_entries[hash_index] == int(tmp_reta_line["queue"])):
                status = "true"
                result.insert(i, 0)
            else:
                status = "fail"
                result.insert(i, 1)
            self.result_table_add([
                i, tmp_reta_line["RSS hash"], hash_index,
                reta_entries[hash_index], tmp_reta_line["queue"], status
            ])
            i = i + 1

        self.result_table_print()
        reta_lines = []
        self.verify(sum(result) == 0, "the reta update function failed!")

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

        self.verify(
            self.nic in [
                "niantic", "fortville_eagle", "fortville_spirit",
                "fortville_spirit_single", "fortville_25g"
            ], "NIC Unsupported: " + str(self.nic))
        self.dut_ports = self.dut.get_ports(self.nic)
        self.verify(len(self.dut_ports) >= 1, "Not enough ports available")

        # 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.vm0 = None
        self.host_testpmd = None
        self.setup_1pf_1vf_1vm_env_flag = 0
        self.setup_1pf_1vf_1vm_env(driver='')

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

    def setup_1pf_1vf_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']

        try:

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

            time.sleep(1)
            vf0_prot = {'opt_host': self.sriov_vfs_port_0[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
                }
                self.host_testpmd.start_testpmd("1S/2C/2T",
                                                eal_param=eal_param)

            # set up VM0 ENV
            self.vm0 = QEMUKvm(self.dut, 'vm0', 'vf_rss')
            self.vm0.set_vm_device(driver=self.vf_assign_method, **vf0_prot)

            self.vm_dut_0 = self.vm0.start()
            if self.vm_dut_0 is None:
                raise Exception("Set up VM0 ENV failed!")

            self.vm0_testpmd = PmdOutput(self.vm_dut_0)

            self.setup_1pf_1vf_1vm_env_flag = 1
        except Exception as e:
            self.destroy_1pf_1vf_1vm_env()
            raise Exception(e)

    def destroy_1pf_1vf_1vm_env(self):
        if getattr(self, 'vm0', None):
            if getattr(self, 'vm0_testpmd', None):
                self.vm0_testpmd.execute_cmd('quit', '# ')
                self.vm0_testpmd = None
            self.vm0_dut_ports = None
            #destroy vm0
            self.vm0.stop()
            self.dut.virt_exit()
            self.vm0 = None

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

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

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

        self.setup_1pf_2vf_1vm_env_flag = 0

    def test_vf_pmdrss_reta(self):

        # niantic kernel host driver not support this case
        if self.nic is 'niantic' and not self.host_testpmd:
            self.logger.warning(
                "niantic kernel host driver not support this case")
            return
        vm0dutPorts = self.vm_dut_0.get_ports('any')
        localPort = self.tester.get_local_port(vm0dutPorts[0])
        itf = self.tester.get_interface(localPort)
        self.vm0_ports_socket = self.vm_dut_0.get_numa_id(vm0dutPorts[0])
        iptypes = ['IPV4']

        self.vm_dut_0.kill_all()

        # test with different rss queues
        eal_param = ''
        for queue in testQueues:

            self.vm0_testpmd.start_testpmd("all",
                                           "--rxq=%d --txq=%d %s" %
                                           (queue, queue, eal_param),
                                           socket=self.vm0_ports_socket)

            for iptype in iptypes:
                self.vm_dut_0.send_expect("set verbose 8", "testpmd> ")
                self.vm_dut_0.send_expect("set fwd rxonly", "testpmd> ")
                self.vm_dut_0.send_expect("set nbcore %d" % (queue + 1),
                                          "testpmd> ")

                # configure the reta with specific mappings.
                if (self.nic in [
                        "niantic", "redrockcanyou", "atwood", "boulderrapid"
                ]):
                    for i in range(128):
                        reta_entries.insert(i, random.randint(0, queue - 1))
                        self.vm_dut_0.send_expect(
                            "port config 0 rss reta (%d,%d)" %
                            (i, reta_entries[i]), "testpmd> ")
                else:
                    for i in range(512):
                        reta_entries.insert(i, random.randint(0, queue - 1))
                        self.vm_dut_0.send_expect(
                            "port config 0 rss reta (%d,%d)" %
                            (i, reta_entries[i]), "testpmd> ")

                self.send_packet(itf, iptype)

            self.vm_dut_0.send_expect("quit", "# ", 30)

    def test_vf_pmdrss(self):
        vm0dutPorts = self.vm_dut_0.get_ports('any')
        localPort = self.tester.get_local_port(vm0dutPorts[0])
        itf = self.tester.get_interface(localPort)
        self.vm0_ports_socket = self.vm_dut_0.get_numa_id(vm0dutPorts[0])
        iptypes = {
            'ipv4-sctp': 'ip',
            'ipv4-other': 'ip',
            'ipv4-udp': 'udp',
            'ipv4-tcp': 'tcp',
            'ipv4-sctp': 'sctp',
            'ipv6-other': 'ip',
            'ipv6-udp': 'udp',
            'ipv6-tcp': 'tcp',
            'ipv6-sctp': 'sctp',
            #  'l2_payload':'ether'
        }

        self.vm_dut_0.kill_all()

        eal_param = ''
        # test with different rss queues
        for queue in testQueues:

            self.vm0_testpmd.start_testpmd("all",
                                           "--rxq=%d --txq=%d %s" %
                                           (queue, queue, eal_param),
                                           socket=self.vm0_ports_socket)

            for iptype, rsstype in iptypes.items():
                self.vm_dut_0.send_expect("set verbose 8", "testpmd> ")
                self.vm_dut_0.send_expect("set fwd rxonly", "testpmd> ")
                out = self.vm_dut_0.send_expect(
                    "port config all rss %s" % rsstype, "testpmd> ")
                self.verify("Operation not supported" not in out,
                            "Operation not supported")
                self.vm_dut_0.send_expect("set nbcore %d" % (queue + 1),
                                          "testpmd> ")

                self.send_packet(itf, iptype)

            self.vm_dut_0.send_expect("quit", "# ", 30)

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

    def tear_down_all(self):
        """
        Run after each test suite.
        """
        #self.vm_dut_0.kill_all()
        self.destroy_1pf_1vf_1vm_env()
Exemplo n.º 3
0
class Testvf_daemon(TestCase):
    def set_up_all(self):

        self.dut_ports = self.dut.get_ports(self.nic)
        self.verify(len(self.dut_ports) >= 1, "Insufficient ports")
        self.vm0 = None
        self.vm1 = None
        self.env_done = False

    def set_up(self):
        self.setup_vm_env()

    def bind_nic_driver(self, ports, driver=""):
        if driver == "igb_uio":
            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 == "":
                    driver = netdev.default_driver
                if driver != driver_now:
                    netdev.bind_driver(driver=driver)

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

        self.bind_nic_driver(self.dut_ports[:1], driver="igb_uio")
        self.used_dut_port = self.dut_ports[0]
        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,
                                            2,
                                            driver=driver)
        self.sriov_vfs_port = self.dut.ports_info[
            self.used_dut_port]['vfs_port']
        for port in self.sriov_vfs_port:
            port.bind_driver('pci-stub')
        time.sleep(1)
        self.dut_testpmd = PmdOutput(self.dut)
        time.sleep(1)
        vf0_prop = {'opt_host': self.sriov_vfs_port[0].pci}

        # set up VM0 ENV
        self.vm0 = QEMUKvm(self.dut, 'vm0', 'vf_daemon')
        self.vm0.set_vm_device(driver='pci-assign', **vf0_prop)
        try:
            self.vm0_dut = self.vm0.start()
            if self.vm0_dut is None:
                raise Exception("Set up VM0 ENV failed!")
        except Exception as e:
            self.destroy_vm_env()
            raise Exception(e)

        self.vm0_dut_ports = self.vm0_dut.get_ports('any')
        self.vm0_testpmd = PmdOutput(self.vm0_dut)

        vf1_prop = {'opt_host': self.sriov_vfs_port[1].pci}
        self.vm1 = QEMUKvm(self.dut, 'vm1', 'vf_daemon')
        self.vm1.set_vm_device(driver='pci-assign', **vf1_prop)
        try:
            self.vm1_dut = self.vm1.start()
            if self.vm1_dut is None:
                raise Exception("Set up VM1 ENV failed!")
        except Exception as e:
            self.destroy_vm_env()
            raise Exception(e)
        self.vm1_dut_ports = self.vm1_dut.get_ports('any')
        self.vm1_testpmd = PmdOutput(self.vm1_dut)

        self.env_done = True

    def destroy_vm_env(self):

        if getattr(self, 'vm0', None):
            self.vm0_dut.kill_all()
            self.vm0_testpmd = None
            self.vm0_dut_ports = None
            # destroy vm0
            self.vm0.stop()
            self.vm0 = None

        if getattr(self, 'vm1', None):
            self.vm1_dut.kill_all()
            self.vm1_testpmd = None
            self.vm1_dut_ports = None
            # destroy vm1
            self.vm1.stop()
            self.vm1 = None

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

        self.env_done = False

    def send_packet(self, dst_mac, vlan_id, pktsize, num):
        """
        Generate packets and send them to dut 
        """
        if vlan_id == 0:
            pkt = Packet(pkt_type='UDP', pkt_len=pktsize)
        else:
            pkt = Packet(pkt_type='VLAN_UDP', pkt_len=pktsize)
            pkt.config_layer('vlan', {'vlan': vlan_id})
        pkt.config_layer('ether', {'dst': dst_mac})
        inst = sniff_packets(self.tester_intf, timeout=5)
        pkt.send_pkt(tx_port=self.tester_intf, count=num)
        return inst

    def strip_mac(self, inst, element="src"):
        """
        Load sniff packets, strip and return mac address from dump message
        """
        pkts = load_sniff_packets(inst)
        macs = []
        for pkt in pkts:
            mac = pkt.strip_element_layer2(element)
            macs.append(mac)
        return macs

    def strip_vlan(self, inst):
        """
        Load sniff packets, strip and return vlan id from dump message
        """
        pkts = load_sniff_packets(inst)
        vlans = []
        for pkt in pkts:
            vlan = pkt.strip_element_vlan("vlan")
            vlans.append(vlan)
        return vlans

    def send_and_pmdout(self, dst_mac, vlan_id=0, pktsize=64, num=1):
        """
        Send packets to dut and return testpmd output message
        Input: dst_mac, vlan_id, packet size, packet number
        Output: testpmd output message
        """
        inst = self.send_packet(dst_mac, vlan_id, pktsize, num)
        out = self.vm0_dut.get_session_output(timeout=2)
        return out

    def send_and_vlanstrip(self, dst_mac, vlan_id=0, pktsize=64, num=1):
        """
        Send packets to dut, strip and return vlan id from dump message
        Input: dst_mac, vlan_id, packet size, packet number
        Output: vlan id stripped from dump message
        """
        inst = self.send_packet(dst_mac, vlan_id, pktsize, num)
        vlans = self.strip_vlan(inst)
        return vlans

    def send_and_macstrip(self, dst_mac, vlan_id=0, pktsize=64, num=1):
        """
        Send packets to dut, strip and return src/dst mac from dump message
        Input: dst_mac, vlan_id, packet size, packet number
        Output: src/dst mac stripped from dump message
        """
        inst = self.send_packet(dst_mac, vlan_id, pktsize, num)
        macs = self.strip_mac(inst)
        return macs

    def test_vlan_insert(self):
        """
        Insert a vlan id for a VF from PF
        If insert vlan id as 0, means disabling vlan id insertion 
        If insert vlan id as 1~4095, means enabling vlan id insertion and 
        vlan id as configured value
        """
        self.dut_testpmd.start_testpmd("Default", "--port-topology=chained")
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK,
                                       '--port-topology=chained')

        self.vf0_mac = self.vm0_testpmd.get_port_mac(0)

        self.vm0_testpmd.execute_cmd('set fwd mac')
        self.vm0_testpmd.execute_cmd('set verbose 1')
        self.vm0_testpmd.execute_cmd('start')
        #Disable vlan insert which means insert vlan id as 0
        rx_vlan = 0
        self.dut_testpmd.execute_cmd('set vf vlan insert 0 0 %s' % rx_vlan)
        time.sleep(1)
        vlans = self.send_and_vlanstrip(self.vf0_mac)
        self.verify(rx_vlan not in vlans, "Failed to disable vlan insert!!!")

        #Enable vlan insert which means insert vlan id as 1~4095
        random_vlan = random.randint(1, MAX_VLAN - 1)
        rx_vlans = [1, random_vlan, MAX_VLAN]
        for rx_vlan in rx_vlans:
            self.dut_testpmd.execute_cmd('set vf vlan insert 0 0 %s' % rx_vlan)
            time.sleep(1)
            vlans = self.send_and_vlanstrip(self.vf0_mac)
            self.verify(rx_vlan in vlans,
                        "Failed to enable vlan insert packet!!!")

        self.vm0_testpmd.quit()
        self.dut_testpmd.quit()

    def test_multicast_mode(self):
        """
        Enable/disable multicast promiscuous mode for a VF from PF
        """
        self.dut_testpmd.start_testpmd("Default", "--port-topology=chained")
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK,
                                       '--port-topology=chained')

        self.vf0_mac = self.vm0_testpmd.get_port_mac(0)

        self.vm0_testpmd.execute_cmd('set fwd rxonly')
        self.vm0_testpmd.execute_cmd('set verbose 1')
        self.vm0_testpmd.execute_cmd('start')
        self.dut_testpmd.execute_cmd('set vf promisc 0 0 off')
        self.dut_testpmd.execute_cmd('set vf allmulti 0 0 off')
        multi_mac = 'F3:00:33:22:11:00'
        out = self.send_and_pmdout(multi_mac)
        self.verify("received" not in out,
                    "Failed to disable vf multicast mode!!!")

        out = self.send_and_pmdout(self.vf0_mac)
        self.verify("received" in out,
                    "Failed to disable vf multicast mode!!!")
        self.verify("dst=%s" % self.vf0_mac in out,
                    "Failed to disable vf multicast mode!!!")

        self.dut_testpmd.execute_cmd('set vf allmulti 0 0 on')
        out = self.send_and_pmdout(multi_mac)
        self.verify("received" in out, "Failed to enable vf multicast mode!!!")
        self.verify("dst=%s" % multi_mac in out,
                    "Failed to enable vf multicast mode!!!")

        out = self.send_and_pmdout(self.vf0_mac)
        self.verify("received" in out, "Failed to enable vf multicast mode!!!")
        self.verify("dst=%s" % self.vf0_mac in out,
                    "Failed to enable vf multicast mode!!!")

        self.vm0_testpmd.quit()
        self.dut_testpmd.quit()

    def test_promisc_mode(self):
        """
        Enable/disable promiscuous mode for a VF from PF
        """
        self.dut_testpmd.start_testpmd("Default", "--port-topology=chained")
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK,
                                       '--port-topology=chained')

        self.vf0_mac = self.vm0_testpmd.get_port_mac(0)

        self.vm0_testpmd.execute_cmd('set fwd rxonly')
        self.vm0_testpmd.execute_cmd('set verbose 1')
        self.vm0_testpmd.execute_cmd('start')
        self.dut_testpmd.execute_cmd('set vf promisc 0 0 off')

        wrong_mac = '9E:AC:72:49:43:11'
        out = self.send_and_pmdout(wrong_mac)
        self.verify("received" not in out,
                    "Failed to disable vf promisc mode!!!")

        out = self.send_and_pmdout(self.vf0_mac)
        self.verify("received" in out, "Failed to disable vf promisc mode!!!")
        self.verify("dst=%s" % self.vf0_mac in out,
                    "Failed to disable vf promisc mode!!!")

        self.dut_testpmd.execute_cmd('set vf promisc 0 0 on')
        out = self.send_and_pmdout(wrong_mac)
        self.verify("received" in out, "Failed to enable vf promisc mode!!!")
        self.verify("dst=%s" % wrong_mac in out,
                    "Failed to enable vf promisc mode!!!")

        out = self.send_and_pmdout(self.vf0_mac)
        self.verify("received" in out, "Failed to enable vf promisc mode!!!")
        self.verify("dst=%s" % self.vf0_mac in out,
                    "Failed to enable vf promisc mode!!!")

        self.vm0_testpmd.quit()
        self.dut_testpmd.quit()

    def test_broadcast_mode(self):
        """
        Enable/disable broadcast mode for a VF from PF
        """
        self.dut_testpmd.start_testpmd("Default", "--port-topology=chained")
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK,
                                       '--port-topology=chained')

        self.vf0_mac = self.vm0_testpmd.get_port_mac(0)

        self.vm0_testpmd.execute_cmd('set fwd rxonly')
        self.vm0_testpmd.execute_cmd('set verbose 1')
        self.vm0_testpmd.execute_cmd('start')
        self.dut_testpmd.execute_cmd('set vf broadcast 0 0 off')

        dst_mac = 'FF:FF:FF:FF:FF:FF'
        out = self.send_and_pmdout(dst_mac)
        self.verify("received" not in out,
                    "Failed to disable vf broadcast mode!!!")

        self.dut_testpmd.execute_cmd('set vf broadcast 0 0 on')
        out = self.send_and_pmdout(dst_mac)
        self.verify("received" in out, "Failed to enable vf broadcast mode!!!")
        self.verify("dst=%s" % dst_mac in out,
                    "Failed to enable vf broadcast mode!!!")

        self.vm0_testpmd.quit()
        self.dut_testpmd.quit()

    def test_vf_mtu(self):
        """
        Enable VF MTU change        
        """
        self.dut.send_expect("ifconfig %s mtu 9000" % self.tester_intf, "#")
        self.dut_testpmd.start_testpmd("Default", "--port-topology=chained")
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK,
                                       '--port-topology=chained')

        self.vf0_mac = self.vm0_testpmd.get_port_mac(0)

        self.vm0_testpmd.execute_cmd('set fwd mac')
        self.vm0_testpmd.execute_cmd('set verbose 1')
        self.vm0_testpmd.execute_cmd('start')
        pktsize = random.randint(1500, 9000)
        out = self.send_and_macstrip(self.vf0_mac, 0, pktsize)
        self.vm0_testpmd.execute_cmd('stop')
        self.verify(self.vf0_mac.lower() not in out,
                    "Failed to receive and forward this length packet!!!")

        self.vm0_testpmd.execute_cmd('port stop all')
        self.vm0_testpmd.execute_cmd('port config mtu 0 %s' % (pktsize + 100))
        self.vm0_testpmd.execute_cmd('port start all')
        self.vm0_testpmd.execute_cmd('start')
        out = self.send_and_macstrip(self.vf0_mac, 0, pktsize)
        self.vm0_testpmd.execute_cmd('stop')
        self.verify(self.vf0_mac.lower() in out,
                    "Failed to receive and forward this length packet!!!")

        self.vm0_testpmd.quit()
        self.dut_testpmd.quit()
        self.dut.send_expect("ifconfig %s mtu 1500" % self.tester_intf, "#")

    def test_vlan_tag(self):
        """
        Enable/disable vlan tag for a VF from PF
        """
        self.dut_testpmd.start_testpmd("Default", "--port-topology=chained")
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK,
                                       '--port-topology=chained')

        self.vf0_mac = self.vm0_testpmd.get_port_mac(0)

        random_vlan = random.randint(1, MAX_VLAN - 1)
        rx_vlans = [1, random_vlan, MAX_VLAN]
        self.vm0_testpmd.execute_cmd('set fwd mac')
        self.vm0_testpmd.execute_cmd('set verbose 1')
        self.vm0_testpmd.execute_cmd('start')
        for rx_vlan in rx_vlans:
            self.vm0_testpmd.execute_cmd('rx_vlan add %s 0' % rx_vlan)
            self.dut_testpmd.execute_cmd('set vf vlan tag 0 0 off')
            time.sleep(1)
            out = self.send_and_macstrip(self.vf0_mac, rx_vlan)
            self.verify(self.vf0_mac.lower() not in out,
                        "Failed to disable vlan tag!!!")

            self.dut_testpmd.execute_cmd('set vf vlan tag 0 0 on')
            time.sleep(1)
            out = self.send_and_macstrip(self.vf0_mac, rx_vlan)
            self.verify(self.vf0_mac.lower() in out,
                        "Failed to enable vlan tag!!!")

        self.vm0_testpmd.quit()
        self.dut_testpmd.quit()

    def test_tx_loopback(self):
        """
        Enable/disable TX loopback from PF
        """
        self.dut_testpmd.start_testpmd("Default", "--port-topology=chained")
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK,
                                       '--port-topology=chained')
        self.vf0_mac = self.vm0_testpmd.get_port_mac(0)
        self.vm1_testpmd.start_testpmd(
            VM_CORES_MASK,
            '--port-topology=chained --eth-peer=0,%s' % self.vf0_mac)

        self.vm0_testpmd.execute_cmd('set fwd rxonly')
        self.vm0_testpmd.execute_cmd('set verbose 1')
        self.vm0_testpmd.execute_cmd('start')
        self.dut_testpmd.execute_cmd('set tx loopback 0 off')

        inst = sniff_packets(self.tester_intf, timeout=5)

        self.vm1_testpmd.execute_cmd('set burst 5')
        self.vm1_testpmd.execute_cmd('start tx_first')

        dumpout = self.strip_mac(inst, "dst")
        out = self.vm0_testpmd.execute_cmd('stop')
        self.verify(self.vf0_mac.lower() in dumpout,
                    "Failed to disable tx loopback!!!")
        self.verify("RX-packets: 0" in out, "Failed to disable tx loopback!!!")

        self.vm0_testpmd.execute_cmd('start')
        self.dut_testpmd.execute_cmd('set tx loopback 0 on')

        inst = sniff_packets(self.tester_intf, timeout=5)

        self.vm1_testpmd.execute_cmd('stop')
        self.vm1_testpmd.execute_cmd('start tx_first')
        dumpout = self.strip_mac(inst, "dst")
        out = self.vm0_testpmd.execute_cmd('stop')
        self.verify(self.vf0_mac.lower() not in dumpout,
                    "Failed to enable tx loopback!!!")
        self.verify("RX-packets: 5" in out, "Failed to enable tx loopback!!!")

        self.vm0_testpmd.quit()
        self.vm1_testpmd.quit()
        self.dut_testpmd.quit()

    def test_all_queues_drop(self):
        """
        Enable/disable drop enable bit for all queues from PF
        """
        self.dut_testpmd.start_testpmd("Default", "--port-topology=chained")
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK,
                                       '--port-topology=chained')
        self.vm1_testpmd.start_testpmd(VM_CORES_MASK,
                                       '--port-topology=chained')

        self.vm0_testpmd.execute_cmd('set fwd rxonly')
        self.vm0_testpmd.execute_cmd('set verbose 1')
        self.vm0_testpmd.execute_cmd('start')
        self.dut_testpmd.execute_cmd('set all queues drop 0 off')
        self.vf0_mac = self.vm0_testpmd.get_port_mac(0)
        self.vf1_mac = self.vm1_testpmd.get_port_mac(0)
        out = self.send_and_pmdout(self.vf1_mac, 0, 64, 200)
        out = self.vm1_testpmd.execute_cmd('show port stats 0')
        self.verify("RX-packets: 127" in out,
                    "Failed to let vf1 full of queues!!!")
        out = self.send_and_pmdout(self.vf0_mac, 0, 64, 20)
        out = self.vm0_testpmd.execute_cmd('show port stats 0')
        self.verify("RX-packets: 0" in out,
                    "Failed to disable all queues drop!!!")
        self.dut_testpmd.execute_cmd('set all queues drop 0 on')
        out = self.vm0_testpmd.execute_cmd('show port stats 0')
        self.verify("RX-packets: 20" in out,
                    "Failed to enable all queues drop!!!")
        out = self.send_and_pmdout(self.vf0_mac, 0, 64, 20)
        out = self.vm0_testpmd.execute_cmd('show port stats 0')
        self.verify("RX-packets: 40" in out,
                    "Failed to enable all queues drop!!!")

        self.vm0_testpmd.quit()
        self.vm1_testpmd.quit()
        self.dut_testpmd.quit()

    def test_mac_antispoof(self):
        """
        Enable/disable mac anti-spoof for a VF from PF
        """
        fake_mac = '00:11:22:33:44:55'
        self.vm0_dut.send_expect("sed -i -e '/uint64_t ol_flags = 0;/a " +\
            "\struct ether_addr fake_mac = {.addr_bytes = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55},};'" +\
            " app/test-pmd/macswap.c", "# ", 30)
        self.vm0_dut.send_expect("sed -i -e '/ether_addr_copy(&addr, &eth_hdr->s_addr);/d' " +\
            " app/test-pmd/macswap.c", "# ", 30)
        self.vm0_dut.send_expect("sed -i -e '/ether_addr_copy(&eth_hdr->s_addr, &eth_hdr->d_addr);/a " +\
            "\ether_addr_copy(&fake_mac, &eth_hdr->s_addr);' app/test-pmd/macswap.c", "# ", 30)
        self.vm0_dut.build_install_dpdk(self.target)
        self.dut_testpmd.start_testpmd("Default", "--port-topology=chained")
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK,
                                       '--port-topology=chained')
        self.vf0_mac = self.vm0_testpmd.get_port_mac(0)

        self.vm0_testpmd.execute_cmd('set fwd macswap')
        self.dut_testpmd.execute_cmd('set vf mac antispoof 0 0 off')
        self.vm0_testpmd.execute_cmd('start')
        dumpout = self.send_and_macstrip(self.vf0_mac)
        out = self.vm0_testpmd.execute_cmd('stop')
        self.verify(fake_mac in dumpout, "Failed to disable vf mac anspoof!!!")
        self.verify("RX-packets: 1" in out, "Failed to receive packet!!!")
        self.verify("TX-packets: 1" in out,
                    "Failed to disable mac antispoof!!!")

        self.dut_testpmd.execute_cmd('set vf mac antispoof 0 0 on')
        out = self.vm0_testpmd.execute_cmd('start')
        dumpout = self.send_and_macstrip(self.vf0_mac)
        out = self.vm0_testpmd.execute_cmd('stop')
        self.verify(fake_mac not in dumpout,
                    "Failed to enable vf mac anspoof!!!")
        self.verify("RX-packets: 1" in out, "Failed to receive packet!!!")
        self.verify("TX-packets: 0" in out,
                    "Failed to enable mac antispoof!!!")

        self.vm0_testpmd.quit()
        self.dut_testpmd.quit()
        self.vm0_dut.send_expect("sed -i '/struct ether_addr fake_mac = {.addr_bytes = " +\
            "{0x00, 0x11, 0x22, 0x33, 0x44, 0x55},};/d' app/test-pmd/macswap.c", "# ", 30)
        self.vm0_dut.send_expect("sed -i '/ether_addr_copy(&fake_mac, &eth_hdr->s_addr);/d' " +\
            "app/test-pmd/macswap.c", "# ", 30)
        self.vm0_dut.send_expect("sed -i '/ether_addr_copy(&eth_hdr->s_addr, &eth_hdr->d_addr);/a " +\
            "\ether_addr_copy(&addr, &eth_hdr->s_addr);' app/test-pmd/macswap.c", "# ", 30)
        self.vm0_dut.build_install_dpdk(self.target)

    def test_vf_mac_set(self):
        """
        Set MAC address for a VF from PF
        """
        expect_mac = 'A2:22:33:44:55:66'
        self.dut_testpmd.start_testpmd("Default", "--port-topology=chained")
        self.dut_testpmd.execute_cmd('set vf mac addr 0 0 %s' % expect_mac)
        out = self.vm0_testpmd.start_testpmd(VM_CORES_MASK,
                                             '--port-topology=chained')
        self.verify("%s" % expect_mac in out, "Failed to set vf mac!!!")
        self.vf0_mac = self.vm0_testpmd.get_port_mac(0)

        self.vm0_testpmd.execute_cmd('set fwd mac')
        self.vm0_testpmd.execute_cmd('start')
        out = self.send_and_macstrip(self.vf0_mac)
        self.verify(expect_mac.lower() in out,
                    "Failed to receive packet on setted vf mac!!!")

        self.vm0_testpmd.quit()
        self.dut_testpmd.quit()

    def test_vlan_antispoof(self):
        """
        Enable/disable vlan antispoof for a VF from PF 
        """
        self.dut_testpmd.start_testpmd("Default", "--port-topology=chained")
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK,
                                       '--port-topology=chained')

        self.vf0_mac = self.vm0_testpmd.get_port_mac(0)
        vf0_mac_lower = self.vf0_mac.lower()
        random_vlan = random.randint(1, MAX_VLAN)
        match_vlan = random_vlan
        unmatch_vlan = (random_vlan + 2) % 4096
        self.vm0_testpmd.execute_cmd('set fwd mac')
        self.vm0_testpmd.execute_cmd('start')
        self.dut_testpmd.execute_cmd('rx_vlan add %d port 0 vf 1' % match_vlan)
        if self.kdriver == "i40e":
            self.dut_testpmd.execute_cmd('set vf vlan stripq 0 0 off')
        else:
            self.dut_testpmd.execute_cmd('vlan set filter off 0')
            self.dut_testpmd.execute_cmd('vlan set strip off 0')
            self.vm0_testpmd.execute_cmd('vlan set strip off 0')

        self.dut_testpmd.execute_cmd('set vf vlan antispoof 0 0 off')
        time.sleep(1)
        out = self.send_and_macstrip(self.vf0_mac, match_vlan)
        self.verify(vf0_mac_lower in out,
                    "Failed to disable vlan antispoof with match vlan!!!")
        out = self.send_and_macstrip(self.vf0_mac, unmatch_vlan)
        self.verify(vf0_mac_lower in out,
                    "Failed to disable vlan antispoof with unmatch vlan!!!")
        out = self.send_and_macstrip(self.vf0_mac)
        self.verify(vf0_mac_lower in out,
                    "Failed to disable vlan antispoof with no vlan!!!")

        if self.kdriver == "ixgbe":
            self.dut_testpmd.execute_cmd('set vf mac antispoof 0 0 on')
        self.dut_testpmd.execute_cmd('set vf vlan antispoof 0 0 on')
        time.sleep(1)

        out = self.send_and_macstrip(self.vf0_mac, match_vlan)
        self.verify(vf0_mac_lower in out,
                    "Failed to enable vlan antispoof with match vlan!!!")

        out = self.send_and_macstrip(self.vf0_mac, unmatch_vlan)
        self.verify(vf0_mac_lower not in out,
                    "Failed to enable vlan antispoof with unmatch vlan!!!")

        out = self.send_and_macstrip(self.vf0_mac)
        self.verify(vf0_mac_lower not in out,
                    "Failed to enable vlan antispoof with no vlan!!!")

        self.vm0_testpmd.quit()
        self.dut_testpmd.quit()

    def test_vlan_strip(self):
        """
        Enable/disable the VLAN strip for all queues in a pool for a VF from PF
        """
        self.dut_testpmd.start_testpmd("Default", "--port-topology=chained")
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK,
                                       '--port-topology=chained')

        self.vf0_mac = self.vm0_testpmd.get_port_mac(0)

        random_vlan = random.randint(1, MAX_VLAN - 1)
        rx_vlans = [1, random_vlan, MAX_VLAN]
        self.vm0_testpmd.execute_cmd('set fwd mac')
        self.vm0_testpmd.execute_cmd('set verbose 1')
        self.vm0_testpmd.execute_cmd('start')
        for rx_vlan in rx_vlans:
            self.vm0_testpmd.execute_cmd('rx_vlan add %s 0' % rx_vlan)
            self.dut_testpmd.execute_cmd('set vf vlan stripq 0 0 off')
            time.sleep(1)
            out = self.send_and_vlanstrip(self.vf0_mac, rx_vlan)
            self.verify(rx_vlan in out, "Failed to disable strip vlan!!!")

            self.dut_testpmd.execute_cmd('set vf vlan stripq 0 0 on')
            time.sleep(1)
            out = self.send_and_vlanstrip(self.vf0_mac, rx_vlan)
            self.verify(rx_vlan not in out, "Failed to disable strip vlan!!!")

        self.vm0_testpmd.quit()
        self.dut_testpmd.quit()

    def test_vlan_filter(self):
        """
        Add/Remove vlan filter for a VF from PF
        """
        self.dut_testpmd.start_testpmd("Default", "--port-topology=chained")
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK,
                                       '--port-topology=chained')

        self.vm0_testpmd.execute_cmd('set fwd rxonly')
        self.vm0_testpmd.execute_cmd('set verbose 1')
        self.vm0_testpmd.execute_cmd('start')

        wrong_mac = '9E:AC:72:49:43:11'
        out = self.send_and_pmdout(wrong_mac)
        self.verify("dst=%s" % wrong_mac in out,
                    "Failed to receive untagged packet!!!")
        random_vlan = random.randint(1, MAX_VLAN)
        out = self.send_and_pmdout(wrong_mac, random_vlan)
        self.verify("dst=%s" % wrong_mac in out,
                    "Failed to receive packet with vlan id!!!")
        self.verify("VLAN tci=%s" % hex(random_vlan) in out,
                    "Failed to receive packet with vlan id!!!")
        random_vlan = random.randint(2, MAX_VLAN - 1)
        rx_vlans = [1, random_vlan, MAX_VLAN]
        for rx_vlan in rx_vlans:
            self.dut_testpmd.execute_cmd('rx_vlan add %s port 0 vf 1' %
                                         rx_vlan)
            time.sleep(1)
            out = self.send_and_pmdout(wrong_mac, rx_vlan)
            self.verify("dst=%s" % wrong_mac in out,
                        "Failed to enable vlan filter!!!")
            self.verify("VLAN tci=%s" % hex(rx_vlan) in out,
                        "Failed to receive packet with vlan id!!!")
            wrong_rx_vlan = (rx_vlan + 1) % 4096
            #Packet for vlan id 0 is equal to untagged packet for this case
            if wrong_rx_vlan == 0:
                wrong_rx_vlan = random.randint(1, MAX_VLAN - 1)
            out = self.send_and_pmdout(wrong_mac, wrong_rx_vlan)
            self.verify("dst=%s" % wrong_mac not in out,
                        "Failed to enable vlan filter!!!")
            self.dut_testpmd.execute_cmd('rx_vlan rm %s port 0 vf 1' % rx_vlan)
            out = self.send_and_pmdout(wrong_mac, rx_vlan)
            self.verify("dst=%s" % wrong_mac in out,
                        "Failed to disable vlan filter!!!")
            self.verify("VLAN tci=%s" % hex(rx_vlan) in out,
                        "Failed to receive packet with vlan id!!!")
            out = self.send_and_pmdout(wrong_mac, wrong_rx_vlan)
            self.verify("dst=%s" % wrong_mac in out,
                        "Failed to disable vlan filter!!!")
            self.verify("VLAN tci=%s" % hex(wrong_rx_vlan) in out,
                        "Failed to receive packet with vlan id!!!")
        out = self.send_and_pmdout(wrong_mac)
        self.verify("dst=%s" % wrong_mac in out,
                    "Failed to receive untagged packet!!!")

        self.vm0_testpmd.quit()
        self.dut_testpmd.quit()

    def tear_down(self):
        self.vm0_dut.kill_all()
        self.vm1_dut.kill_all()
        pass

    def tear_down_all(self):
        self.destroy_vm_env()
        pass
Exemplo n.º 4
0
class TestVF2VFBridge(TestCase):

    def set_up_all(self):
        self.dut_ports = self.dut.get_ports(self.nic)
        self.verify(len(self.dut_ports) >= 1, "Insufficient ports")
        self.vm0 = None
        self.vm1 = None

    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('pci-stub')
            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 = QEMUKvm(self.dut, 'vm0', 'vf_to_vf_bridge')
        self.vm0.set_vm_device(driver='pci-assign', **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 = QEMUKvm(self.dut, 'vm1', 'vf_to_vf_bridge')
        self.vm1.set_vm_device(driver='pci-assign', **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('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.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
Exemplo n.º 5
0
class TestEtag(TestCase):
    supported_vf_driver = ['pci-stub', 'vfio-pci']

    def set_up_all(self):
        self.dut_ports = self.dut.get_ports(self.nic)
        self.verify(self.nic in ['sagepond', 'sageville'],
                    '802.1BR only support by sagepond and sageville')
        self.verify(len(self.dut_ports) >= 1, 'Insufficient ports')
        self.src_intf = self.tester.get_interface(
            self.tester.get_local_port(0))
        self.src_mac = self.tester.get_mac(self.tester.get_local_port(0))
        self.dst_mac = self.dut.get_mac_address(0)
        self.vm0 = None
        self.printFlag = self._enable_debug
        self.dut.send_expect('ls', '#')
        self.setup_vm_env_flag = 0
        self.preset_host_cmds = list()

    def set_up(self):
        pass

    def setup_vm_env(self, driver='default'):
        '''
        setup qemu virtual environment
        '''
        if self.setup_vm_env_flag == 1:
            return

        self.used_dut_port_0 = self.dut_ports[0]
        self.dut.generate_sriov_vfs_by_port(self.used_dut_port_0,
                                            2,
                                            driver=driver)
        self.sriov_vfs_port_0 = self.dut.ports_info[
            self.used_dut_port_0]['vfs_port']

        # 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', '#')

        try:
            for port in self.sriov_vfs_port_0:
                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_0[1].pci}

            # 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_0[1].pci
            }

            self.preset_host_testpmd(VM_CORES_MASK, eal_param)

            # set up VM0 ENV
            self.vm0 = QEMUKvm(self.dut, 'vm0', 'vf_etag')
            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!')

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

    def destroy_vm_env(self):
        #destroy testpmd in vm0
        if getattr(self, 'vm0_testpmd', None) and self.vm0_testpmd:
            self.vm0_testpmd.execute_cmd('stop')
            self.vm0_testpmd.execute_cmd('quit', '# ')
            self.vm0_testpmd = None

        #destroy vm0
        if getattr(self, 'vm0', None) and self.vm0:
            self.vm0_dut_ports = None
            self.vm0.stop()
            self.vm0 = None

        #destroy host testpmd
        if getattr(self, 'host_testpmd', None):
            self.host_testpmd.execute_cmd('quit', '# ')
            self.host_testpmd = None

        # reset used port's sriov
        if getattr(self, 'used_dut_port_0', None):
            self.dut.destroy_sriov_vfs_by_port(self.used_dut_port_0)
            port = self.dut.ports_info[self.used_dut_port_0]['port']
            port.bind_driver()
            self.used_dut_port_0 = None

        # bind used ports with default driver
        for port_id in self.dut_ports:
            port = self.dut.ports_info[port_id]['port']
            port.bind_driver()
        self.setup_vm_env_flag = 0

    def check_packet_transmission(self, pkt_types):
        time.sleep(1)
        for pkt_type in pkt_types.keys():
            intf = self.src_intf
            pkt = Packet(pkt_type=pkt_type)
            # set packet every layer's input parameters
            if 'layer_configs' in pkt_types[pkt_type].keys():
                pkt_configs = pkt_types[pkt_type]['layer_configs']
                if pkt_configs:
                    for layer in pkt_configs.keys():
                        pkt.config_layer(layer, pkt_configs[layer])
            pkt.send_pkt(tx_port=self.src_intf)

            # check vm testpmd packet received information
            if 'vm' in pkt_types[pkt_type].keys():
                out = self.vm0_testpmd.get_output(timeout=2)
                if self.printFlag:  # debug output
                    print out
                for pkt_attribute in pkt_types[pkt_type]['vm']:
                    if self.printFlag:  # debug output
                        print pkt_attribute
                    if pkt_attribute not in out:
                        print utils.RED('Fail to detect %s' % pkt_attribute)
                        if not self.printFlag:  # print out all info in debug mode
                            raise VerifyFailure('Failed to detect %s' %
                                                pkt_attribute)
                print utils.GREEN('VM detected %s successfully' % pkt_type)

            # check dut testpmd packet received information
            if 'dut' in pkt_types[pkt_type].keys():
                out = self.host_testpmd.get_output(timeout=2)
                if self.printFlag:  # debug output
                    print out
                for pkt_attribute in pkt_types[pkt_type]['dut']:
                    if self.printFlag:  # debug output
                        print pkt_attribute
                    if pkt_attribute not in out:
                        print utils.RED('Fail to detect %s' % pkt_attribute)
                        if not self.printFlag:  # print out all info in debug mode
                            raise VerifyFailure('Failed to detect %s' %
                                                pkt_attribute)
                print utils.GREEN('DUT detected %s successfully' % pkt_type)
            time.sleep(1)

    def preset_host_testpmd(self, core_mask, eal_param):
        if self.setup_vm_env_flag == 0:
            self.host_testpmd.start_testpmd(core_mask,
                                            param='--port-topology=loop',
                                            eal_param=eal_param)
            self.execute_host_testpmd_cmd(self.preset_host_cmds)
            self.preset_host_cmds = list()
            time.sleep(2)

    def execute_host_testpmd_cmd(self, cmds):
        if len(cmds) == 0:
            return
        for item in cmds:
            if len(item) == 2:
                self.host_testpmd.execute_cmd(item[0], int(item[1]))
            else:
                self.host_testpmd.execute_cmd(item[0])

        time.sleep(2)

    def preset_guest_testpmd(self):
        if self.setup_vm_env_flag == 0:
            self.vm0_testpmd = PmdOutput(self.vm_dut_0)
            self.vm0_testpmd.start_testpmd(VM_CORES_MASK,
                                           param='--port-topology=loop')
            time.sleep(1)
        elif self.vm0_testpmd:
            self.vm0_testpmd.quit()
            self.vm0_testpmd.start_testpmd(VM_CORES_MASK,
                                           param='--port-topology=loop')
            time.sleep(1)

    def execute_guest_testpmd_cmd(self, cmds):
        if len(cmds) == 0:
            return
        for item in cmds:
            if len(item) == 2:
                self.vm0_testpmd.execute_cmd(item[0], int(item[1]))
            else:
                self.vm0_testpmd.execute_cmd(item[0])

    def preset_test_enviroment(self):
        self.setup_vm_env(driver='igb_uio')
        self.preset_guest_testpmd()
        self.setup_vm_env_flag = 1
        time.sleep(2)

    def test_l2_tunnel_filter(self):
        '''
        Enable E-tag l2 tunnel support means enabling ability of parsing E-tag packet.
        This ability should be enabled before we enable filtering, forwarding,
        offloading for this specific type of tunnel.
        '''
        host_cmds = [['port config 0 l2-tunnel E-tag enable'],
                     ['set fwd rxonly'], ['set verbose 1'], ['start']]
        guest_cmds = [['set fwd rxonly'], ['set verbose 1'], ['start']]
        config_layers = {
            'ether': {
                'src': self.src_mac
            },
            'etag': {
                'ECIDbase': 1000
            }
        }
        pkt_types = {
            'ETAG_UDP': {
                'dut': ['type=0x893f'],
                'vm': ['type=0x893f'],
                'layer_configs': config_layers
            }
        }

        self.preset_test_enviroment()
        self.execute_host_testpmd_cmd(host_cmds)
        self.execute_guest_testpmd_cmd(guest_cmds)
        self.check_packet_transmission(pkt_types)

    def test_etag_filter(self):
        '''
        when E-tag packet forwarding and add E-tag on VF0
        '''
        test_types = ['etag_pf', 'etag_remove', 'etag_vf_0', 'etag_vf_1']
        host_cmds = [['port config 0 l2-tunnel E-tag enable'],
                     ['E-tag set forwarding on port 0']]
        self.preset_test_enviroment()
        self.execute_host_testpmd_cmd(host_cmds)
        for test_type in test_types:
            host_cmds = list()
            guest_cmds = [['set fwd rxonly'], ['set verbose 1'], ['start']]
            if test_type == 'etag_pf':
                # Same E-tag forwarding to PF0, Send 802.1BR packet with broadcast mac and
                # check packet only received on PF

                host_cmds = [[
                    'E-tag set filter add e-tag-id 1000 dst-pool 2 port 0'
                ], ['set fwd mac'], ['set verbose 1'], ['start']]
                # set packet type and its expecting result
                config_layers = {
                    'ether': {
                        'src': self.src_mac,
                        'dst': self.dst_mac
                    },
                    'etag': {
                        'ECIDbase': 1000
                    }
                }
                pkt_types = {
                    'ETAG_UDP': {
                        'dut': ['type=0x893f'],
                        'layer_configs': config_layers
                    }
                }
            elif test_type == 'etag_remove':
                # Remove E-tag, Send 802.1BR packet with broadcast mac and check packet not
                # received
                host_cmds = [['E-tag set filter del e-tag-id 1000 port 0'],
                             ['set fwd rxonly'], ['set verbose 1'], ['start']]
                config_layers = {
                    'ether': {
                        'src': self.src_mac
                    },
                    'etag': {
                        'ECIDbase': 1000
                    }
                }
                pkt_types = {
                    'ETAG_UDP': {
                        'vm': [''],
                        'dut': [''],
                        'layer_configs': config_layers
                    }
                }
            else:
                # Same E-tag forwarding to VF0, Send 802.1BR packet with broadcast mac and
                # check packet only received on VF0 or VF1
                host_cmds = [[
                    'E-tag set filter add e-tag-id 1000 dst-pool %d port 0' %
                    int(test_type[-1:])
                ], ['set fwd rxonly'], ['set verbose 1'], ['start']]
                config_layers = {
                    'ether': {
                        'src': self.src_mac
                    },
                    'etag': {
                        'ECIDbase': 1000
                    }
                }
                pkt_types = {
                    'ETAG_UDP': {
                        'vm': ['type=0x893f'],
                        'layer_configs': config_layers
                    }
                }

            self.execute_host_testpmd_cmd(host_cmds)
            self.execute_guest_testpmd_cmd(guest_cmds)
            self.check_packet_transmission(pkt_types)
        self.host_testpmd.execute_cmd('E-tag set forwarding off port 0')

    def test_etag_insertion(self):
        '''
        When E-tag insertion enable in VF0
        '''
        host_cmds = [['port config 0 l2-tunnel E-tag enable'],
                     ['E-tag set insertion on port-tag-id 1000 port 0 vf 0'],
                     ['set fwd mac'], ['set verbose 1'], ['start']]
        guest_cmds = [['set fwd mac'], ['set verbose 1'], ['start']]
        self.preset_test_enviroment()
        self.execute_host_testpmd_cmd(host_cmds)
        self.execute_guest_testpmd_cmd(guest_cmds)

        self.vm0_dut_ports = self.vm_dut_0.get_ports('any')
        config_layers = {'ether': {'src': self.src_mac}}
        pkt_types = {'IP_RAW': {'layer_configs': config_layers}}

        intf = self.src_intf
        inst = self.tester.tcpdump_sniff_packets(intf)

        self.check_packet_transmission(pkt_types)
        time.sleep(1)
        pkts = self.tester.load_tcpdump_sniff_packets(inst)
        self.host_testpmd.execute_cmd(
            'E-tag set insertion off port-tag-id 1000 port 0 vf 0')

        # load sniff pcap file, check received packet's content
        packetContentFile = "/tmp/packetContent.log"
        pcap_file = "/tmp/sniff_%s.pcap" % intf
        fp = open(packetContentFile, 'w')
        backup_out = sys.stdout
        sys.stdout = fp
        pkts = rdpcap(pcap_file)
        pkts.show()
        fp.close()
        sys.stdout = backup_out
        fp = open(packetContentFile, 'r')
        out = fp.read()
        fp.close()
        if self.printFlag:  # debug output
            print out
        self.verify("Dot1BR" in out,
                    "tester %s hasn't receiver etag packet" % intf)

    def test_etag_strip(self):
        '''
        When E-tag strip enable on PF
        '''
        host_cmds = [['port config 0 l2-tunnel E-tag enable'],
                     ['set fwd rxonly'], ['set verbose 1'], ['start']]
        guest_cmds = [['set fwd rxonly'], ['set verbose 1'], ['start']]
        config_layers = {
            'ether': {
                'src': self.src_mac
            },
            'etag': {
                'ECIDbase': 1000
            }
        }
        pkt_types_on = {
            'ETAG_UDP': {
                'vm': ['type=0x0800', 'type=0x893f'],
                'layer_configs': config_layers
            }
        }
        pkt_types_off = {
            'ETAG_UDP': {
                'vm': ['type=0x893f', 'type=0x893f'],
                'layer_configs': config_layers
            }
        }

        self.preset_test_enviroment()
        self.execute_host_testpmd_cmd(host_cmds)
        self.execute_guest_testpmd_cmd(guest_cmds)
        # Enable E-tag strip on PF, Send 802.1BR packet to VF and check forwarded packet without E-tag
        self.host_testpmd.execute_cmd('E-tag set stripping on port 0')
        self.check_packet_transmission(pkt_types_on)

        # Disable E-tag strip on PF, Send 802.1BR packet and check forwarded packet with E-tag
        self.host_testpmd.execute_cmd('E-tag set stripping off port 0')
        self.check_packet_transmission(pkt_types_off)

    def tear_down(self):
        pass

    def tear_down_all(self):
        if self.setup_vm_env_flag == 1:
            self.destroy_vm_env()

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

        for port_id in self.dut_ports:
            self.dut.destroy_sriov_vfs_by_port(port_id)

        self.tester.send_expect(
            "kill -9 $(ps aux | grep -i qemu | grep -v grep  | awk  {'print $2'})",
            '# ', 5)
Exemplo n.º 6
0
class Testddp_mpls(TestCase):
    def set_up_all(self):
        self.verify('fortville' in self.nic,
                    'ddp mpls can not support %s nic' % self.nic)
        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
        profile_file = r'dep/mpls.pkgo'
        profile_dst = "/tmp/"
        self.dut.session.copy_file_to(profile_file, profile_dst)

    def set_up(self):
        self.setup_vm_env()

    def bind_nic_driver(self, ports, driver=""):
        if driver == "igb_uio":
            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 == "":
                    driver = netdev.default_driver
                if driver != driver_now:
                    netdev.bind_driver(driver=driver)

    def setup_vm_env(self, driver='igb_uio'):
        """
        Create testing environment with VF generated from 1PF
        """
        if self.env_done == False:
            self.bind_nic_driver(self.dut_ports[:1], driver="igb_uio")
            self.used_dut_port = self.dut_ports[0]
            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']
            for port in self.sriov_vfs_port:
                port.bind_driver('pci-stub')
            time.sleep(1)
            self.dut_testpmd = PmdOutput(self.dut)
            time.sleep(1)
            vf0_prop = {'opt_host': self.sriov_vfs_port[0].pci}

            # set up VM0 ENV
            self.vm0 = QEMUKvm(self.dut, 'vm0', 'ddp_mpls')
            self.vm0.set_vm_device(driver='pci-assign', **vf0_prop)
            try:
                self.vm0_dut = self.vm0.start()
                if self.vm0_dut is None:
                    raise Exception("Set up VM0 ENV failed!")
            except Exception as e:
                self.destroy_vm_env()
                raise Exception(e)

            self.vm0_dut_ports = self.vm0_dut.get_ports('any')
            self.vm0_testpmd = PmdOutput(self.vm0_dut)
            self.env_done = True

        self.dut_testpmd.start_testpmd(
            "Default", "--port-topology=chained --txq=%s --rxq=%s" %
            (PF_MAX_QUEUE, PF_MAX_QUEUE))
        self.vm0_testpmd.start_testpmd(
            VM_CORES_MASK, "--port-topology=chained --txq=%s --rxq=%s" %
            (VF_MAX_QUEUE, VF_MAX_QUEUE))

    def destroy_vm_env(self):

        if getattr(self, 'vm0', None):
            self.vm0_dut.kill_all()
            self.vm0_testpmd = None
            self.vm0_dut_ports = None
            # destroy vm0
            self.vm0.stop()
            self.vm0 = None

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

        self.env_done = False

    def load_profile(self):
        """
        Load profile to update FVL configuration tables, profile will be
        stored in binary file and need to be passed to AQ to program FVL
        during initialization stage.
        """
        self.dut_testpmd.execute_cmd('port stop all')
        time.sleep(1)
        out = self.dut_testpmd.execute_cmd('ddp get list 0')
        self.verify("Profile number is: 0" in out,
                    "Failed to get ddp profile info list!!!")
        self.dut_testpmd.execute_cmd('ddp add 0 /tmp/mpls.pkgo,/tmp/mpls.bak')
        out = self.dut_testpmd.execute_cmd('ddp get list 0')
        self.verify("Profile number is: 1" in out,
                    "Failed to load ddp profile!!!")
        self.dut_testpmd.execute_cmd('port start all')
        time.sleep(1)

    def mpls_test(self, port='pf', pkt='udp'):
        """
        Send mpls packet to dut, receive packet from configured queue.
        Input: port type, packet type
        """
        pkts = []
        if port == 'pf':
            queue = random.randint(1, PF_MAX_QUEUE - 1)
            self.dut_testpmd.execute_cmd('set fwd rxonly')
            self.dut_testpmd.execute_cmd('set verbose 1')
            self.dut_testpmd.execute_cmd('start')
        else:
            queue = random.randint(1, VF_MAX_QUEUE - 1)
            self.vm0_testpmd.execute_cmd('set fwd rxonly')
            self.vm0_testpmd.execute_cmd('set verbose 1')
            self.vm0_testpmd.execute_cmd('start')
        random_label = random.randint(0x0, 0xFFFFF)
        label = hex(random_label)
        wrong_label = hex((random_label + 2) % int(0xFFFFF))
        self.dut_testpmd.execute_cmd('flow create 0 ingress pattern eth / ipv4\
            / %s / mpls label is %s / end actions %s / queue index %d / end' %
                                     (pkt, label, port, queue))
        for times in range(2):
            if pkt == 'udp':
                pkts = {
                    'mpls/good chksum udp':
                    'Ether()/IP()/UDP(dport=6635)\
                            /MPLS(label=%s)/Ether()/IP()/TCP()' % label,
                    'mpls/bad chksum udp':
                    'Ether()/IP()/UDP(chksum=0x1234,\
                            dport=6635)/MPLS(label=%s)/Ether()/IP()/TCP()' %
                    label
                }
            else:
                pkts = {
                    'mpls/good chksum gre':
                    'Ether()/IP(proto=47)/GRE(proto=0x8847)\
                            /MPLS(label=%s)/Ether()/IP()/UDP()' % label,
                    'mpls/bad chksum gre':
                    'Ether()/IP(proto=47)/GRE(chksum=0x1234,\
                            proto=0x8847)/MPLS(label=%s)/Ether()/IP()/UDP()' %
                    label
                }
            for packet_type in pkts.keys():
                self.tester.scapy_append('sendp([%s], iface="%s")' %
                                         (pkts[packet_type], self.tester_intf))
                self.tester.scapy_execute()
                if port == 'pf':
                    out = self.dut.get_session_output(timeout=2)
                else:
                    out = self.vm0_dut.get_session_output(timeout=2)

                self.verify("port 0/queue %d" % queue in out,
                            "Failed to receive packet in this queue!!!")
                self.verify("PKT_RX_L4_CKSUM_GOOD" in out,
                            "Failed to check CKSUM!!!")
            label = wrong_label
            queue = 0

    def test_load_ddp(self):
        """
        Load profile to update FVL configuration tables.
        """
        self.load_profile()

    def test_mpls_udp_pf(self):
        """
        MPLS is supported by NVM with profile updated. Send mpls udp packet to PF,
        check PF could receive packet using configured queue, checksum is good.
        """
        self.load_profile()
        self.mpls_test(port='pf', pkt='udp')

    def test_mpls_gre_pf(self):
        """
        MPLS is supported by NVM with profile updated. Send mpls gre packet to PF, 
        check PF could receive packet using configured queue, checksum is good.
        """
        self.load_profile()
        self.mpls_test(port='pf', pkt='gre')

    def test_mpls_udp_vf(self):
        """
        MPLS is supported by NVM with profile updated. Send mpls udp packet to VF,
        check VF could receive packet using configured queue, checksum is good.
        """
        self.load_profile()
        self.mpls_test(port='vf id 0', pkt='udp')

    def test_mpls_gre_vf(self):
        """
        MPLS is supported by NVM with profile updated. Send mpls gre packet to VF, 
        check VF could receive packet using configured queue, checksum is good.
        """
        self.load_profile()
        self.mpls_test(port='vf id 0', pkt='gre')

    def tear_down(self):
        self.vm0_testpmd.execute_cmd('stop')
        self.dut_testpmd.execute_cmd('stop')
        out = self.dut_testpmd.execute_cmd('ddp get list 0')
        if "Profile number is: 0" not in out:
            self.dut_testpmd.execute_cmd('port stop all')
            time.sleep(1)
            self.dut_testpmd.execute_cmd('ddp del 0 /tmp/mpls.bak')
            out = self.dut_testpmd.execute_cmd('ddp get list 0')
            self.verify("Profile number is: 0" in out,
                        "Failed to delete mpls profile!!!")
            self.dut_testpmd.execute_cmd('port start all')
        self.vm0_testpmd.quit()
        self.dut_testpmd.quit()

    def tear_down_all(self):
        self.destroy_vm_env()
        pass
Exemplo n.º 7
0
class TestVhostPmdXstats(TestCase):
    def set_up_all(self):
        """
        Run at the start of each test suite.
        """
        self.dut_ports = self.dut.get_ports(self.nic)
        self.unbind_ports = copy.deepcopy(self.dut_ports)
        self.unbind_ports.remove(0)
        self.dut.unbind_interfaces_linux(self.unbind_ports)
        cores = self.dut.get_core_list("1S/4C/1T")
        self.coremask = utils.create_mask(cores)

        self.scapy_num = 0
        self.dmac = self.dut.get_mac_address(self.dut_ports[0])
        self.virtio1_mac = "52:54:00:00:00:01"

        # build sample app
        out = self.dut.build_dpdk_apps("./examples/vhost")
        self.verify("Error" not in out, "compilation error 1")
        self.verify("No such file" not in out, "compilation error 2")

    def set_up(self):
        """ 
        Run before each test case.
        Launch vhost sample using default params
        """
        self.dut.send_expect("rm -rf ./vhost.out", "#")
        self.dut.send_expect("rm -rf ./vhost-net*", "#")
        self.dut.send_expect("killall vhost-switch", "#")
        self.dut.send_expect("killall qemu-system-x86_64", "#")

    def vm_testpmd_start(self):
        """
        Start testpmd in vm
        """
        self.vm_testpmd = "./%s/app/testpmd -c 0x3 -n 4 -- -i --txqflags=0xf01" % self.target
        if self.vm_dut is not None:
            self.vm_dut.send_expect(self.vm_testpmd, "testpmd>", 60)

    def vm_tx_first_start(self):
        """
        Start tx_first
        """
        if self.vm_dut is not None:
            # Start tx_first
            self.vm_dut.send_expect("set fwd mac", "testpmd>")
            self.vm_dut.send_expect("start tx_first", "testpmd>")

    def start_onevm(self):
        """
        Start One VM with one virtio device
        """
        self.vm_dut = None
        self.vm = QEMUKvm(self.dut, 'vm0', 'vhost_pmd_xstats')
        vm_params = {}
        vm_params['driver'] = 'vhost-user'
        vm_params['opt_path'] = './vhost-net'
        vm_params['opt_mac'] = self.virtio1_mac
        self.vm.set_vm_device(**vm_params)

        try:
            self.vm_dut = self.vm.start()
            if self.vm_dut is None:
                raise Exception("Set up VM ENV failed")
        except Exception as e:
            self.logger.error("Failure for %s" % str(e))
        return True

    def scapy_send_packet(self, pktsize, dmac, num=1):
        """
        Send a packet to port
        """
        self.scapy_num += 1
        txport = self.tester.get_local_port(self.dut_ports[0])
        self.txItf = self.tester.get_interface(txport)
        pkt = Packet(pkt_type='TCP', pkt_len=pktsize)
        pkt.config_layer('ether', {
            'dst': dmac,
        })
        pkt.send_pkt(tx_port=self.txItf, count=num)

    def send_verify(self, scope, mun):
        """
        according the scope to check results
        """
        out = self.dut.send_expect("show port xstats %s" % self.dut_ports[0],
                                   "testpmd>", 60)
        packet = re.search("rx_%s_packets:\s*(\d*)" % scope, out)
        sum_packet = packet.group(1)
        self.verify(
            int(sum_packet) >= mun, "Insufficient the received package")

    def prepare_start(self):
        """
        prepare all of the conditions for start
        """
        self.dut.send_expect(
            "./%s/app/testpmd -c %s -n %s --socket-mem 1024,0 --vdev 'net_vhost0,iface=vhost-net,queues=1' -- -i --nb-cores=1"
            % (self.target, self.coremask, self.dut.get_memory_channels()),
            "testpmd>", 60)
        self.start_onevm()
        self.vm_testpmd_start()
        self.dut.send_expect("set fwd mac", "testpmd>", 60)
        self.dut.send_expect("start tx_first", "testpmd>", 60)
        self.vm_tx_first_start()

    def test_based_size(self):
        """
        Verify receiving and transmitting packets correctly in the Vhsot PMD xstats
        """
        self.prepare_start()
        sizes = [64, 65, 128, 256, 513, 1025]
        scope = ''
        for pktsize in sizes:
            if pktsize == 64:
                scope = 'size_64'
            elif 65 <= pktsize <= 127:
                scope = 'size_65_to_127'
            elif 128 <= pktsize <= 255:
                scope = 'size_128_to_255'
            elif 256 <= pktsize <= 511:
                scope = 'size_256_to_511'
            elif 512 <= pktsize <= 1023:
                scope = 'size_512_to_1023'
            elif 1024 <= pktsize:
                scope = 'size_1024_to_max'

            self.scapy_send_packet(pktsize, self.dmac, 10000)
            self.send_verify(scope, 10000)
            self.clear_port_xstats(scope)

    def clear_port_xstats(self, scope):

        self.dut.send_expect("clear port xstats all", "testpmd>", 60)
        out = self.dut.send_expect("show port xstats %s" % self.dut_ports[0],
                                   "testpmd>", 60)
        packet = re.search("rx_%s_packets:\s*(\d*)" % scope, out)
        sum_packet = packet.group(1)
        self.verify(int(sum_packet) == 0, "Insufficient the received package")

    def test_based_types(self):
        """
        Verify different type of packets receiving and transmitting packets correctly in the Vhsot PMD xstats
        """
        self.prepare_start()
        types = ['ff:ff:ff:ff:ff:ff', '01:00:00:33:00:01']
        scope = ''
        for p in types:
            if p == 'ff:ff:ff:ff:ff:ff':
                scope = 'broadcast'
                self.dmac = 'ff:ff:ff:ff:ff:ff'
            elif p == '01:00:00:33:00:01':
                scope = 'multicast'
                self.dmac = '01:00:00:33:00:01'
            self.scapy_send_packet(64, self.dmac, 10000)
            self.send_verify(scope, 10000)
            self.clear_port_xstats(scope)

    def test_stability(self):
        """
        Verify stability case with multiple queues for Vhsot PMD xstats 
        Send packets for 30 minutes, check the Xstatsa still can work correctly
        """
        self.scapy_num = 0
        self.prepare_start()
        date_old = datetime.datetime.now()
        date_new = date_old + datetime.timedelta(minutes=2)
        while (1):
            date_now = datetime.datetime.now()
            self.scapy_send_packet(64, self.dmac, 1)
            if date_now >= date_new:
                break
        out_0 = self.dut.send_expect("show port xstats %s" % self.dut_ports[0],
                                     "testpmd>", 60)
        rx_packet = re.search("rx_size_64_packets:\s*(\d*)", out_0)
        rx_packets = rx_packet.group(1)
        self.verify(
            self.scapy_num == int(rx_packets),
            "Error for rx_package:%s != tx_package :%s" %
            (self.scapy_num, int(rx_packets)))

    def tear_down(self):
        """
        Run after each test case.
        """
        self.vm._stop_vm()
        self.dut.kill_all()
        time.sleep(2)

    def tear_down_all(self):
        """
        Run after each test suite.
        """
        self.dut.bind_interfaces_linux(nics_to_bind=self.unbind_ports)
Exemplo n.º 8
0
class TestVfVlan(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

        # 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.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 == "":
                    driver = netdev.default_driver
                if driver != driver_now:
                    netdev.bind_driver(driver=driver)

    def setup_vm_env(self, driver='default'):
        """
        Create testing environment with 2VFs generated from 2PFs
        """
        if self.env_done:
            return

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

        self.used_dut_port_0 = self.dut_ports[0]
        self.host_intf0 = self.dut.ports_info[self.used_dut_port_0]['intf']
        tester_port = self.tester.get_local_port(self.used_dut_port_0)
        self.tester_intf0 = self.tester.get_interface(tester_port)

        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.vf0_mac = "00:10:00:00:00:00"
        self.dut.send_expect("ip link set %s vf 0 mac %s" %
                             (self.host_intf0, self.vf0_mac), "# ")

        self.used_dut_port_1 = self.dut_ports[1]
        self.host_intf1 = self.dut.ports_info[self.used_dut_port_1]['intf']
        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']
        tester_port = self.tester.get_local_port(self.used_dut_port_1)
        self.tester_intf1 = self.tester.get_interface(tester_port)

        self.vf1_mac = "00:20:00:00:00:00"
        self.dut.send_expect("ip link set %s vf 0 mac %s" %
                             (self.host_intf1, self.vf1_mac), "# ")

        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}

            # set up VM0 ENV
            self.vm0 = QEMUKvm(self.dut, 'vm0', 'vf_vlan')
            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!")

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

        self.env_done = True

    def destroy_vm_env(self):
        if getattr(self, 'vm0', None):
            if getattr(self, 'vm_dut_0', None):
                self.vm_dut_0.kill_all()
            self.vm0_testpmd = None
            self.vm0_dut_ports = None
            # destroy vm0
            self.vm0.stop()
            self.dut.virt_exit()
            self.vm0 = None

        if getattr(self, 'used_dut_port_0', None) != None:
            self.dut.destroy_sriov_vfs_by_port(self.used_dut_port_0)
            port = self.dut.ports_info[self.used_dut_port_0]['port']
            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']
            self.used_dut_port_1 = None

        self.bind_nic_driver(self.dut_ports[:2], driver='default')

        self.env_done = False

    def test_pvid_vf_tx(self):
        """
        Add port based vlan on vf device and check vlan tx work
        """
        random_vlan = random.randint(1, MAX_VLAN)

        self.dut.send_expect(
            "ip link set %s vf 0 vlan %d" % (self.host_intf0, random_vlan), "# ")
        out = self.dut.send_expect("ip link show %s" % self.host_intf0, "# ")
        self.verify("vlan %d" %
                    random_vlan in out, "Failed to add pvid on VF0")

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

        self.vm0_testpmd = PmdOutput(self.vm_dut_0)
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK)
        self.vm0_testpmd.execute_cmd('set fwd mac')
        self.vm0_testpmd.execute_cmd('start')

        pkt = Packet(pkt_type='UDP')
        pkt.config_layer('ether', {'dst': self.vf1_mac})
        inst = sniff_packets(self.tester_intf0, timeout=5)
        pkt.send_pkt(tx_port=self.tester_intf1)
        pkts = load_sniff_packets(inst)

        self.verify(len(pkts), "Not receive expected packet")
        self.vm0_testpmd.quit()

        # disable pvid
        self.dut.send_expect(
            "ip link set %s vf 0 vlan 0" % (self.host_intf0), "# ")

    def send_and_getout(self, vlan=0, pkt_type="UDP"):

        if pkt_type == "UDP":
            pkt = Packet(pkt_type='UDP')
            pkt.config_layer('ether', {'dst': self.vf0_mac})
        elif pkt_type == "VLAN_UDP":
            pkt = Packet(pkt_type='VLAN_UDP')
            pkt.config_layer('vlan', {'vlan': vlan})
            pkt.config_layer('ether', {'dst': self.vf0_mac})

        pkt.send_pkt(tx_port=self.tester_intf0)
        out = self.vm_dut_0.get_session_output(timeout=2)

        return out

    def test_add_pvid_vf(self):
        random_vlan = random.randint(1, MAX_VLAN)

        self.dut.send_expect(
            "ip link set %s vf 0 vlan %d" % (self.host_intf0, random_vlan), "# ")
        out = self.dut.send_expect("ip link show %s" % self.host_intf0, "# ")
        self.verify("vlan %d" %
                    random_vlan in out, "Failed to add pvid on VF0")

        # start testpmd in VM
        self.vm0_dut_ports = self.vm_dut_0.get_ports('any')

        self.vm0_testpmd = PmdOutput(self.vm_dut_0)
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK)
        self.vm0_testpmd.execute_cmd('set fwd rxonly')
        self.vm0_testpmd.execute_cmd('set verbose 1')
        self.vm0_testpmd.execute_cmd('start')

        out = self.send_and_getout(vlan=random_vlan, pkt_type="VLAN_UDP")
        self.verify("received" in out, "Failed to received vlan packet!!!")

        # send packet without vlan
        out = self.send_and_getout(pkt_type="UDP")
        self.verify("received" not in out, "Received packet without vlan!!!")

        # send packet with vlan not matched
        wrong_vlan = (random_vlan + 1) % 4096
        out = self.send_and_getout(vlan=wrong_vlan, pkt_type="VLAN_UDP")
        self.verify(
            "received" not in out, "Received pacekt with wrong vlan!!!")

        # remove vlan
        self.dut.send_expect(
            "ip link set %s vf 0 vlan 0" % self.host_intf0, "# ")

        # send packet with vlan
        out = self.send_and_getout(vlan=random_vlan, pkt_type="VLAN_UDP")
        if self.kdriver == "i40e":
            self.verify("received" in out, "Failed to received vlan packet!!!")
        else:
            self.verify(
                "received" not in out, "Received vlan packet without pvid!!!")

        # send packe with vlan 0
        out = self.send_and_getout(vlan=0, pkt_type="VLAN_UDP")
        self.verify(
            "received" in out, "Not recevied packet with vlan 0!!!")

        # send packet without vlan
        out = self.send_and_getout(vlan=0, pkt_type="UDP")
        self.verify("received" in out, "Not received packet without vlan!!!")

        self.vm0_testpmd.quit()

        # disable pvid
        self.dut.send_expect(
            "ip link set %s vf 0 vlan 0" % (self.host_intf0), "# ")

    def tx_and_check(self, tx_vlan=1):
        inst = sniff_packets(self.tester_intf0, timeout=5)
        self.vm0_testpmd.execute_cmd('set burst 1')
        self.vm0_testpmd.execute_cmd('start tx_first')
        self.vm0_testpmd.execute_cmd('stop')

        # strip sniffered vlans
        pkts = load_sniff_packets(inst)
        vlans = []
        for pkt in pkts:
            vlan = pkt.strip_element_vlan("vlan")
            vlans.append(vlan)

        self.verify(
            tx_vlan in vlans, "Tx packet with vlan not received!!!")

    def test_vf_vlan_tx(self):
        self.verify(self.kdriver not in ["ixgbe"], "NIC Unsupported: " + str(self.nic))
        random_vlan = random.randint(1, MAX_VLAN)
        tx_vlans = [1, random_vlan, MAX_VLAN]
        # start testpmd in VM
        self.vm0_dut_ports = self.vm_dut_0.get_ports('any')

        self.vm0_testpmd = PmdOutput(self.vm_dut_0)
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK)
        self.vm0_testpmd.execute_cmd('set verbose 1')

        for tx_vlan in tx_vlans:
            # for fortville ,
            # if you want insert tx_vlan,
            # please enable rx_vlan at the same time
            if self.kdriver == "i40e":
                self.vm0_testpmd.execute_cmd('rx_vlan add %d 0' % tx_vlan)
            self.vm0_testpmd.execute_cmd('tx_vlan set 0 %d' % tx_vlan)
            self.tx_and_check(tx_vlan=tx_vlan)

        self.vm0_testpmd.quit()

    def test_vf_vlan_rx(self):
        random_vlan = random.randint(1, MAX_VLAN - 1)
        rx_vlans = [1, random_vlan, MAX_VLAN]
        # start testpmd in VM
        self.vm0_dut_ports = self.vm_dut_0.get_ports('any')

        self.vm0_testpmd = PmdOutput(self.vm_dut_0)
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK)
        self.vm0_testpmd.execute_cmd('set fwd rxonly')
        self.vm0_testpmd.execute_cmd('set verbose 1')
        self.vm0_testpmd.execute_cmd('vlan set strip on 0')
        self.vm0_testpmd.execute_cmd('vlan set filter on 0')
        self.vm0_testpmd.execute_cmd("set promisc all off")
        self.vm0_testpmd.execute_cmd('start')

        # send packet without vlan
        out = self.send_and_getout(vlan=0, pkt_type="UDP")
        self.verify(
            "received 1 packets" in out, "Not received normal packet as default!!!")

        # send packet with vlan 0
        out = self.send_and_getout(vlan=0, pkt_type="VLAN_UDP")
        self.verify("VLAN tci=0x0"
                    in out, "Not received vlan 0 packet as default!!!")

        for rx_vlan in rx_vlans:
            self.vm0_testpmd.execute_cmd('rx_vlan add %d 0' % rx_vlan)
            time.sleep(1)
            # send packet with same vlan
            out = self.send_and_getout(vlan=rx_vlan, pkt_type="VLAN_UDP")
            vlan_hex = hex(rx_vlan)
            self.verify("VLAN tci=%s" %
                        vlan_hex in out, "Not received expected vlan packet!!!")

            pkt = Packet(pkt_type='VLAN_UDP')
            if rx_vlan == MAX_VLAN:
                continue
            wrong_vlan = (rx_vlan + 1) % 4096

            # send packet with wrong vlan
            out = self.send_and_getout(vlan=wrong_vlan, pkt_type="VLAN_UDP")
            self.verify(
                "received 1 packets" not in out, "Received filtered vlan packet!!!")

        for rx_vlan in rx_vlans:
            self.vm0_testpmd.execute_cmd('rx_vlan rm %d 0' % rx_vlan)

        # send packet with vlan 0
        out = self.send_and_getout(vlan=0, pkt_type="VLAN_UDP")
        self.verify("VLAN tci=0x0"
                    in out, "Not received vlan 0 packet as default!!!")

        # send packet without vlan
        out = self.send_and_getout(pkt_type="UDP")
        self.verify("received 1 packets" in out,
                    "Not received normal packet after remove vlan filter!!!")

        # send packet with vlan
        out = self.send_and_getout(vlan=random_vlan, pkt_type="VLAN_UDP")
        if self.kdriver == "i40e":
            self.verify(
                "received 1 packets" in out, "Received mismatched vlan packet while vlan filter on")
        else:
            self.verify(
                "received 1 packets" not in out, "Received mismatched vlan packet while vlan filter on")

        self.vm0_testpmd.quit()

    def test_vf_vlan_strip(self):
        random_vlan = random.randint(1, MAX_VLAN - 1)
        rx_vlans = [1, random_vlan, MAX_VLAN]
        # start testpmd in VM
        self.vm0_dut_ports = self.vm_dut_0.get_ports('any')

        self.vm0_testpmd = PmdOutput(self.vm_dut_0)
        if self.kdriver == "i40e":
            self.vm0_testpmd.start_testpmd(VM_CORES_MASK, '')
        else:
            self.vm0_testpmd.start_testpmd(VM_CORES_MASK)
        self.vm0_testpmd.execute_cmd('set fwd rxonly')
        self.vm0_testpmd.execute_cmd('set verbose 1')
        self.vm0_testpmd.execute_cmd('start')

        for rx_vlan in rx_vlans:
            self.vm0_testpmd.execute_cmd('vlan set strip on 0')
            self.vm0_testpmd.execute_cmd('rx_vlan add %d 0' % rx_vlan)
            time.sleep(1)
            out = self.send_and_getout(vlan=rx_vlan, pkt_type="VLAN_UDP")
            # enable strip, vlan will be in mbuf
            vlan_hex = hex(rx_vlan)
            self.verify("VLAN tci=%s" %
                        vlan_hex in out, "Failed to strip vlan packet!!!")
            self.verify("PKT_RX_VLAN_STRIPPED" in out, "Failed to strip vlan packet!")

            self.vm0_testpmd.execute_cmd('vlan set strip off 0')

            out = self.send_and_getout(vlan=rx_vlan, pkt_type="VLAN_UDP")
            self.verify(
                "received 1 packets" in out, "Not received vlan packet as expected!!!")
            self.verify(
                "PKT_RX_VLAN_STRIPPED" not in out, "Failed to disable strip vlan!!!")

        self.vm0_testpmd.quit()

    def tear_down(self):
        self.destroy_vm_env()

    def tear_down_all(self):
        self.destroy_vm_env()
        pass
Exemplo n.º 9
0
class TestVfKernel(TestCase):
    def set_up_all(self):
        """
        Run at the start of each test suite.
        """
        self.dut.send_expect("service network-manager stop", "#", 60)
        self.dut_ports = self.dut.get_ports(self.nic)
        self.verify(len(self.dut_ports) >= 1, "Insufficient ports")
        self.cores = self.dut.get_core_list("1S/4C/1T")
        self.coremask = utils.create_mask(self.cores)

        self.dmac = self.dut.get_mac_address(self.dut_ports[0])
        txport = self.tester.get_local_port(self.dut_ports[0])
        self.tester_intf = self.tester.get_interface(txport)
        self.tester_mac = self.tester.get_mac(txport)

        self.intf = self.dut.ports_info[self.dut_ports[0]]['intf']
        self.pci = self.dut.ports_info[self.dut_ports[0]]['pci'].split(':')

        self.src_logo = '12:34:56:78:90:10'
        self.setup_vm_env()

    def set_up(self):
        """
        Run before each test case.
        """
        self.verify(self.check_pf_vf_link_status(self.vm0_dut, self.vm0_intf0),
                    "vf link down")
        pass

    def generate_pcap_pkt(self, macs, pktname='flow.pcap'):
        """
        generate pcap pkt
        """
        pkts = ''
        for mac in macs:
            pkt = "Ether(dst='%s',src='%s')/IP()/Raw(load='X'*18)," % (
                mac, self.src_logo)
            pkts += pkt
        self.tester.send_expect("rm -rf flow.pcap", "#", 10)
        self.tester.scapy_append('wrpcap("flow.pcap", [%s])' % pkts)
        self.tester.scapy_execute()

    def setup_vm_env(self):
        """
        1pf -> 6vfs , 4vf->vm0, 2vf->vm1
        """
        self.used_dut_port = self.dut_ports[0]
        self.dut.generate_sriov_vfs_by_port(self.used_dut_port,
                                            6,
                                            driver='igb_uio')
        self.sriov_vfs_port = self.dut.ports_info[
            self.used_dut_port]['vfs_port']
        for port in self.sriov_vfs_port:
            port.bind_driver('pci-stub')
        time.sleep(1)

        self.dut_testpmd = PmdOutput(self.dut)
        self.dut_testpmd.start_testpmd(
            "Default", "--rxq=4 --txq=4 --port-topology=chained")
        # dpdk-2208
        # since there is no forward engine on DPDK PF to forward or drop packet in packet pool,
        # so finally the pool will be full, then no more packet will be
        # received by VF
        self.dut_testpmd.execute_cmd("start")
        time.sleep(5)

        vf0_prop_1 = {'opt_host': self.sriov_vfs_port[0].pci}
        vf0_prop_2 = {'opt_host': self.sriov_vfs_port[1].pci}
        vf0_prop_3 = {'opt_host': self.sriov_vfs_port[2].pci}
        vf0_prop_4 = {'opt_host': self.sriov_vfs_port[3].pci}

        self.vm0 = QEMUKvm(self.dut, 'vm0', 'vf_kernel')
        self.vm0.set_vm_device(driver='pci-assign', **vf0_prop_1)
        self.vm0.set_vm_device(driver='pci-assign', **vf0_prop_2)
        self.vm0.set_vm_device(driver='pci-assign', **vf0_prop_3)
        self.vm0.set_vm_device(driver='pci-assign', **vf0_prop_4)
        try:
            self.vm0_dut = self.vm0.start()
            if self.vm0_dut is None:
                raise Exception("Set up VM ENV failed")
            else:
                self.verify(self.vm0_dut.ports_info[0]['intf'] != 'N/A',
                            "Not interface")
        except Exception as e:
            self.destroy_vm_env()
            self.logger.error("Failure for %s" % str(e))

        vf1_prop_5 = {'opt_host': self.sriov_vfs_port[4].pci}
        vf1_prop_6 = {'opt_host': self.sriov_vfs_port[5].pci}
        self.vm1 = QEMUKvm(self.dut, 'vm1', 'vf_kernel')
        self.vm1.set_vm_device(driver='pci-assign', **vf1_prop_5)
        self.vm1.set_vm_device(driver='pci-assign', **vf1_prop_6)

        try:
            self.vm1_dut = self.vm1.start()
            if self.vm1_dut is None:
                raise Exception("Set up VM1 ENV failed!")
            else:
                # fortville: PF not up ,vf will not get interface
                self.verify(self.vm1_dut.ports_info[0]['intf'] != 'N/A',
                            "Not interface")
        except Exception as e:
            self.destroy_vm_env()
            raise Exception(e)

        self.vm0_testpmd = PmdOutput(self.vm0_dut)
        self.vm1_testpmd = PmdOutput(self.vm1_dut)

        self.vm0_vf0_mac = self.vm0_dut.get_mac_address(0)
        self.vm0_vf1_mac = self.vm0_dut.get_mac_address(1)
        self.vm0_vf2_mac = self.vm0_dut.get_mac_address(2)
        self.vm0_vf3_mac = self.vm0_dut.get_mac_address(3)

        self.vm1_vf0_mac = self.vm1_dut.get_mac_address(0)
        self.vm1_vf1_mac = self.vm1_dut.get_mac_address(1)

        self.vm0_intf0 = self.vm0_dut.ports_info[0]['intf']
        self.vm0_intf1 = self.vm0_dut.ports_info[1]['intf']

        self.vm1_intf0 = self.vm1_dut.ports_info[0]['intf']

        self.vm0_dut.restore_interfaces_linux()
        self.vm1_dut.restore_interfaces_linux()

        # stop NetworkManager, this if for centos7
        # you may change it when the os no support
        self.vm0_dut.send_expect("systemctl stop NetworkManager", "# ", 60)
        self.vm1_dut.send_expect("systemctl stop NetworkManager", "# ", 60)

    def destroy_vm_env(self):
        """
        destroy vm environment
        """
        if getattr(self, 'vm0', None):
            self.vm0_dut.kill_all()
            self.vm0_dut_ports = None
            # destroy vm0
            self.vm0.stop()
            self.vm0 = None

        if getattr(self, 'vm1', None):
            self.vm1_dut.kill_all()
            self.vm1_dut_ports = None
            # destroy vm1
            self.vm1.stop()
            self.vm1 = None

        self.dut.virt_exit()

        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']
            self.used_dut_port = None

    def test_link(self):
        """
        verify the link state
        """
        for i in range(5):
            # pf up + vf up -> vf up
            self.vm0_dut.send_expect("ifconfig %s up" % self.vm0_intf0, "#")
            out = self.vm0_dut.send_expect("ethtool %s" % self.vm0_intf0, "#")
            self.verify("Link detected: yes" in out, "Wrong link status")
            time.sleep(3)

            # pf up + vf down -> vf down
            self.vm0_dut.send_expect("ifconfig %s down" % self.vm0_intf0, "#")
            out = self.vm0_dut.send_expect("ethtool %s" % self.vm0_intf0, "#")
            self.verify("Link detected: no" in out, "Wrong link status")
            time.sleep(3)

    def ping4(self, session, intf, ipv4):
        """
        using seesion , ping -I $intf $ip
        sometimes it failed, so we try 5 times.
        """
        for i in range(5):
            out = session.send_expect(
                "ping -w 5 -c 5 -A -I %s %s" % (intf, ipv4), "# ")
            if '64 bytes from' not in out:
                print GREEN("%s ping %s failed, retry" % (intf, ipv4))
            else:
                return True
        return False

    def test_ping(self):
        """
        verify the ping state
        """
        for i in range(5):
            random_ip = random.randint(2, 249)
            vm0_ip0 = "5.5.5.%d" % random_ip
            vm0_ip1 = "5.5.5.%d" % (random_ip + 1)
            pf_ip = "5.5.5.%d" % (random_ip + 2)

            # down-up link
            for port_info in self.vm0_dut.ports_info:
                vm0_intf = port_info['intf']
                self.verify(
                    self.check_pf_vf_link_status(self.vm0_dut, vm0_intf),
                    "VM0_vf: %s link down" % vm0_intf)

            self.vm0_dut.send_expect(
                "ifconfig %s %s netmask 255.255.255.0" %
                (self.vm0_intf0, vm0_ip0), "#")
            self.vm0_dut.send_expect(
                "ifconfig %s %s netmask 255.255.255.0" %
                (self.vm0_intf1, vm0_ip1), "#")
            self.tester.send_expect(
                "ifconfig %s %s netmask 255.255.255.0" %
                (self.tester_intf, pf_ip), "#")

            # pf ping vm0_vf0
            self.verify(self.ping4(self.tester, self.tester_intf, vm0_ip0),
                        "%s ping %s failed" % (self.tester_intf, vm0_ip0))
            # vm0_vf0 ping pf
            self.verify(self.ping4(self.vm0_dut, self.vm0_intf0, pf_ip),
                        "%s ping %s failed" % (self.vm0_intf0, pf_ip))

            # pf ping vm0_vf1
            self.verify(self.ping4(self.tester, self.tester_intf, vm0_ip1),
                        "%s ping %s failed" % (self.tester_intf, vm0_ip1))
            # vm0_pf1 ping pf
            self.verify(self.ping4(self.vm0_dut, self.vm0_intf1, pf_ip),
                        "%s ping %s failed" % (self.vm0_intf1, pf_ip))

            # clear ip
            self.vm0_dut.send_expect("ifconfig %s 0.0.0.0" % self.vm0_intf0,
                                     "#")
            self.vm0_dut.send_expect("ifconfig %s 0.0.0.0" % self.vm0_intf1,
                                     "#")
            self.tester.send_expect("ifconfig %s 0.0.0.0" % self.tester_intf,
                                    "#")

    def test_reset(self):
        """
        verify reset the vf1 impact on VF0
        """
        self.verify(self.check_pf_vf_link_status(self.vm0_dut, self.vm0_intf0),
                    "VM0_VF0 link up failed")
        self.verify(self.check_pf_vf_link_status(self.vm1_dut, self.vm1_intf0),
                    "VM1_VF0 link up failed")

        # Link down VF1 in VM1 and check no impact on VF0 status
        self.vm1_dut.send_expect("ifconfig %s down" % self.vm1_intf0, "#")
        out = self.vm0_dut.send_expect("ethtool %s" % self.vm0_intf0, "#")
        self.verify("Link detected: yes" in out, "Wrong link status")

        # Unload VF1 kernel driver and expect no problem for VF0
        self.vm1_dut.send_expect("rmmod %svf" % self.kdriver, "#")
        out = self.vm0_dut.send_expect("ethtool %s" % self.vm0_intf0, "#")
        self.verify("Link detected: yes" in out, "Wrong link status")
        vm0_vf0_mac = self.vm0_dut.ports_info[0]['port'].get_mac_addr()
        self.verify(
            self.verify_vm_tcpdump(self.vm0_dut, self.vm0_intf0, vm0_vf0_mac),
            "Unload VF1 kernel driver impact VF0")

        self.verify(self.check_pf_vf_link_status(self.vm0_dut, self.vm0_intf0),
                    "vm0_vf0 link down")

        time.sleep(10)
        vm0_vf0_mac = self.vm0_dut.ports_info[0]['port'].get_mac_addr()
        self.verify(
            self.verify_vm_tcpdump(self.vm0_dut, self.vm0_intf0, vm0_vf0_mac),
            "reset PF testpmd impact VF RX failure")

        self.vm1_dut.send_expect("modprobe %svf" % self.kdriver, "#")
        out = self.vm0_dut.send_expect("ethtool %s" % self.vm0_intf0, "#")
        self.verify("Link detected: yes" in out, "Wrong link status")
        vm0_vf0_mac = self.vm0_dut.ports_info[0]['port'].get_mac_addr()
        self.verify(
            self.verify_vm_tcpdump(self.vm0_dut, self.vm0_intf0, vm0_vf0_mac),
            "load VF1 kernel driver impact VF0")

        self.vm1_dut.send_expect("rmmod %svf" % self.kdriver, "#")
        out = self.vm0_dut.send_expect("ethtool %s" % self.vm0_intf0, "#")
        self.verify("Link detected: yes" in out, "Wrong link status")
        vm0_vf0_mac = self.vm0_dut.ports_info[0]['port'].get_mac_addr()
        self.verify(
            self.verify_vm_tcpdump(self.vm0_dut, self.vm0_intf0, vm0_vf0_mac),
            "Reset VF1 kernel driver impact VF0")
        self.vm1_dut.send_expect("modprobe %svf" % self.kdriver, "#")

    def test_address(self):
        """
        verify add/delete IP/MAC address
        """
        # ipv4 test:
        random_ip = random.randint(2, 249)
        vm0_ip0 = "5.5.5.%d" % random_ip
        pf_ip = "5.5.5.%d" % (random_ip + 2)
        self.vm0_dut.send_expect(
            "ifconfig %s %s netmask 255.255.255.0" % (self.vm0_intf0, vm0_ip0),
            "#")
        self.tester.send_expect(
            "ifconfig %s %s netmask 255.255.255.0" % (self.tester_intf, pf_ip),
            "#")

        # pf ping vm0_vf0
        self.verify(self.ping4(self.tester, self.tester_intf, vm0_ip0),
                    "%s ping %s failed" % (self.tester_intf, vm0_ip0))
        # vm0_vf0 ping pf
        self.verify(self.ping4(self.vm0_dut, self.vm0_intf0, pf_ip),
                    "%s ping %s failed" % (self.vm0_intf0, pf_ip))
        # clear ip
        self.vm0_dut.send_expect("ifconfig %s 0.0.0.0" % self.vm0_intf0, "#")
        self.tester.send_expect("ifconfig %s 0.0.0.0" % self.tester_intf, "#")

        # ipv6 test:
        add_ipv6 = 'efdd::9fc8:6a6d:c232:f1c0'
        self.vm0_dut.send_expect(
            "ifconfig %s add %s" % (self.vm0_intf0, add_ipv6), "#")
        out = self.vm0_dut.send_expect("ifconfig %s " % self.vm0_intf0, "#",
                                       10)
        self.verify(add_ipv6 in out, "Failed to add ipv6 address")
        self.vm0_dut.send_expect(
            "ifconfig %s del %s" % (self.vm0_intf0, add_ipv6), "#")
        out = self.vm0_dut.send_expect("ifconfig %s " % self.vm0_intf0, "#",
                                       10)
        self.verify(add_ipv6 not in out, "Failed to del ipv6 address")

        # mac test:
        modify_mac = 'aa:bb:cc:dd:ee:ff'
        self.vm0_dut.send_expect(
            "ifconfig %s hw ether %s" % (self.vm0_intf0, modify_mac), "#")
        out = self.vm0_dut.send_expect("ifconfig %s " % self.vm0_intf0, "#",
                                       10)
        self.verify(modify_mac in out, "Failed to add mac address")
        time.sleep(5)
        self.verify(
            self.verify_vm_tcpdump(self.vm0_dut, self.vm0_intf0, modify_mac),
            "modify mac address can't received packet")

    def verify_vm_tcpdump(self,
                          vm_dut,
                          intf,
                          mac,
                          pkt_lens=64,
                          num=1,
                          vlan_id='',
                          param=''):
        vm_dut.send_expect(
            "tcpdump -i %s %s -e ether src %s" %
            (intf, param, self.tester_mac), "tcpdump", 10)
        self.send_packet(mac, pkt_lens, num, vlan_id)
        out = vm_dut.get_session_output(timeout=10)
        vm_dut.send_expect("^C", "#", 10)
        if self.tester_mac in out:
            return True
        else:
            return False

    def send_packet(self, mac, pkt_lens=64, num=1, vlan_id=''):
        if vlan_id == '':
            pkt = Packet(pkt_type='TCP', pkt_len=pkt_lens)
            pkt.config_layer('ether', {'dst': mac, 'src': self.tester_mac})
            pkt.send_pkt(tx_port=self.tester_intf, count=num)
        else:
            pkt = Packet(pkt_type='VLAN_UDP', pkt_len=pkt_lens)
            pkt.config_layer('ether', {'dst': mac, 'src': self.tester_mac})
            pkt.config_layer('vlan', {'vlan': vlan_id})
            pkt.send_pkt(tx_port=self.tester_intf, count=num)

    def test_vlan(self):
        """
        verify add/delete vlan
        """
        vlan_ids = random.randint(1, 4095)
        self.vm0_dut.send_expect("ifconfig %s up" % self.vm0_intf0, "#")
        vm0_vf0_mac = self.vm0_dut.ports_info[0]['port'].get_mac_addr()

        self.vm0_dut.send_expect("modprobe 8021q", "#")
        out = self.vm0_dut.send_expect("lsmod |grep 8021q", "#")
        self.verify("8021q" in out, "modprobe 8021q failure")

        # Add random vlan id(0~4095) on kernel VF0
        self.vm0_dut.send_expect(
            "vconfig add %s %s" % (self.vm0_intf0, vlan_ids), "#")
        out = self.vm0_dut.send_expect("ls /proc/net/vlan/ ", "#")
        self.verify("%s.%s" % (self.vm0_intf0, vlan_ids) in out,
                    "take vlan id failure")

        # Send packet from tester to VF MAC with not-matching vlan id, check
        # the packet can't be received at the vlan device
        wrong_vlan = vlan_ids % 4095 + 1

        self.verify(
            self.verify_vm_tcpdump(self.vm0_dut,
                                   self.vm0_intf0,
                                   vm0_vf0_mac,
                                   vlan_id='%d' % wrong_vlan) == False,
            "received wrong vlan packet")

        # Send packet from tester to VF MAC with matching vlan id, check the packet can be received at the vlan device.
        # check_result = self.verify_vm_tcpdump(self.vm0_dut, self.vm0_intf0, self.vm0_vf0_mac, vlan_id='%d' %vlan_ids)
        check_result = self.verify_vm_tcpdump(self.vm0_dut,
                                              self.vm0_intf0,
                                              vm0_vf0_mac,
                                              vlan_id='%d' % vlan_ids)
        self.verify(check_result,
                    "can't received vlan_id=%d packet" % vlan_ids)

        # Delete configured vlan device
        self.vm0_dut.send_expect(
            "vconfig rem %s.%s" % (self.vm0_intf0, vlan_ids), "#")
        out = self.vm0_dut.send_expect("ls /proc/net/vlan/ ", "#")
        self.verify("%s.%s" % (self.vm0_intf0, vlan_ids) not in out,
                    "vlan error")
        # behavior is diffrent bettwn niantic and fortville ,because of kernel
        # driver
        if self.nic.startswith('fortville'):
            self.verify(
                self.verify_vm_tcpdump(self.vm0_dut,
                                       self.vm0_intf0,
                                       vm0_vf0_mac,
                                       vlan_id='%d' % vlan_ids) == True,
                "delete vlan error")
        else:
            self.verify(
                self.verify_vm_tcpdump(self.vm0_dut,
                                       self.vm0_intf0,
                                       vm0_vf0_mac,
                                       vlan_id='%d' % vlan_ids) == False,
                "delete vlan error")

    def test_packet_statistic(self):
        """
        verify packet statistic
        """
        time.sleep(10)
        out = self.vm0_dut.send_expect("ethtool -S %s" % self.vm0_intf0, "#")
        rx_packets_before = re.findall("\s*rx.*packets:\s*(\d*)", out)
        nb_rx_pkts_before = 0
        for i in range(len(rx_packets_before)):
            nb_rx_pkts_before += int(rx_packets_before[i])

        vm0_vf0_mac = self.vm0_dut.ports_info[0]['port'].get_mac_addr()
        self.verify(
            self.verify_vm_tcpdump(self.vm0_dut,
                                   self.vm0_intf0,
                                   vm0_vf0_mac,
                                   num=10), "VM reveive packet failed")

        out = self.vm0_dut.send_expect("ethtool -S %s" % self.vm0_intf0, "#")
        rx_packets_after = re.findall("\s*rx.*packets:\s*(\d*)", out)
        nb_rx_pkts_after = 0
        for i in range(len(rx_packets_after)):
            nb_rx_pkts_after += int(rx_packets_after[i])

        self.verify(nb_rx_pkts_after == 10 + nb_rx_pkts_before,
                    "rx_packets calculate error")

    def check_pf_vf_link_status(self, session, intf):
        """
        sometimes pf/vf will up abnormal, retry 5 times
        """
        for i in range(5):
            # down-up get new mac form pf.
            # because  dpdk pf will give an random mac when dpdk pf restart.
            session.send_expect("ifconfig %s down" % intf, "#")
            out = session.send_expect("ifconfig %s up" % intf, "#")
            # SIOCSIFFLAGS: Network is down
            # i think the pf link abnormal
            if "Network is down" in out:
                print GREEN(out)
                print GREEN("Try again")
                self.vm0_dut.restore_interfaces_linux()
            else:
                out = session.send_expect("ethtool %s" % intf, "#")
                if "Link detected: yes" in out:
                    return True
            time.sleep(1)
        return False

    def test_mtu(self):
        """
        verify mtu change
        HW limitation on 82599, need add '--max-pkt-len=<length>' on testpmd to set mtu value, 
        all the VFs and PF share same MTU, the largest one take effect.
        """
        vm0_intf0 = self.vm0_dut.ports_info[0]['intf']
        vm0_intf1 = self.vm0_dut.ports_info[1]['intf']
        self.vm0_dut.send_expect("ifconfig %s up" % self.vm0_intf0, "#")
        out = self.vm0_dut.send_expect("ifconfig %s" % self.vm0_intf0, "#")
        self.verify('mtu 1500' in out, "modify MTU failed")
        self.tester.send_expect("ifconfig %s mtu 3000" % self.tester_intf, "#")

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

        # Send one packet with length as 2000 with DPDK PF MAC as DEST MAC,
        # check that DPDK PF can't receive packet
        self.send_packet(self.dmac, pkt_lens=2000)
        out = self.dut.get_session_output(timeout=10)
        self.verify(self.dmac.upper() not in out, "PF receive error packet")

        # send one packet with length as 2000 with kernel VF MAC as DEST MAC,
        # check that Kernel VF can't receive packet
        vm0_vf0_mac = self.vm0_dut.ports_info[0]['port'].get_mac_addr()
        self.verify(
            self.verify_vm_tcpdump(self.vm0_dut,
                                   self.vm0_intf0,
                                   vm0_vf0_mac,
                                   pkt_lens=2000) == False,
            "kernel VF receive error packet")

        # Change DPDK PF mtu as 3000,check no confusion/crash on kernel VF
        self.dut_testpmd.execute_cmd('stop')
        self.dut_testpmd.execute_cmd('port stop all')
        self.dut_testpmd.execute_cmd('port config mtu 0 3000')
        self.dut_testpmd.execute_cmd('port start all')

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

        # sleep 5s to wait vf up , because of pf down-up
        self.verify(self.check_pf_vf_link_status(self.vm0_dut, self.vm0_intf0),
                    "VM0_VF0 link down")

        # clear output
        self.dut.get_session_output(timeout=10)

        # send one packet with length as 2000 with DPDK PF MAC as DEST MAC ,
        # check that DPDK PF can receive packet
        self.send_packet(self.dmac, pkt_lens=2000)
        out = self.dut.get_session_output(timeout=10)
        self.verify(self.dmac.upper() in out, "PF can't receive packet")

        # Change kernel VF mtu as 3000,check no confusion/crash on DPDK PF
        if self.nic.startswith('fortville'):
            self.vm0_dut.send_expect("ifconfig %s mtu 3000" % self.vm0_intf0,
                                     "#")

        # send one packet with length as 2000 with kernel VF MAC as DEST MAC,
        # check Kernel VF can receive packet
        vm0_vf0_mac = self.vm0_dut.ports_info[0]['port'].get_mac_addr()
        self.verify(
            self.verify_vm_tcpdump(self.vm0_dut,
                                   self.vm0_intf0,
                                   vm0_vf0_mac,
                                   pkt_lens=2000), "VF can't receive packet")

        self.dut_testpmd.execute_cmd('stop')
        self.dut_testpmd.execute_cmd('port stop all')
        self.dut_testpmd.execute_cmd('port config mtu 0 1500')
        self.dut_testpmd.execute_cmd('port start all')

        self.dut_testpmd.execute_cmd('start')

        self.vm0_dut.send_expect("ifconfig %s mtu 1500" % self.vm0_intf0, "#",
                                 10)

    def test_promisc_mode(self):
        """
        verify Enable/disable promisc mode
        """
        self.verify(self.nic not in ["niantic"],
                    "%s NIC not support" % self.nic)
        wrong_mac = '01:02:03:04:05:06'
        # Set up kernel VF tcpdump with -p parameter, which means disable promisc
        # Start DPDK PF, enable promisc mode, set rxonly forwarding
        self.dut_testpmd.execute_cmd('stop')
        self.dut_testpmd.execute_cmd('set promisc all on')
        self.dut_testpmd.execute_cmd('start')
        self.verify(self.check_pf_vf_link_status(self.vm0_dut, self.vm0_intf0),
                    "VM0_VF0 link down")
        self.dut.get_session_output()

        # Send packet from tester to VF with correct DST MAC, check the packet
        # can be received by kernel VF
        vm0_vf0_mac = self.vm0_dut.ports_info[0]['port'].get_mac_addr()
        self.verify(
            self.verify_vm_tcpdump(self.vm0_dut, self.vm0_intf0, vm0_vf0_mac),
            "VM reveive packet failed")
        # Send packet from tester to PF with correct DST MAC, check the packet
        # can be received by DPDK PF
        self.send_packet(self.dmac)
        out = self.dut.get_session_output()
        self.verify(self.tester_mac.upper() in out, "PF reveive packet failed")

        # Send packet from tester with random DST MAC, check the packet can be
        # received by DPDK PF and kernel VF
        self.verify(
            self.verify_vm_tcpdump(self.vm0_dut, self.vm0_intf0, wrong_mac),
            "VM reveive misc packet failed")
        self.send_packet(wrong_mac)
        out = self.dut.get_session_output()
        self.verify(self.tester_mac.upper() in out,
                    "PF reveive misc packet failed")

        # Send packet from tester to VF with correct DST MAC, check the packet
        # can be received by kernel VF
        vm0_vf0_mac = self.vm0_dut.ports_info[0]['port'].get_mac_addr()
        self.verify(
            self.verify_vm_tcpdump(self.vm0_dut, self.vm0_intf0, vm0_vf0_mac),
            "VM reveive packet failed")
        # Send packet from tester to PF with correct DST MAC, check the packet
        # can be received by DPDK PF
        self.send_packet(self.dmac)
        out = self.dut.get_session_output()
        self.verify(self.tester_mac.upper() in out, "PF reveive packet failed")

        # Disable DPDK PF promisc mode
        self.dut_testpmd.execute_cmd('stop')
        self.dut_testpmd.execute_cmd('set promisc all off')
        self.dut_testpmd.execute_cmd('set fwd rxonly')
        self.dut_testpmd.execute_cmd('set verbose 1')
        self.dut_testpmd.execute_cmd('start')
        self.dut.get_session_output()

        # Set up kernel VF tcpdump with -p parameter, which means disable promisc mode
        # Send packet from tester with random DST MAC, check the packet can't
        # be received by DPDK PF and kernel VF
        self.verify(
            self.verify_vm_tcpdump(self.vm0_dut,
                                   self.vm0_intf0,
                                   wrong_mac,
                                   param='-p') == False,
            "VM should not reveive misc packet")
        self.send_packet(wrong_mac)
        out = self.dut.get_session_output()
        self.verify(wrong_mac not in out, "PF should not receive misc packet")

        # Send packet from tester to VF with correct DST MAC, check the packet
        # can be received by kernel VF
        vm0_vf0_mac = self.vm0_dut.ports_info[0]['port'].get_mac_addr()
        self.verify(
            self.verify_vm_tcpdump(self.vm0_dut,
                                   self.vm0_intf0,
                                   vm0_vf0_mac,
                                   param='-p'), "VM reveive packet failed")
        # Send packet from tester to PF with correct DST MAC, check the packet
        # can be received by DPDK PF
        self.send_packet(self.dmac)
        out = self.dut.get_session_output()
        self.verify(self.tester_mac.upper() in out, "PF reveive packet failed")

    def test_rss(self):
        """
        verify kernel VF each queue can receive packets
        """
        self.verify(self.nic not in ["niantic"],
                    "%s NIC not support tcpid " % self.nic)

        # Verify kernel VF RSS using ethtool -"l" (lower case L) <devx> that the
        # default RSS setting is equal to the number of CPUs in the system and
        # that the maximum number of RSS queues displayed is correct for the
        # DUT
        self.verify(self.check_pf_vf_link_status(self.vm0_dut, self.vm0_intf0),
                    "VM0_VF0 link down")

        cpus = self.vm0_dut.send_expect(
            "cat /proc/cpuinfo| grep 'processor'| wc -l", "#")
        out = self.vm0_dut.send_expect("ethtool -l %s" % self.vm0_intf0, "#",
                                       10)
        combined = re.findall("Combined:\s*(\d*)", out)
        self.verify(cpus == combined[0], "the queues count error")

        # Run "ethtool -S <devx> | grep rx_bytes | column" to see the current
        # queue count and verify that it is correct to step 1
        out = self.vm0_dut.send_expect(
            "ethtool -S %s |grep rx-.*bytes" % self.vm0_intf0, "#")
        rx_bytes_before = re.findall("rx-.*bytes:\s*(\d*)", out)
        self.verify(
            len(rx_bytes_before) == int(combined[0]), "the queues count error")

        # Send multi-threaded traffics to the DUT with a number of threads
        # Check kernel VF each queue can receive packets
        vm0_vf0_mac = self.vm0_dut.ports_info[0]['port'].get_mac_addr()
        for i in xrange(5):
            mythread = threading.Thread(target=self.send_packet(vm0_vf0_mac))
            mythread.start()

        out = self.vm0_dut.send_expect(
            "ethtool -S %s |grep rx-*bytes" % self.vm0_intf0, "#")
        rx_bytes_after = re.findall("rx-*.bytes:\s*(\d*)", out)
        for i in range(len(rx_bytes_after)):
            self.verify(rx_bytes_after[i] > rx_bytes_before[i],
                        "NOT each queue receive packets")

    def test_dpf_kvf_dvf(self):
        """
        Check DPDK VF0 and kernel VF1 don't impact each other and no performance drop
        """
        self.vm0_dut.send_expect("ifconfig %s up " % self.vm0_intf0, "#")
        self.vm0_dut.send_expect("ifconfig %s up " % self.vm0_intf1, "#")
        self.vm0_dut.ports_info[1]['port'].bind_driver('igb_uio')

        self.vm0_testpmd.start_testpmd("Default")
        self.vm0_testpmd.execute_cmd('set promisc all on')
        self.vm0_testpmd.execute_cmd('set fwd rxonly')
        self.vm0_testpmd.execute_cmd('set verbose 1')
        self.vm0_testpmd.execute_cmd('start')

        vm0_vf0_mac = self.vm0_dut.ports_info[0]['port'].get_mac_addr()
        vm0_vf1_mac = self.vm0_testpmd.get_port_mac(0)

        macs = [vm0_vf0_mac, vm0_vf1_mac]
        self.generate_pcap_pkt(macs)

        vm0_newvmsession = self.vm0_dut.new_session()
        date_old = datetime.datetime.now()
        date_new = date_old + datetime.timedelta(minutes=.5)
        while (1):
            date_now = datetime.datetime.now()
            vm0_newvmsession.send_expect(
                "tcpdump -i %s -e ether src %s " %
                (self.vm0_intf0, self.src_logo), "tcpdump")
            self.send_packets()

            out = self.vm0_dut.get_session_output(timeout=20)
            self.verify(self.src_logo in out,
                        "VM PF Confiscated to the specified package")

            put = vm0_newvmsession.send_expect("^C", "#", 10)
            rx_packet = re.findall("(\d*) packe.* captured", put)
            if rx_packet[0] == '1':
                self.verify(
                    rx_packet[0] == '1',
                    "VM KF Confiscated to the specified package\n'%s'" % put)

            if date_now >= date_new:
                break
        time.sleep(3)

    def send_packets(self):
        self.tester.scapy_foreground()
        self.tester.scapy_append("pkts=rdpcap('flow.pcap')")
        self.tester.scapy_append("sendp(pkts, iface='%s')" % self.tester_intf)
        self.tester.scapy_execute()

    def reboot_vm1(self):
        """
        reboot vm1.
        """
        self.vm1.stop()
        vf1_prop_5 = {'opt_host': self.sriov_vfs_port[4].pci}
        vf1_prop_6 = {'opt_host': self.sriov_vfs_port[5].pci}
        self.vm1 = QEMUKvm(self.dut, 'vm1', 'vf_kernel')
        self.vm1.set_vm_device(driver='pci-assign', **vf1_prop_5)
        self.vm1.set_vm_device(driver='pci-assign', **vf1_prop_6)

        try:
            self.vm1_dut = self.vm1.start()
            if self.vm1_dut is None:
                raise Exception("Set up VM1 ENV failed!")
            else:
                self.verify(self.vm1_dut.ports_info[0]['intf'] != 'N/A',
                            "Not interface")
        except Exception as e:
            self.destroy_vm_env()
            raise Exception(e)

    def test_zdpf_2kvf_2dvf_2vm(self):
        """
        Check DPDK PF 2kernel VFs 2DPDK VFs 2VMs link change impact on other VFs
        DPDK PF + 2kernel VFs + 2DPDK VFs + 2VMs
        Host one DPDK PF and create 6 VFs, pass through VF0, VF1, VF2 and VF3 to VM0, pass through VF4, VF5 to VM1, power on VM0 and VM1.
        Load host DPDK driver, VM DPDK driver and kernel driver.
        """
        for port_info in self.vm0_dut.ports_info:
            vm0_intf = port_info['intf']
            self.verify(self.check_pf_vf_link_status(self.vm0_dut, vm0_intf),
                        "VM0_vf: %s link down" % vm0_intf)

        for port_info in self.vm1_dut.ports_info:
            vm1_intf = port_info['intf']
            self.verify(self.check_pf_vf_link_status(self.vm1_dut, vm1_intf),
                        "VM1_vf: %s link down" % vm1_intf)

        # Bind kernel VF0, VF1 to igb_uio in VM0, bind kernel VF4 to igb_uio in
        # VM1
        self.vm0_dut.ports_info[0]['port'].bind_driver('igb_uio')
        self.vm0_dut.ports_info[1]['port'].bind_driver('igb_uio')
        self.vm1_dut.ports_info[0]['port'].bind_driver('igb_uio')

        # Start DPDK VF0, VF1 in VM0 and VF4 in VM1, enable promisc mode
        self.vm0_testpmd.start_testpmd("Default")
        self.vm0_testpmd.execute_cmd('set promisc all on')
        self.vm0_testpmd.execute_cmd('set fwd rxonly')
        self.vm0_testpmd.execute_cmd('set verbose 1')
        self.vm0_testpmd.execute_cmd('start')

        self.vm1_testpmd.start_testpmd("Default")
        self.vm1_testpmd.execute_cmd('set promisc all on')
        self.vm1_testpmd.execute_cmd('set fwd rxonly')
        self.vm1_testpmd.execute_cmd('set verbose 1')
        self.vm1_testpmd.execute_cmd('start')

        vm0_vf0_mac = self.vm0_testpmd.get_port_mac(0)
        vm0_vf1_mac = self.vm0_testpmd.get_port_mac(1)
        vm0_vf2_mac = self.vm0_dut.ports_info[2]['port'].get_mac_addr()
        vm0_vf3_mac = self.vm0_dut.ports_info[3]['port'].get_mac_addr()
        vm1_vf0_mac = self.vm1_testpmd.get_port_mac(0)
        vm1_vf1_mac = self.vm1_dut.ports_info[1]['port'].get_mac_addr()
        pf0_mac = self.dut_testpmd.get_port_mac(0)
        pf1_mac = self.dut_testpmd.get_port_mac(1)

        macs = [
            vm0_vf0_mac, vm0_vf1_mac, vm0_vf2_mac, vm0_vf3_mac, vm1_vf0_mac,
            vm1_vf1_mac, pf0_mac, pf1_mac
        ]
        self.generate_pcap_pkt(macs)

        self.send_packets()

        vm0_vf2_newvmsession = self.vm0_dut.new_session()
        vm0_vf3_newvmsession = self.vm0_dut.new_session()
        vm1_newvmsession = self.vm1_dut.new_session()

        # Set up kernel VF2, VF3 in VM0 and VF5 in VM1  tcpdump without -p
        # parameter on promisc mode
        vm0_vf2_newvmsession.send_expect(
            "tcpdump -i %s -p -e ether src %s" %
            (self.vm0_dut.ports_info[2]['intf'], self.src_logo), "tcpdump", 10)
        vm0_vf3_newvmsession.send_expect(
            "tcpdump -i %s -p -e ether src %s" %
            (self.vm0_dut.ports_info[3]['intf'], self.src_logo), "tcpdump", 10)
        vm1_newvmsession.send_expect(
            "tcpdump -i %s -e -p ether src %s" %
            (self.vm0_dut.ports_info[1]['intf'], self.src_logo), "tcpdump", 10)

        self.send_packets()

        out = self.vm0_dut.get_session_output()
        self.verify(self.src_logo in out,
                    "VM0 PF Confiscated to the specified package")

        vm0_vf2_out = vm0_vf2_newvmsession.send_expect("^C", "#")
        vm0_vf2_out_rx_packet = re.findall("(\d*) packe.* captured",
                                           vm0_vf2_out)
        self.verify(vm0_vf2_out_rx_packet[0] == '1',
                    "vm0 vf2 Confiscated to the specified package")

        vm0_vf3_out = vm0_vf3_newvmsession.send_expect("^C", "#")
        vm0_vf3_out_rx_packet = re.findall("(\d*) packe.* captured",
                                           vm0_vf3_out)
        self.verify(vm0_vf3_out_rx_packet[0] == '1',
                    "vm0 vf3 Confiscated to the specified package")

        out = self.vm1_dut.get_session_output()
        self.verify(self.src_logo in out,
                    "VM1 PF Confiscated to the specified package")

        vm1_vf1_out = vm1_newvmsession.send_expect("^C", "#")
        vm1_vf1_out_rx_packet = re.findall("(\d*) packe.* captured",
                                           vm0_vf2_out)
        self.verify(vm1_vf1_out_rx_packet[0] == '1',
                    "vm1 vf1 Confiscated to the specified package")

        # Link down DPDK VF0 and expect no impact on other VFs
        self.vm0_testpmd.quit()
        eal_param = '-b %(vf0)s' % ({'vf0': self.vm0_dut.ports_info[0]['pci']})
        self.vm0_testpmd.start_testpmd("Default", eal_param=eal_param)
        self.vm0_testpmd.execute_cmd('set promisc all on')
        self.vm0_testpmd.execute_cmd('set fwd rxonly')
        self.vm0_testpmd.execute_cmd('set verbose 1')
        self.vm0_testpmd.execute_cmd('start')

        vm0_vf2_newvmsession.send_expect(
            "tcpdump -i %s -p -e ether src %s" %
            (self.vm0_dut.ports_info[2]['intf'], self.src_logo), "tcpdump", 10)
        vm0_vf3_newvmsession.send_expect(
            "tcpdump -i %s -p -e ether src %s" %
            (self.vm0_dut.ports_info[3]['intf'], self.src_logo), "tcpdump", 10)
        vm1_newvmsession.send_expect(
            "tcpdump -i %s -p -e ether src %s" %
            (self.vm0_dut.ports_info[1]['intf'], self.src_logo), "tcpdump", 10)

        self.send_packets()

        out = self.vm0_dut.get_session_output()
        self.verify(self.src_logo in out,
                    "link down impact VM0 PF receive package")

        vm0_vf2_out = vm0_vf2_newvmsession.send_expect("^C", "#")
        vm0_vf2_out_rx_packet = re.findall("(\d*) packe.* captured",
                                           vm0_vf2_out)
        self.verify(vm0_vf2_out_rx_packet[0] == '1',
                    "link down impact vm0 vf2 receive package")

        vm0_vf3_out = vm0_vf3_newvmsession.send_expect("^C", "#")
        vm0_vf3_out_rx_packet = re.findall("(\d*) packe.* captured",
                                           vm0_vf3_out)
        self.verify(vm0_vf3_out_rx_packet[0] == '1',
                    "link down impact vm0 vf3 receive package")

        out = self.vm1_dut.get_session_output()
        self.verify(self.src_logo in out,
                    "link down impact VM1 PF receive package")

        vm1_vf1_out = vm1_newvmsession.send_expect("^C", "#")
        vm1_vf1_out_rx_packet = re.findall("(\d*) packe.* captured",
                                           vm0_vf2_out)
        self.verify(vm1_vf1_out_rx_packet[0] == '1',
                    "link down impact vm1 vf1 receive package")

        # Link down kernel VF2 and expect no impact on other VFs
        vm0_vf2_newvmsession.send_expect(
            "ifconfig %s down" % self.vm0_dut.ports_info[2]['intf'], "#", 10)

        vm0_vf3_newvmsession.send_expect(
            "tcpdump -i %s -p -e ether src %s" %
            (self.vm0_dut.ports_info[3]['intf'], self.src_logo), "tcpdump", 10)
        vm1_newvmsession.send_expect(
            "tcpdump -i -p %s -e ether src %s" %
            (self.vm0_dut.ports_info[1]['intf'], self.src_logo), "tcpdump", 10)

        self.send_packets()

        out = self.vm0_dut.get_session_output()
        self.verify(self.src_logo in out,
                    "link down kernel vf2 impact VM0 PF receive package")

        vm0_vf3_out = vm0_vf3_newvmsession.send_expect("^C", "#")
        vm0_vf3_out_rx_packet = re.findall("(\d*) packe.* captured",
                                           vm0_vf3_out)
        self.verify(vm0_vf3_out_rx_packet[0] == '1',
                    "link down kernel vf2 impact vm0 vf3 receive package")

        out = self.vm1_dut.get_session_output()
        self.verify(self.src_logo in out,
                    "link down kernel vf2 impact VM1 PF receive package")

        vm1_vf1_out = vm1_newvmsession.send_expect("^C", "#")
        vm1_vf1_out_rx_packet = re.findall("(\d*) packe.* captured",
                                           vm0_vf2_out)
        self.verify(vm1_vf1_out_rx_packet[0] == '1',
                    "link down kernel vf2 impact vm1 vf1 receive package")

        vm0_vf2_newvmsession.send_expect(
            "ifconfig %s up" % self.vm0_dut.ports_info[2]['intf'], "#")

        # Quit VF4 DPDK testpmd and expect no impact on other VFs
        self.vm1_testpmd.quit()

        vm0_vf2_newvmsession.send_expect(
            "tcpdump -i %s -p -e ether src %s" %
            (self.vm0_dut.ports_info[2]['intf'], self.src_logo), "tcpdump", 10)
        vm0_vf3_newvmsession.send_expect(
            "tcpdump -i %s -p -e ether src %s" %
            (self.vm0_dut.ports_info[3]['intf'], self.src_logo), "tcpdump", 10)
        vm1_newvmsession.send_expect(
            "tcpdump -i %s -p -e ether src %s" %
            (self.vm0_dut.ports_info[1]['intf'], self.src_logo), "tcpdump", 10)

        self.send_packets()

        out = self.vm0_dut.get_session_output()
        self.verify(self.src_logo in out,
                    "quit vf4 DPDK testpmd impact VM0 PF receive package")

        vm0_vf2_out = vm0_vf2_newvmsession.send_expect("^C", "#")
        vm0_vf2_out_rx_packet = re.findall("(\d*) packe.* captured",
                                           vm0_vf2_out)
        self.verify(vm0_vf2_out_rx_packet[0] == '1',
                    "quit vf4 DPDK testpmd impact vm0 vf2 receive package")

        vm0_vf3_out = vm0_vf3_newvmsession.send_expect("^C", "#")
        vm0_vf3_out_rx_packet = re.findall("(\d*) packe.* captured",
                                           vm0_vf3_out)
        self.verify(vm0_vf3_out_rx_packet[0] == '1',
                    "quit vf4 DPDK testpmd impact vm0 vf3 receive package")

        vm1_vf1_out = vm1_newvmsession.send_expect("^C", "#")
        vm1_vf1_out_rx_packet = re.findall("(\d*) packe.* captured",
                                           vm0_vf2_out)
        self.verify(vm1_vf1_out_rx_packet[0] == '1',
                    "quit vf4 DPDK testpmd impact vm1 vf1 receive package")

        self.vm1_testpmd.start_testpmd("Default")
        self.vm1_testpmd.execute_cmd('set promisc all on')
        self.vm1_testpmd.execute_cmd('set fwd rxonly')
        self.vm1_testpmd.execute_cmd('set verbose 1')
        self.vm1_testpmd.execute_cmd('start')

        # Unload VF5 kernel driver and expect no impact on other VFs
        vm1_newvmsession.send_expect(
            "./usertools/dpdk-devbind.py -b pci-stub %s" %
            (self.vm1_dut.ports_info[1]['pci']), "#")

        vm0_vf2_newvmsession.send_expect(
            "tcpdump -i %s -p -e ether src %s" %
            (self.vm0_dut.ports_info[2]['intf'], self.src_logo), "tcpdump")
        vm0_vf3_newvmsession.send_expect(
            "tcpdump -i %s -p -e ether src %s" %
            (self.vm0_dut.ports_info[3]['intf'], self.src_logo), "tcpdump")

        self.send_packets()

        out = self.vm0_dut.get_session_output()
        self.verify(self.src_logo in out,
                    "unload vf5 kernel driver impact VM0 PF receive package")

        vm0_vf2_out = vm0_vf2_newvmsession.send_expect("^C", "#")
        vm0_vf2_out_rx_packet = re.findall("(\d*) packe.* captured",
                                           vm0_vf2_out)
        self.verify(vm0_vf2_out_rx_packet[0] == '1',
                    "unload vf5 kernel driver impact vm0 vf2 receive package")

        vm0_vf3_out = vm0_vf3_newvmsession.send_expect("^C", "#", 10)
        vm0_vf3_out_rx_packet = re.findall("(\d*) packe.* captured",
                                           vm0_vf3_out)
        self.verify(vm0_vf3_out_rx_packet[0] == '1',
                    "unload vf5 kernel driver impact vm0 vf3 receive package")

        out = self.vm1_dut.get_session_output(timeout=20)
        self.verify(self.src_logo in out,
                    "unload vf5 kernel driver impact VM1 PF receive package")

        # Reboot VM1 and expect no impact on VFs of VM0
        self.vm1_dut.send_expect("quit", "#")
        self.reboot_vm1()

        vm0_vf2_newvmsession.send_expect(
            "tcpdump -i %s -p -e ether src %s" %
            (self.vm0_dut.ports_info[2]['intf'], self.src_logo), "tcpdump")
        vm0_vf3_newvmsession.send_expect(
            "tcpdump -i %s -p -e ether src %s" %
            (self.vm0_dut.ports_info[3]['intf'], self.src_logo), "tcpdump")

        self.send_packets()

        out = self.vm0_dut.get_session_output()
        self.verify(self.src_logo in out,
                    "reboot vm1 impact VM0 PF receive package")

        vm0_vf2_out = vm0_vf2_newvmsession.send_expect("^C", "#")
        vm0_vf2_out_rx_packet = re.findall("(\d*) packe.* captured",
                                           vm0_vf2_out)
        self.verify(vm0_vf2_out_rx_packet[0] == '1',
                    "reboot vm1 impact vm0 vf2 receive package")

        vm0_vf3_out = vm0_vf3_newvmsession.send_expect("^C", "#")
        vm0_vf3_out_rx_packet = re.findall("(\d*) packe.* captured",
                                           vm0_vf3_out)
        self.verify(vm0_vf3_out_rx_packet[0] == '1',
                    "reboot vm1 impact vm0 vf3 receive package")

    def test_stress(self):
        """
        Load kernel driver stress
        """
        for i in xrange(100):
            out = self.vm0_dut.send_expect("rmmod %svf" % self.kdriver, "#")
            self.verify('error' not in out,
                        "stress error for rmmod %svf:%s" % (self.kdriver, out))
            out = self.vm0_dut.send_expect("modprobe %svf" % self.kdriver, "#")
            self.verify(
                'error' not in out,
                "stress error for modprobe %svf:%s" % (self.kdriver, out))

    def tear_down(self):
        """
        Run after each test case.
        """
        self.vm0_testpmd.quit()
        self.vm0_dut.restore_interfaces_linux()
        if getattr(self, 'vm0_newvmsession', None):
            self.vm0_dut.close_session(vm0_newvmsession)
        if getattr(self, 'vm0_vf2_newvmsession', None):
            self.vm0_dut.close_session(vm0_vf2_newvmsession)
        if getattr(self, 'vm0_vf3_newvmsession', None):
            self.vm0_dut.close_session(vm0_vf3_newvmsession)

        # Sometime test failed ,we still need clear ip.
        self.vm0_dut.send_expect("ifconfig %s 0.0.0.0" % self.vm0_intf0, "#")
        self.vm0_dut.send_expect("ifconfig %s 0.0.0.0" % self.vm0_intf1, "#")
        self.tester.send_expect("ifconfig %s 0.0.0.0" % self.tester_intf, "#")
        time.sleep(5)

    def tear_down_all(self):
        """
        Run after each test suite.
        """
        self.dut_testpmd.quit()
        self.destroy_vm_env()
        self.dut.kill_all()
        time.sleep(2)
Exemplo n.º 10
0
class TestVhostUserOneCopyOneVm(TestCase):
    def set_up_all(self):
        # Get and verify the ports
        self.dut_ports = self.dut.get_ports()
        self.verify(len(self.dut_ports) >= 1, "Insufficient ports for testing")

        # Get the port's socket
        self.pf = self.dut_ports[0]
        netdev = self.dut.ports_info[self.pf]['port']
        self.socket = netdev.get_nic_socket()
        self.cores = self.dut.get_core_list("1S/3C/1T", socket=self.socket)

        # Set the params of vhost sample
        self.vhost_app = "./examples/vhost/build/vhost-switch"
        self.vm2vm = 0
        # This parameter is used to define mergeable on/off
        self.jumbo = 0

        # Using file to save the vhost sample output since in jumboframe case,
        # there will be lots of output
        self.vhost_test = self.vhost_app + \
            " -c %s -n %d --socket-mem 2048,2048  -- -p 0x1 --mergeable %d" + \
            " --vm2vm %d --socket-file ./vhost-net  > ./vhost.out &"
        # build the vhost sample in vhost-user mode.
        if self.nic in ['niantic']:
            self.dut.send_expect(
                "sed -i -e 's/#define MAX_QUEUES.*$/#define MAX_QUEUES 128/' "
                "./examples/vhost/main.c", "#", 10)
        elif self.nic.startswith('fortville'):
            self.dut.send_expect(
                "sed -i -e 's/#define MAX_QUEUES.*$/#define MAX_QUEUES 512/' "
                "./examples/vhost/main.c", "#", 10)
        out = self.dut.send_expect("make -C examples/vhost", "#")
        self.verify("Error" not in out, "compilation error")
        self.verify("No such file" not in out, "Not found file error")

        self.virtio1 = "eth1"
        self.virtio1_mac = "52:54:00:00:00:01"
        self.src1 = "192.168.4.1"
        self.dst1 = "192.168.3.1"
        self.vm_dut = None

        self.number_of_ports = 1
        self.header_row = [
            "FrameSize(B)", "Throughput(Mpps)", "LineRate(%)", "Cycle"
        ]
        self.memory_channel = 4

    def set_up(self):
        #
        # Run before each test case.
        #
        # Launch vhost sample using default params
        #
        self.dut.send_expect("rm -rf ./vhost.out", "#")
        self.dut.send_expect("rm -rf ./vhost-net*", "#")
        self.dut.send_expect("killall -s INT vhost-switch", "#")

        self.frame_sizes = [64, 128, 256, 512, 1024, 1500]
        self.vm_testpmd_vector = self.target + "/app/testpmd -c 0x3 -n 3" \
                                 + " -- -i --tx-offloads=0 --disable-hw-vlan-filter"
        self.vm_testpmd_normal = self.target + "/app/testpmd -c 0x3 -n 3" \
                                 + " -- -i --tx-offloads=0x8000 --disable-hw-vlan-filter"

    def launch_vhost_sample(self):
        #
        # Launch the vhost sample with different parameters
        #
        self.coremask = utils.create_mask(self.cores)
        self.vhostapp_testcmd = self.vhost_test % (
            self.coremask, self.memory_channel, self.jumbo, self.vm2vm)
        self.dut.send_expect(self.vhostapp_testcmd, "# ", 40)
        time.sleep(30)
        try:
            self.logger.info("Launch vhost sample:")
            self.dut.session.copy_file_from(self.dut.base_dir + "vhost.out")
            fp = open('./vhost.out', 'r')
            out = fp.read()
            fp.close()
            if "Error" in out:
                raise Exception("Launch vhost sample failed")
            else:
                self.logger.info("Launch vhost sample finished")
        except Exception as e:
            self.logger.error("ERROR: Failed to launch vhost sample: %s" %
                              str(e))

    def start_onevm(self, path="", modem=0):
        #
        # Start One VM with one virtio device
        #

        self.vm = QEMUKvm(self.dut, 'vm0', 'vhost_sample')
        if (path != ""):
            self.vm.set_qemu_emulator(path)
        vm_params = {}
        vm_params['driver'] = 'vhost-user'
        vm_params['opt_path'] = './vhost-net'
        vm_params['opt_mac'] = self.virtio1_mac
        if (modem == 1):
            vm_params['opt_settings'] = 'disable-modern=false'
        self.vm.set_vm_device(**vm_params)

        try:
            self.vm_dut = self.vm.start()
            if self.vm_dut is None:
                raise Exception("Set up VM ENV failed")
        except Exception as e:
            self.logger.error("ERROR: Failure for %s" % str(e))

        return True

    def vm_testpmd_start(self):
        #
        # Start testpmd in vm
        #
        if self.vm_dut is not None:
            self.vm_dut.send_expect(self.vm_testpmd_vector, "testpmd>", 20)
            self.vm_dut.send_expect("set fwd mac", "testpmd>", 20)
            self.vm_dut.send_expect("start tx_first", "testpmd>")

    def send_verify(self, case, frame_sizes, vlan_id1=0, tag="Performance"):
Exemplo n.º 11
0
class TestVfMacFilter(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.pf0_vf0_mac = "00:12:34:56:78:01"
        self.iplinkset = True

        # 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.setup_2pf_2vf_1vm_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']
        pf_intf0 = self.dut.ports_info[0]['port'].get_interface_name()
        
        if self.iplinkset: 
            self.dut.send_expect("ip link set %s vf 0 mac %s" %(pf_intf0, self.pf0_vf0_mac), "#")
       
        self.used_dut_port_1 = self.dut_ports[1]
        self.dut.generate_sriov_vfs_by_port(self.used_dut_port_1, 1, driver=driver)
        self.sriov_vfs_port_1 = self.dut.ports_info[self.used_dut_port_1]['vfs_port']


        try:

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

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

            time.sleep(1)
            vf0_prop = {'opt_host': self.sriov_vfs_port_0[0].pci}
            vf1_prop = {'opt_host': self.sriov_vfs_port_1[0].pci}

            if driver == 'igb_uio':
                # start testpmd without the two VFs on the host
                self.host_testpmd = PmdOutput(self.dut)
                eal_param = '-b %(vf0)s -b %(vf1)s' % {'vf0': self.sriov_vfs_port_0[0].pci,
                                                       'vf1': self.sriov_vfs_port_1[0].pci}
                self.host_testpmd.start_testpmd("1S/2C/2T", eal_param=eal_param)

            # set up VM0 ENV
            self.vm0 = QEMUKvm(self.dut, 'vm0', 'vf_macfilter')
            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.dut.virt_exit()
            self.vm0 = None

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

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

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

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

        self.setup_2pf_2vf_1vm_env_flag = 0

######1. test case for kernel pf and dpdk vf 2pf_2vf_1vm MAC filter scenario
###### kernel pf will first run 'ip link set pf_interface vf 0 mac xx:xx:xx:xx:xx:xx, then 
###### in the vm, send packets with this MAC to VF, check if the MAC filter works. Also 
###### send the packets with wrong MAC address to VF, check if the VF will not RX the packets.
 
    def test_kernel_2pf_2vf_1vm_iplink_macfilter(self):

        self.setup_2pf_2vf_1vm_env(driver='')

        self.vm0_dut_ports = self.vm_dut_0.get_ports('any')
        self.vm0_testpmd = PmdOutput(self.vm_dut_0)
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK)
        # Get VF's MAC
        pmd_vf0_mac = self.vm0_testpmd.get_port_mac(0)
        vf0_wrongmac = "00:11:22:33:48:55"
        self.vm0_testpmd.execute_cmd('set promisc all off')
        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 = self.pf0_vf0_mac
        src_mac = self.tester.get_mac(tx_port)
        pkt_param=[("ether", {'dst': dst_mac, 'src': src_mac})]
        
        print "\nfirst send packets to the kernel PF set MAC, expected result is RX packets=TX packets\n"
        result1 = self.tester.check_random_pkts(tgen_ports, pktnum=100, allow_miss=False, params=pkt_param)
	print "\nshow port stats in testpmd for double check: \n", self.vm0_testpmd.execute_cmd('show port stats all')   
        self.verify(result1 != False, "VF0 failed to forward packets to VF1")
        
        print "\nSecondly, negative test, send packets to a wrong MAC, expected result is RX packets=0\n"
        dst_mac = vf0_wrongmac
        pkt_param=[("ether", {'dst': dst_mac, 'src': src_mac})]
        result2 = self.tester.check_random_pkts(tgen_ports, pktnum=100, allow_miss=False, params=pkt_param)
        print "\nshow port stats in testpmd for double check: \n", self.vm0_testpmd.execute_cmd('show port stats all')
        self.verify(result2 != True, "VF0 failed to forward packets to VF1")

#######2. test case for kernel pf and dpdk vf 2pf_2vf_1vm MAC filter scenario.
####### kernel pf will not set MAC address and the VF will get a random generated MAC
####### in the testpmd in VM, and then add VF mac address in the testpmd,for example, VF_MAC1
####### then send packets to the VF with the random generated MAC and the new added VF_MAC1 
####### and the expected result is that all packets can be RXed and TXed. What's more, send
####### packets with a wrong MAC address to the VF will not received by the VF. 

    def test_kernel_2pf_2vf_1vm_mac_add_filter(self):

        self.iplinkset = False
        self.setup_2pf_2vf_1vm_env(driver='')

        self.vm0_dut_ports = self.vm_dut_0.get_ports('any')
        self.vm0_testpmd = PmdOutput(self.vm_dut_0)
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK)
        
        # Get VF0 port MAC address
        pmd_vf0_mac = self.vm0_testpmd.get_port_mac(0)
        vf0_setmac = "00:11:22:33:44:55"
        vf0_wrongmac = "00:11:22:33:48:55"
        self.vm0_testpmd.execute_cmd('set promisc all off')
        ret = self.vm0_testpmd.execute_cmd('mac_addr add 0 %s' %vf0_setmac)
        # check the operation is supported or not.
        print ret 
 
        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))
        src_mac = self.tester.get_mac(tx_port)
        dst_mac = pmd_vf0_mac
        pkt_param=[("ether", {'dst': dst_mac, 'src': src_mac})]
        
        print "\nfirst send packets to the random generated VF MAC, expected result is RX packets=TX packets\n"
        result1 = self.tester.check_random_pkts(tgen_ports, pktnum=100, allow_miss=False, params=pkt_param)
        print "\nshow port stats in testpmd for double check: \n", self.vm0_testpmd.execute_cmd('show port stats all')
        self.verify(result1 != False, "VF0 failed to forward packets to VF1")
        
        print "\nsecondly, send packets to the new added MAC, expected result is RX packets=TX packets\n"
        dst_mac = vf0_setmac
        pkt_param=[("ether", {'dst': dst_mac, 'src': src_mac})]
        result2 = self.tester.check_random_pkts(tgen_ports, pktnum=100, allow_miss=False, params=pkt_param)
        print "\nshow port stats in testpmd for double check: \n", self.vm0_testpmd.execute_cmd('show port stats all')
        self.verify(result2 != False, "VF0 failed to forward packets to VF1")

        print "\nThirdly, negative test, send packets to a wrong MAC, expected result is RX packets=0\n"
        dst_mac = vf0_wrongmac
        pkt_param=[("ether", {'dst': dst_mac, 'src': src_mac})]
        result3 = self.tester.check_random_pkts(tgen_ports, pktnum=100, allow_miss=False, params=pkt_param)
        print "\nshow port stats in testpmd for double check: \n", self.vm0_testpmd.execute_cmd('show port stats all')
        self.verify(result3 != True, "VF0 failed to forward packets to VF1")

 
    def tear_down(self):

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

    def tear_down_all(self):

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

        self.dut.virt_exit()

        for port_id in self.dut_ports:
            self.dut.destroy_sriov_vfs_by_port(port_id)
Exemplo n.º 12
0
class TestVxlanSample(TestCase):
    FEAT_ENABLE = 1
    FEAT_DISABLE = 0
    INNER_VLAN_VNI = 1
    INNER_VNI = 2
    OUTER_INNER_VNI = 3

    def set_up_all(self):
        """
        Run before each test suite.
        """

        # this feature only enable in FVL now
        self.verify(
            self.nic in [
                "fortville_eagle", "fortville_spirit",
                "fortville_spirit_single", "fortpark_TLV", "fortville_25g"
            ], "Vxlan Only supported by Fortville")
        # Based on h/w type, choose how many ports to use
        self.dut_ports = self.dut.get_ports()

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

        # get pf socket
        self.pf = self.dut_ports[0]
        netdev = self.dut.ports_info[self.pf]['port']
        self.socket = netdev.get_nic_socket()
        self.pf_mac = self.dut.get_mac_address(self.pf)

        # build sample app
        out = self.dut.send_expect("make -C examples/tep_termination", "# ")
        self.verify("Error" not in out, "compilation error 1")
        self.verify("No such file" not in out, "compilation error 2")

        self.def_mac = "00:00:20:00:00:20"
        self.vm_dut = None
        self.tep_app = "./examples/tep_termination/build/tep_termination"
        self.vxlan_port = 4789
        self.vm_testpmd = "./x86_64-native-linuxapp-gcc/app/testpmd -c f -n 3" \
                          + " -- -i --txqflags=0xf00 --disable-hw-vlan"

        # params for tep_termination
        self.cores = self.dut.get_core_list("1S/4C/1T", socket=self.socket)
        self.capture_file = "/tmp/vxlan_cap.pcap"
        self.def_mss = 256

        # performance measurement, checksum based on encap
        self.perf_cfg = [{
            'Func': 'Decap',
            'VirtIO': 'Single',
            'Mpps': {},
            'pct': {}
        }, {
            'Func': 'Encap',
            'VirtIO': 'Single',
            'Mpps': {},
            'pct': {}
        }, {
            'Func': 'Decap&Encap',
            'VirtIO': 'Single',
            'Mpps': {},
            'pct': {}
        }, {
            'Func': 'Checksum',
            'VirtIO': 'Single',
            'Mpps': {},
            'pct': {}
        }, {
            'Func': 'Checksum&Decap',
            'VirtIO': 'Single',
            'Mpps': {},
            'pct': {}
        }, {
            'Func': 'Decap',
            'VirtIO': 'Two Ports',
            'Mpps': {},
            'pct': {}
        }, {
            'Func': 'Encap',
            'VirtIO': 'Two Ports',
            'Mpps': {},
            'pct': {}
        }, {
            'Func': 'Decap&Encap',
            'VirtIO': 'Two Ports',
            'Mpps': {},
            'pct': {}
        }, {
            'Func': 'Checksum',
            'VirtIO': 'Two Ports',
            'Mpps': {},
            'pct': {}
        }, {
            'Func': 'Checksum&Decap',
            'VirtIO': 'Two Ports',
            'Mpps': {},
            'pct': {}
        }]

    def set_up(self):
        """
        Run before each test case.
        """
        # create coremask
        self.coremask = utils.create_mask(self.cores)

        if "2VM" not in self.running_case:
            vm_num = 1
        else:
            vm_num = 2

        encap = self.FEAT_ENABLE
        decap = self.FEAT_ENABLE
        chksum = self.FEAT_ENABLE
        if self.running_case == "test_vxlan_sample_encap":
            encap = self.FEAT_ENABLE
            decap = self.FEAT_DISABLE
            chksum = self.FEAT_ENABLE
        elif self.running_case == "test_vxlan_sample_decap":
            encap = self.FEAT_DISABLE
            decap = self.FEAT_ENABLE
        elif self.running_case == "test_vxlan_sample_chksum":
            chksum = self.FEAT_ENABLE
        elif self.running_case == "test_vxlan_sample_tso":
            chksum = self.FEAT_ENABLE

        tep_cmd_temp = self.tep_app + " -c %(COREMASK)s -n %(CHANNELS)d " \
            + "--socket-mem 2048,2048 -- -p 0x1 " \
            + "--udp-port %(VXLAN_PORT)d --nb-devices %(NB_DEVS)d " \
            + "--filter-type %(FILTERS)d " \
            + "--tx-checksum %(TX_CHKS)d --encap %(ENCAP)d --decap %(DECAP)d"

        tep_cmd = tep_cmd_temp % {
            'COREMASK': self.coremask,
            'CHANNELS': self.dut.get_memory_channels(),
            'VXLAN_PORT': self.vxlan_port,
            'NB_DEVS': vm_num * 2,
            'FILTERS': self.OUTER_INNER_VNI,
            'TX_CHKS': chksum,
            'ENCAP': encap,
            'DECAP': decap
        }

        if self.running_case == "test_vxlan_sample_tso":
            tep_cmd += " --tso-segsz=%d" % self.def_mss

        if self.running_case != "test_perf_vxlan_sample":
            self.prepare_vxlan_sample_env(tep_cmd, vm_num=vm_num)

        pass

    def prepare_vxlan_sample_env(self, tep_cmd, vm_num=1):
        # remove unexpected socke
        self.dut.send_expect("rm -rf vhost-net", "# ")

        # start tep_termination first
        self.dut.send_expect(tep_cmd, "VHOST_CONFIG: bind to vhost-net")

        # start one vm
        self.vm = QEMUKvm(self.dut, 'vm0', 'vxlan_sample')

        # add two virtio user netdevices
        vm_params = {}
        vm_params['driver'] = 'vhost-user'
        vm_params['opt_path'] = './vhost-net'
        vm_params['opt_mac'] = self.def_mac
        self.vm.set_vm_device(**vm_params)
        vm_params['opt_mac'] = self.mac_address_add(1)
        self.vm.set_vm_device(**vm_params)

        try:
            self.vm_dut = self.vm.start()
            if self.vm_dut is None:
                raise Exception("Set up VM ENV failed!")
        except Exception as e:
            print utils.RED("Failure for %s" % str(e))

        # create another vm
        if vm_num == 2:
            print "not implemented now"

        return True

    def clear_vxlan_sample_env(self):
        if self.vm_dut:
            self.vm_dut.kill_all()
            time.sleep(1)

        if self.vm:
            self.vm.stop()
            self.vm = None

        self.dut.virt_exit()

    def mac_address_add(self, number):
        if number > 15:
            return ''
        mac = int(self.def_mac[-1]) + number
        return self.def_mac[:-1] + '%x' % mac

    def vm_testpmd_start(self, vm_id=0):
        """
        Start testpmd in virtual machine
        """
        if vm_id == 0 and self.vm_dut is not None:
            # start testpmd
            self.vm_dut.send_expect(self.vm_testpmd, "testpmd>", 20)
            # set fwd mac
            self.vm_dut.send_expect("set fwd io", "testpmd>")
            # start tx_first
            self.vm_dut.send_expect("start tx_first", "testpmd>")

    def test_vxlan_sample_encap(self):
        self.vm_testpmd_start(vm_id=0)
        self.send_and_verify(vm_id=0, vf_id=0, pkt_type="normal_udp")
        self.send_and_verify(vm_id=0, vf_id=1, pkt_type="normal_udp")

    def test_vxlan_sample_decap(self):
        self.vm_testpmd_start(vm_id=0)
        self.send_and_verify(vm_id=0, vf_id=0, pkt_type="vxlan_udp_decap")
        self.send_and_verify(vm_id=0, vf_id=1, pkt_type="vxlan_udp_decap")

    def test_vxlan_sample_encap_decap(self):
        self.vm_testpmd_start(vm_id=0)
        self.send_and_verify(vm_id=0, vf_id=0, pkt_type="vxlan_udp")
        self.send_and_verify(vm_id=0, vf_id=1, pkt_type="vxlan_udp")

    def test_vxlan_sample_chksum(self):
        self.vm_testpmd_start(vm_id=0)
        self.send_and_verify(vm_id=0, vf_id=0, pkt_type="vxlan_udp_chksum")
        self.send_and_verify(vm_id=0, vf_id=0, pkt_type="vxlan_tcp_chksum")
        self.send_and_verify(vm_id=0, vf_id=0, pkt_type="vxlan_sctp_chksum")

    def test_vxlan_sample_tso(self):
        self.vm_testpmd_start(vm_id=0)
        self.send_and_verify(vm_id=0, vf_id=0, pkt_type="vxlan_tcp_tso")

    def start_capture(self, itf, pkt_smac="", pkt_dmac="", count=1):
        self.tester.send_expect("rm -f %s" % self.capture_file, "# ")
        self.tester.scapy_background()
        if pkt_smac != "":
            self.tester.scapy_append('p = sniff(filter="ether src %s",' %
                                     pkt_smac +
                                     'iface="%s", count=%d, timeout=5)' %
                                     (itf, count))
        if pkt_dmac != "":
            self.tester.scapy_append('p = sniff(filter="ether dst %s",' %
                                     pkt_dmac +
                                     'iface="%s", count=%d, timeout=5)' %
                                     (itf, count))
        self.tester.scapy_append('wrpcap(\"%s\", p)' % self.capture_file)
        self.tester.scapy_foreground()

    def transfer_capture_file(self):
        # copy capture file from tester
        if os.path.isfile('vxlan_cap.pcap'):
            os.remove('vxlan_cap.pcap')
        self.tester.session.copy_file_from(self.capture_file)

        if os.path.isfile('vxlan_cap.pcap'):
            self.verify(
                os.path.getsize('vxlan_cap.pcap') != 0,
                "Packets receive error")
            pkts = rdpcap('vxlan_cap.pcap')
        else:
            pkts = []
        return pkts

    def send_and_verify(self, vm_id, vf_id, pkt_type):
        params = {}
        case_pass = True
        tester_recv_port = self.tester.get_local_port(self.pf)
        tester_iface = self.tester.get_interface(tester_recv_port)
        tester_smac = self.tester.get_mac(tester_recv_port)

        if pkt_type == "normal_udp":
            self.start_capture(tester_iface, pkt_smac=self.pf_mac)
            self.tester.scapy_append(
                'sendp([Ether(dst="%s",src="%s")/IP()/UDP()/Raw("X"*18)], iface="%s")'
                % (self.pf_mac, tester_smac, tester_iface))
            self.tester.scapy_execute()
            time.sleep(5)

            pkts = self.transfer_capture_file()
            self.verify(len(pkts) >= 1, "Failed to capture packets")
            self.verify(pkts[0].haslayer(Vxlan) == 1,
                        "Packet not encapsulated")
            try:
                payload = str(pkts[0][UDP][Vxlan][UDP].payload)
                for i in range(18):
                    self.verify(ord(payload[i]) == 88, "Check udp data failed")
            except:
                case_pass = False
                print utils.RED("Failure in checking packet payload")

            if case_pass:
                print utils.GREEN("Check normal udp packet forward pass on "
                                  "virtIO port %d" % vf_id)

        if pkt_type == "vxlan_udp_decap":
            # create vxlan packet pf mac + vni=1000 + inner virtIO port0 mac
            params['outer_mac_dst'] = self.pf_mac
            params['vni'] = 1000 + vm_id
            mac_incr = 2 * vm_id + vf_id
            params['inner_mac_dst'] = self.mac_address_add(mac_incr)

            # create vxlan pcap file and tranfer it to tester
            vxlan_pkt = VxlanTestConfig(self, **params)
            vxlan_pkt.create_pcap()

            # start capture
            self.start_capture(tester_iface, pkt_dmac=params['inner_mac_dst'])
            vxlan_pkt.send_pcap(tester_iface)
            time.sleep(5)

            # transfer capture pcap to server
            pkts = self.transfer_capture_file()
            # check packet number and payload
            self.verify(len(pkts) >= 1, "Failed to capture packets")
            self.verify(pkts[0].haslayer(Vxlan) == 0,
                        "Packet not de-encapsulated")

            try:
                payload = str(pkts[0][UDP].payload)
                for i in range(18):
                    self.verify(ord(payload[i]) == 88, "Check udp data failed")
            except:
                case_pass = False
                print utils.RED("Failure in checking packet payload")

            if case_pass:
                print utils.GREEN(
                    "Check vxlan packet decap pass on virtIO port"
                    " %d" % vf_id)

        if pkt_type == "vxlan_udp":
            # create vxlan packet pf mac + vni=1000 + inner virtIO port0 mac
            params['outer_mac_dst'] = self.pf_mac
            params['vni'] = 1000 + vm_id
            mac_incr = 2 * vm_id + vf_id
            params['inner_mac_dst'] = self.mac_address_add(mac_incr)

            # create vxlan pcap file and tranfer it to tester
            vxlan_pkt = VxlanTestConfig(self, **params)
            vxlan_pkt.create_pcap()

            # start capture
            self.start_capture(tester_iface, pkt_smac=self.pf_mac)
            vxlan_pkt.send_pcap(tester_iface)
            time.sleep(5)

            # transfer capture pcap to server
            pkts = self.transfer_capture_file()

            # check packet number and payload
            self.verify(len(pkts) >= 1, "Failed to capture packets")
            self.verify(pkts[0].haslayer(Vxlan) == 1,
                        "Packet not encapsulated")
            try:
                payload = str(pkts[0][UDP][Vxlan][UDP].payload)
                for i in range(18):
                    self.verify(ord(payload[i]) == 88, "Check udp data failed")
            except:
                case_pass = False
                print utils.RED("Failure in checking packet payload")

            if case_pass:
                print utils.GREEN("Check vxlan packet decap and encap pass on "
                                  "virtIO port %d" % vf_id)

        if pkt_type == "vxlan_udp_chksum":
            params['inner_l4_type'] = 'UDP'
        if pkt_type == "vxlan_tcp_chksum":
            params['inner_l4_type'] = 'TCP'
        if pkt_type == "vxlan_sctp_chksum":
            params['inner_l4_type'] = 'SCTP'

        if 'chksum' in pkt_type:
            # create vxlan packet pf mac + vni=1000 + inner virtIO port0 mac
            params['outer_mac_dst'] = self.pf_mac
            params['vni'] = 1000 + vm_id
            mac_incr = 2 * vm_id + vf_id
            params['inner_mac_dst'] = self.mac_address_add(mac_incr)
            # extract reference chksum value
            vxlan_pkt = VxlanTestConfig(self, **params)
            vxlan_pkt.create_pcap()
            chksums_ref = vxlan_pkt.get_chksums()
            print utils.GREEN("Checksum reference: %s" % chksums_ref)

            params['inner_ip_invalid'] = 1
            params['inner_l4_invalid'] = 1

            # create vxlan pcap file and tranfer it to tester
            vxlan_pkt = VxlanTestConfig(self, **params)
            vxlan_pkt.create_pcap()

            # start capture
            self.start_capture(tester_iface, pkt_smac=self.pf_mac)
            vxlan_pkt.send_pcap(tester_iface)
            time.sleep(5)
            # transfer capture pcap to server
            pkts = self.transfer_capture_file()
            # check packet number and payload
            self.verify(len(pkts) >= 1, "Failed to capture packets")
            self.verify(pkts[0].haslayer(Vxlan) == 1,
                        "Packet not encapsulated")
            chksums = vxlan_pkt.get_chksums(pcap='vxlan_cap.pcap')
            print utils.GREEN("Checksum : %s" % chksums)
            for key in chksums_ref:
                if 'inner' in key:  # only check inner packet chksum
                    self.verify(
                        chksums[key] == chksums_ref[key],
                        "%s not matched to %s" % (key, chksums_ref[key]))

            print utils.GREEN("%s checksum pass" % params['inner_l4_type'])

        if pkt_type == "vxlan_tcp_tso":
            # create vxlan packet pf mac + vni=1000 + inner virtIO port0 mac +
            # tcp
            params['inner_l4_type'] = 'TCP'
            params['outer_mac_dst'] = self.pf_mac
            params['vni'] = 1000 + vm_id
            mac_incr = 2 * vm_id + vf_id
            params['inner_mac_dst'] = self.mac_address_add(mac_incr)
            params['payload_size'] = 892  # 256 + 256 + 256 + 124

            # extract reference chksum value
            vxlan_pkt = VxlanTestConfig(self, **params)
            vxlan_pkt.create_pcap()

            # start capture
            self.start_capture(tester_iface, pkt_smac=self.pf_mac, count=4)
            vxlan_pkt.send_pcap(tester_iface)
            time.sleep(5)

            # transfer capture pcap to server
            pkts = self.transfer_capture_file()
            # check packet number and payload
            self.verify(len(pkts) == 4, "Failed to capture tso packets")

            # calculation  checksum, and checkt it
            for pkt in pkts:
                inner = pkt[Vxlan]
                inner_ip_chksum = inner[IP].chksum
                del inner.chksum
                inner[IP] = inner[IP].__class__(str(inner[IP]))
                inner_ip_chksum_ref = inner[IP].chksum
                print utils.GREEN("inner ip checksum reference: %x" %
                                  inner_ip_chksum_ref)
                print utils.GREEN("inner ip checksum: %x" % inner_ip_chksum)
                self.verify(inner_ip_chksum == inner_ip_chksum_ref,
                            "inner ip checksum error")
                inner_l4_chksum = inner[params['inner_l4_type']].chksum
                del inner[params['inner_l4_type']].chksum
                inner[params['inner_l4_type']] = inner[
                    params['inner_l4_type']].__class__(
                        str(inner[params['inner_l4_type']]))
                inner_l4_chksum_ref = inner[params['inner_l4_type']].chksum
                print utils.GREEN("inner l4 checksum reference: %x" %
                                  inner_l4_chksum_ref)
                print utils.GREEN("inner l4 checksum: %x" % inner_l4_chksum)
                self.verify(
                    inner_l4_chksum == inner_l4_chksum_ref,
                    "inner %s checksum error" % params['inner_l4_type'])

            length = 0
            for pkt in pkts:
                self.verify(
                    pkt.haslayer(Vxlan) == 1, "Packet not encapsulated")
                try:
                    payload = str(pkt[UDP][Vxlan][TCP].payload)
                    self.verify(
                        len(payload) <= self.def_mss, "TCP payload oversized")
                    length += len(payload)
                except:
                    case_pass = False
                    print utils.RED("Failure in checking tso payload")

            self.verify(length == 892, "Total tcp payload size not match")
            if case_pass:
                print utils.GREEN("Vxlan packet tso pass on virtIO port %d" %
                                  vf_id)

    def test_perf_vxlan_sample(self):
        # vxlan payload length for performance test
        # inner packet not contain crc, should need add four
        vxlan_payload = PACKET_LEN - HEADER_SIZE['eth'] - \
            HEADER_SIZE['ip'] - HEADER_SIZE['udp'] - \
            HEADER_SIZE['vxlan'] - HEADER_SIZE['eth'] - \
            HEADER_SIZE['ip'] - HEADER_SIZE['udp'] + 4

        vxlansample_header = ['Type', 'Queue', 'Mpps', '% linerate']
        self.result_table_create(vxlansample_header)
        for perf_cfg in self.perf_cfg:
            func = perf_cfg['Func']
            if func is 'Decap':
                encap = self.FEAT_DISABLE
                decap = self.FEAT_ENABLE
                chksum = self.FEAT_DISABLE
            elif func is 'Encap':
                encap = self.FEAT_ENABLE
                decap = self.FEAT_DISABLE
                chksum = self.FEAT_DISABLE
            elif func is 'Decap&Encap':
                encap = self.FEAT_ENABLE
                decap = self.FEAT_ENABLE
                chksum = self.FEAT_DISABLE
            elif func is 'Checksum':
                encap = self.FEAT_ENABLE
                decap = self.FEAT_DISABLE
                chksum = self.FEAT_ENABLE
            elif func is 'Checksum&Decap':
                encap = self.FEAT_ENABLE
                decap = self.FEAT_ENABLE
                chksum = self.FEAT_ENABLE

            tep_cmd_temp = self.tep_app + " -c %(COREMASK)s -n %(CHANNELS)d " \
                + "--socket-mem 2048,2048 -- -p 0x1 --udp-port " \
                + "%(VXLAN_PORT)d  --nb-devices %(NB_DEVS)d --filter-type " \
                + "%(FILTERS)d --tx-checksum %(TX_CHKS)d --encap %(ENCAP)d " \
                + "--decap %(DECAP)d --rx-retry 1 --rx-retry-num 4 " \
                + "--rx-retry-delay 15"

            tep_cmd = tep_cmd_temp % {
                'COREMASK': self.coremask,
                'CHANNELS': self.dut.get_memory_channels(),
                'VXLAN_PORT': self.vxlan_port,
                'NB_DEVS': 2,
                'FILTERS': self.OUTER_INNER_VNI,
                'TX_CHKS': chksum,
                'ENCAP': encap,
                'DECAP': decap
            }

            self.prepare_vxlan_sample_env(tep_cmd, vm_num=1)
            self.vm_testpmd_start(vm_id=0)

            # create vxlan packet pf mac + vni=1000 + inner virtIO port0 mac
            params = {}
            params['outer_mac_dst'] = self.pf_mac
            params['vni'] = 1000
            mac_incr = 0
            params['inner_mac_dst'] = self.mac_address_add(mac_incr)
            params['payload_size'] = vxlan_payload
            params['pcap_file'] = 'vxlan_sample.pcap'

            # create vxlan pcap file and tranfer it to tester
            vxlan_pkt = VxlanTestConfig(self, **params)
            vxlan_pkt.create_pcap()

            if perf_cfg['VirtIO'] == "Two Ports":
                # create vxlan packet pf mac + vni=1000 + inner virtIO port0
                # mac
                params['outer_mac_dst'] = self.pf_mac
                params['vni'] = 1000
                mac_incr = 1
                params['inner_mac_dst'] = self.mac_address_add(mac_incr)
                params['pcap_file'] = 'vxlan_sample_1.pcap'

                # create vxlan pcap file and tranfer it to tester
                vxlan_pkt = VxlanTestConfig(self, **params)
                vxlan_pkt.create_pcap(scp=False)

                self.combine_pcap("vxlan_sample.pcap", "vxlan_sample_1.pcap")

            self.tester.session.copy_file_to("vxlan_sample.pcap")

            # config the flows
            tgen_input = []
            tgen_input.append(
                (self.tester.get_local_port(self.pf),
                 self.tester.get_local_port(self.pf), "vxlan_sample.pcap"))

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

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

            pps /= 1000000.0
            perf_cfg['Mpps'] = pps
            wirespeed = self.wirespeed(self.nic, PACKET_LEN, 1)
            perf_cfg['pct'] = pps * 100 / wirespeed

            table_row = [
                perf_cfg['Func'], perf_cfg['VirtIO'], perf_cfg['Mpps'],
                perf_cfg['pct']
            ]

            self.result_table_add(table_row)

            self.tear_down()

        self.result_table_print()

    def combine_pcap(self, dest_pcap, src_pcap):
        pkts = rdpcap(dest_pcap)
        if len(pkts) != 1:
            return

        pkts_src = rdpcap(src_pcap)
        pkts += pkts_src

        wrpcap(dest_pcap, pkts)

    def tear_down(self):
        """
        Run after each test suite.
        """
        # send packet to pf, verify capture packet sent from virtIO port1
        self.clear_vxlan_sample_env()

        self.dut.kill_all()
        time.sleep(2)
        pass

    def tear_down_all(self):
        """
        Run after each test suite.
        """
        # Restore the config file and recompile the package.
        self.dut.send_expect(
            "sed -i -e 's/RTE_LIBRTE_VHOST=y$/" +
            "RTE_LIBRTE_VHOST=n/' config/common_base", "# ", 30)
        # temporary disable skip_setup
        skip_setup = self.dut.skip_setup
        self.dut.skip_setup = False
        self.dut.build_install_dpdk(self.target)
        self.dut.skip_setup = skip_setup
        # wait for build done
        time.sleep(20)
        pass
Exemplo n.º 13
0
class TestVirtioIperf(TestCase):
    def set_up_all(self):
        self.vhost_legacy_virtio_cmdline = "csum=off,gso=off,guest_csum=off,guest_tso4=off,guest_tso6=off,guest_ecn=off"
        self.vhost_cuse_virtio_cmdline = "csum=off,gso=off,guest_csum=off,guest_tso4=off,guest_tso6=off,guest_ecn=off"
        self.vhost_user_virtio_cmdline = ""
        self.virtio_mac = ["52:54:00:00:00:01", "52:54:00:00:00:02"]
        self.virtio_ip = ["1.1.1.2", "1.1.1.3"]
        self.vm = []
        self.vm_dut = []

        self.dut_ports = self.dut.get_ports(self.nic)
        self.verify(len(self.dut_ports) >= 1, 'Insufficient ports for test')

        self.phy_function = self.dut_ports[0]
        netdev = self.dut.ports_info[self.phy_function]['port']
        self.socket = netdev.get_nic_socket()
        self.cores = self.dut.get_core_list("1S/3C/1T", socket=self.socket)
        self.coremask = utils.create_mask(self.cores)

    def set_up(self):
        pass

    def dut_execut_cmd(self, cmdline, ex='#', timout=30):
        return self.dut.send_expect(cmdline, ex, timout)

    def build_vhost_lib(self, vhost='user'):
        self.dut_execut_cmd('git clean -x -d -f')
        self.dut_execut_cmd('git checkout *')
        if vhost == 'cuse':
            self.dut_execut_cmd(
                "sed -i -e 's/CONFIG_RTE_LIBRTE_VHOST_USER=.*$/CONFIG_RTE_LIBRTE"
                + "_VHOST_USER=n/' ./config/common_base")
        else:
            self.dut_execut_cmd(
                "sed -i -e 's/CONFIG_RTE_LIBRTE_VHOST_USER=.*$/CONFIG_RTE_LIBRTE"
                + "_VHOST_USER=y/' ./config/common_base")
        self.dut.build_install_dpdk(self.target)
        self.dut_execut_cmd("cd ./lib/librte_vhost")
        out = self.dut_execut_cmd("make")
        self.verify('Error' not in out, 'bulid err: build lib vhost failed')
        self.dut_execut_cmd("cd ./eventfd_link")
        out = self.dut_execut_cmd("make")
        self.verify('Error' not in out, 'bulid err: build eventfd_link failed')
        self.dut_execut_cmd("cd ~/dpdk")

    def build_vhost_app(self):
        if self.nic in "niantic":
            self.dut_execut_cmd(
                "sed -i -e 's/define MAX_QUEUES.*/define MAX_QUEUES 128/' " +
                "./examples/vhost/main.c")
        else:
            self.dut_execut_cmd(
                "sed -i -e 's/define MAX_QUEUES.*/define MAX_QUEUES 512/' " +
                "./examples/vhost/main.c")
        out = self.dut_execut_cmd("make -C ./examples/vhost")
        self.verify("Error" not in out, "compilation error")
        self.verify("No such file" not in out, "Not found file error")

    def launch_vhost_switch(self, coremask, channel, jumbo, scenario):
        self.vhost_switch = "./examples/vhost/build/vhost-switch"
        self.vhost_switch_cmd = self.vhost_switch + \
        " -c %s -n %d --socket-mem 2048,2048 -- -p 0x1" + \
        " --mergeable %d --zero-copy 0 --vm2vm %d  > ./vhost.out &"
        self.dut_execut_cmd(self.vhost_switch_cmd %
                            (coremask, channel, jumbo, scenario))
        time.sleep(20)
        self.dut.session.copy_file_from('/root/dpdk/vhost.out')
        time.sleep(5)
        fp = open('./vhost.out')
        fmsg = fp.read()
        fp.close()
        if 'Error' or 'error' in fmsg:
            print 'launch vhost sample failed'
            return False
        else:
            return True

    def iperf_result_verify(self, vm_client):
        '''
        vm_client.session.copy_file_from("/root/dpdk/iperf_client.log")
        self.tester.send_expect('scp -P')
        '''
        vm_client.session.copy_file_from("/root/dpdk/iperf_client.log")
        fp = open("./iperf_client.log")
        fmsg = fp.read()
        iperfdata = re.compile('[\d+]*.[\d+] [M|G]bits/sec').findall(fmsg)
        self.result_table_create(['Data', 'Unit'])
        for data in iperfdata:
            self.results_table_add([data.split()[0], data.split()[1]])
        self.result_table_print()
        os.popen("rm -rf ./iperf_client.log")

    def test_perf_vhost_legacy_virtio_iperf(self):
        pass

    def test_perf_vhost_cuse_virtio_iperf(self):
        """
        vhost cuse as back end, legacy virtio dirver as front end
        """
        self.build_vhost_lib(vhost='cuse')
        self.build_vhost_app()
        self.dut_execut_cmd('rm -rf /dev/vhost-net')
        self.dut_execut_cmd('rmmod igb_uio -f')
        self.dut_execut_cmd('rmmod eventfd_link')
        self.dut_execut_cmd('modprobe uio')
        self.dut_execut_cmd('modprobe fuse')
        self.dut_execut_cmd('modprobe cuse')
        self.dut_execut_cmd(
            'insmod ./x86_64-native-linuxapp-gcc/kmod/igb_uio.ko')
        self.dut_execut_cmd(
            'insmod ./lib/librte_vhost/eventfd_link/eventfd_link.ko')
        self.dut.bind_interfaces_linux(self.drivername)
        self.launch_vhost_switch(self.coremask, 4, 0, 1)

        self.vm1 = QEMUKvm(self.dut, 'vm0', 'virtio_iperf')
        vm1_params = {}
        vm1_params['driver'] = 'vhost-cuse'
        vm1_params['opt_tap'] = 'vhost0'
        vm1_params['opt_mac'] = self.virtio_mac[0]
        vm1_params['opt_settings'] = self.vhost_cuse_virtio_cmdline
        self.vm1.set_vm_device(**vm1_params)
        try:
            self.vm1_dut = self.vm1.start(auto_portmap=False)
            time.sleep(10)
            if self.vm1_dut is None:
                raise Exception('VM1 start failed')
        except Exception as e0:
            print utils.RED('VM1 already exist, powerdown it first')
        self.vm1_dut.restore_interfaces()

        self.vm2 = QEMUKvm(self.dut, 'vm1', 'virtio_iperf')
        vm2_params = {}
        vm2_params['driver'] = 'vhost-cuse'
        vm2_params['opt_tap'] = 'vhost1'
        vm2_params['opt_mac'] = self.virtio_mac[1]
        vm2_params['opt_settings'] = self.vhost_cuse_virtio_cmdline
        self.vm2.set_vm_device(**vm2_params)
        try:
            self.vm2_dut = self.vm2.start(auto_portmap=False)
            time.sleep(10)
            if self.vm2_dut is None:
                raise Exception('VM2 start failed')
        except Exception as e1:
            print utils.RED('VM2 already exist, powerdown it first')
        self.vm2_dut.restore_interfaces()

        #self.start_iperf_server()
        vm1_vport = self.vm1_dut.send_expect('ifconfig -a', '#', 30)
        print 'vm net port:'
        print vm1_vport
        intfs = re.compile('eth\d').findall(vm1_vport)
        for intf in intfs:
            outmac = self.vm1_dut.send_expect('ifconfig %s' % intf, '#', 30)
            if self.virtio_mac[0] in outmac:
                self.vm1_intf = intf
        self.vm1_dut.send_expect(
            'ifconfig %s %s' % (self.vm1_intf, self.virtio_ip[0]), '#', 10)
        self.vm1_dut.send_expect('ifconfig %s up' % self.vm1_intf, '#', 10)
        self.vm1_dut.send_expect(
            'arp -s %s %s' % (self.virtio_ip[1], self.virtio_mac[1]), '#', 10)
        self.vm1_dut.send_expect('iperf -s -p 12345 -i 1 > iperf_server.log &',
                                 '', 10)

        #self.start_iperf_client()
        vm2_vport = self.vm2_dut.send_expect('ifconfig -a', '#', 30)
        print 'vm net port:'
        print vm2_vport
        intfs = re.compile('eth\d').findall(vm2_vport)
        for intf in intfs:
            outmac = self.vm2_dut.send_expect('ifconfig %s' % intf, '#', 30)
            if self.virtio_mac[1] in outmac:
                self.vm2_intf = intf
        self.vm2_dut.send_expect(
            'ifconfig %s %s' % (self.vm2_intf, self.virtio_ip[1]), '#', 10)
        self.vm2_dut.send_expect('ifconfig %s up' % self.vm2_intf, '#', 10)
        self.vm2_dut.send_expect(
            'arp -s %s %s' % (self.virtio_ip[0], self.virtio_mac[0]), '#', 10)
        self.vm2_dut.send_expect(
            'iperf -c %s -p 12345 -i 1 -t 60 > iperf_client.log &' %
            self.virtio_ip[0], '', 60)
        time.sleep(70)
        self.vm1_dut.send_expect("killall -s INT iperf", '', 10)
        self.iperf_result_verify(self.vm2_dut)

    def test_perf_vhost_user_virtio_iperf(self):
        """
        vhost user as back end, legacy virtio dirver as front end
        """
        self.build_vhost_lib(vhost='user')
        self.build_vhost_app()
        #self.dut_execut_cmd('rm -rf /dev/vhost-net')
        self.dut_execut_cmd('rmmod igb_uio -f')
        self.dut_execut_cmd('rmmod eventfd_link')
        self.dut_execut_cmd('modprobe uio')
        #self.dut_execut_cmd('modprobe fuse')
        #self.dut_execut_cmd('modprobe cuse')
        self.dut_execut_cmd(
            'insmod ./x86_64-native-linuxapp-gcc/kmod/igb_uio.ko')
        self.dut_execut_cmd(
            'insmod ./lib/librte_vhost/eventfd_link/eventfd_link.ko')
        self.dut.bind_interfaces_linux(self.drivername)
        self.launch_vhost_switch(self.coremask, 4, 0, 1)

        self.vm1 = QEMUKvm(self.dut, 'vm0', 'virtio_iperf')
        vm1_params = {}
        vm1_params['driver'] = 'vhost-user'
        vm1_params['opt_path'] = './vhost-net'
        vm1_params['opt_mac'] = self.virtio_mac[0]
        self.vm1.set_vm_device(**vm1_params)
        try:
            self.vm1_dut = self.vm1.start(auto_portmap=False)
            if self.vm1_dut is None:
                raise Exception('VM1 start failed')
        except Exception as e0:
            print utils.RED('VM1 already exist, powerdown it first')
        self.vm1_dut.restore_interfaces()

        self.vm2 = QEMUKvm(self.dut, 'vm1', 'virtio_iperf')
        vm2_params = {}
        vm2_params['driver'] = 'vhost-user'
        vm2_params['opt_path'] = './vhost-net'
        vm2_params['opt_mac'] = self.virtio_mac[1]
        self.vm2.set_vm_device(**vm2_params)
        try:
            self.vm2_dut = self.vm2.start(auto_portmap=False)
            if self.vm2_dut is None:
                raise Exception('VM2 start failed')
        except Exception as e1:
            print utils.RED('VM2 already exist, powerdown it first')

        self.vm2_dut.restore_interfaces()

        #self.start_iperf_server()
        vm1_vport = self.vm1_dut.send_expect('ifconfig -a', '#', 30)
        print 'vm net port:'
        print vm1_vport
        intfs = re.compile('eth\d').findall(vm1_vport)
        for intf in intfs:
            outmac = self.vm1_dut.send_expect('ifconfig %s' % intf, '#', 30)
            if self.virtio_mac[0] in outmac:
                self.vm1_intf = intf
        self.vm1_dut.send_expect(
            'ifconfig %s %s' % (self.vm1_intf, self.virtio_ip[0]), '#', 10)
        self.vm1_dut.send_expect('ifconfig %s up' % self.vm1_intf, '#', 10)
        self.vm1_dut.send_expect(
            'arp -s %s %s' % (self.virtio_ip[1], self.virtio_mac[1]), '#', 10)
        self.vm1_dut.send_expect('iperf -s -p 12345 -i 1 > iperf_server.log &',
                                 '', 10)

        #self.start_iperf_client()
        vm2_vport = self.vm2_dut.send_expect('ifconfig -a', '#', 30)
        print 'vm net port:'
        print vm2_vport
        intfs = re.compile('eth\d').findall(vm2_vport)
        for intf in intfs:
            outmac = self.vm2_dut.send_expect('ifconfig %s' % intf, '#', 30)
            if self.virtio_mac[1] in outmac:
                self.vm2_intf = intf
        self.vm2_dut.send_expect(
            'ifconfig %s %s' % (self.vm2_intf, self.virtio_ip[1]), '#', 10)
        self.vm2_dut.send_expect('ifconfig %s up' % self.vm2_intf, '#', 10)
        self.vm2_dut.send_expect(
            'arp -s %s %s' % (self.virtio_ip[0], self.virtio_mac[0]), '#', 10)
        self.vm2_dut.send_expect(
            'iperf -c %s -p 12345 -i 1 -t 60 > iperf_client.log &' %
            self.virtio_ip[0], '', 60)
        time.sleep(70)

        self.vm1_dut.session.send_expect('killall -s INT iperf', '#', 10)
        self.iperf_result_verify(self.vm2_dut)

    def tear_down(self):
        if self.vm2:
            self.vm2.stop()
            self.vm2 = None
        if self.vm1:
            self.vm1.stop()
            self.vm1 = None
        self.dut.send_expect("killall -s INT vhost-switch", "#")

    def tear_down_all(self):
        pass
Exemplo n.º 14
0
class TestVfOffload(TestCase):
    def set_up_all(self):
        self.dut_ports = self.dut.get_ports(self.nic)
        self.verify(len(self.dut_ports) > 1, "Insufficient ports")
        self.vm0 = None
        self.setup_2pf_2vf_1vm_env_flag = 0
        self.setup_2pf_2vf_1vm_env(driver='')
        self.vm0_dut_ports = self.vm_dut_0.get_ports('any')
        self.portMask = utils.create_mask([self.vm0_dut_ports[0]])
        self.vm0_testpmd = PmdOutput(self.vm_dut_0)

    def set_up(self):
        pass

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

        self.used_dut_port_0 = self.dut_ports[0]
        self.dut.generate_sriov_vfs_by_port(self.used_dut_port_0,
                                            1,
                                            driver=driver)
        self.sriov_vfs_port_0 = self.dut.ports_info[
            self.used_dut_port_0]['vfs_port']
        self.used_dut_port_1 = self.dut_ports[1]
        self.dut.generate_sriov_vfs_by_port(self.used_dut_port_1,
                                            1,
                                            driver=driver)
        self.sriov_vfs_port_1 = self.dut.ports_info[
            self.used_dut_port_1]['vfs_port']

        try:

            for port in self.sriov_vfs_port_0:
                port.bind_driver('pci-stub')

            for port in self.sriov_vfs_port_1:
                port.bind_driver('pci-stub')

            time.sleep(1)
            vf0_prop = {'opt_host': self.sriov_vfs_port_0[0].pci}
            vf1_prop = {'opt_host': self.sriov_vfs_port_1[0].pci}

            if driver == 'igb_uio':
                # start testpmd without the two VFs on the host
                self.host_testpmd = PmdOutput(self.dut)
                eal_param = '-b %(vf0)s -b %(vf1)s' % {
                    'vf0': self.sriov_vfs_port_0[0].pci,
                    'vf1': self.sriov_vfs_port_1[0].pci
                }
                self.host_testpmd.start_testpmd("1S/2C/2T",
                                                eal_param=eal_param)

            # set up VM0 ENV
            self.vm0 = QEMUKvm(self.dut, 'vm0', 'vf_offload')
            self.vm0.set_vm_device(driver='pci-assign', **vf0_prop)
            self.vm0.set_vm_device(driver='pci-assign', **vf1_prop)
            self.vm_dut_0 = self.vm0.start()
            if self.vm_dut_0 is None:
                raise Exception("Set up VM0 ENV failed!")

            self.setup_2pf_2vf_1vm_env_flag = 1
        except Exception as e:
            self.destroy_2pf_2vf_1vm_env()
            raise Exception(e)

    def destroy_2pf_2vf_1vm_env(self):
        if getattr(self, 'vm0', None):
            #destroy testpmd in vm0
            self.vm0_testpmd = None
            self.vm0_dut_ports = None
            #destroy vm0
            self.vm0.stop()
            self.dut.virt_exit()
            self.vm0 = None

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

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

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

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

        self.setup_2pf_2vf_1vm_env_flag = 0

    def checksum_enablehw(self, port, dut):
        dut.send_expect("csum set ip hw %d" % port, "testpmd>")
        dut.send_expect("csum set udp hw %d" % port, "testpmd>")
        dut.send_expect("csum set tcp hw %d" % port, "testpmd>")
        dut.send_expect("csum set sctp hw %d" % port, "testpmd>")

    def checksum_enablesw(self, port, dut):
        dut.send_expect("csum set ip sw %d" % port, "testpmd>")
        dut.send_expect("csum set udp sw %d" % port, "testpmd>")
        dut.send_expect("csum set tcp sw %d" % port, "testpmd>")
        dut.send_expect("csum set sctp sw %d" % port, "testpmd>")

    def checksum_validate(self, packets_sent, packets_expected):
        """
        Validate the checksum.
        """
        tx_interface = self.tester.get_interface(
            self.tester.get_local_port(self.dut_ports[0]))
        rx_interface = self.tester.get_interface(
            self.tester.get_local_port(self.dut_ports[0]))

        sniff_src = self.vm0_testpmd.get_port_mac(0)
        checksum_pattern = re.compile("chksum.*=.*(0x[0-9a-z]+)")

        chksum = dict()
        result = dict()

        self.tester.send_expect("scapy", ">>> ")

        for packet_type in packets_expected.keys():
            self.tester.send_expect("p = %s" % packets_expected[packet_type],
                                    ">>>")
            out = self.tester.send_expect("p.show2()", ">>>")
            chksums = checksum_pattern.findall(out)
            chksum[packet_type] = chksums
            print packet_type, ": ", chksums

        self.tester.send_expect("exit()", "#")

        self.tester.scapy_background()
        self.tester.scapy_append(
            'p = sniff(filter="ether src %s", iface="%s", count=%d)' %
            (sniff_src, rx_interface, len(packets_sent)))
        self.tester.scapy_append('nr_packets=len(p)')
        self.tester.scapy_append(
            'reslist = [p[i].sprintf("%IP.chksum%;%TCP.chksum%;%UDP.chksum%;%SCTP.chksum%") for i in range(nr_packets)]'
        )
        self.tester.scapy_append('import string')
        self.tester.scapy_append('RESULT = string.join(reslist, ",")')

        # Send packet.
        self.tester.scapy_foreground()

        for packet_type in packets_sent.keys():
            self.tester.scapy_append('sendp([%s], iface="%s")' %
                                     (packets_sent[packet_type], tx_interface))

        self.tester.scapy_execute()
        out = self.tester.scapy_get_result()
        packets_received = out.split(',')
        self.verify(
            len(packets_sent) == len(packets_received),
            "Unexpected Packets Drop")

        for packet_received in packets_received:
            ip_checksum, tcp_checksum, udp_checksup, sctp_checksum = packet_received.split(
                ';')
            print "ip_checksum: ", ip_checksum, "tcp_checksum:, ", tcp_checksum, "udp_checksup: ", udp_checksup, "sctp_checksum: ", sctp_checksum

            packet_type = ''
            l4_checksum = ''
            if tcp_checksum != '??':
                packet_type = 'TCP'
                l4_checksum = tcp_checksum
            elif udp_checksup != '??':
                packet_type = 'UDP'
                l4_checksum = udp_checksup
            elif sctp_checksum != '??':
                packet_type = 'SCTP'
                l4_checksum = sctp_checksum

            if ip_checksum != '??':
                packet_type = 'IP/' + packet_type
                if chksum[packet_type] != [ip_checksum, l4_checksum]:
                    result[packet_type] = packet_type + " checksum error"
            else:
                packet_type = 'IPv6/' + packet_type
                if chksum[packet_type] != [l4_checksum]:
                    result[packet_type] = packet_type + " checksum error"

        return result

    def test_checksum_offload_enable(self):
        """
        Enable HW Checksum offload.
        Send packet with incorrect checksum, 
        can rx it and reported the checksum error, 
        verify forwarded packets have correct checksum
        """
        self.vm0_testpmd.start_testpmd(
            VM_CORES_MASK, "--portmask=%s " % (self.portMask) +
            "--disable-hw-vlan --enable-rx-cksum " + "--txqflags=0 " +
            "--port-topology=loop")
        self.vm0_testpmd.execute_cmd('set fwd csum')

        time.sleep(2)
        port_id_0 = 0
        mac = self.vm0_testpmd.get_port_mac(0)

        sndIP = '10.0.0.1'
        sndIPv6 = '::1'
        pkts = {
            'IP/UDP':
            'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="%s", chksum=0xf)/UDP(chksum=0xf)/("X"*46)'
            % (mac, sndIP),
            'IP/TCP':
            'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="%s", chksum=0xf)/TCP(chksum=0xf)/("X"*46)'
            % (mac, sndIP),
            'IP/SCTP':
            'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="%s", chksum=0xf)/SCTP(chksum=0xf)/("X"*48)'
            % (mac, sndIP),
            'IPv6/UDP':
            'Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="%s")/UDP(chksum=0xf)/("X"*46)'
            % (mac, sndIPv6),
            'IPv6/TCP':
            'Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="%s")/TCP(chksum=0xf)/("X"*46)'
            % (mac, sndIPv6)
        }

        expIP = sndIP
        expIPv6 = sndIPv6
        pkts_ref = {
            'IP/UDP':
            'Ether(dst="02:00:00:00:00:00", src="%s")/IP(src="%s")/UDP()/("X"*46)'
            % (mac, expIP),
            'IP/TCP':
            'Ether(dst="02:00:00:00:00:00", src="%s")/IP(src="%s")/TCP()/("X"*46)'
            % (mac, expIP),
            'IP/SCTP':
            'Ether(dst="02:00:00:00:00:00", src="%s")/IP(src="%s")/SCTP()/("X"*48)'
            % (mac, expIP),
            'IPv6/UDP':
            'Ether(dst="02:00:00:00:00:00", src="%s")/IPv6(src="%s")/UDP()/("X"*46)'
            % (mac, expIPv6),
            'IPv6/TCP':
            'Ether(dst="02:00:00:00:00:00", src="%s")/IPv6(src="%s")/TCP()/("X"*46)'
            % (mac, expIPv6)
        }

        if self.nic in ['redrockcanyou', 'atwood']:
            del pkts['IP/SCTP']
            del pkts_ref['IP/SCTP']

        self.checksum_enablehw(0, self.vm_dut_0)

        self.vm0_testpmd.execute_cmd('start')
        result = self.checksum_validate(pkts, pkts_ref)

        # Validate checksum on the receive packet
        out = self.vm0_testpmd.execute_cmd('stop')
        bad_ipcsum = self.vm0_testpmd.get_pmd_value("Bad-ipcsum:", out)
        bad_l4csum = self.vm0_testpmd.get_pmd_value("Bad-l4csum:", out)
        self.verify(bad_ipcsum == 3, "Bad-ipcsum check error")
        self.verify(bad_l4csum == 5, "Bad-l4csum check error")

        self.verify(len(result) == 0, string.join(result.values(), ","))

    def test_checksum_offload_disable(self):
        """
        disable HW checksum offload on tx port, SW Checksum check.
        SW Checksum on by default.
        Send same packet with incorrect checksum and verify checksum is valid.
        """

        self.vm0_testpmd.start_testpmd(
            VM_CORES_MASK, "--portmask=%s " % (self.portMask) +
            "--disable-hw-vlan --enable-rx-cksum " + "--port-topology=loop")
        self.vm0_testpmd.execute_cmd('set fwd csum')

        time.sleep(2)

        mac = self.vm0_testpmd.get_port_mac(0)
        sndIP = '10.0.0.1'
        sndIPv6 = '::1'
        sndPkts = {
            'IP/UDP':
            'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="%s",chksum=0xf)/UDP(chksum=0xf)/("X"*46)'
            % (mac, sndIP),
            'IP/TCP':
            'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="%s",chksum=0xf)/TCP(chksum=0xf)/("X"*46)'
            % (mac, sndIP),
            'IPv6/UDP':
            'Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="%s")/UDP(chksum=0xf)/("X"*46)'
            % (mac, sndIPv6),
            'IPv6/TCP':
            'Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="%s")/TCP(chksum=0xf)/("X"*46)'
            % (mac, sndIPv6)
        }

        expIP = sndIP
        expIPv6 = sndIPv6
        expPkts = {
            'IP/UDP':
            'Ether(dst="02:00:00:00:00:00", src="%s")/IP(src="%s")/UDP()/("X"*46)'
            % (mac, expIP),
            'IP/TCP':
            'Ether(dst="02:00:00:00:00:00", src="%s")/IP(src="%s")/TCP()/("X"*46)'
            % (mac, expIP),
            'IPv6/UDP':
            'Ether(dst="02:00:00:00:00:00", src="%s")/IPv6(src="%s")/UDP()/("X"*46)'
            % (mac, expIPv6),
            'IPv6/TCP':
            'Ether(dst="02:00:00:00:00:00", src="%s")/IPv6(src="%s")/TCP()/("X"*46)'
            % (mac, expIPv6)
        }

        self.vm0_testpmd.execute_cmd('start')
        result = self.checksum_validate(sndPkts, expPkts)

        # Validate checksum on the receive packet
        out = self.vm0_testpmd.execute_cmd('stop')
        bad_ipcsum = self.vm0_testpmd.get_pmd_value("Bad-ipcsum:", out)
        bad_l4csum = self.vm0_testpmd.get_pmd_value("Bad-l4csum:", out)
        self.verify(bad_ipcsum == 2, "Bad-ipcsum check error")
        self.verify(bad_l4csum == 4, "Bad-l4csum check error")

        self.verify(len(result) == 0, string.join(result.values(), ","))

    def tcpdump_start_sniffing(self, ifaces=[]):
        """
        Starts tcpdump in the background to sniff the tester interface where
        the packets are transmitted to and from the self.dut.
        All the captured packets are going to be stored in a file for a
        post-analysis.
        """

        for iface in ifaces:
            command = ('tcpdump -w tcpdump_{0}.pcap -i {0} 2>tcpdump_{0}.out &'
                       ).format(iface)
            self.tester.send_expect('rm -f tcpdump_{0}.pcap',
                                    '#').format(iface)
            self.tester.send_expect(command, '#')

    def tcpdump_stop_sniff(self):
        """
        Stops the tcpdump process running in the background.
        """
        self.tester.send_expect('killall tcpdump', '#')
        time.sleep(1)
        self.tester.send_expect('echo "Cleaning buffer"', '#')
        time.sleep(1)

    def tcpdump_command(self, command):
        """
        Sends a tcpdump related command and returns an integer from the output
        """

        result = self.tester.send_expect(command, '#')
        print result
        return int(result.strip())

    def number_of_packets(self, iface):
        """
        By reading the file generated by tcpdump it counts how many packets were
        forwarded by the sample app and received in the self.tester. The sample app
        will add a known MAC address for the test to look for.
        """

        command = (
            'tcpdump -A -nn -e -v -r tcpdump_{iface}.pcap 2>/dev/null | ' +
            'grep -c "seq"')
        return self.tcpdump_command(command.format(**locals()))

    def test_tso(self):
        """
        TSO IPv4 TCP, IPv6 TCP, VXLan testing
        """
        tx_interface = self.tester.get_interface(
            self.tester.get_local_port(self.dut_ports[0]))
        rx_interface = self.tester.get_interface(
            self.tester.get_local_port(self.dut_ports[1]))

        self.frame_sizes = [128, 1458]
        self.headers_size = HEADER_SIZE['eth'] + HEADER_SIZE[
            'ip'] + HEADER_SIZE['tcp']
        padding = self.frame_sizes[0] - self.headers_size

        self.tester.send_expect(
            "ethtool -K %s rx off tx off tso off gso off gro off lro off" %
            tx_interface, "# ")
        self.tester.send_expect("ip l set %s up" % tx_interface, "# ")

        self.portMask = utils.create_mask([self.vm0_dut_ports[0]])
        self.vm0_testpmd.start_testpmd(
            VM_CORES_MASK, "--portmask=%s " % (self.portMask) +
            "--enable-rx-cksum " + "--txqflags=0 " + "--port-topology=loop")

        mac = self.vm0_testpmd.get_port_mac(0)

        self.checksum_enablehw(0, self.vm_dut_0)
        self.vm0_testpmd.execute_cmd("tso set 800 %d" % self.vm0_dut_ports[1])
        self.vm0_testpmd.execute_cmd("set fwd csum")
        self.vm0_testpmd.execute_cmd("start")

        self.tester.scapy_foreground()
        time.sleep(5)

        # IPv4 tcp test

        self.tcpdump_start_sniffing([tx_interface, rx_interface])
        self.tester.scapy_append(
            'sendp([Ether(dst="%s",src="52:00:00:00:00:00")/IP(src="192.168.1.1",dst="192.168.1.2")/TCP(sport=1021,dport=1021)/("X"*%s)], iface="%s")'
            % (mac, padding, tx_interface))
        out = self.tester.scapy_execute()
        out = self.vm0_testpmd.execute_cmd("show port stats all")
        print out
        self.tcpdump_stop_sniff()
        rx_stats = self.number_of_packets(rx_interface)
        if (rx_stats == 2):
            self.verify(1, "Pass")

        # IPv6 tcp test

        self.tcpdump_start_sniffing([tx_interface, rx_interface])
        self.tester.scapy_append(
            'sendp([Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="FE80:0:0:0:200:1FF:FE00:200", dst="3555:5555:6666:6666:7777:7777:8888:8888")/TCP(sport=1021,dport=1021)/("X"*%s)], iface="%s")'
            % (mac, padding, tx_interface))
        out = self.tester.scapy_execute()
        out = self.vm0_testpmd.execute_cmd("show port stats all")
        print out
        self.tcpdump_stop_sniff()
        rx_stats = self.number_of_packets(rx_interface)
        if (rx_stats == 2):
            self.verify(1, "Pass")

    def tear_down(self):
        self.vm0_testpmd.execute_cmd('quit', '# ')
        pass

    def tear_down_all(self):
        print "tear_down_all"
        if self.setup_2pf_2vf_1vm_env_flag == 1:
            self.destroy_2pf_2vf_1vm_env()
Exemplo n.º 15
0
class TestVhostCuseOneCopyOneVm(TestCase, IxiaPacketGenerator):
    def set_up_all(self):
        # To Extend IXIA packet generator method, call the tester's method.
        self.tester.extend_external_packet_generator(TestVhostCuseOneCopyOneVm,
                                                     self)

        # Change config file to enable vhost-cuse compiled.
        self.dut.send_expect(
            "sed -i -e 's/CONFIG_RTE_LIBRTE_VHOST_USER=.*$/CONFIG_RTE_LIBRTE"
            "_VHOST_USER=n/' ./config/common_base", "# ", 30)
        self.dut.build_install_dpdk(self.target)
        self.dut.send_expect("cd ./lib/librte_vhost", "#", 30)
        print self.dut.send_expect("make", "#", 30)
        self.dut.send_expect("cd ./eventfd_link", "#", 30)
        print self.dut.send_expect("make", "#", 30)
        self.dut.send_expect("cd ~/dpdk", "#", 30)

        # build the vhost sample in vhost-cuse mode.
        if self.nic in ['niantic']:
            self.dut.send_expect(
                "sed -i -e 's/#define MAX_QUEUES.*$/#define MAX_QUEUES 128/' "
                "./examples/vhost/main.c", "#")
        else:
            self.dut.send_expect(
                "sed -i -e 's/#define MAX_QUEUES.*$/#define MAX_QUEUES 512/' "
                "./examples/vhost/main.c", "#")
        out = self.dut.send_expect("make -C examples/vhost", "#")
        self.verify("Error" not in out, "compilation error")
        self.verify("No such file" not in out, "Not found file error")

        # Build target with modified config file
        self.dut.build_install_dpdk(self.target)

        # Get and verify the ports
        self.dut_ports = self.dut.get_ports()
        self.verify(len(self.dut_ports) >= 1, "Insufficient ports for testing")

        # Get the port's socket
        self.pf = self.dut_ports[0]
        netdev = self.dut.ports_info[self.pf]['port']
        self.socket = netdev.get_nic_socket()
        self.cores = self.dut.get_core_list("1S/3C/1T", socket=self.socket)

        # Set the params of vhost-cuse sample
        self.vhost_app = "./examples/vhost/build/vhost-switch"
        self.zero_copy = 0
        self.vm2vm = 0
        self.jumbo = 0
        self.vhost_test = self.vhost_app + \
            " -c %s -n %d --socket-mem 1024,1024 -- -p 0x1 --mergeable %d" + \
            " --zero-copy %d --vm2vm %d 2 > ./vhost.out &"

        # Define the virtio/VM variables
        self.virtio1 = "eth1"
        self.virtio2 = "eth2"
        self.virtio1_mac = "52:54:00:00:00:01"
        self.virtio2_mac = "52:54:00:00:00:02"
        self.src1 = "192.168.4.1"
        self.src2 = "192.168.3.1"
        self.dst1 = "192.168.3.1"
        self.dst2 = "192.168.4.1"
        self.vm_dut = None
        self.virtio_cmd_params = \
        'csum=off,gso=off,guest_csum=off,guest_tso4=off,guest_tso6=off,guest_ecn=off'
        # Define the table columns
        self.header_row = [
            "FrameSize(B)", "Injection(Mpps)", "Throughput(Mpps)",
            "LineRate(%)"
        ]
        self.memory_channel = 4

    def set_up(self):
        #
        # Run before each test case.
        #
        # Launch vhost sample using default params

        if "jumbo" in self.running_case:
            self.jumbo = 1
            self.frame_sizes = [
                64, 128, 256, 512, 1024, 1280, 1518, 2048, 5000, 9000
            ]
            self.vm_testpmd = "./x86_64-native-linuxapp-gcc/app/testpmd -c 0x3 -n 3" \
                + " -- -i --txqflags=0xf00 " \
                + "--disable-hw-vlan-filter --max-pkt-len 9600"
        else:
            self.jumbo = 0
            self.frame_sizes = [64, 128, 256, 512, 1024, 1280, 1518]
            self.vm_testpmd = "./x86_64-native-linuxapp-gcc/app/testpmd -c 0x3 -n 3" \
                + " -- -i --txqflags=0xf00 --disable-hw-vlan-filter"
        self.dut.send_expect("rm -rf ./vhost.out", "#")

        self.launch_vhost_sample()

        # start VM with 2virtio
        self.start_onevm()

    def launch_vhost_sample(self):
        #
        # Launch the vhost sample with different parameters
        #
        self.coremask = utils.create_mask(self.cores)
        self.vhostapp_testcmd = self.vhost_test % (
            self.coremask, self.memory_channel, self.jumbo, self.zero_copy,
            self.vm2vm)
        # Clean and prepare the vhost cuse modules
        self.dut.send_expect("rm -rf /dev/vhost-net", "#", 20)
        self.dut.send_expect("modprobe fuse", "#", 20)
        self.dut.send_expect("modprobe cuse", "#", 20)
        self.dut.send_expect("rmmod eventfd_link", "#", 20)
        self.dut.send_expect(
            "insmod lib/librte_vhost/eventfd_link/eventfd_link.ko", "#", 20)
        self.dut.send_expect(self.vhostapp_testcmd, "# ", 40)
        time.sleep(30)
        try:
            print "Launch vhost sample:"
            self.dut.session.copy_file_from("/root/dpdk/vhost.out")
            fp = open('./vhost.out', 'r')
            out = fp.read()
            fp.close()
            if "Error" in out:
                raise Exception("Launch vhost sample failed")
            else:
                print "Launch vhost sample finished"
        except Exception as e:
            print utils.RED("Failed to launch vhost sample: %s" % str(e))

    def start_onevm(self):
        #
        # Start One VM with 2 virtio devices
        #

        self.vm = QEMUKvm(self.dut, 'vm0', 'vhost_cuse_sample')
        if "cuse" in self.running_case:
            vm_params = {}
            vm_params['driver'] = 'vhost-cuse'
            vm_params['opt_mac'] = self.virtio1_mac
            vm_params['opt_settings'] = self.virtio_cmd_params
            self.vm.set_vm_device(**vm_params)

            vm_params['opt_mac'] = self.virtio2_mac
            vm_params['opt_settings'] = self.virtio_cmd_params
            self.vm.set_vm_device(**vm_params)
        try:
            self.vm_dut = self.vm.start()
            if self.vm_dut is None:
                raise Exception("Set up VM ENV failed")
        except Exception as e:
            print utils.RED("Failure for %s" % str(e))

        return True

    def vm_testpmd_start(self):
        #
        # Start testpmd in vm
        #
        if self.vm_dut is not None:
            # Start testpmd with user
            self.vm_dut.send_expect(self.vm_testpmd, "testpmd>", 20)
            # Start tx_first
            self.vm_dut.send_expect("start tx_first", "testpmd>")

    def clear_vhost_env(self):
        #
        # Kill all vhost sample, shutdown VM
        #
        if self.vm_dut:
            self.vm_dut.kill_all()
            time.sleep(1)
        if self.vm:
            self.vm.stop()
            self.vm = None

    def set_legacy_disablefw(self):
        #
        # Disable firewall and ip tables in legacy case
        #
        if self.vm_dut is not None:
            self.vm_dut.send_expect("systemctl stop firewalld.service", "#")
            self.vm_dut.send_expect("systemctl disable firewalld.service", "#")
            self.vm_dut.send_expect("systemctl stop ip6tables.service", "#")
            self.vm_dut.send_expect("systemctl disable ip6tables.service", "#")
            self.vm_dut.send_expect("systemctl stop iptables.service", "#")
            self.vm_dut.send_expect("systemctl disable iptables.service", "#")
            self.vm_dut.send_expect("systemctl stop NetworkManager.service",
                                    "#")
            self.vm_dut.send_expect("systemctl disable NetworkManager.service",
                                    "#")
            self.vm_dut.send_expect("echo 1 >/proc/sys/net/ipv4/ip_forward",
                                    "#")

    def set_onevm_legacy_fwd(self):
        if self.vm_dut is not None:
            ifcfg = self.vm_dut.send_expect("ifconfig -a", "#", 10)
            intfs = re.compile('eth\d').findall(ifcfg)
            # Get the virito1/virtio2's interface names
            for intf in intfs:
                out_mac = self.vm_dut.send_expect("ifconfig %s" % intf, "#",
                                                  10)
                if self.virtio1_mac in out_mac:
                    self.virtio1 = intf
                if self.virtio2_mac in out_mac:
                    self.virtio2 = intf
            print "Virtio1's intf is %s" % self.virtio1
            print "Virtio2's intf is %s" % self.virtio2
            # Set the MTU for jumboframe enabled case
            if self.jumbo == 1:
                self.vm_dut.send_expect("ifconfig %s mtu 9000" % self.virtio1,
                                        "#")
                self.vm_dut.send_expect("ifconfig %s mtu 9000" % self.virtio2,
                                        "#")
            # Set the ipv4 fwd rules
            self.vm_dut.send_expect(
                "ip addr add 192.168.4.2/24 dev %s" % self.virtio1, "#")
            self.vm_dut.send_expect(
                "ip addr add 192.168.3.2/24 dev %s" % self.virtio2, "#")
            self.vm_dut.send_expect("ip link set dev %s up" % self.virtio1,
                                    "#")
            self.vm_dut.send_expect("ip link set dev %s up" % self.virtio2,
                                    "#")
            self.vm_dut.send_expect(
                "ip neigh add 192.168.4.1 lladdr 52:00:00:00:00:01 dev %s" %
                self.virtio1, "#")
            self.vm_dut.send_expect(
                "ip neigh add 192.168.3.1 lladdr 52:00:00:00:00:02 dev %s" %
                self.virtio2, "#")
            self.vm_dut.send_expect("ip route show", "#")
            print self.vm_dut.send_expect("arp -a", "#")

    def get_transmission_results(self, rx_port_list, tx_port_list, delay=5):
        time.sleep(delay)
        recvbpsRate = 0
        recvRate = 0
        txbpsRate = 0
        txRate = 0
        for port in tx_port_list:
            self.stat_get_rate_stat_all_stats(port)
            out = self.send_expect('stat cget -framesSent', '%', 10)
            txRate += int(out.strip())
            self.logger.info("Port %s: TX %f Mpps" %
                             (port, (txRate * 1.0 / 1000000)))
            out = self.send_expect('stat cget -bitsSent', '%', 10)
            txbpsRate += int(out.strip())
            self.logger.info("Port %s: TX %f Mbps" %
                             (port, (txbpsRate * 1.0 / 1000000)))
        for port in rx_port_list:
            self.stat_get_rate_stat_all_stats(port)
            out = self.send_expect('stat cget -framesReceived', '%', 10)
            recvRate += int(out.strip())
            out = self.send_expect('stat cget -oversize', '%', 10)
            recvRate += int(out.strip())
            self.logger.info("Port %s: RX %f Mpps" %
                             (port, (recvRate * 1.0 / 1000000)))
            out = self.send_expect('stat cget -bitsReceived', '%', 10)
            recvbpsRate += int(out.strip())
            self.logger.info("Port %s: RX %f Mbps" %
                             (port, (recvbpsRate * 1.0 / 1000000)))

        self.hook_transmissoin_func()
        self.send_expect("ixStopTransmit portList", "%", 30)

        return (txRate, recvRate)

    def send_verify(self, case, frame_sizes, vlan_id1=0, vlan_id2=0):
class TestVhostUserLiveMigration(TestCase):

    def set_up_all(self):
        # verify at least two duts
        self.verify(len(self.duts) >= 2, "Insufficient duts for live migration!!!")

        # each dut required one ports
        self.dut_ports = self.dut.get_ports()
        # Verify that enough ports are available
        self.verify(len(self.dut_ports) >= 1, "Insufficient ports for testing")
        self.dut_port = self.dut_ports[0]
        dut_ip = self.dut.crb['My IP']
        self.host_tport = self.tester.get_local_port_bydut(self.dut_port, dut_ip)
        self.host_tintf = self.tester.get_interface(self.host_tport)

        self.backup_ports = self.duts[1].get_ports()
        # Verify that enough ports are available
        self.verify(len(self.backup_ports) >= 1, "Insufficient ports for testing")
        self.backup_port = self.backup_ports[0]
        # backup host ip will be used in migrate command
        self.backup_dutip = self.duts[1].crb['My IP']
        self.backup_tport = self.tester.get_local_port_bydut(self.backup_port, self.backup_dutip)
        self.backup_tintf = self.tester.get_interface(self.backup_tport)

        # Use testpmd as vhost-user application on host/backup server
        self.vhost = "./%s/app/testpmd" % self.target
        self.vm_testpmd = "./%s/app/testpmd -c 0x3 -n 4 -- -i" % self.target
        self.virio_mac = "52:54:00:00:00:01"

        # flag for environment
        self.env_done = False

    def set_up(self):
        self.setup_vm_env()
        pass

    def bind_nic_driver(self, crb,  ports, driver=""):
        # modprobe vfio driver
        if driver == "vfio-pci":
            for port in ports:
                netdev = crb.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 = crb.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 = crb.ports_info[port]['port']
                driver_now = netdev.get_nic_driver()
                if driver == "":
                    driver = netdev.default_driver
                if driver != driver_now:
                    netdev.bind_driver(driver=driver)

    def setup_vm_env(self, driver='default'):
        """
        Create testing environment on Host and Backup
        """
        if self.env_done:
            return

        # start vhost application on host and backup machines
        self.logger.info("Start vhost on host and backup host")
        for crb in self.duts[:2]:
            self.bind_nic_driver(crb, [crb.get_ports()[0]], driver="igb_uio")
            # start vhost app: testpmd, predict hugepage on both sockets
            base_dir = crb.base_dir.replace('~', '/root')
            crb.send_expect("rm -f %s/vhost-net" % base_dir, "# ")
            crb.send_expect("%s -c f -n 4 --socket-mem 512,512 --vdev 'eth_vhost0,iface=./vhost-net,queues=1' -- -i" % self.vhost, "testpmd> ",60)
            crb.send_expect("start", "testpmd> ")

        try:
            # set up host virtual machine
            self.host_vm = QEMUKvm(self.duts[0], 'host', 'vhost_user_live_migration')
            vhost_params = {}
            vhost_params['driver'] = 'vhost-user'
            # qemu command can't use ~
            base_dir = self.dut.base_dir.replace('~', '/root')
            vhost_params['opt_path'] = base_dir + '/vhost-net'
            vhost_params['opt_mac'] = self.virio_mac
            self.host_vm.set_vm_device(**vhost_params)

            self.logger.info("Start virtual machine on host")
            self.vm_host = self.host_vm.start()

            if self.vm_host is None:
                raise Exception("Set up host VM ENV failed!")

            self.host_serial = self.host_vm.connect_serial_port(name='vhost_user_live_migration')
            if self.host_serial is None:
                raise Exception("Connect host serial port failed!")

            self.logger.info("Start virtual machine on backup host")
            # set up backup virtual machine
            self.backup_vm = QEMUKvm(self.duts[1], 'backup', 'vhost_user_live_migration')
            vhost_params = {}
            vhost_params['driver'] = 'vhost-user'
            # qemu command can't use ~
            base_dir = self.dut.base_dir.replace('~', '/root')
            vhost_params['opt_path'] = base_dir + '/vhost-net'
            vhost_params['opt_mac'] = self.virio_mac
            self.backup_vm.set_vm_device(**vhost_params)

            # start qemu command
            self.backup_vm.start()

        except Exception as ex:
            if ex is VirtDutInitException:
                self.host_vm.stop()
                self.host_vm = None
                # no session created yet, call internal stop function
                self.backup_vm._stop_vm()
                self.backup_vm = None
            else:
                self.destroy_vm_env()
                raise Exception(ex)

        self.env_done = True

    def destroy_vm_env(self):
        # if environment has been destroyed, just skip
        if self.env_done is False:
            return

        if getattr(self, 'host_serial', None):
            if self.host_vm is not None:
                self.host_vm.close_serial_port()

        if getattr(self, 'backup_serial', None):
            if self.backup_serial is not None and self.backup_vm is not None:
                self.backup_vm.close_serial_port()


        if getattr(self, 'vm_host', None):
            if self.vm_host is not None:
                self.host_vm.stop()
                self.host_vm = None

        self.logger.info("Stop virtual machine on backup host")
        if getattr(self, 'vm_backup', None):
            if self.vm_backup is not None:
                self.vm_backup.kill_all()
                # backup vm dut has been initialized, destroy backup vm
                self.backup_vm.stop()
                self.backup_vm = None

        if getattr(self, 'backup_vm', None):
            # only qemu start, no session created
            if self.backup_vm is not None:
                self.backup_vm.stop()
                self.backup_vm = None

        # after vm stopped, stop vhost testpmd
        for crb in self.duts[:2]:
            crb.kill_all()

        for crb in self.duts[:2]:
            self.bind_nic_driver(crb, [crb.get_ports()[0]], driver="igb_uio")

        self.env_done = False

    def send_pkts(self, intf, number=0):
        """
        send packet from tester
        """
        sendp_fmt = "sendp([Ether(dst='%(DMAC)s')/IP()/UDP()/Raw('x'*18)], iface='%(INTF)s', count=%(COUNT)d)"
        sendp_cmd = sendp_fmt % {'DMAC': self.virio_mac, 'INTF': intf, 'COUNT': number}
        self.tester.scapy_append(sendp_cmd)
        self.tester.scapy_execute()
        # sleep 10 seconds for heavy load with backup host
        time.sleep(10)

    def verify_dpdk(self, tester_port, serial_session):
        num_pkts = 10

        stats_pat = re.compile("RX-packets: (\d+)")
        intf = self.tester.get_interface(tester_port)
        serial_session.send_expect("stop", "testpmd> ")
        serial_session.send_expect("set fwd rxonly", "testpmd> ")
        serial_session.send_expect("clear port stats all", "testpmd> ")
        serial_session.send_expect("start tx_first", "testpmd> ")

        # send packets from tester
        self.send_pkts(intf, number=num_pkts)

        out = serial_session.send_expect("show port stats 0", "testpmd> ")
        m = stats_pat.search(out)
        if m:
            num_received = int(m.group(1))
        else:
            num_received = 0

        self.logger.info("Verified %s packets recevied" % num_received)
        self.verify(num_received >= num_pkts, "Not receive packets as expected!!!")

    def verify_kernel(self, tester_port, vm_dut):
        """
        Function to verify packets received by virtIO
        """
        intf = self.tester.get_interface(tester_port)
        num_pkts = 10

        # get host interface
        vm_intf = vm_dut.ports_info[0]['port'].get_interface_name()
        # start tcpdump the interface
        vm_dut.send_expect("ifconfig %s up" % vm_intf, "# ")

        direct_pat = re.compile(r"(\s+)\[ (\S+) in\|out\|inout \]")
        vm_dut.send_expect("tcpdump -h", "# ")
        out = vm_dut.get_session_output(timeout=1)
        m = direct_pat.search(out)
        if m:
            direct_param = "-" + m.group(2)[1] + " in"
        else:
            direct_param = ""

        vm_dut.send_expect("tcpdump -i %s %s -v" % (vm_intf, direct_param), "listening on", 120)
        # wait for promisc on
        time.sleep(3)
        # send packets from tester
        self.send_pkts(intf, number=num_pkts)

        # killall tcpdump and verify packet received
        out = vm_dut.get_session_output(timeout=1)
        vm_dut.send_expect("^C", "# ")
        num = out.count('UDP')
        self.logger.info("Verified %s packets recevied" % num_pkts)
        self.verify(num == num_pkts, "Not receive packets as expected!!!")

    def test_migrate_with_kernel(self):
        """
        Verify migrate virtIO device from host to backup host,
        Verify before/in/after migration, device with kernel driver can receive packets
        """
        # bind virtio-net back to virtio-pci
        self.bind_nic_driver(self.vm_host, [self.vm_host.get_ports()[0]], driver="")
        # verify host virtio-net work fine
        self.verify_kernel(self.host_tport, self.vm_host)

        self.logger.info("Migrate host VM to backup host")
        # start live migration
        ret = self.host_vm.start_migration(self.backup_dutip, self.backup_vm.migrate_port)
        self.verify(ret, "Failed to migration, please check VM and qemu version")

        # make sure still can receive packets in migration process
        self.verify_kernel(self.host_tport, self.vm_host)

        self.logger.info("Waiting migration process done")
        # wait live migration done
        self.host_vm.wait_migration_done()

        # check vhost testpmd log after migration
        out = self.duts[0].get_session_output(timeout=1)
        self.verify("closed" in out, "Vhost Connection NOT closed on host")
        out = self.duts[1].get_session_output(timeout=1)
        self.verify("established" in out, "Device not ready on backup host")

        self.logger.info("Migration process done, then go to backup VM")
        # connected backup VM
        self.vm_backup = self.backup_vm.migrated_start()

        # make sure still can receive packets
        self.verify_kernel(self.backup_tport, self.vm_backup)

    def test_migrate_with_dpdk(self):
        # bind virtio-net to igb_uio
        self.bind_nic_driver(self.vm_host, [self.vm_host.get_ports()[0]], driver="igb_uio")

        # start testpmd on host vm
        base_dir = self.vm_host.base_dir.replace('~', '/root')
        self.host_serial.send_expect('cd %s' % base_dir, "# ")
        self.host_serial.send_expect(self.vm_testpmd, "testpmd> ", 120)

        # verify testpmd receive packets
        self.verify_dpdk(self.host_tport, self.host_serial)

        self.logger.info("Migrate host VM to backup host")
        # start live migration

        ret = self.host_vm.start_migration(self.backup_dutip, self.backup_vm.migrate_port)
        self.verify(ret, "Failed to migration, please check VM and qemu version")

        # make sure still can receive packets in migration process
        self.verify_dpdk(self.host_tport, self.host_serial)

        self.logger.info("Waiting migration process done")
        # wait live migration done
        self.host_vm.wait_migration_done()

        # check vhost testpmd log after migration
        out = self.duts[0].get_session_output(timeout=1)
        self.verify("closed" in out, "Vhost Connection NOT closed on host")
        out = self.duts[1].get_session_output(timeout=1)
        self.verify("established" in out, "Device not ready on backup host")

        self.logger.info("Migration process done, then go to backup VM")
        time.sleep(5)

        # make sure still can receive packets
        self.backup_serial = self.backup_vm.connect_serial_port(name='vhost_user_live_migration', first=False)
        if self.backup_serial is None:
            raise Exception("Connect backup host serial port failed!")

        self.verify_dpdk(self.backup_tport, self.backup_serial)

        # quit testpmd
        self.backup_serial.send_expect("quit", "# ")

    def tear_down(self):
        self.destroy_vm_env()
        pass

    def tear_down_all(self):
        pass
Exemplo n.º 17
0
class TestDdpGtp(TestCase):
    def set_up_all(self):
        self.verify(self.nic in ['fortville_25g'],
                    'ddp gtp can not support %s nic' % self.nic)
        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
        profile_file = 'dep/gtp.pkgo'
        profile_dst = "/tmp/"
        self.dut.session.copy_file_to(profile_file, profile_dst)
        PF_Q_strip = 'CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF'
        VF_Q_strip = 'CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF'
        self.PF_QUEUE = self.search_queue_number(PF_Q_strip)
        self.VF_QUEUE = self.search_queue_number(VF_Q_strip)

    def set_up(self):
        self.setup_vm_env()
        self.load_profile()

    def search_queue_number(self, Q_strip):
        """
        Search max queue number from configuration.
        """
        out = self.dut.send_expect("cat config/common_base", "]# ", 10)
        pattern = "(%s=)(\d*)" % Q_strip
        s = re.compile(pattern)
        res = s.search(out)
        if res is None:
            print utils.RED('Search no queue number.')
            return None
        else:
            queue = res.group(2)
            return int(queue)

    def bind_nic_driver(self, ports, driver=""):
        if driver == "igb_uio":
            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 == "":
                    driver = netdev.default_driver
                if driver != driver_now:
                    netdev.bind_driver(driver=driver)

    def setup_vm_env(self, driver='igb_uio'):
        """
        Create testing environment with VF generated from 1PF
        """
        if self.env_done is False:
            self.bind_nic_driver(self.dut_ports[:1], driver="igb_uio")
            self.used_dut_port = self.dut_ports[0]
            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']
            for port in self.sriov_vfs_port:
                port.bind_driver('pci-stub')
            time.sleep(1)
            self.dut_testpmd = PmdOutput(self.dut)
            time.sleep(1)
            vf0_prop = {'opt_host': self.sriov_vfs_port[0].pci}
            # set up VM0 ENV
            self.vm0 = QEMUKvm(self.dut, 'vm0', 'ddp_gtp')
            self.vm0.set_vm_device(driver='pci-assign', **vf0_prop)
            try:
                self.vm0_dut = self.vm0.start()
                if self.vm0_dut is None:
                    raise Exception("Set up VM0 ENV failed!")
            except Exception as e:
                self.destroy_vm_env()
                raise Exception(e)
            self.vm0_dut_ports = self.vm0_dut.get_ports('any')
            self.vm0_testpmd = PmdOutput(self.vm0_dut)
            self.env_done = True

    def destroy_vm_env(self):

        if getattr(self, 'vm0', None):
            self.vm0_dut.kill_all()
            self.vm0_testpmd = None
            self.vm0_dut_ports = None
            # destroy vm0
            self.vm0.stop()
            self.vm0 = None

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

        self.env_done = False

    def load_profile(self):
        """
        Load profile to update FVL configuration tables, profile will be
        stored in binary file and need to be passed to AQ to program FVL
        during initialization stage.
        """
        self.dut_testpmd.start_testpmd(
            "Default", "--pkt-filter-mode=perfect --port-topology=chained \
            --txq=%s --rxq=%s" % (self.PF_QUEUE, self.PF_QUEUE))
        self.vm0_testpmd.start_testpmd(
            VM_CORES_MASK, "--port-topology=chained --txq=%s --rxq=%s" %
            (self.VF_QUEUE, self.VF_QUEUE))
        self.dut_testpmd.execute_cmd('port stop all')
        time.sleep(1)
        out = self.dut_testpmd.execute_cmd('ddp get list 0')
        self.dut_testpmd.execute_cmd('ddp add 0 /tmp/gtp.pkgo')
        out = self.dut_testpmd.execute_cmd('ddp get list 0')
        self.verify("Profile number is: 1" in out,
                    "Failed to load ddp profile!!!")
        self.dut_testpmd.execute_cmd('port start all')
        time.sleep(1)
        self.dut_testpmd.execute_cmd('set fwd rxonly')
        self.dut_testpmd.execute_cmd('set verbose 1')
        self.dut_testpmd.execute_cmd('start')
        self.vm0_testpmd.execute_cmd('set fwd rxonly')
        self.vm0_testpmd.execute_cmd('set verbose 1')
        self.vm0_testpmd.execute_cmd('start')

    def gtp_packets(self,
                    type='fdir',
                    tunnel_pkt='gtpu',
                    inner_L3='ipv4',
                    match_opt='matched',
                    chk='',
                    teid=0xF):
        """
        Generate different GTP types according to different parameters.
        Input:
        filter type: includes flow director and cloud filter
        tunnel packet: includes GTPC and GTPU
        inner_L3: GTPC has no inner L3. GTPU has no, IPV4 and IPV6 inner L3.
        match_opt: PF or VSIs receive match packets to configured queue, but
                   receive not match packets to queue 0. Flow director
                   directs different TEIDs, inner L3 GTP packets to different
                   queues. Cloud filter directs different TEIDs GTP packets
                   to different queues.
        chk: checksum
        teid: GTP teid
        """
        pkts = []
        pkts_gtpc_pay = {
            'IPV4/GTPC':
            'Ether()/IP()/UDP(%sdport=2123)/GTP_U_Header(teid=%s)/Raw("X"*20)'
            % (chk, teid),
            'IPV6/GTPC':
            'Ether()/IPv6()/UDP(%sdport=2123)/GTP_U_Header(teid=%s)/Raw("X"*20)'
            % (chk, teid)
        }

        pkts_gtpu_pay = {
            'IPV4/GTPU':
            'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/Raw("X"*20)'
            % (chk, teid),
            'IPV6/GTPU':
            'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/Raw("X"*20)'
            % (chk, teid)
        }

        pkts_gtpu_ipv4 = {
            'IPV4/GTPU/IPV4':
            'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/Raw("X"*20)'
            % (chk, teid),
            'IPV4/GTPU/IPV4/FRAG':
            'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP(frag=5)/Raw("X"*20)'
            % (chk, teid),
            'IPV4/GTPU/IPV4/UDP':
            'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/UDP()/Raw("X"*20)'
            % (chk, teid),
            'IPV4/GTPU/IPV4/TCP':
            'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/TCP()/Raw("X"*20)'
            % (chk, teid),
            'IPV4/GTPU/IPV4/SCTP':
            'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/SCTP()/Raw("X"*20)'
            % (chk, teid),
            'IPV4/GTPU/IPV4/ICMP':
            'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/ICMP()/Raw("X"*20)'
            % (chk, teid),
            'IPV6/GTPU/IPV4':
            'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/Raw("X"*20)'
            % (chk, teid),
            'IPV6/GTPU/IPV4/FRAG':
            'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP(frag=5)/Raw("X"*20)'
            % (chk, teid),
            'IPV6/GTPU/IPV4/UDP':
            'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/UDP()/Raw("X"*20)'
            % (chk, teid),
            'IPV6/GTPU/IPV4/TCP':
            'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/TCP()/Raw("X"*20)'
            % (chk, teid),
            'IPV6/GTPU/IPV4/SCTP':
            'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/SCTP()/Raw("X"*20)'
            % (chk, teid),
            'IPV6/GTPU/IPV4/ICMP':
            'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/ICMP()/Raw("X"*20)'
            % (chk, teid)
        }

        pkts_gtpu_ipv6 = {
            'IPV4/GTPU/IPV6/FRAG':
            'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/IPv6ExtHdrFragment()/Raw("X"*20)'
            % (chk, teid),
            'IPV4/GTPU/IPV6':
            'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/Raw("X"*20)'
            % (chk, teid),
            'IPV4/GTPU/IPV6/UDP':
            'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/UDP()/Raw("X"*20)'
            % (chk, teid),
            'IPV4/GTPU/IPV6/TCP':
            'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/TCP()/Raw("X"*20)'
            % (chk, teid),
            'IPV4/GTPU/IPV6/SCTP':
            'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/SCTP()/Raw("X"*20)'
            % (chk, teid),
            'IPV4/GTPU/IPV6/ICMP':
            'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6(nh=58)/ICMP()/Raw("X"*20)'
            % (chk, teid),
            'IPV6/GTPU/IPV6/FRAG':
            'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/IPv6ExtHdrFragment()/Raw("X"*20)'
            % (chk, teid),
            'IPV6/GTPU/IPV6':
            'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/Raw("X"*20)'
            % (chk, teid),
            'IPV6/GTPU/IPV6/UDP':
            'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/UDP()/Raw("X"*20)'
            % (chk, teid),
            'IPV6/GTPU/IPV6/TCP':
            'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/TCP()/Raw("X"*20)'
            % (chk, teid),
            'IPV6/GTPU/IPV6/SCTP':
            'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/SCTP()/Raw("X"*20)'
            % (chk, teid),
            'IPV6/GTPU/IPV6/ICMP':
            'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6(nh=58)/ICMP()/Raw("X"*20)'
            % (chk, teid)
        }

        if match_opt == 'matched':
            if tunnel_pkt is 'gtpc' and inner_L3 is None:
                pkts = pkts_gtpc_pay
            if tunnel_pkt is 'gtpu' and inner_L3 is None:
                pkts = pkts_gtpu_pay
            if tunnel_pkt is 'gtpu' and inner_L3 is 'ipv4':
                pkts = pkts_gtpu_ipv4
            if tunnel_pkt is 'gtpu' and inner_L3 is 'ipv6':
                pkts = pkts_gtpu_ipv6

        if match_opt == 'not matched':
            if type is 'fdir':
                if tunnel_pkt is 'gtpc' and inner_L3 is None:
                    pkts = dict(pkts_gtpu_pay.items() +
                                pkts_gtpu_ipv4.items() +
                                pkts_gtpu_ipv6.items())
                if tunnel_pkt is 'gtpu' and inner_L3 is None:
                    pkts = dict(pkts_gtpc_pay.items() +
                                pkts_gtpu_ipv4.items() +
                                pkts_gtpu_ipv6.items())
                if tunnel_pkt is 'gtpu' and inner_L3 is 'ipv4':
                    pkts = dict(pkts_gtpc_pay.items() + pkts_gtpu_pay.items() +
                                pkts_gtpu_ipv6.items())
                if tunnel_pkt is 'gtpu' and inner_L3 is 'ipv6':
                    pkts = dict(pkts_gtpc_pay.items() + pkts_gtpu_pay.items() +
                                pkts_gtpu_ipv4.items())
            if type is 'clfter':
                if tunnel_pkt is 'gtpc':
                    pkts = dict(pkts_gtpu_pay.items() +
                                pkts_gtpu_ipv4.items() +
                                pkts_gtpu_ipv6.items())
                if tunnel_pkt is 'gtpu':
                    pkts = pkts_gtpc_pay
        return pkts

    def gtp_test(self,
                 type='fdir',
                 port='pf',
                 tunnel_pkt='gtpu',
                 inner_L3='ipv4'):
        """
        Send GTP packet to dut, receive packet from configured queue.
        Input: filter type, port type, packet type, inner L3 type
        """
        queue = random.randint(1, self.PF_QUEUE - 1)
        if port != 'pf':
            queue = random.randint(1, self.VF_QUEUE - 1)
        random_teid = random.randint(0x0, 0xFFFFFFFF)
        correct_teid = hex(random_teid)
        wrong_teid = hex((random_teid + 2) % int(0xFFFFFFFF))
        if type is 'fdir':
            if inner_L3 is None:
                self.dut_testpmd.execute_cmd(
                    'flow create 0 ingress pattern eth / ipv4 / udp / \
                    %s teid is %s / end actions queue index %d / end' %
                    (tunnel_pkt, correct_teid, queue))
            else:
                self.dut_testpmd.execute_cmd(
                    'flow create 0 ingress pattern eth / ipv4 / udp / \
                    %s teid is %s / %s / end actions queue index %d / end' %
                    (tunnel_pkt, correct_teid, inner_L3, queue))
        if type is 'clfter':
            self.dut_testpmd.execute_cmd(
                'flow create 0 ingress pattern eth / ipv4 / udp / \
                %s teid is %s / end actions %s / queue index %d / end' %
                (tunnel_pkt, correct_teid, port, queue))
        for match_opt in ['matched', 'not matched']:
            teid = correct_teid
            pkts = []
            for teid_opt in ['correct teid', 'wrong teid']:
                chk = ''
                for chksum_opt in ['good chksum', 'bad chksum']:
                    pkts = self.gtp_packets(type, tunnel_pkt, inner_L3,
                                            match_opt, chk, teid)
                    for packet_type in pkts.keys():
                        self.tester.scapy_append(
                            'sendp([%s], iface="%s")' %
                            (pkts[packet_type], self.tester_intf))
                        self.tester.scapy_execute()
                        if port is 'pf':
                            out = self.dut.get_session_output(timeout=2)
                        else:
                            out = self.vm0_dut.get_session_output(timeout=2)
                        self.verify(
                            "port 0/queue %d" % queue in out,
                            "Failed to receive packet in this queue!!!")

                        if port is 'pf':
                            layerparams = [
                                'L3_', 'TUNNEL_', 'INNER_L3_', 'INNER_L4_'
                            ]
                            ptypes = packet_type.split('/')
                            endparams = [
                                '_EXT_UNKNOWN', '', '_EXT_UNKNOWN', ''
                            ]
                            for layerparam, ptype, endparam in zip(
                                    layerparams, ptypes, endparams):
                                layer_type = layerparam + ptype + endparam
                                self.verify(
                                    layer_type in out,
                                    "Failed to output ptype information!!!")
                        if queue != 0 and type is 'fdir':
                            self.verify("PKT_RX_FDIR" in out,
                                        "Failed to test flow director!!!")
                    if teid == wrong_teid or match_opt == 'not matched':
                        break
                    chk = 'chksum=0x1234,'
                if match_opt == 'not matched':
                    break
                queue = 0
                teid = wrong_teid

    def test_fdir_gtpc_pf(self):
        """
        GTP is supported by NVM with profile updated. Select flow director to
        do classfication, send gtpc packet to PF, check PF could receive
        packet using configured queue, checksum is good.
        """
        self.gtp_test(type='fdir', port='pf', tunnel_pkt='gtpc', inner_L3=None)

    def test_fdir_gtpu_pf(self):
        """
        GTP is supported by NVM with profile updated. Select flow director to
        do classfication, send gtpu packet to PF, check PF could receive
        packet using configured queue, checksum is good.
        """
        self.gtp_test(type='fdir', port='pf', tunnel_pkt='gtpu', inner_L3=None)
        self.gtp_test(type='fdir',
                      port='pf',
                      tunnel_pkt='gtpu',
                      inner_L3='ipv4')
        self.gtp_test(type='fdir',
                      port='pf',
                      tunnel_pkt='gtpu',
                      inner_L3='ipv6')

    def test_clfter_gtpc_pf(self):
        """
        GTP is supported by NVM with profile updated. Select cloud filter,
        send gtpc packet to PF, check PF could receive packet using
        configured queue, checksum is good.
        """
        self.gtp_test(type='clfter',
                      port='pf',
                      tunnel_pkt='gtpc',
                      inner_L3=None)

    def test_clfter_gtpu_pf(self):
        """
        GTP is supported by NVM with profile updated. Select cloud filter,
        send gtpu packet to PF, check PF could receive packet using configured
        queue, checksum is good.
        """
        self.gtp_test(type='clfter',
                      port='pf',
                      tunnel_pkt='gtpu',
                      inner_L3=None)
        self.gtp_test(type='clfter',
                      port='pf',
                      tunnel_pkt='gtpu',
                      inner_L3='ipv4')
        self.gtp_test(type='clfter',
                      port='pf',
                      tunnel_pkt='gtpu',
                      inner_L3='ipv6')

    def test_clfter_gtpc_vf(self):
        """
        GTP is supported by NVM with profile updated. Select cloud filter,
        send gtpc packet to VF, check PF could receive packet using configured
        queue, checksum is good.
        """
        self.gtp_test(type='clfter',
                      port='vf id 0',
                      tunnel_pkt='gtpc',
                      inner_L3=None)

    def test_clfter_gtpu_vf(self):
        """
        GTP is supported by NVM with profile updated. Select cloud filter,
        send gtpu packet to VF, check PF could receive packet using configured
        queue, checksum is good.
        """
        self.gtp_test(type='clfter',
                      port='vf id 0',
                      tunnel_pkt='gtpu',
                      inner_L3=None)
        self.gtp_test(type='clfter',
                      port='vf id 0',
                      tunnel_pkt='gtpu',
                      inner_L3='ipv4')
        self.gtp_test(type='clfter',
                      port='vf id 0',
                      tunnel_pkt='gtpu',
                      inner_L3='ipv6')

    def tear_down(self):
        if self.vm0_testpmd:
            self.dut_testpmd.execute_cmd('write reg 0 0xb8190 1')
            self.dut_testpmd.execute_cmd('write reg 0 0xb8190 2')
            self.vm0_testpmd.quit()
            self.dut_testpmd.quit()

    def tear_down_all(self):
        self.destroy_vm_env()
Exemplo n.º 18
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
Exemplo n.º 19
0
class TestVfPortStartStop(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.filename = "/tmp/vf.pcap"

        # 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.setup_1pf_2vf_1vm_env_flag = 0

    def pktgen_prerequisites(self):
        """
        igb_uio.ko should be put in ~ before you using pktgen
        """
        out = self.tester.send_expect("ls", "#")
        self.verify("igb_uio.ko" in out, "No file igb_uio.ko, please add it in ~")
        self.tester.send_expect("modprobe uio", "#", 70)
        out = self.tester.send_expect("lsmod | grep igb_uio", "#")
        if "igb_uio" in out:
            self.tester.send_expect("rmmod -f igb_uio", "#", 70)
        self.tester.send_expect("insmod ~/igb_uio.ko", "#", 60)
        out = self.tester.send_expect("lsmod | grep igb_uio", "#")
        assert ("igb_uio" in out), "Failed to insmod igb_uio"

        total_huge_pages = self.tester.get_total_huge_pages()
        if total_huge_pages == 0:
            self.tester.mount_huge_pages()
            self.tester.set_huge_pages(2048)

    def pktgen_kill(self):
        """
        Kill all pktgen on tester.
        """
        pids = []
        pid_reg = r'p(\d+)'
        out = self.tester.alt_session.send_expect("lsof -Fp /var/run/.pg_config", "#", 20)
        if len(out):
            lines = out.split('\r\n')
            for line in lines:
                m = re.match(pid_reg, line)
                if m:
                    pids.append(m.group(1))
        for pid in pids:
            self.tester.alt_session.send_expect('kill -9 %s' % pid, '# ', 20)

    def send_and_verify(self, dst_mac, testpmd):
        """
        Generates packets by pktgen
        """
        self.testpmd_reset_status(testpmd)

        self.pktgen_prerequisites()
        # bind ports
        self.tester_tx_port = self.tester.get_local_port(self.dut_ports[0])
        self.tester_tx_pci = self.tester.ports_info[self.tester_tx_port]['pci']
        port = self.tester.ports_info[self.tester_tx_port]['port']
        self.tester_port_driver = port.get_nic_driver()
        self.tester.send_expect("./dpdk-devbind.py --bind=igb_uio %s" % self.tester_tx_pci, "#")

        src_mac = self.tester.get_mac(self.tester_tx_port) 
        if src_mac == 'N/A':
            src_mac = "02:00:00:00:01"

        self.create_pcap_file(self.filename, dst_mac, src_mac)

        self.tester.send_expect("./pktgen -c 0x1f -n 2  --proc-type auto --socket-mem 128,128 --file-prefix pg -- -P -T -m '1.0' -s 0:%s" % self.filename, "Pktgen >", 100)
        time.sleep(1)
        self.tester.send_expect("start all", "Pktgen>")
        time.sleep(1)
        self.check_port_start_stop(testpmd)
        # quit pktgen
        self.tester.send_expect("stop all", "Pktgen>")
        self.tester.send_expect("quit", "# ")

    def create_pcap_file(self, filename, dst_mac, src_mac):
        """
        Generates a valid PCAP file with the given configuration.
        """
        def_pkts = {'IP/UDP': Ether(dst="%s" % dst_mac, src="%s" % src_mac)/IP(src="127.0.0.2")/UDP()/("X"*46),
                    'IP/TCP': Ether(dst="%s" % dst_mac, src="%s" % src_mac)/IP(src="127.0.0.2")/TCP()/("X"*46),
                    'IP/SCTP': Ether(dst="%s" % dst_mac, src="%s" % src_mac)/IP(src="127.0.0.2")/SCTP()/("X"*48),
                    'IPv6/UDP': Ether(dst="%s" % dst_mac, src="%s" % src_mac)/IPv6(src="::2")/UDP()/("X"*46),
                    'IPv6/TCP': Ether(dst="%s" % dst_mac, src="%s" % src_mac)/IPv6(src="::2")/TCP()/("X"*46),}

        pkts = []
        for key in def_pkts.keys():
            pkts.append(def_pkts[key])

        wrpcap(filename, pkts)

    def testpmd_reset_status(self, testpmd):
        """
        Reset testpmd :stop forword & stop port
        """
        testpmd.execute_cmd('stop')
        testpmd.execute_cmd('port stop all')
        testpmd.execute_cmd('clear port stats all')

    def check_port_start_stop(self, testpmd, times=10):
        """
        VF port start/stop several times , check if it work well.
        """
        for i in range(times):
            out = testpmd.execute_cmd('port start all')
            self.verify("Checking link statuses" in out, "ERROR: port start all")
            testpmd.execute_cmd('start')
            time.sleep(.5)
            testpmd.execute_cmd('stop')
            out = testpmd.execute_cmd('port stop all')
            self.verify("Checking link statuses" in out, "ERROR: port stop all")

        port_id_0 = 0
        port_id_1 = 1
        vf0_stats = self.vm0_testpmd.get_pmd_stats(port_id_0)
        vf1_stats = self.vm0_testpmd.get_pmd_stats(port_id_1)

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

        vf0_rx_err = vf0_stats['RX-errors']
        self.verify(vf0_rx_err == 0, "vm0_VF0 rx-errors")
    
        vf1_tx_cnt = vf1_stats['TX-packets']
        self.verify(vf1_tx_cnt != 0, "no packet was transmitted by vm0_VF1")

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

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

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

        try:

            for port in self.sriov_vfs_port:
                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}

            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].pci,
                                                       'vf1': self.sriov_vfs_port[1].pci}
                self.host_testpmd.start_testpmd("1S/2C/2T", eal_param=eal_param)

            # set up VM0 ENV
            self.vm0 = QEMUKvm(self.dut, 'vm0', 'vf_port_start_stop')
            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_1pf_2vf_1vm_env_flag = 1
        except Exception as e:
            self.destroy_1pf_2vf_1vm_env()
            raise Exception(e)

    def destroy_1pf_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

        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_1pf_2vf_1vm_env_flag = 0

    def test_start_stop_with_kernel_1pf_2vf_1vm(self):

        self.setup_1pf_2vf_1vm_env(driver='')

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

        self.vm0_testpmd = PmdOutput(self.vm_dut_0)
        self.vm0_testpmd.start_testpmd(VM_CORES_MASK)
        self.vm0_testpmd.execute_cmd('set fwd mac')

        time.sleep(2)

        dst_mac = self.vm0_testpmd.get_port_mac(self.vm0_dut_ports[0])
        self.send_and_verify(dst_mac, self.vm0_testpmd) 

    def tear_down(self):

        if self.setup_1pf_2vf_1vm_env_flag == 1:
            self.destroy_1pf_2vf_1vm_env()

    def tear_down_all(self):

        self.pktgen_kill()
        if getattr(self, 'tester_port_driver', None) and \
           getattr(self, 'tester_tx_pci', None):
            self.tester.send_expect("./dpdk_nic_bind.py --bind=%s %s" \
                %(self.tester_port_driver, self.tester_tx_pci), "#")

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

        self.dut.virt_exit()

        for port_id in self.dut_ports:
            self.dut.destroy_sriov_vfs_by_port(port_id)
Exemplo n.º 20
0
class TestVfInterruptPmd(TestCase):
    def set_up_all(self):
        """
        Run at the start of each test suite.
        """
        self.dut_ports = self.dut.get_ports(self.nic)
        self.verify(len(self.dut_ports) >= 2, "Insufficient ports")
        cores = self.dut.get_core_list("1S/4C/1T")
        self.coremask = utils.create_mask(cores)
        self.portmask = utils.create_mask(self.dut_ports)

        self.path = "./examples/l3fwd-power/build/l3fwd-power"

        testport_0 = self.tester.get_local_port(self.dut_ports[0])
        self.rx_intf_0 = self.tester.get_interface(testport_0)
        testport_1 = self.tester.get_local_port(self.dut_ports[1])
        self.rx_intf_1 = self.tester.get_interface(testport_1)

        self.mac_port_0 = self.dut.get_mac_address(self.dut_ports[0])
        self.mac_port_1 = self.dut.get_mac_address(self.dut_ports[1])

        self.dut.virt_exit()

    def build_app(self, use_dut):
        # build sample app
        out = use_dut.build_dpdk_apps("./examples/l3fwd-power")
        self.verify("Error" not in out, "compilation error 1")
        self.verify("No such file" not in out, "compilation error 2")

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

    def generate_sriov_vfport(self, use_driver):
        """
        generate sriov vfs by port
        """
        self.used_dut_port_0 = self.dut_ports[0]
        self.used_dut_port_1 = self.dut_ports[1]
        self.dut.generate_sriov_vfs_by_port(self.used_dut_port_0,
                                            1,
                                            driver=use_driver)
        self.sriov_vfs_port_0 = self.dut.ports_info[
            self.used_dut_port_0]['vfs_port']
        self.dut.generate_sriov_vfs_by_port(self.used_dut_port_1,
                                            1,
                                            driver=use_driver)
        self.sriov_vfs_port_1 = self.dut.ports_info[
            self.used_dut_port_1]['vfs_port']

    def bind_vfs(self, driver):
        """
        bind vfs to driver
        """
        for port in self.sriov_vfs_port_0:
            port.bind_driver(driver)
        time.sleep(1)
        for port in self.sriov_vfs_port_1:
            port.bind_driver(driver)
        time.sleep(1)

    def setup_vm_env(self):
        """
        Start One VM with one virtio device
        """
        self.dut_testpmd = PmdOutput(self.dut)
        self.dut_testpmd.start_testpmd(
            "Default", "--rxq=4 --txq=4 --port-topology=chained")
        self.dut_testpmd.execute_cmd("start")

        vf0_prop_1 = {'opt_host': self.sriov_vfs_port_0[0].pci}
        vf0_prop_2 = {'opt_host': self.sriov_vfs_port_1[0].pci}
        self.vm0 = QEMUKvm(self.dut, 'vm0', 'vf_interrupt_pmd')
        self.vm0.set_vm_device(driver='pci-assign', **vf0_prop_1)
        self.vm0.set_vm_device(driver='pci-assign', **vf0_prop_2)
        try:
            self.vm0_dut = self.vm0.start()
            if self.vm0_dut is None:
                raise Exception("Set up VM ENV failed")
            else:
                self.verify(self.vm0_dut.ports_info[0]['intf'] != 'N/A',
                            "Not interface")
        except Exception as e:
            self.destroy_vm_env()
            self.logger.error("Failure for %s" % str(e))

        self.vm0_vf0_mac = self.vm0_dut.get_mac_address(0)
        self.vm0_vf1_mac = self.vm0_dut.get_mac_address(1)
        self.vm0_dut.send_expect("systemctl stop NetworkManager", "# ", 60)

    def destroy_vm_env(self):
        """
        destroy vm environment
        """
        if getattr(self, 'vm0', None):
            self.vm0_dut.kill_all()
            self.vm0_dut_ports = None
            # destroy vm0
            self.vm0.stop()
            self.vm0 = None

        if getattr(self, 'used_dut_port_0', None) != None:
            self.dut.destroy_sriov_vfs_by_port(self.used_dut_port_0)
            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)
            self.used_dut_port_1 = None

        self.env_done = False

    def change_port_conf(self, use_dut, lsc_enable=True, rxq_enable=True):
        """
        change interrupt enable
        """
        sed_cmd_fmt = "/intr_conf.*=.*{/,/\}\,$/c\    .intr_conf = {\\n\\t\\t.lsc = %d,\\n\\t\\t.rxq = %d,\\n\\t},"
        lsc = 1
        rxq = 1
        if lsc_enable:
            lsc = 0
        if rxq_enable:
            rxq = 1
        sed_cmd_str = sed_cmd_fmt % (lsc, rxq)
        out = use_dut.send_expect(
            "sed -i '%s' examples/l3fwd-power/main.c" % sed_cmd_str, "# ", 60)

    def scapy_send_packet(self, mac, testinterface, queuenum=1):
        """
        Send a packet to port
        """
        if queuenum == 1:
            self.tester.scapy_append(
                'sendp([Ether(dst="%s")/IP()/UDP()/Raw(\'X\'*18)], iface="%s")'
                % (mac, testinterface))
        elif queuenum == 2:
            for dst in range(16):
                self.tester.scapy_append(
                    'sendp([Ether(dst="%s")/IP(dst="127.0.0.%d")/UDP()/Raw(\'X\'*18)], iface="%s")'
                    % (mac, dst, testinterface))
        else:
            for dst in range(256):
                self.tester.scapy_append(
                    'sendp([Ether(dst="%s")/IP(dst="127.0.0.%d")/UDP()/Raw(\'X\'*18)], iface="%s")'
                    % (mac, dst, testinterface))
        self.tester.scapy_execute()

    def test_vf_VM_uio(self):
        """
        verify VF interrupt pmd in VM with uio
        """
        self.verify(self.drivername in ['igb_uio'], "NOT Support")
        self.generate_sriov_vfport('igb_uio')
        self.bind_vfs('pci-stub')
        self.setup_vm_env()
        self.change_port_conf(self.vm0_dut, lsc_enable=True, rxq_enable=False)
        self.build_app(self.vm0_dut)

        cmd = self.path + \
            " -c f -n %d -- -p 0x3 -P --config='(0,0,1),(1,0,2)'" % (
                self.vm0_dut.get_memory_channels())
        self.vm0_dut.send_expect(cmd, "L3FWD_POWER", 60)
        self.scapy_send_packet(self.vm0_vf0_mac, self.rx_intf_0)
        self.scapy_send_packet(self.vm0_vf1_mac, self.rx_intf_1)
        out = self.vm0_dut.get_session_output(timeout=30)
        self.destroy_vm_env()
        self.dut.send_expect("quit", "# ", 60)
        self.verify("lcore 1 is waked up from rx interrupt on port 0" in out,
                    "lcore 1 not waked up")
        self.verify("lcore 1 sleeps until interrupt triggers" in out,
                    "lcore 1 not sleeps")
        self.verify("lcore 2 is waked up from rx interrupt on port 1" in out,
                    "lcore 2 not waked up")
        self.verify("lcore 2 sleeps until interrupt triggers" in out,
                    "lcore 2 not sleeps")

    def test_vf_host_uio(self):
        """
        verify VF interrupt pmd in Host with uio
        """
        self.verify(self.drivername in ['igb_uio'], "NOT Support")
        self.dut.restore_interfaces()
        self.generate_sriov_vfport('ixgbe')
        self.bind_vfs('igb_uio')
        self.change_port_conf(self.dut, lsc_enable=True, rxq_enable=False)
        self.build_app(self.dut)

        cmd = self.path + " -c %s -n %d -- -p %s -P --config='(0,0,1),(1,0,2)'" % (
            self.coremask, self.dut.get_memory_channels(), self.portmask)
        self.dut.send_expect(cmd, "L3FWD_POWER", 60)
        self.scapy_send_packet(self.mac_port_0, self.rx_intf_0)
        self.scapy_send_packet(self.mac_port_1, self.rx_intf_1)
        out = self.dut.get_session_output(timeout=60)
        self.dut.send_expect("^C", "# ", 60)
        self.verify("lcore 1 is waked up from rx interrupt on port 0" in out,
                    "lcore 1 not waked up")
        self.verify("lcore 1 sleeps until interrupt triggers" in out,
                    "lcore 1 not sleeps")
        self.verify("lcore 2 is waked up from rx interrupt on port 1" in out,
                    "lcore 2 not waked up")
        self.verify("lcore 2 sleeps until interrupt triggers" in out,
                    "lcore 2 not sleeps")

    def test_vf_host_vfio(self):
        """
        verify VF interrupt pmd in Host with vfio
        """
        self.verify(self.drivername in ['vfio-pci'], "NOT Support")
        self.dut.restore_interfaces()
        self.generate_sriov_vfport('ixgbe')
        self.bind_vfs('vfio-pci')
        self.change_port_conf(self.dut, lsc_enable=True, rxq_enable=False)
        self.build_app(self.dut)

        cmd = self.path + " -c %s -n %d -- -p %s -P --config='(0,0,1),(0,1,2)(1,0,3),(1,1,4)'" % (
            self.coremask, self.dut.get_memory_channels(), self.portmask)
        self.dut.send_expect(cmd, "L3FWD_POWER", 60)
        self.scapy_send_packet(self.mac_port_0, self.rx_intf_0, 2)
        self.scapy_send_packet(self.mac_port_1, self.rx_intf_1, 2)
        out = self.dut.get_session_output(timeout=60)
        self.dut.send_expect("^C", "# ", 60)
        print out
        self.verify("lcore 1 is waked up from rx interrupt on port 0" in out,
                    "lcore 1 not waked up")
        self.verify("lcore 1 sleeps until interrupt triggers" in out,
                    "lcore 1 not sleeps")
        self.verify("lcore 2 is waked up from rx interrupt on port 0" in out,
                    "lcore 2 not waked up")
        self.verify("lcore 2 sleeps until interrupt triggers" in out,
                    "lcore 2 not sleeps")
        self.verify("lcore 3 is waked up from rx interrupt on port 1" in out,
                    "lcore 2 not waked up")
        self.verify("lcore 3 sleeps until interrupt triggers" in out,
                    "lcore 2 not sleeps")
        self.verify("lcore 4 is waked up from rx interrupt on port 1" in out,
                    "lcore 2 not waked up")
        self.verify("lcore 4 sleeps until interrupt triggers" in out,
                    "lcore 2 not sleeps")

    def tear_down(self):
        """
        Run after each test case.
        """
        self.dut.virt_exit()
        self.dut.kill_all()
        time.sleep(2)

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