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 TestNvgre(TestCase): # # # Utility methods and other non-test code. # # Insert or move non-test functions here. # # # # Test cases. # def set_up_all(self): """ nvgre Prerequisites """ # this feature only enable in FVL now if self.nic in [ "fortville_eagle", "fortville_spirit", "fortville_spirit_single", "fortville_25g", "fortpark_TLV", "cavium_a063" ]: self.compile_switch = 'CONFIG_RTE_LIBRTE_I40E_INC_VECTOR' elif self.nic in ["sageville", "sagepond"]: self.compile_switch = 'CONFIG_RTE_IXGBE_INC_VECTOR' else: self.verify(False, "%s not support NVGRE case" % self.nic) # Based on h/w type, choose how many ports to use ports = self.dut.get_ports(self.nic) self.portmask = utils.create_mask(self.dut.get_ports(self.nic)) # Verify that enough ports are available self.verify(len(ports) >= 2, "Insufficient ports for testing") # Verify that enough threads are available self.all_cores_mask = utils.create_mask(self.dut.get_core_list("all")) cores = self.dut.get_core_list("1S/5C/1T") self.verify(cores is not None, "Insufficient cores for speed testing") self.coremask = utils.create_mask(cores) # start testpmd self.pmdout = PmdOutput(self.dut) # init port self.dut_rx_port = ports[0] self.dut_tx_port = ports[1] self.dut_rx_port_mac = self.dut.get_mac_address(self.dut_rx_port) self.dut_tx_port_mac = self.dut.get_mac_address(self.dut_tx_port) self.tester_tx_port = self.tester.get_local_port(self.dut_rx_port) self.tester_tx_iface = self.tester.get_interface(self.tester_tx_port) self.tester_rx_port = self.tester.get_local_port(self.dut_tx_port) self.tester_rx_iface = self.tester.get_interface(self.tester_rx_port) # invalid parameter self.invalid_mac = "00:00:00:00:01" self.invalid_ip = "192.168.1.256" self.invalid_vlan = 4097 self.invalid_queue = 64 # performance test cycle self.test_cycles = [{ 'cores': '1S/1C/1T', 'Mpps': {}, 'pct': {} }, { 'cores': '1S/1C/2T', 'Mpps': {}, 'pct': {} }, { 'cores': '1S/2C/1T', 'Mpps': {}, 'pct': {} }] """ self.cal_type = [ {'Type': 'SOFTWARE ALL', 'tx_checksum': '0x0'}, {'Type': 'HW OUTER L3', 'tx_checksum': '0x1'}, {'Type': 'HW OUTER L4', 'tx_checksum': '0x2'}, {'Type': 'HW OUTER L3&L4', 'tx_checksum': '0x3'}, {'Type': 'HW INNER L3', 'tx_checksum': '0x10'}, {'Type': 'HW INNER L4', 'tx_checksum': '0x20'}, {'Type': 'HW INNER L3&L4', 'tx_checksum': '0x30'}, {'Type': 'HARDWARE ALL', 'tx_checksum': '0xff'} ] """ self.table_header = ['Calculate Type'] for test_cycle in self.test_cycles: self.table_header.append("%s Mpps" % test_cycle['cores']) self.table_header.append("% linerate") # tunnel filter performance test self.default_vlan = 1 self.tunnel_multiqueue = 2 self.tunnel_header = [ 'Packet', 'Filter', 'Queue', 'Mpps', '% linerate' ] self.tunnel_perf = [{ 'Packet': 'Normal', 'tunnel_filter': 'None', 'recvqueue': 'Single', 'Mpps': {}, 'pct': {} }, { 'Packet': 'NVGRE', 'tunnel_filter': 'None', 'recvqueue': 'Single', 'Mpps': {}, 'pct': {} }, { 'Packet': 'NVGRE', 'tunnel_filter': 'imac-ivlan', 'recvqueue': 'Single', 'Mpps': {}, 'pct': {} }, { 'Packet': 'NVGRE', 'tunnel_filter': 'imac-ivlan-tenid', 'recvqueue': 'Single', 'Mpps': {}, 'pct': {} }, { 'Packet': 'NVGRE', 'tunnel_filter': 'imac-tenid', 'recvqueue': 'Single', 'Mpps': {}, 'pct': {} }, { 'Packet': 'NVGRE', 'tunnel_filter': 'imac', 'recvqueue': 'Single', 'Mpps': {}, 'pct': {} }, { 'Packet': 'NVGRE', 'tunnel_filter': 'omac-imac-tenid', 'recvqueue': 'Single', 'Mpps': {}, 'pct': {} }, { 'Packet': 'NVGRE', 'tunnel_filter': 'imac-ivlan', 'recvqueue': 'Multi', 'Mpps': {}, 'pct': {} }, { 'Packet': 'NVGRE', 'tunnel_filter': 'imac-ivlan-tenid', 'recvqueue': 'Multi', 'Mpps': {}, 'pct': {} }, { 'Packet': 'NVGRE', 'tunnel_filter': 'imac-tenid', 'recvqueue': 'Multi', 'Mpps': {}, 'pct': {} }, { 'Packet': 'NVGRE', 'tunnel_filter': 'imac', 'recvqueue': 'Multi', 'Mpps': {}, 'pct': {} }, { 'Packet': 'NVGRE', 'tunnel_filter': 'omac-imac-tenid', 'recvqueue': 'Multi' }] self.ports_socket = self.dut.get_numa_id(self.dut_rx_port) def nvgre_detect(self, **kwargs): """ send nvgre packet and check whether testpmd detect the correct packet type """ out = self.dut.send_expect( "./%s/app/testpmd -c %s -n %d -- -i --disable-rss --rxq=4 --txq=4 --nb-cores=4 --portmask=%s" % (self.target, self.coremask, self.dut.get_memory_channels(), self.portmask), "testpmd>", 30) out = self.dut.send_expect("set fwd rxonly", "testpmd>", 10) self.dut.send_expect("set verbose 1", "testpmd>", 10) arg_str = "" for arg in kwargs: arg_str += "[%s = %s]" % (arg, kwargs[arg]) # create pcap file with supplied arguments self.logger.info("send nvgre pkts %s" % arg_str) config = NvgreTestConfig(self, **kwargs) # now cloud filter will default enable L2 mac filter, so dst mac must be same config.outer_mac_dst = self.dut_rx_port_mac config.create_pcap() self.dut.send_expect("start", "testpmd>", 10) config.send_pcap() # check whether detect nvgre type out = self.dut.get_session_output() print out self.verify( config.packet_type(self.nic) in out, "Nvgre Packet not detected") self.dut.send_expect("show port stats all", "testpmd>", 10) self.dut.send_expect("stop", "testpmd>", 10) self.dut.send_expect("quit", "#", 10) def nvgre_filter(self, filter_type="omac-imac-tenid", queue_id=3, vlan=False, remove=False): """ send nvgre packet and check whether receive packet in assigned queue """ self.dut.send_expect( "./%s/app/testpmd -c %s -n %d -- -i --disable-rss --rxq=4 --txq=4 --nb-cores=4 --portmask=%s" % (self.target, self.coremask, self.dut.get_memory_channels(), self.portmask), "testpmd>", 30) self.dut.send_expect("set fwd rxonly", "testpmd>", 10) self.dut.send_expect("set verbose 1", "testpmd>", 10) if vlan is not False: config = NvgreTestConfig(self, inner_vlan=vlan) vlan_id = vlan else: config = NvgreTestConfig(self) vlan_id = 1 # now cloud filter will default enable L2 mac filter, so dst mac must be same config.outer_mac_dst = self.dut_rx_port_mac # tunnel_filter add port_id outer_mac inner_mac ip_addr inner_vlan tunnel_type(vxlan|nvgre) # filter_type (imac-ivlan|imac-ivlan-tenid|imac-tenid|imac|omac-imac-tenid|iip) tenant_id queue_num out = self.dut.send_expect( "tunnel_filter add %d %s %s %s %d nvgre %s %d %d" % (self.dut_rx_port, config.outer_mac_dst, config.inner_mac_dst, config.inner_ip_dst, vlan_id, filter_type, config.tni, queue_id), "testpmd>", 10) print out # invalid case request to remove tunnel filter if remove is True: queue_id = 0 self.dut.send_expect( "tunnel_filter rm %d %s %s %s %d nvgre %s %d %d" % (self.dut_rx_port, config.outer_mac_dst, config.inner_mac_dst, config.inner_ip_dst, vlan_id, filter_type, config.tni, queue_id), "testpmd>", 10) # send nvgre packet config.create_pcap() self.dut.send_expect("start", "testpmd>", 10) config.send_pcap() out = self.dut.get_session_output() print out queue = -1 pattern = re.compile("- Receive queue=0x(\d)") m = pattern.search(out) if m is not None: queue = m.group(1) # verify received in expected queue self.verify(queue_id == int(queue), "invalid receive queue") self.dut.send_expect("stop", "testpmd>", 10) self.dut.send_expect("quit", "#", 10) def nvgre_checksum(self, **kwargs): # create pcap file with correct arguments args = {} for arg in kwargs: if "invalid" not in arg: args[arg] = kwargs[arg] config = NvgreTestConfig(self, **args) # now cloud filter will default enable L2 mac filter, so dst mac must be same config.outer_mac_dst = self.dut_rx_port_mac # csum function will not change outer ipv src address already if config.outer_ip6_src != "N/A": config.outer_ip6_src = config.outer_ip6_src else: config.outer_ip_src = config.outer_ip_src # csum function will not auto change nvgre inner ipv src address already if config.inner_ip6_src != "N/A": config.inner_ip6_src = config.inner_ip6_src else: config.inner_ip_src = config.inner_ip_src # create abnormal package with wrong checksum config.create_pcap() chksums_default = config.get_chksums() self.logger.info("chksums_ref:" + str(chksums_default)) # start testpmd with 2queue/1port out = self.dut.send_expect( "./%s/app/testpmd -c %s -n %d -- -i --disable-rss --rxq=4 --txq=4 --nb-cores=4 --portmask=%s --enable-rx-cksum" % (self.target, self.coremask, self.dut.get_memory_channels(), self.portmask), "testpmd>", 30) # disable vlan filter self.dut.send_expect('vlan set filter off %d' % self.dut_rx_port, "testpmd") # enable tx checksum offload self.dut.send_expect("set verbose 1", "testpmd>", 10) self.dut.send_expect("set fwd csum", "testpmd>", 10) self.dut.send_expect("port stop all", "testpmd>") self.dut.send_expect("csum set ip hw %d" % (self.dut_tx_port), "testpmd>", 10) self.dut.send_expect("csum set udp hw %d" % (self.dut_tx_port), "testpmd>", 10) self.dut.send_expect("csum set tcp hw %d" % (self.dut_tx_port), "testpmd>", 10) self.dut.send_expect("csum set sctp hw %d" % (self.dut_tx_port), "testpmd>", 10) self.dut.send_expect("csum set outer-ip hw %d" % (self.dut_tx_port), "testpmd>", 10) self.dut.send_expect("csum parse-tunnel on %d" % (self.dut_tx_port), "testpmd>", 10) self.dut.send_expect("port start all", "testpmd>") # log the nvgre format arg_str = "" for arg in kwargs: arg_str += "[%s = %s]" % (arg, kwargs[arg]) self.logger.info("nvgre packet %s" % arg_str) out = self.dut.send_expect("start", "testpmd>", 10) # create pcap file with supplied arguments config = NvgreTestConfig(self, **kwargs) config.outer_mac_dst = self.dut_rx_port_mac config.create_pcap() # remove temporary files self.tester.send_expect("rm -rf %s" % config.capture_file, "# ") # save the capture packet into pcap format self.tester.scapy_background() self.tester.scapy_append( 'p=sniff(iface="%s",filter="ether[12:2]!=0x88cc",count=1,timeout=5)' % self.tester_rx_iface) self.tester.scapy_append('wrpcap(\"%s\", p)' % config.capture_file) self.tester.scapy_foreground() config.send_pcap() time.sleep(5) # extract the checksum offload from saved pcap file chksums = config.get_chksums(pcap=config.capture_file) os.remove(config.capture_file) self.logger.info("chksums_tx:" + str(chksums)) out = self.dut.send_expect("stop", "testpmd>", 10) # verify detected l4 invalid checksum if "inner_l4_invalid" in kwargs and config.inner_l4_type is not 'UDP': self.verify( self.pmdout.get_pmd_value("Bad-l4csum:", out) == 1, "Failed to count inner l4 chksum error") # verify detected l3 invalid checksum if "inner_ip_invalid" in kwargs: self.verify( self.pmdout.get_pmd_value("Bad-ipcsum:", out) == 1, "Failed to count inner ip chksum error") self.dut.send_expect("quit", "#", 10) # verify saved pcap checksum same to expected checksum for key in chksums_default: self.verify(chksums[key] == chksums_default[key], "%s not matched to %s" % (key, chksums_default[key])) def test_nvgre_ipv4(self): """ verify nvgre packet with ipv4 """ # packet type detect must used without VECTOR pmd out = self.dut.send_expect("cat config/common_base", "]# ", 10) src_vec_model = re.findall("%s=." % self.compile_switch, out)[0][-1] if src_vec_model == 'y': self.dut.send_expect( "sed -i -e 's/%s=.*$/" % self.compile_switch + "%s=n/' config/common_base" % self.compile_switch, "# ", 30) self.dut.skip_setup = False self.dut.build_install_dpdk(self.target) # check no nvgre packet self.nvgre_detect(outer_ip_proto=0xFF) # check nvgre + IP inner packet self.nvgre_detect(inner_l3_type="IPv4", inner_l4_type='None') # check nvgre + udp inner packet self.nvgre_detect(inner_l4_type='TCP') # check nvgre + SCTP inner packet # self.nvgre_detect(inner_l4_type='SCTP') # check nvgre + vlan inner packet self.nvgre_detect(outer_vlan=1) # check vlan nvgre + vlan inner packet self.nvgre_detect(outer_vlan=1, inner_vlan=1) out = self.dut.send_expect("cat config/common_base", "]# ", 10) dst_vec_model = re.findall("%s=." % self.compile_switch, out)[0][-1] if src_vec_model != dst_vec_model: self.dut.send_expect( "sed -i -e 's/%s=.*$/" % self.compile_switch + "%s=%s/' config/common_base" % (self.compile_switch, src_vec_model), "# ", 30) self.dut.skip_setup = False self.dut.build_install_dpdk(self.target) def test_tunnel_filter(self): # verify tunnel filter feature # check outer mac self.nvgre_filter(filter_type="omac-imac-tenid") # check inner mac + inner vlan filter can work self.nvgre_filter(filter_type="imac-ivlan", vlan=1) # check inner mac + inner vlan + tunnel id filter can work self.nvgre_filter(filter_type="imac-ivlan-tenid", vlan=1) # check inner mac + tunnel id filter can work self.nvgre_filter(filter_type="imac-tenid") # check inner mac filter can work self.nvgre_filter(filter_type="imac") # check outer mac + inner mac + tunnel id filter can work self.nvgre_filter(filter_type="omac-imac-tenid") # check iip filter can work # self.nvgre_filter(filter_type="iip") def test_tunnel_filter_invalid(self): # verify tunnel filter parameter check function # invalid parameter vlan_id = 1 filter_type = 'omac-imac-tenid' queue_id = 3 self.nvgre_filter(filter_type="imac", remove=True) config = NvgreTestConfig(self) # config.outer_mac_dst = self.dut_port_mac self.dut.send_expect( "./%s/app/testpmd -c %s -n %d -- -i --disable-rss --rxq=4 --txq=4 --nb-cores=4 --portmask=%s" % (self.target, self.coremask, self.dut.get_memory_channels(), self.portmask), "testpmd>", 30) out = self.dut.send_expect( "tunnel_filter add %d %s %s %s %d nvgre %s %d %d" % (self.dut_rx_port, config.outer_mac_dst, self.invalid_mac, config.inner_ip_dst, vlan_id, filter_type, config.tni, queue_id), "testpmd>", 10) self.verify("Bad arguments" in out, "Failed to detect invalid mac") out = self.dut.send_expect( "tunnel_filter add %d %s %s %s %d nvgre %s %d %d" % (self.dut_rx_port, config.outer_mac_dst, config.inner_mac_dst, self.invalid_ip, vlan_id, filter_type, config.tni, queue_id), "testpmd>", 10) self.verify("Bad arguments" in out, "Failed to detect invalid ip") out = self.dut.send_expect( "tunnel_filter add %d %s %s %s %d nvgre %s %d %d" % (self.dut_rx_port, config.outer_mac_dst, config.inner_mac_dst, config.inner_ip_dst, self.invalid_vlan, filter_type, config.tni, queue_id), "testpmd>", 10) self.verify("Input/output error" in out, "Failed to detect invalid vlan") out = self.dut.send_expect( "tunnel_filter add %d %s %s %s %d nvgre %s %d %d" % (self.dut_rx_port, config.outer_mac_dst, config.inner_mac_dst, config.inner_ip_dst, vlan_id, filter_type, config.tni, self.invalid_queue), "testpmd>", 10) self.verify("Input/output error" in out, "Failed to detect invalid queue") self.dut.send_expect("stop", "testpmd>", 10) self.dut.send_expect("quit", "#", 10) def test_nvgre_ipv4_checksum_offload(self): # check normal packet self.nvgre_checksum() # check normal packet + ip checksum invalid self.nvgre_checksum(outer_ip_invalid=1) # check nvgre packet + inner ip checksum invalid self.nvgre_checksum(inner_ip_invalid=1) # check nvgre packet + outer ip checksum invalid self.nvgre_checksum(outer_ip_invalid=1) # check nvgre packet + outer ip + inner ip checksum invalid self.nvgre_checksum(outer_ip_invalid=1, inner_ip_invalid=1) # check nvgre packet + inner udp checksum invalid self.nvgre_checksum(inner_l4_invalid=1) # check nvgre packet + inner tcp checksum invalid self.nvgre_checksum(inner_l4_invalid=1, inner_l4_type='TCP') # check nvgre packet + inner sctp checksum invalid self.nvgre_checksum(inner_l4_invalid=1, inner_l4_type='SCTP') # check vlan nvgre packet + outer ip checksum invalid self.nvgre_checksum(outer_vlan=1, outer_ip_invalid=1) # check vlan nvgre packet + inner ip checksum invalid self.nvgre_checksum(outer_vlan=1, inner_ip_invalid=1) # check vlan nvgre packet + outer&inner ip checksum invalid self.nvgre_checksum(outer_vlan=1, outer_ip_invalid=1, inner_ip_invalid=1) # check vlan nvgre packet + inner vlan + outer ip checksum invalid self.nvgre_checksum(outer_vlan=1, inner_vlan=1, outer_ip_invalid=1) # check vlan nvgre packet + inner vlan + inner ip checksum invalid self.nvgre_checksum(outer_vlan=1, inner_vlan=1, inner_ip_invalid=1) # check vlan nvgre packet + inner vlan + outer&inner ip checksum invalid self.nvgre_checksum(outer_vlan=1, inner_vlan=1, outer_ip_invalid=1, inner_ip_invalid=1) # check vlan nvgre packet + inner vlan + inner udp checksum invalid self.nvgre_checksum(outer_vlan=1, inner_l4_invalid=1, inner_l4_type='UDP') # check vlan nvgre packet + inner vlan + inner tcp checksum invalid self.nvgre_checksum(outer_vlan=1, inner_l4_invalid=1, inner_l4_type='TCP') # check vlan nvgre packet + inner vlan + inner sctp checksum invalid self.nvgre_checksum(outer_vlan=1, inner_l4_invalid=1, inner_l4_type='SCTP') def test_perf_nvgre_tunnelfilter_performance_2ports(self): self.result_table_create(self.tunnel_header) core_list = self.dut.get_core_list('1S/%dC/1T' % (self.tunnel_multiqueue * 2), socket=self.ports_socket) core_mask = utils.create_mask(core_list) command_line = "./%s/app/testpmd -c %s -n %d -- -i --disable-rss --coremask=%s --rxq=4 --txq=4 --portmask=%s" % ( self.target, self.all_cores_mask, self.dut.get_memory_channels(), core_mask, self.portmask) for perf_config in self.tunnel_perf: pkts = [] config = NvgreTestConfig(self) config.inner_vlan = self.default_vlan config.outer_mac_dst = self.dut.get_mac_address(self.dut_port) # get frame size config.create_pcap() frame_size = config.pcap_len() # restart testpmd in each performance config self.dut.send_expect(command_line, "testpmd> ", 100) if perf_config['tunnel_filter'] != 'None': self.dut.send_expect( "tunnel_filter add %d %s %s %s %d vxlan %s %d %d" % (self.dut_port, config.outer_mac_dst, config.inner_mac_dst, config.inner_ip_dst, config.inner_vlan, perf_config['tunnel_filter'], config.tni, 0), "testpmd>", 10) if perf_config['Packet'] == 'Normal': config.outer_udp_dst = 63 config.outer_mac_dst = self.dut.get_mac_address(self.dut_port) config.payload_size = frame_size - HEADER_SIZE[ 'eth'] - HEADER_SIZE['ip'] - HEADER_SIZE['udp'] # add default pkt into pkt list pkt = config.create_pcap() pkts.append(pkt) # add other pkts into pkt list when enable multi receive queues if perf_config['recvqueue'] == 'Multi': for queue in range(self.tunnel_multiqueue - 1): if 'imac' in perf_config['tunnel_filter']: config.inner_mac_dst = "00:00:20:00:00:0%d" % (queue + 2) if 'ivlan' in perf_config['tunnel_filter']: config.inner_vlan = (queue + 2) if 'tenid' in perf_config['tunnel_filter']: config.vni = (queue + 2) # add tunnel filter the same as pkt pkt = config.create_pcap() pkts.append(pkt) out = self.dut.send_expect( "tunnel_filter add %d %s %s %s %d vxlan %s %d %d" % (self.dut_port, config.outer_mac_dst, config.inner_mac_dst, config.inner_ip_dst, config.inner_vlan, perf_config['tunnel_filter'], config.vni, (queue + 1)), "testpmd>", 10) # save pkt list into pcap file wrpcap(config.pcap_file, pkts) self.tester.session.copy_file_to(config.pcap_file) # config the flows tgen_input = [] tgen_input.append( (self.tester.get_local_port(self.dut_port), self.tester.get_local_port(self.recv_port), config.pcap_file)) self.dut.send_expect("set fwd mac", "testpmd>", 10) self.dut.send_expect("start", "testpmd>", 10) frame_size = config.pcap_len() wirespeed = self.wirespeed(self.nic, frame_size, 2) # run traffic generator _, pps = self.tester.traffic_generator_throughput(tgen_input) pps /= 1000000.0 perf_config['Mpps'] = pps perf_config['pct'] = pps * 100 / wirespeed out = self.dut.send_expect("stop", "testpmd>", 10) self.dut.send_expect("quit", "# ", 10) # verify every queue work fine if perf_config['recvqueue'] == 'Multi': for queue in range(self.tunnel_multiqueue): self.verify( "RX Port= 0/Queue= %d -> TX Port= 1/Queue= %d" % (queue, queue) in out, "Queue %d no traffic" % queue) table_row = [ perf_config['Packet'], perf_config['tunnel_filter'], perf_config['recvqueue'], perf_config['Mpps'], perf_config['pct'] ] self.result_table_add(table_row) self.result_table_print() def test_perf_nvgre_checksum_performance_2ports(self): config = NvgreTestConfig(self) config.outer_mac_dst = self.dut.get_mac_address(self.dut_port) config.pcap_file = "nvgre1.pcap" config.create_pcap() config.outer_mac_dst = self.dut.get_mac_address(self.recv_port) config.pcap_file = "nvgre.pcap" config.create_pcap() # configure flows tgen_input = [] tgen_input.append( (self.tester.get_local_port(self.dut_port), self.tester.get_local_port(self.recv_port), "nvgre.pcap")) tgen_input.append( (self.tester.get_local_port(self.recv_port), self.tester.get_local_port(self.dut_port), "nvgre.pcap")) all_cores_mask = utils.create_mask(self.dut.get_core_list("all")) # socket/core/thread for test_cycle in self.test_cycles: core_config = test_cycle['cores'] # take care the corelist when enable numa if '2S' not in core_config: core_list = self.dut.get_core_list(core_config, socket=self.ports_socket) else: core_list = self.dut.get_core_list(core_config) core_mask = utils.create_mask(core_list) command_line = "./%s/app/testpmd -c %s -n %d -- -i \ --disable-rss --coremask=%s --portmask=%s" % (self.target, all_cores_mask, self.dut.get_memory_channels(), core_mask, self.portmask) self.dut.send_expect(command_line, "testpmd> ", 100) self.dut.send_expect("set fwd csum", "testpmd>", 10) # different calculate type for cal in self.cal_type: self.dut.send_expect( "tx_checksum set %s %d" % (cal['tx_checksum'], self.dut_port), "testpmd>", 10) self.dut.send_expect( "tx_checksum set %s %d" % (cal['tx_checksum'], self.recv_port), "testpmd>", 10) self.dut.send_expect("start", "testpmd>", 10) frame_size = config.pcap_len() wirespeed = self.wirespeed(self.nic, frame_size, 2) # run traffic generator _, pps = self.tester.traffic_generator_throughput(tgen_input) pps /= 1000000.0 test_cycle['Mpps'][cal['Type']] = pps test_cycle['pct'][cal['Type']] = pps * 100 / wirespeed self.dut.send_expect("stop", "testpmd>", 10) self.dut.send_expect("quit", "# ", 10) self.result_table_create(self.table_header) # save the results for cal in self.cal_type: table_row = [cal['Type']] for test_cycle in self.test_cycles: table_row.append(test_cycle['Mpps'][cal['Type']]) table_row.append(test_cycle['pct'][cal['Type']]) self.result_table_add(table_row) self.result_table_print() def set_up(self): """ Run before each test case. """ pass def tear_down(self): """ Run after each test case. """ self.dut.kill_all() def tear_down_all(self): """ Run after each test suite. """ pass