class TestVfOffload(TestCase): supported_vf_driver = ['pci-stub', 'vfio-pci'] def set_up_all(self): self.dut_ports = self.dut.get_ports(self.nic) self.verify(len(self.dut_ports) > 1, "Insufficient ports") self.vm0 = None # set vf assign method and vf driver self.vf_driver = self.get_suite_cfg()['vf_driver'] if self.vf_driver is None: self.vf_driver = 'pci-stub' self.verify(self.vf_driver in self.supported_vf_driver, "Unsupported vf driver") if self.vf_driver == 'pci-stub': self.vf_assign_method = 'pci-assign' else: self.vf_assign_method = 'vfio-pci' self.dut.send_expect('modprobe vfio-pci', '#') self.setup_2pf_2vf_1vm_env_flag = 0 self.setup_2pf_2vf_1vm_env(driver='') self.vm0_dut_ports = self.vm_dut_0.get_ports('any') self.portMask = utils.create_mask([self.vm0_dut_ports[0]]) self.vm0_testpmd = PmdOutput(self.vm_dut_0) def set_up(self): pass def setup_2pf_2vf_1vm_env(self, driver='default'): self.used_dut_port_0 = self.dut_ports[0] self.dut.generate_sriov_vfs_by_port(self.used_dut_port_0, 1, driver=driver) self.sriov_vfs_port_0 = self.dut.ports_info[self.used_dut_port_0]['vfs_port'] self.used_dut_port_1 = self.dut_ports[1] self.dut.generate_sriov_vfs_by_port(self.used_dut_port_1, 1, driver=driver) self.sriov_vfs_port_1 = self.dut.ports_info[self.used_dut_port_1]['vfs_port'] try: for port in self.sriov_vfs_port_0: port.bind_driver(self.vf_driver) for port in self.sriov_vfs_port_1: port.bind_driver(self.vf_driver) time.sleep(1) vf0_prop = {'opt_host': self.sriov_vfs_port_0[0].pci} vf1_prop = {'opt_host': self.sriov_vfs_port_1[0].pci} if driver == 'igb_uio': # start testpmd without the two VFs on the host self.host_testpmd = PmdOutput(self.dut) eal_param = '-b %(vf0)s -b %(vf1)s' % {'vf0': self.sriov_vfs_port_0[0].pci, 'vf1': self.sriov_vfs_port_1[0].pci} self.host_testpmd.start_testpmd("1S/2C/2T", eal_param=eal_param) # set up VM0 ENV self.vm0 = VM(self.dut, 'vm0', 'vf_offload') self.vm0.set_vm_device(driver=self.vf_assign_method, **vf0_prop) self.vm0.set_vm_device(driver=self.vf_assign_method, **vf1_prop) self.vm_dut_0 = self.vm0.start() if self.vm_dut_0 is None: raise Exception("Set up VM0 ENV failed!") self.setup_2pf_2vf_1vm_env_flag = 1 except Exception as e: self.destroy_2pf_2vf_1vm_env() raise Exception(e) def destroy_2pf_2vf_1vm_env(self): if getattr(self, 'vm0', None): #destroy testpmd in vm0 self.vm0_testpmd = None self.vm0_dut_ports = None #destroy vm0 self.vm0.stop() self.dut.virt_exit() self.vm0 = None if getattr(self, 'host_testpmd', None): self.host_testpmd.execute_cmd('quit', '# ') self.host_testpmd = None if getattr(self, 'used_dut_port_0', None) != None: self.dut.destroy_sriov_vfs_by_port(self.used_dut_port_0) port = self.dut.ports_info[self.used_dut_port_0]['port'] port.bind_driver() self.used_dut_port_0 = None if getattr(self, 'used_dut_port_1', None) != None: self.dut.destroy_sriov_vfs_by_port(self.used_dut_port_1) port = self.dut.ports_info[self.used_dut_port_1]['port'] port.bind_driver() self.used_dut_port_1 = None for port_id in self.dut_ports: port = self.dut.ports_info[port_id]['port'] port.bind_driver() self.setup_2pf_2vf_1vm_env_flag = 0 def checksum_enablehw(self, port, dut): dut.send_expect("port stop all", "testpmd>") dut.send_expect("csum set ip hw %d" % port, "testpmd>") dut.send_expect("csum set udp hw %d" % port, "testpmd>") dut.send_expect("csum set tcp hw %d" % port, "testpmd>") dut.send_expect("csum set sctp hw %d" % port, "testpmd>") dut.send_expect("port start all", "testpmd>") def checksum_enablesw(self, port, dut): dut.send_expect("port stop all", "testpmd>") dut.send_expect("csum set ip sw %d" % port, "testpmd>") dut.send_expect("csum set udp sw %d" % port, "testpmd>") dut.send_expect("csum set tcp sw %d" % port, "testpmd>") dut.send_expect("csum set sctp sw %d" % port, "testpmd>") dut.send_expect("port start all", "testpmd>") def checksum_validate(self, packets_sent, packets_expected): """ Validate the checksum. """ tx_interface = self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0])) rx_interface = self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0])) sniff_src = self.vm0_testpmd.get_port_mac(0) checksum_pattern = re.compile("chksum.*=.*(0x[0-9a-z]+)") chksum = dict() result = dict() self.tester.send_expect("scapy", ">>> ") for packet_type in packets_expected.keys(): self.tester.send_expect("p = %s" % packets_expected[packet_type], ">>>") out = self.tester.send_expect("p.show2()", ">>>") chksums = checksum_pattern.findall(out) chksum[packet_type] = chksums print packet_type, ": ", chksums self.tester.send_expect("exit()", "#") self.tester.scapy_background() self.tester.scapy_append('p = sniff(filter="ether src %s", iface="%s", count=%d)' % (sniff_src, rx_interface, len(packets_sent))) self.tester.scapy_append('nr_packets=len(p)') self.tester.scapy_append('reslist = [p[i].sprintf("%IP.chksum%;%TCP.chksum%;%UDP.chksum%;%SCTP.chksum%") for i in range(nr_packets)]') self.tester.scapy_append('import string') self.tester.scapy_append('RESULT = string.join(reslist, ",")') # Send packet. self.tester.scapy_foreground() for packet_type in packets_sent.keys(): self.tester.scapy_append('sendp([%s], iface="%s")' % (packets_sent[packet_type], tx_interface)) self.tester.scapy_execute() out = self.tester.scapy_get_result() packets_received = out.split(',') self.verify(len(packets_sent) == len(packets_received), "Unexpected Packets Drop") for packet_received in packets_received: ip_checksum, tcp_checksum, udp_checksup, sctp_checksum = packet_received.split(';') print "ip_checksum: ", ip_checksum, "tcp_checksum:, ", tcp_checksum, "udp_checksup: ", udp_checksup, "sctp_checksum: ", sctp_checksum packet_type = '' l4_checksum = '' if tcp_checksum != '??': packet_type = 'TCP' l4_checksum = tcp_checksum elif udp_checksup != '??': packet_type = 'UDP' l4_checksum = udp_checksup elif sctp_checksum != '??': packet_type = 'SCTP' l4_checksum = sctp_checksum if ip_checksum != '??': packet_type = 'IP/' + packet_type if chksum[packet_type] != [ip_checksum, l4_checksum]: result[packet_type] = packet_type + " checksum error" else: packet_type = 'IPv6/' + packet_type if chksum[packet_type] != [l4_checksum]: result[packet_type] = packet_type + " checksum error" return result def test_checksum_offload_enable(self): """ Enable HW checksum offload. Send packet with incorrect checksum, can rx it and report the checksum error, verify forwarded packets have correct checksum. """ self.vm0_testpmd.start_testpmd(VM_CORES_MASK, "--portmask=%s " % (self.portMask) + "--enable-rx-cksum " + "" + "--port-topology=loop") self.vm0_testpmd.execute_cmd('set fwd csum') time.sleep(2) port_id_0 = 0 mac = self.vm0_testpmd.get_port_mac(0) sndIP = '10.0.0.1' sndIPv6 = '::1' pkts = {'IP/UDP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="%s", chksum=0xf)/UDP(chksum=0xf)/("X"*46)' % (mac, sndIP), 'IP/TCP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="%s", chksum=0xf)/TCP(chksum=0xf)/("X"*46)' % (mac, sndIP), 'IP/SCTP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="%s", chksum=0xf)/SCTP(chksum=0xf)/("X"*48)' % (mac, sndIP), 'IPv6/UDP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="%s")/UDP(chksum=0xf)/("X"*46)' % (mac, sndIPv6), 'IPv6/TCP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="%s")/TCP(chksum=0xf)/("X"*46)' % (mac, sndIPv6)} expIP = sndIP expIPv6 = sndIPv6 pkts_ref = {'IP/UDP': 'Ether(dst="02:00:00:00:00:00", src="%s")/IP(src="%s")/UDP()/("X"*46)' % (mac, expIP), 'IP/TCP': 'Ether(dst="02:00:00:00:00:00", src="%s")/IP(src="%s")/TCP()/("X"*46)' % (mac, expIP), 'IP/SCTP': 'Ether(dst="02:00:00:00:00:00", src="%s")/IP(src="%s")/SCTP()/("X"*48)' % (mac, expIP), 'IPv6/UDP': 'Ether(dst="02:00:00:00:00:00", src="%s")/IPv6(src="%s")/UDP()/("X"*46)' % (mac, expIPv6), 'IPv6/TCP': 'Ether(dst="02:00:00:00:00:00", src="%s")/IPv6(src="%s")/TCP()/("X"*46)' % (mac, expIPv6)} if self.nic in ['redrockcanyou', 'atwood']: del pkts['IP/SCTP'] del pkts_ref['IP/SCTP'] self.checksum_enablehw(0,self.vm_dut_0) self.vm0_testpmd.execute_cmd('start') result = self.checksum_validate(pkts, pkts_ref) # Validate checksum on the receive packet out = self.vm0_testpmd.execute_cmd('stop') bad_ipcsum = self.vm0_testpmd.get_pmd_value("Bad-ipcsum:", out) bad_l4csum = self.vm0_testpmd.get_pmd_value("Bad-l4csum:", out) self.verify(bad_ipcsum == 3, "Bad-ipcsum check error") self.verify(bad_l4csum == 5, "Bad-l4csum check error") self.verify(len(result) == 0, string.join(result.values(), ",")) def test_checksum_offload_disable(self): """ Enable SW checksum offload. Send same packet with incorrect checksum and verify checksum is valid. """ self.vm0_testpmd.start_testpmd(VM_CORES_MASK, "--portmask=%s " % (self.portMask) + "--enable-rx-cksum " + "--port-topology=loop") self.vm0_testpmd.execute_cmd('set fwd csum') time.sleep(2) mac = self.vm0_testpmd.get_port_mac(0) sndIP = '10.0.0.1' sndIPv6 = '::1' sndPkts = {'IP/UDP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="%s",chksum=0xf)/UDP(chksum=0xf)/("X"*46)' % (mac, sndIP), 'IP/TCP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="%s",chksum=0xf)/TCP(chksum=0xf)/("X"*46)' % (mac, sndIP), 'IPv6/UDP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="%s")/UDP(chksum=0xf)/("X"*46)' % (mac, sndIPv6), 'IPv6/TCP': 'Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="%s")/TCP(chksum=0xf)/("X"*46)' % (mac, sndIPv6)} expIP = sndIP expIPv6 = sndIPv6 expPkts = {'IP/UDP': 'Ether(dst="02:00:00:00:00:00", src="%s")/IP(src="%s")/UDP()/("X"*46)' % (mac, expIP), 'IP/TCP': 'Ether(dst="02:00:00:00:00:00", src="%s")/IP(src="%s")/TCP()/("X"*46)' % (mac, expIP), 'IPv6/UDP': 'Ether(dst="02:00:00:00:00:00", src="%s")/IPv6(src="%s")/UDP()/("X"*46)' % (mac, expIPv6), 'IPv6/TCP': 'Ether(dst="02:00:00:00:00:00", src="%s")/IPv6(src="%s")/TCP()/("X"*46)' % (mac, expIPv6)} self.checksum_enablesw(0, self.vm_dut_0) self.vm0_testpmd.execute_cmd('start') result = self.checksum_validate(sndPkts, expPkts) # Validate checksum on the receive packet out = self.vm0_testpmd.execute_cmd('stop') bad_ipcsum = self.vm0_testpmd.get_pmd_value("Bad-ipcsum:", out) bad_l4csum = self.vm0_testpmd.get_pmd_value("Bad-l4csum:", out) self.verify(bad_ipcsum == 2, "Bad-ipcsum check error") self.verify(bad_l4csum == 4, "Bad-l4csum check error") self.verify(len(result) == 0, string.join(result.values(), ",")) def tcpdump_start_sniffing(self, ifaces=[]): """ Start tcpdump in the background to sniff the tester interface where the packets are transmitted to and from the self.dut. All the captured packets are going to be stored in a file for a post-analysis. """ for iface in ifaces: command = ('tcpdump -w tcpdump_{0}.pcap -i {0} 2>tcpdump_{0}.out &').format(iface) self.tester.send_expect('rm -f tcpdump_{0}.pcap', '#').format(iface) self.tester.send_expect(command, '#') def tcpdump_stop_sniff(self): """ Stop the tcpdump process running in the background. """ self.tester.send_expect('killall tcpdump', '#') time.sleep(1) self.tester.send_expect('echo "Cleaning buffer"', '#') time.sleep(1) def tcpdump_command(self, command): """ Send a tcpdump related command and return an integer from the output. """ result = self.tester.send_expect(command, '#') print result return int(result.strip()) def number_of_packets(self, iface): """ By reading the file generated by tcpdump it counts how many packets are forwarded by the sample app and received in the self.tester. The sample app will add a known MAC address for the test to look for. """ command = ('tcpdump -A -nn -e -v -r tcpdump_{iface}.pcap 2>/dev/null | ' + 'grep -c "seq"') return self.tcpdump_command(command.format(**locals())) def test_tso(self): """ TSO IPv4 TCP, IPv6 TCP testing. """ tx_interface = self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0])) rx_interface = self.tester.get_interface(self.tester.get_local_port(self.dut_ports[1])) self.frame_sizes = [128, 1458] self.headers_size = HEADER_SIZE['eth'] + HEADER_SIZE['ip'] + HEADER_SIZE['tcp'] padding = self.frame_sizes[0] - self.headers_size self.tester.send_expect("ethtool -K %s rx off tx off tso off gso off gro off lro off" % tx_interface, "# ") self.tester.send_expect("ip l set %s up" % tx_interface, "# ") self.portMask = utils.create_mask([self.vm0_dut_ports[0]]) self.vm0_testpmd.start_testpmd(VM_CORES_MASK, "--portmask=%s " % (self.portMask) + "--enable-rx-cksum " + "" + "--port-topology=loop") mac = self.vm0_testpmd.get_port_mac(0) self.checksum_enablehw(0,self.vm_dut_0) self.vm0_testpmd.execute_cmd("tso set 800 %d" % self.vm0_dut_ports[1]) self.vm0_testpmd.execute_cmd("set fwd csum") self.vm0_testpmd.execute_cmd("start") self.tester.scapy_foreground() time.sleep(5) # IPv4 tcp test self.tcpdump_start_sniffing([tx_interface, rx_interface]) self.tester.scapy_append('sendp([Ether(dst="%s",src="52:00:00:00:00:00")/IP(src="192.168.1.1",dst="192.168.1.2")/TCP(sport=1021,dport=1021)/("X"*%s)], iface="%s")' % (mac, padding, tx_interface)) out = self.tester.scapy_execute() out = self.vm0_testpmd.execute_cmd("show port stats all") print out self.tcpdump_stop_sniff() rx_stats = self.number_of_packets(rx_interface) if (rx_stats == 2): self.verify(1, "Pass") # IPv6 tcp test self.tcpdump_start_sniffing([tx_interface, rx_interface]) self.tester.scapy_append('sendp([Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="FE80:0:0:0:200:1FF:FE00:200", dst="3555:5555:6666:6666:7777:7777:8888:8888")/TCP(sport=1021,dport=1021)/("X"*%s)], iface="%s")' % (mac, padding, tx_interface)) out = self.tester.scapy_execute() out = self.vm0_testpmd.execute_cmd("show port stats all") print out self.tcpdump_stop_sniff() rx_stats = self.number_of_packets(rx_interface) if (rx_stats == 2): self.verify(1, "Pass") def tear_down(self): self.vm0_testpmd.execute_cmd('quit', '# ') pass def tear_down_all(self): print "tear_down_all" if self.setup_2pf_2vf_1vm_env_flag == 1: self.destroy_2pf_2vf_1vm_env()
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 forward & 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 = VM(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), "#") tx_interface = self.tester.get_interface(self.tester_tx_port) self.tester.send_expect("ifconfig %s up" % tx_interface, "#") 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)
class TestPVPQemuMultiPathPortRestart(TestCase): def set_up_all(self): """ Run at the start of each test suite. """ self.frame_sizes = [64, 128, 256, 512, 1024, 1280, 1518] self.core_config = "1S/3C/1T" self.dut_ports = self.dut.get_ports() self.verify(len(self.dut_ports) >= 1, "Insufficient ports for testing") # get core mask self.ports_socket = self.dut.get_numa_id(self.dut_ports[0]) self.core_list = self.dut.get_core_list(self.core_config, socket=self.ports_socket) self.core_mask = utils.create_mask(self.core_list) self.dst_mac = self.dut.get_mac_address(self.dut_ports[0]) self.vm_dut = None self.virtio1_mac = "52:54:00:00:00:01" def set_up(self): """ Run before each test case. """ # Clean the execution ENV self.dut.send_expect("rm -rf ./vhost.out", "#") self.dut.send_expect("killall -s INT testpmd", "#") self.dut.send_expect("killall -s INT qemu-system-x86_64", "#") # Prepare the result table self.table_header = [ "FrameSize(B)", "Mode", "Throughput(Mpps)", "% linerate", "Cycle" ] self.result_table_create(self.table_header) self.vhost = self.dut.new_session(suite="vhost-user") def start_vhost_testpmd(self): """ start testpmd on vhost """ self.dut.send_expect("killall -s INT testpmd", "#") self.dut.send_expect("rm -rf ./vhost-net*", "#") command_client = self.dut.target + "/app/testpmd " + \ " -n %d -c %s --socket-mem 1024,1024 " + \ " --legacy-mem --file-prefix=vhost " + \ " --vdev 'net_vhost0,iface=vhost-net,queues=1' " + \ " -- -i --nb-cores=1 --txd=1024 --rxd=1024" command_line_client = command_client % (self.dut.get_memory_channels(), self.core_mask) self.vhost.send_expect(command_line_client, "testpmd> ", 120) self.vhost.send_expect("set fwd mac", "testpmd> ", 120) self.vhost.send_expect("start", "testpmd> ", 120) def start_vm_testpmd(self, path): """ start testpmd in vm depend on different path """ if path == "mergeable": command = self.dut.target + "/app/testpmd " + \ "-c 0x3 -n 3 -- -i " + \ "--nb-cores=1 --txd=1024 --rxd=1024" elif path == "normal": command = self.dut.target + "/app/testpmd " + \ "-c 0x3 -n 3 -- -i " + \ "--tx-offloads=0x0 --enable-hw-vlan-strip " + \ "--nb-cores=1 --txd=1024 --rxd=1024" elif path == "vector_rx": command = self.dut.target + "/app/testpmd " + \ "-c 0x3 -n 3 -- -i " + \ "--nb-cores=1 --txd=1024 --rxd=1024" self.vm_dut.send_expect(command, "testpmd> ", 30) self.vm_dut.send_expect("set fwd mac", "testpmd> ", 30) self.vm_dut.send_expect("start", "testpmd> ", 30) def start_one_vm(self, modem=0, mergeable=0): """ start qemu """ self.vm = VM(self.dut, 'vm0', 'vhost_sample') vm_params = {} vm_params['driver'] = 'vhost-user' vm_params['opt_path'] = './vhost-net' vm_params['opt_mac'] = self.virtio1_mac if modem == 1 and mergeable == 0: vm_params[ 'opt_settings'] = "disable-modern=false,mrg_rxbuf=off,rx_queue_size=1024,tx_queue_size=1024" elif modem == 1 and mergeable == 1: vm_params[ 'opt_settings'] = "disable-modern=false,mrg_rxbuf=on,rx_queue_size=1024,tx_queue_size=1024" elif modem == 0 and mergeable == 0: vm_params[ 'opt_settings'] = "disable-modern=true,mrg_rxbuf=off,rx_queue_size=1024,tx_queue_size=1024" elif modem == 0 and mergeable == 1: vm_params[ 'opt_settings'] = "disable-modern=true,mrg_rxbuf=on,rx_queue_size=1024,tx_queue_size=1024" 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)) def check_port_throughput_after_port_stop(self): """ check the throughput after port stop """ loop = 1 while (loop <= 5): out = self.vhost.send_expect("show port stats 0", "testpmd>", 60) lines = re.search("Rx-pps:\s*(\d*)", out) result = lines.group(1) if result == "0": break time.sleep(3) loop = loop + 1 self.verify(result == "0", "port stop failed, it alse can recevie data after stop.") def check_port_link_status_after_port_restart(self): """ check the link status after port restart """ loop = 1 while (loop <= 5): out = self.vhost.send_expect("show port info all", "testpmd> ", 120) port_status = re.findall("Link\s*status:\s*([a-z]*)", out) if ("down" not in port_status): break time.sleep(3) loop = loop + 1 self.verify("down" not in port_status, "port can not up after restart") def port_restart(self): self.vhost.send_expect("stop", "testpmd> ", 120) self.vhost.send_expect("port stop 0", "testpmd> ", 120) self.check_port_throughput_after_port_stop() self.vhost.send_expect("clear port stats all", "testpmd> ", 120) self.vhost.send_expect("port start all", "testpmd> ", 120) self.check_port_link_status_after_port_restart() self.vhost.send_expect("start", "testpmd> ", 120) def update_table_info(self, case_info, frame_size, Mpps, throughtput, Cycle): results_row = [frame_size] results_row.append(case_info) results_row.append(Mpps) results_row.append(throughtput) results_row.append(Cycle) self.result_table_add(results_row) def calculate_avg_throughput(self, frame_size): """ start to send packet and get the throughput """ payload = frame_size - HEADER_SIZE['eth'] - HEADER_SIZE['ip'] flow = '[Ether(dst="%s")/IP(src="192.168.4.1",dst="192.168.3.1")/("X"*%d)]' % ( self.dst_mac, payload) self.tester.scapy_append('wrpcap("pvp_multipath.pcap", %s)' % flow) self.tester.scapy_execute() tgenInput = [] port = self.tester.get_local_port(self.dut_ports[0]) tgenInput.append((port, port, "pvp_multipath.pcap")) _, pps = self.tester.traffic_generator_throughput(tgenInput, delay=30) Mpps = pps / 1000000.0 self.verify(Mpps > 0, "can not receive packets of frame size %d" % (frame_size)) throughput = Mpps * 100 / \ float(self.wirespeed(self.nic, frame_size, 1)) return Mpps, throughput def send_and_verify(self, case_info): """ start to send packets and verify it """ for frame_size in self.frame_sizes: info = "Running test %s, and %d frame size." % (self.running_case, frame_size) self.logger.info(info) Mpps, throughput = self.calculate_avg_throughput(frame_size) self.update_table_info(case_info, frame_size, Mpps, throughput, "Before Restart") self.port_restart() Mpps, throughput = self.calculate_avg_throughput(frame_size) self.update_table_info(case_info, frame_size, Mpps, throughput, "After Restart") def close_all_testpmd(self): """ close testpmd about vhost-user and vm_testpmd """ self.vhost.send_expect("quit", "#", 60) self.vm_dut.send_expect("quit", "#", 60) def close_session(self): """ close session of vhost-user """ self.dut.close_session(self.vhost) def test_perf_pvp_qemu_mergeable_mac(self): """ performance for [frame_sizes] and restart port on virtio 0.95 mergeable path """ self.start_vhost_testpmd() self.start_one_vm(modem=0, mergeable=1) self.start_vm_testpmd(path="mergeable") self.send_and_verify("virtio0.95 mergeable") self.close_all_testpmd() self.result_table_print() self.vm.stop() def test_perf_pvp_qemu_normal_mac(self): """ performance for [frame_sizes] and restart port ob virtio0.95 normal path """ self.start_vhost_testpmd() self.start_one_vm(modem=0, mergeable=0) self.start_vm_testpmd(path="normal") self.send_and_verify("virtio0.95 normal") self.close_all_testpmd() self.result_table_print() self.vm.stop() def test_perf_pvp_qemu_vector_rx_mac(self): """ performance for [frame_sizes] and restart port on virtio0.95 vector_rx """ self.start_vhost_testpmd() self.start_one_vm(modem=0, mergeable=0) self.start_vm_testpmd(path="vector_rx") self.send_and_verify("virtio0.95 vector_rx") self.close_all_testpmd() self.result_table_print() self.vm.stop() def test_perf_pvp_qemu_modern_mergeable_mac(self): """ performance for [frame_sizes] and restart port on virtio1.0 mergeable path """ self.start_vhost_testpmd() self.start_one_vm(modem=1, mergeable=1) self.start_vm_testpmd(path="mergeable") self.send_and_verify("virtio1.0 mergeable") self.close_all_testpmd() self.result_table_print() self.vm.stop() def test_perf_pvp_qemu_modern_normal_path(self): """ performance for [frame_sizes] and restart port on virito1.0 normal path """ self.start_vhost_testpmd() self.start_one_vm(modem=1, mergeable=0) self.start_vm_testpmd(path="normal") self.send_and_verify("virtio1.0 normal") self.close_all_testpmd() self.result_table_print() self.vm.stop() def test_perf_pvp_qemu_modern_vector_rx_mac(self): """ performance for frame_sizes and restart port on virtio1.0 vector rx """ self.start_vhost_testpmd() self.start_one_vm(modem=1, mergeable=0) self.start_vm_testpmd(path="vector_rx") self.send_and_verify("virtio1.0 vector_rx") self.close_all_testpmd() self.result_table_print() self.vm.stop() def tear_down(self): """ Run after each test case. """ self.dut.send_expect("killall -s INT testpmd", "#") self.dut.send_expect("killall -s INT qemu-system-x86_64", "#") self.close_session() time.sleep(2) def tear_down_all(self): """
class TestVfMacFilter(TestCase): supported_vf_driver = ['pci-stub', 'vfio-pci'] vf0_wrongmac = "00:11:22:33:48:55" vf0_setmac = "00:11:22:33:44:55" 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" # set vf assign method and vf driver self.vf_driver = self.get_suite_cfg()['vf_driver'] if self.vf_driver is None: self.vf_driver = 'pci-stub' self.verify(self.vf_driver in self.supported_vf_driver, "Unsupported vf driver") if self.vf_driver == 'pci-stub': self.vf_assign_method = 'pci-assign' else: self.vf_assign_method = 'vfio-pci' self.dut.send_expect('modprobe vfio-pci', '#') def set_up(self): self.setup_2pf_2vf_1vm_env_flag = 0 def setup_2pf_2vf_1vm_env(self, set_mac, 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 set_mac: 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 } 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/2C/2T", eal_param=eal_param) # set up VM0 ENV self.vm0 = VM(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 def test_kernel_2pf_2vf_1vm_iplink_macfilter(self): """ 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 send packets with this MAC to VF, check if the MAC filter works. Also send the packets with wrong MAC address to VF, check the VF will not RX the packets. """ self.setup_2pf_2vf_1vm_env(True, driver='') self.result_verify_iplink(True) def result_verify_iplink(self, set_mac): if set_mac == False: self.host_testpmd.execute_cmd('set vf mac addr 0 0 %s' % self.pf0_vf0_mac) 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) 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 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 = self.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") def test_kernel_2pf_2vf_1vm_mac_add_filter(self): """ 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 be received by the VF. """ self.setup_2pf_2vf_1vm_env(False, driver='') self.send_packet_and_verify() def test_dpdk_2pf_2vf_1vm_mac_add_filter(self): """ test case for dpdk pf and dpdk vf 2pf_2vf_1vm MAC filter scenario. dpdk 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, check the VF will not RX packets. """ self.verify( self.nic.startswith('fortville') == True, "NIC is [%s], skip this case" % self.nic) self.setup_2pf_2vf_1vm_env(False, driver='igb_uio') self.send_packet_and_verify() def test_dpdk_2pf_2vf_1vm_iplink_macfilter(self): """ test case for dpdk pf and dpdk vf 2pf_2vf_1vm MAC filter scenario. dpdk pf will not set MAC address and the VF will get a random generated MAC in the testpmd in VM, then send packets with this MAC to VF, check that all packets can be RXed and TXed, send the packets with a wrong MAC address to VF, check the VF will not RX packets. """ self.setup_2pf_2vf_1vm_env(False, driver='igb_uio') self.result_verify_iplink(False) def send_packet_and_verify(self): 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) self.vm0_testpmd.execute_cmd('set promisc all off') ret = self.vm0_testpmd.execute_cmd('mac_addr add 0 %s' % self.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 = self.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 = self.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)
class TestVF2VFBridge(TestCase): supported_vf_driver = ['pci-stub', 'vfio-pci'] def set_up_all(self): self.dut_ports = self.dut.get_ports(self.nic) self.verify(len(self.dut_ports) >= 1, "Insufficient ports") self.vm0 = None self.vm1 = None # set vf assign method and vf driver self.vf_driver = self.get_suite_cfg()['vf_driver'] if self.vf_driver is None: self.vf_driver = 'pci-stub' self.verify(self.vf_driver in self.supported_vf_driver, "Unspported vf driver") if self.vf_driver == 'pci-stub': self.vf_assign_method = 'pci-assign' else: self.vf_assign_method = 'vfio-pci' self.dut.send_expect('modprobe vfio-pci', '#') def set_up(self): self.set_up_vf_to_vf_env() def set_up_vf_to_vf_env(self, driver='default'): self.pf_port_for_vfs = self.dut_ports[0] self.dut.restore_interfaces() self.dut.generate_sriov_vfs_by_port( self.pf_port_for_vfs, VF_NUMS_ON_ONE_PF, driver=driver) self.sriov_vfs_ports = self.dut.ports_info[ self.pf_port_for_vfs]['vfs_port'] self.host_port_intf = self.dut.ports_info[self.pf_port_for_vfs]['intf'] for i in range(VF_NUMS_ON_ONE_PF): self.dut.send_expect('ip link set dev %s vf %d mac %s' % (self.host_port_intf, i, VF_TEMP_MAC % i), '#', 10) try: for port in self.sriov_vfs_ports: port.bind_driver(self.vf_driver) time.sleep(1) except Exception as e: raise Exception(e) vf0_prop = {'opt_host': self.sriov_vfs_ports[0].pci} vf1_prop = {'opt_host': self.sriov_vfs_ports[1].pci} time.sleep(1) self.vm0 = VM(self.dut, 'vm0', 'vf_to_vf_bridge') self.vm0.set_vm_device(driver=self.vf_assign_method, **vf0_prop) try: self.vm0_dut = self.vm0.start() if self.vm0_dut is None: raise Exception('Set up VM0 failed') except Exception as e: print utils.RED(str(e)) self.vm1 = VM(self.dut, 'vm1', 'vf_to_vf_bridge') self.vm1.set_vm_device(driver=self.vf_assign_method, **vf1_prop) try: self.vm1_dut = self.vm1.start() if self.vm1_dut is None: raise Exception('Set up VM1 failed') except Exception as e: print utils.RED(str(e)) def clear_vf_to_vf_env(self): if self.vm0 is not None: self.vm0.stop() self.vm0 = None if self.vm1 is not None: self.vm1.stop() self.vm1 = None self.dut.virt_exit() if self.pf_port_for_vfs is not None: self.dut.destroy_sriov_vfs_by_port(self.pf_port_for_vfs) port = self.dut.ports_info[self.pf_port_for_vfs]['port'] port.bind_driver() self.pf_port_for_vfs = 0 def generate_pcap_pkt(self, dst, src, load, pktname='flow.pcap'): """ dst: server: dst server object ether: dst mac ip: dst ip udp: dst udp protocol tcp: dst tcp protocal src: server: src server object ether: src mac ip: src ip udp: src udp protocol tcp: src tcp protocal load: content: pay load length: content length """ context = '[Ether(dst="%s", src="%s")/IP()/Raw(load=%s)]' % \ (str(dst['ether']), str(src['ether']), load['content']) src['server'].send_expect('scapy', '>>> ', 10) src['server'].send_expect( 'wrpcap("%s", %s)' % (pktname, context), '>>> ', 10) src['server'].send_expect('quit()', '#', 10) def prepare_pktgen(self, vm): vm.session.copy_file_to('./dep/tgen.tgz') vm.send_expect("cd /root", "#", 10) vm.send_expect("tar xvf tgen.tgz", '#', 20) def send_stream_pktgen(self, vm, pktname='flow.pcap'): vm.send_expect( "echo 2048 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages", "#", 10) vm.send_expect(" mount -t hugetlbfs nodedev /mnt/huge/", "#", 10) vm.send_expect( "./pktgen -c 0xf -n 2 --proc-type auto -- -P -T -m '1.0' -s 0:%s" % pktname, "", 100) time.sleep(60) vm.send_expect("set 0 rate 50", "", 20) time.sleep(5) vm.send_expect("set 0 count %d" % SEND_PACKET, "", 20) time.sleep(5) vm.send_expect("start all", "", 20) time.sleep(20) def stop_stream_pktgen(self, vm): vm.send_expect("stop all", "", 20) time.sleep(5) vm.send_expect("quit", "#", 20) def test_2vf_d2d_pktgen_stream(self): self.vm0_ports = self.vm0_dut.get_ports('any') self.vm0_pmd = PmdOutput(self.vm0_dut) self.vm0_pmd.start_testpmd('all') self.vm0_pmd.execute_cmd('set fwd rxonly') self.vm0_pmd.execute_cmd("set promisc all off") self.vm0_pmd.execute_cmd('start') self.vm1_ports = self.vm1_dut.get_ports('any') self.prepare_pktgen(self.vm1_dut) dst = {} dst['server'] = self.vm0_dut dst['ether'] = self.vm0_dut.ports_info[self.vm0_ports[0]]['mac'] src = {} src['server'] = self.vm1_dut src['ether'] = self.vm1_dut.ports_info[self.vm1_ports[0]]['mac'] load = {} load['content'] = "'X'*46" self.generate_pcap_pkt(dst, src, load) self.vm0_pmd.execute_cmd('clear port stats all') self.send_stream_pktgen(self.vm1_dut) recv_num = self.vm0_pmd.get_pmd_stats(0)['RX-packets'] time.sleep(1) self.stop_stream_pktgen(self.vm1_dut) self.vm0_pmd.execute_cmd('stop') self.vm0_pmd.execute_cmd('quit', '# ') self.verify(recv_num is SEND_PACKET, 'Rx port recv error: %d' % recv_num) def test_2vf_d2k_pktgen_stream(self): self.vm0_dut.restore_interfaces() self.vm0_ports = self.vm0_dut.get_ports('any') vf0_intf = self.vm0_dut.ports_info[self.vm0_ports[0]]['intf'] self.vm1_ports = self.vm1_dut.get_ports('any') self.prepare_pktgen(self.vm1_dut) dst = {} dst['server'] = self.vm0_dut dst['ether'] = self.vm0_dut.ports_info[self.vm0_ports[0]]['mac'] src = {} src['server'] = self.vm1_dut src['ether'] = self.vm1_dut.ports_info[self.vm1_ports[0]]['mac'] load = {} load['content'] = "'X'*46" self.generate_pcap_pkt(dst, src, load) self.vm0_dut.send_expect( 'tcpdump -i %s -s 1000 "ether src %s and ether dst %s"' % (vf0_intf, src['ether'], dst['ether']), 'tcpdump', 30) self.send_stream_pktgen(self.vm1_dut) self.stop_stream_pktgen(self.vm1_dut) recv_tcpdump = self.vm0_dut.send_expect('^C', '#', 30) time.sleep(5) recv_pattern = re.compile("(\d+) packets captured") recv_info = recv_pattern.search(recv_tcpdump) recv_str = recv_info.group(0).split(' ')[0] recv_number = int(recv_str, 10) self.vm0_dut.bind_interfaces_linux(self.drivername) self.verify(recv_number is SEND_PACKET, 'Rx port recv error: %d' % recv_number) def test_2vf_k2d_scapy_stream(self): self.vm0_ports = self.vm0_dut.get_ports('any') self.vm0_pmd = PmdOutput(self.vm0_dut) self.vm0_pmd.start_testpmd('all') self.vm1_ports = self.vm1_dut.get_ports('any') self.vm1_dut.restore_interfaces() vf1_intf = self.vm1_dut.ports_info[self.vm1_ports[0]]['intf'] dst_mac = self.vm0_dut.ports_info[self.vm0_ports[0]]['mac'] src_mac = self.vm1_dut.ports_info[self.vm1_ports[0]]['mac'] pkt_content = 'Ether(dst="%s", src="%s")/IP()/Raw(load="X"*46)' % \ (dst_mac, src_mac) self.vm1_dut.send_expect('scapy', '>>> ', 10) self.vm0_pmd.execute_cmd('set promisc all off') self.vm0_pmd.execute_cmd('set fwd rxonly') self.vm0_pmd.execute_cmd('set verbose 1') self.vm0_pmd.execute_cmd('start') self.vm1_dut.send_expect('sendp([%s], iface="%s", count=%d)' % (pkt_content, vf1_intf, SEND_PACKET), '>>> ', 30) out = self.vm0_dut.get_session_output(timeout=60) rx_packets = re.findall("src=%s - dst=%s" % (src_mac, dst_mac), out) recv_num = len(rx_packets) self.vm1_dut.send_expect('quit()', '# ', 10) self.vm1_dut.bind_interfaces_linux(self.drivername) self.vm0_pmd.execute_cmd('stop') self.vm0_pmd.execute_cmd('quit', '# ') self.verify(recv_num is SEND_PACKET, 'Rx port recv error: %d' % recv_num) def tear_down(self): self.clear_vf_to_vf_env() def tear_down_all(self): pass
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 = VM(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 = self.tester.tcpdump_sniff_packets(self.tester_intf0, timeout=5) pkt.send_pkt(tx_port=self.tester_intf1) pkts = self.tester.load_tcpdump_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 packet 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 = self.tester.tcpdump_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 = self.tester.load_tcpdump_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('stop') self.vm0_testpmd.execute_cmd('port stop all') self.vm0_testpmd.execute_cmd('tx_vlan set 0 %d' % tx_vlan) self.vm0_testpmd.execute_cmd('port start all') 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('vlan set filter 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
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") local_port = self.tester.get_local_port(self.dut_ports[0]) self.tx_interface = self.tester.get_interface(local_port) # 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) self.verify( len(self.cores) >= 3, "Insufficient cores for speed testing") self.queue_number = 2 # Using file to save the vhost sample output since in jumboframe case, # there will be lots of output self.virtio1 = "eth1" self.virtio1_mac = "52:54:00:00:00:01" self.vm_dut = None self.number_of_ports = 1 self.header_row = [ "FrameSize(B)", "Throughput(Mpps)", "LineRate(%)", "Cycle" ] self.memory_channel = self.dut.get_memory_channels() def set_up(self): """ Run before each test case. """ 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 %s -n 3" + \ " -- -i --tx-offloads=0x0 " + \ " --rxq=%d --txq=%d --rss-ip --nb-cores=2" % (self.queue_number, self.queue_number) def launch_testpmd(self): """ Launch the vhost sample with different parameters """ testcmd = self.target + "/app/testpmd -c %s -n %d --socket-mem 1024,1024" + \ " --vdev 'net_vhost0,iface=vhost-net,queues=%d' -- -i --rxq=%d --txq=%d --nb-cores=2" self.coremask = utils.create_mask(self.cores) testcmd_start = testcmd % (self.coremask, self.memory_channel, self.queue_number, self.queue_number, self.queue_number) self.dut.send_expect(testcmd_start, "testpmd> ", 120) self.dut.send_expect("set fwd mac", "testpmd> ", 120) self.dut.send_expect("start", "testpmd> ", 120) def start_onevm(self): """ Start One VM with one virtio device """ self.vm = VM(self.dut, 'vm0', 'vhost_sample') vm_params = {} vm_params['driver'] = 'vhost-user' vm_params['opt_path'] = './vhost-net' vm_params['opt_mac'] = self.virtio1_mac vm_params['opt_queue'] = self.queue_number vm_params['opt_settings'] = 'mrg_rxbuf=on,mq=on,vectors=%d' % ( 2 * self.queue_number + 2) 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 get_vm_coremask(self): """ Get the vm coremask """ cores = self.vm_dut.get_core_list("1S/3C/1T") self.verify( len(cores) >= 3, "Insufficient cores for speed testing, add the cpu number in cfg file." ) self.vm_coremask = utils.create_mask(cores) def vhost_performance(self): """ Verify the testpmd can receive and forward the data """ self.result_table_create(self.header_row) for frame_size in self.frame_sizes: info = "Running test %s, and %d frame size." % (self.running_case, frame_size) self.logger.info(info) payload_size = frame_size - HEADER_SIZE['eth'] - HEADER_SIZE[ 'ip'] - HEADER_SIZE['udp'] tgenInput = [] pkt1 = Packet() pkt1.assign_layers(['ether', 'ipv4', 'udp', 'raw']) pkt1.config_layers([('ether', { 'dst': '%s' % self.virtio1_mac }), ('ipv4', { 'dst': '1.1.1.1' }), ('udp', { 'src': 4789, 'dst': 4789 }), ('raw', { 'payload': ['01'] * int('%d' % payload_size) })]) pkt2 = Packet() pkt2.assign_layers(['ether', 'ipv4', 'udp', 'raw']) pkt2.config_layers([('ether', { 'dst': '%s' % self.virtio1_mac }), ('ipv4', { 'dst': '1.1.1.20' }), ('udp', { 'src': 4789, 'dst': 4789 }), ('raw', { 'payload': ['01'] * int('%d' % payload_size) })]) pkt3 = Packet() pkt3.assign_layers(['ether', 'ipv4', 'udp', 'raw']) pkt3.config_layers([('ether', { 'dst': '%s' % self.virtio1_mac }), ('ipv4', { 'dst': '1.1.1.7' }), ('udp', { 'src': 4789, 'dst': 4789 }), ('raw', { 'payload': ['01'] * int('%d' % payload_size) })]) pkt4 = Packet() pkt4.assign_layers(['ether', 'ipv4', 'udp', 'raw']) pkt4.config_layers([('ether', { 'dst': '%s' % self.virtio1_mac }), ('ipv4', { 'dst': '1.1.1.8' }), ('udp', { 'src': 4789, 'dst': 4789 }), ('raw', { 'payload': ['01'] * int('%d' % payload_size) })]) pkt = [pkt1, pkt2, pkt3, pkt4] save_packets(pkt, "/root/multiqueue_2.pcap") port = self.tester.get_local_port(self.pf) tgenInput.append((port, port, "multiqueue_2.pcap")) _, pps = self.tester.traffic_generator_throughput(tgenInput, delay=30) Mpps = pps / 1000000.0 pct = Mpps * 100 / float( self.wirespeed(self.nic, frame_size, self.number_of_ports)) data_row = [ frame_size, str(Mpps), str(pct), "Mergeable Multiqueue Performance" ] self.result_table_add(data_row) self.verify(Mpps != 0, "The receive data of frame-size: %d is 0" % frame_size) self.result_table_print() def send_and_verify(self, verify_type): """ Verify the virtio-pmd can receive the data before/after change queue size While verify_type is "vhost queue = virtio queue", the vhost should forward all set of data While verify_type is "vhost queue < virtio queue", the vhost should forward all set of data While verify_type is "vhost queue > virtio queue", the vhost should forward at least one set of data """ for frame_size in self.frame_sizes: info = "Running test %s, and %d frame size." % (self.running_case, frame_size) self.logger.info(info) self.dut.send_expect("clear port stats all", "testpmd> ", 120) payload_size = frame_size - HEADER_SIZE['eth'] - HEADER_SIZE[ 'ip'] - HEADER_SIZE['udp'] pkt1 = Packet() pkt1.assign_layers(['ether', 'ipv4', 'udp', 'raw']) pkt1.config_layers([('ether', { 'dst': '%s' % self.virtio1_mac }), ('ipv4', { 'dst': '1.1.1.1' }), ('udp', { 'src': 4789, 'dst': 4789 }), ('raw', { 'payload': ['01'] * int('%d' % payload_size) })]) pkt2 = Packet() pkt2.assign_layers(['ether', 'ipv4', 'udp', 'raw']) pkt2.config_layers([('ether', { 'dst': '%s' % self.virtio1_mac }), ('ipv4', { 'dst': '1.1.1.20' }), ('udp', { 'src': 4789, 'dst': 4789 }), ('raw', { 'payload': ['01'] * int('%d' % payload_size) })]) pkt3 = Packet() pkt3.assign_layers(['ether', 'ipv4', 'udp', 'raw']) pkt3.config_layers([('ether', { 'dst': '%s' % self.virtio1_mac }), ('ipv4', { 'dst': '1.1.1.7' }), ('udp', { 'src': 4789, 'dst': 4789 }), ('raw', { 'payload': ['01'] * int('%d' % payload_size) })]) pkt4 = Packet() pkt4.assign_layers(['ether', 'ipv4', 'udp', 'raw']) pkt4.config_layers([('ether', { 'dst': '%s' % self.virtio1_mac }), ('ipv4', { 'dst': '1.1.1.8' }), ('udp', { 'src': 4789, 'dst': 4789 }), ('raw', { 'payload': ['01'] * int('%d' % payload_size) })]) pkt = [pkt1, pkt2, pkt3, pkt4] * 10 send_packets(self.tx_interface, pkt) out = self.dut.send_expect("show port stats 0", "testpmd> ", 120) print out rx_packet = re.search("RX-packets:\s*(\d*)", out) rx_num = int(rx_packet.group(1)) tx_packet = re.search("TX-packets:\s*(\d*)", out) tx_num = int(tx_packet.group(1)) if verify_type == "vhost queue = virtio queue" or verify_type == "vhost queue < virtio queue": verify_rx_num = 40 verify_tx_num = 40 elif verify_type == "vhost queue > virtio queue": verify_rx_num = 40 verify_tx_num = 10 self.verify( rx_num >= verify_rx_num and tx_num >= verify_tx_num, "The rx or tx lost some packets of frame-size:%d" % frame_size) def test_perf_pvp_multiqemu_mergeable_pmd(self): """ Test the performance for mergeable path """ self.launch_testpmd() self.start_onevm() self.get_vm_coremask() self.vm_dut.send_expect(self.vm_testpmd_vector % self.vm_coremask, "testpmd>", 20) self.vm_dut.send_expect("set fwd mac", "testpmd>", 20) self.vm_dut.send_expect("start", "testpmd>") self.dut.send_expect("stop", "testpmd> ", 120) self.dut.send_expect("start", "testpmd> ", 120) time.sleep(5) self.vhost_performance() self.vm_dut.kill_all() def test_dynamic_change_virtio_queue_size(self): """ Test the performance for change virtio queue size """ self.launch_testpmd() self.start_onevm() self.vm_testpmd_queue_1 = self.target + "/app/testpmd -c %s -n 3" + \ " -- -i --tx-offloads=0x0 " + \ " --rxq=1 --txq=1 --rss-ip --nb-cores=1" self.get_vm_coremask() self.vm_dut.send_expect(self.vm_testpmd_queue_1 % self.vm_coremask, "testpmd>", 20) self.vm_dut.send_expect("set fwd mac", "testpmd>", 20) self.vm_dut.send_expect("start", "testpmd>") self.dut.send_expect("clear port stats all", "testpmd> ", 120) self.send_and_verify("vhost queue > virtio queue") self.vm_dut.send_expect("stop", "testpmd>", 20) self.vm_dut.send_expect("port stop all", "testpmd>") self.vm_dut.send_expect("port config all rxq 2", "testpmd>", 20) self.vm_dut.send_expect("port config all txq 2", "testpmd>") self.vm_dut.send_expect("port start all", "testpmd>", 20) self.vm_dut.send_expect("start", "testpmd>") self.dut.send_expect("stop", "testpmd> ", 120) self.dut.send_expect("start", "testpmd> ", 120) self.dut.send_expect("clear port stats all", "testpmd> ", 120) self.send_and_verify("vhost queue = virtio queue") self.vm_dut.kill_all() self.dut.send_expect("quit", "# ", 120) def test_dynamic_change_vhost_queue_size(self): """ Test the performance for change vhost queue size """ self.queue_number = 2 testcmd = self.target + "/app/testpmd -c %s -n %d --socket-mem 1024,1024" + \ " --vdev 'net_vhost0,iface=vhost-net,queues=2' -- -i --rxq=1 --txq=1 --nb-cores=1" self.coremask = utils.create_mask(self.cores) testcmd_start = testcmd % (self.coremask, self.memory_channel) self.dut.send_expect(testcmd_start, "testpmd> ", 120) self.dut.send_expect("set fwd mac", "testpmd> ", 120) self.dut.send_expect("start", "testpmd> ", 120) self.start_onevm() self.get_vm_coremask() self.vm_dut.send_expect(self.vm_testpmd_vector % self.vm_coremask, "testpmd>", 20) self.vm_dut.send_expect("set fwd mac", "testpmd>", 20) self.vm_dut.send_expect("start", "testpmd>") self.dut.send_expect("clear port stats all", "testpmd> ", 120) self.send_and_verify("vhost queue < virtio queue") self.dut.send_expect("stop", "testpmd>", 20) self.dut.send_expect("port stop all", "testpmd>") self.dut.send_expect("port config all rxq 2", "testpmd>", 20) self.dut.send_expect("port config all txq 2", "testpmd>") self.dut.send_expect("port start all", "testpmd>", 20) self.dut.send_expect("start", "testpmd>") self.dut.send_expect("clear port stats all", "testpmd>") self.send_and_verify("vhost queue = virtio queue") self.vm_dut.kill_all() self.dut.send_expect("quit", "# ", 120) def tear_down(self): """ Run after each test case. Clear vhost-switch and qemu to avoid blocking the following TCs """ self.vm.stop() time.sleep(2) def tear_down_all(self): """ Run after each test suite. """ pass
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 = VM(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 --tx-offloads=0x8000" % (ETHER_STANDARD_MTU)) self.vm_testpmd.execute_cmd("set fwd mac") self.vm_testpmd.execute_cmd("set promisc all off") 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 forwarding 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 --tx-offloads=0x8000" % (ETHER_JUMBO_FRAME_MTU)) self.vm_testpmd.execute_cmd("set fwd mac") self.vm_testpmd.execute_cmd("set promisc all off") 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 --tx-offloads=0x8000") self.vm_testpmd.execute_cmd("set fwd mac") self.vm_testpmd.execute_cmd("set promisc all off") 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 leveraged 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 --tx-offloads=0x8000" % (ETHER_JUMBO_FRAME_MTU)) self.vm_testpmd.execute_cmd("set fwd mac") self.vm_testpmd.execute_cmd("set promisc all off") 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 --tx-offloads=0x8000" % (ETHER_JUMBO_FRAME_MTU)) self.vm_testpmd.execute_cmd("set fwd mac") self.vm_testpmd.execute_cmd("set promisc all off") 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 environment should clear up. """ self.destroy_vm_env() self.netobj.enable_jumbo(framesize=ETHER_STANDARD_MTU)
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, "Unsupported 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 = VM(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()
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.dut.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 = VM(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("set promisc all off") 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 } 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/2C/2T", eal_param=eal_param) # set up VM0 ENV self.vm0 = VM(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 = VM(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_kernel_pf_vf_reset(self): self.setup_3vf_2vm_env(driver='') self.vf_reset() def test_dpdk_pf_vf_reset(self): self.setup_3vf_2vm_env(driver='igb_uio') self.vf_reset() def vf_reset(self): 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("set promisc all off") 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.vm0_testpmd.execute_cmd('clear port stats all') 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