From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 89F546D45 for ; Mon, 20 Nov 2017 04:29:16 +0100 (CET) Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Nov 2017 19:29:15 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.44,424,1505804400"; d="scan'208";a="178256834" Received: from dpdk-test32.sh.intel.com (HELO [10.67.118.217]) ([10.67.118.217]) by fmsmga006.fm.intel.com with ESMTP; 19 Nov 2017 19:29:14 -0800 Message-ID: <5A12BAF2.2010003@intel.com> Date: Mon, 20 Nov 2017 19:22:26 +0800 From: "Liu, Yong" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 To: Xueqin Lin , dts@dpdk.org References: <1510728865-79456-1-git-send-email-xueqin.lin@intel.com> In-Reply-To: <1510728865-79456-1-git-send-email-xueqin.lin@intel.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [dts] [PATCH v2] add ddp gtp test suite X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Nov 2017 03:29:17 -0000 Thanks Xueqin, two comments below. Regards, Marvin On 11/15/2017 02:54 PM, Xueqin Lin wrote: > --- > tests/TestSuite_ddp_gtp.py | 385 +++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 385 insertions(+) > create mode 100644 tests/TestSuite_ddp_gtp.py > > diff --git a/tests/TestSuite_ddp_gtp.py b/tests/TestSuite_ddp_gtp.py > new file mode 100644 > index 0000000..f28bf34 > --- /dev/null > +++ b/tests/TestSuite_ddp_gtp.py > @@ -0,0 +1,385 @@ > +# > + > +import time > +import re > +import sys > +import utils > +from qemu_kvm import QEMUKvm > +from test_case import TestCase > +from pmd_output import PmdOutput > +from settings import get_nic_name > +import random > + > +VM_CORES_MASK = 'all' > + > + > +class Testddp_gtp(TestCase): > + > + def set_up_all(self): > + self.verify( > + self.nic in ['fortville_25g'], 'ddp gtp can not support %s nic' > + % self.nic) > + self.dut_ports = self.dut.get_ports(self.nic) > + self.verify(len(self.dut_ports) >= 1, "Insufficient ports") > + self.vm0 = None > + self.env_done = False > + profile_file = 'dep/gtp.pkgo' > + profile_dst = "/tmp/" > + self.dut.session.copy_file_to(profile_file, profile_dst) > + PF_Q_strip = 'CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF' > + VF_Q_strip = 'CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF' > + self.PF_QUEUE = self.search_queue_number(PF_Q_strip) > + self.VF_QUEUE = self.search_queue_number(VF_Q_strip) > + > + def set_up(self): > + self.setup_vm_env() > + self.load_profile() > + > + def search_queue_number(self, Q_strip): > + """ > + Search max queue number from configuration. > + """ > + out = self.dut.send_expect("cat config/common_base", "]# ", 10) > + pattern = "(%s=)(\d*)" % Q_strip > + s = re.compile(pattern) > + res = s.search(out) > + if res is None: > + print "search no queue number" > + return None > + else: > + queue = res.group(2) > + return int(queue) > + > + def bind_nic_driver(self, ports, driver=""): > + if driver == "igb_uio": > + for port in ports: > + netdev = self.dut.ports_info[port]['port'] > + driver = netdev.get_nic_driver() > + if driver != 'igb_uio': > + netdev.bind_driver(driver='igb_uio') > + else: > + for port in ports: > + netdev = self.dut.ports_info[port]['port'] > + driver_now = netdev.get_nic_driver() > + if driver == "": > + driver = netdev.default_driver > + if driver != driver_now: > + netdev.bind_driver(driver=driver) > + > + def setup_vm_env(self, driver='igb_uio'): > + """ > + Create testing environment with VF generated from 1PF > + """ > + if self.env_done is False: > + self.bind_nic_driver(self.dut_ports[:1], driver="igb_uio") > + self.used_dut_port = self.dut_ports[0] > + tester_port = self.tester.get_local_port(self.used_dut_port) > + self.tester_intf = self.tester.get_interface(tester_port) > + self.dut.generate_sriov_vfs_by_port( > + self.used_dut_port, 1, driver=driver) > + self.sriov_vfs_port = self.dut.ports_info[ > + self.used_dut_port]['vfs_port'] > + for port in self.sriov_vfs_port: > + port.bind_driver('pci-stub') > + time.sleep(1) > + self.dut_testpmd = PmdOutput(self.dut) > + time.sleep(1) > + vf0_prop = {'opt_host': self.sriov_vfs_port[0].pci} > + # set up VM0 ENV > + self.vm0 = QEMUKvm(self.dut, 'vm0', 'ddp_gtp') > + self.vm0.set_vm_device(driver='pci-assign', **vf0_prop) > + try: > + self.vm0_dut = self.vm0.start() > + if self.vm0_dut is None: > + raise Exception("Set up VM0 ENV failed!") > + except Exception as e: > + self.destroy_vm_env() > + raise Exception(e) > + self.vm0_dut_ports = self.vm0_dut.get_ports('any') > + self.vm0_testpmd = PmdOutput(self.vm0_dut) > + self.env_done = True > + > + def destroy_vm_env(self): > + > + if getattr(self, 'vm0', None): > + self.vm0_dut.kill_all() > + self.vm0_testpmd = None > + self.vm0_dut_ports = None > + # destroy vm0 > + self.vm0.stop() > + self.vm0 = None > + > + if getattr(self, 'used_dut_port', None): > + self.dut.destroy_sriov_vfs_by_port(self.used_dut_port) > + port = self.dut.ports_info[self.used_dut_port]['port'] > + self.used_dut_port = None > + > + self.env_done = False > + > + def load_profile(self): > + """ > + Load profile to update FVL configuration tables, profile will be > + stored in binary file and need to be passed to AQ to program FVL > + during initialization stage. > + """ > + self.dut_testpmd.start_testpmd( > + "Default", "--pkt-filter-mode=perfect --port-topology=chained \ > + --txq=%s --rxq=%s" > + % (self.PF_QUEUE, self.PF_QUEUE)) > + self.vm0_testpmd.start_testpmd( > + VM_CORES_MASK, "--port-topology=chained --txq=%s --rxq=%s" > + % (self.VF_QUEUE, self.VF_QUEUE)) > + self.dut_testpmd.execute_cmd('port stop all') > + time.sleep(1) > + out = self.dut_testpmd.execute_cmd('ddp get list 0') > + self.dut_testpmd.execute_cmd('ddp add 0 /tmp/gtp.pkgo') > + out = self.dut_testpmd.execute_cmd('ddp get list 0') > + self.verify("Profile number is: 1" in out, > + "Failed to load ddp profile!!!") > + self.dut_testpmd.execute_cmd('port start all') > + time.sleep(1) > + self.dut_testpmd.execute_cmd('set fwd rxonly') > + self.dut_testpmd.execute_cmd('set verbose 1') > + self.dut_testpmd.execute_cmd('start') > + self.vm0_testpmd.execute_cmd('set fwd rxonly') > + self.vm0_testpmd.execute_cmd('set verbose 1') > + self.vm0_testpmd.execute_cmd('start') > + > + def gtp_packets( > + self, type='fdir', tunnel_pkt='gtpu', inner_L3='ipv4', > + nomatch_pkt=1, chk='', teid=0xF): > + """ > + Generate different GTP types according to different parameters. > + Input: > + filter type: includes flow director and cloud filter > + tunnel packet: includes GTPC and GTPU > + inner_L3: GTPC has no inner L3. GTPU has no, IPV4 and IPV6 inner L3. > + nomatch_pkt: PF or VSIs receive match packets to configured queue, but > + receive non match packets to queue 0. Flow director > + directs different TEIDs, inner L3 GTP packets to > + different queues. Cloud filter directs different TEIDs > + GTP packets to different queues. > + chk: checksum > + teid: GTP teid > + """ > + pkts = [] > + pkts_gtpc_pay = {'IPV4/GTPC': 'Ether()/IP()/UDP(%sdport=2123)/GTP_U_Header(teid=%s)/Raw("X"*20)' % (chk, teid), > + 'IPV6/GTPC': 'Ether()/IPv6()/UDP(%sdport=2123)/GTP_U_Header(teid=%s)/Raw("X"*20)' % (chk, teid)} > + > + pkts_gtpu_pay = {'IPV4/GTPU': 'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/Raw("X"*20)' % (chk, teid), > + 'IPV6/GTPU': 'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/Raw("X"*20)' % (chk, teid)} > + > + pkts_gtpu_ipv4 = {'IPV4/GTPU/IPV4': 'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/Raw("X"*20)' % (chk, teid), > + 'IPV4/GTPU/IPV4/FRAG': 'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP(frag=5)/Raw("X"*20)' % (chk, teid), > + 'IPV4/GTPU/IPV4/UDP': 'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/UDP()/Raw("X"*20)' % (chk, teid), > + 'IPV4/GTPU/IPV4/TCP': 'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/TCP()/Raw("X"*20)' % (chk, teid), > + 'IPV4/GTPU/IPV4/SCTP': 'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/SCTP()/Raw("X"*20)' % (chk, teid), > + 'IPV4/GTPU/IPV4/ICMP': 'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/ICMP()/Raw("X"*20)' % (chk, teid), > + 'IPV6/GTPU/IPV4': 'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/Raw("X"*20)' % (chk, teid), > + 'IPV6/GTPU/IPV4/FRAG': 'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP(frag=5)/Raw("X"*20)' % (chk, teid), > + 'IPV6/GTPU/IPV4/UDP': 'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/UDP()/Raw("X"*20)' % (chk, teid), > + 'IPV6/GTPU/IPV4/TCP': 'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/TCP()/Raw("X"*20)' % (chk, teid), > + 'IPV6/GTPU/IPV4/SCTP': 'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/SCTP()/Raw("X"*20)' % (chk, teid), > + 'IPV6/GTPU/IPV4/ICMP': 'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IP()/ICMP()/Raw("X"*20)' % (chk, teid)} > + > + pkts_gtpu_ipv6 = {'IPV4/GTPU/IPV6/FRAG': 'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/IPv6ExtHdrFragment()/Raw("X"*20)' % (chk, teid), > + 'IPV4/GTPU/IPV6': 'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/Raw("X"*20)' % (chk, teid), > + 'IPV4/GTPU/IPV6/UDP': 'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/UDP()/Raw("X"*20)' % (chk, teid), > + 'IPV4/GTPU/IPV6/TCP': 'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/TCP()/Raw("X"*20)' % (chk, teid), > + 'IPV4/GTPU/IPV6/SCTP': 'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/SCTP()/Raw("X"*20)' % (chk, teid), > + 'IPV4/GTPU/IPV6/ICMP': 'Ether()/IP()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6(nh=58)/ICMP()/Raw("X"*20)' % (chk, teid), > + 'IPV6/GTPU/IPV6/FRAG': 'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/IPv6ExtHdrFragment()/Raw("X"*20)' % (chk, teid), > + 'IPV6/GTPU/IPV6': 'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/Raw("X"*20)' % (chk, teid), > + 'IPV6/GTPU/IPV6/UDP': 'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/UDP()/Raw("X"*20)' % (chk, teid), > + 'IPV6/GTPU/IPV6/TCP': 'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/TCP()/Raw("X"*20)' % (chk, teid), > + 'IPV6/GTPU/IPV6/SCTP': 'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6()/SCTP()/Raw("X"*20)' % (chk, teid), > + 'IPV6/GTPU/IPV6/ICMP': 'Ether()/IPv6()/UDP(%sdport=2152)/GTP_U_Header(teid=%s)/IPv6(nh=58)/ICMP()/Raw("X"*20)' % (chk, teid)} > + if nomatch_pkt is 0: > + if tunnel_pkt is 'gtpc' and inner_L3 is None: > + pkts = pkts_gtpc_pay > + if tunnel_pkt is 'gtpu' and inner_L3 is None: > + pkts = pkts_gtpu_pay > + if tunnel_pkt is 'gtpu' and inner_L3 is 'ipv4': > + pkts = pkts_gtpu_ipv4 > + if tunnel_pkt is 'gtpu' and inner_L3 is 'ipv6': > + pkts = pkts_gtpu_ipv6 > + > + if nomatch_pkt == 1: > + if type is 'fdir': > + if tunnel_pkt is 'gtpc' and inner_L3 is None: > + pkts = dict( > + pkts_gtpu_pay.items() + > + pkts_gtpu_ipv4.items() + > + pkts_gtpu_ipv6.items()) > + if tunnel_pkt is 'gtpu' and inner_L3 is None: > + pkts = dict( > + pkts_gtpc_pay.items() + > + pkts_gtpu_ipv4.items() + > + pkts_gtpu_ipv6.items()) > + if tunnel_pkt is 'gtpu' and inner_L3 is 'ipv4': > + pkts = dict( > + pkts_gtpc_pay.items() + > + pkts_gtpu_pay.items() + > + pkts_gtpu_ipv6.items()) > + if tunnel_pkt is 'gtpu' and inner_L3 is 'ipv6': > + pkts = dict( > + pkts_gtpc_pay.items() + > + pkts_gtpu_pay.items() + > + pkts_gtpu_ipv4.items()) > + if type is 'clfter': > + if tunnel_pkt is 'gtpc': > + pkts = dict( > + pkts_gtpu_pay.items() + > + pkts_gtpu_ipv4.items() + > + pkts_gtpu_ipv6.items()) > + if tunnel_pkt is 'gtpu': > + pkts = pkts_gtpc_pay > + return pkts > + > + def gtp_test( > + self, type='fdir', port='pf', tunnel_pkt='gtpu', inner_L3='ipv4'): > + """ > + Send GTP packet to dut, receive packet from configured queue. > + Input: filter type, port type, packet type, inner L3 type > + """ > + queue = random.randint(1, self.PF_QUEUE - 1) > + if port != 'pf': > + queue = random.randint(1, self.VF_QUEUE - 1) > + random_teid = random.randint(0x0, 0xFFFFFFFF) > + correct_teid = hex(random_teid) > + wrong_teid = hex((random_teid + 2) % int(0xFFFFFFFF)) > + if type is 'fdir': > + if inner_L3 is None: > + self.dut_testpmd.execute_cmd( > + 'flow create 0 ingress pattern eth / ipv4 / udp / \ > + %s teid is %s / end actions queue index %d / end' > + % (tunnel_pkt, correct_teid, queue)) > + else: > + self.dut_testpmd.execute_cmd( > + 'flow create 0 ingress pattern eth / ipv4 / udp / \ > + %s teid is %s / %s / end actions queue index %d / end' > + % (tunnel_pkt, correct_teid, inner_L3, queue)) > + if type is 'clfter': > + self.dut_testpmd.execute_cmd( > + 'flow create 0 ingress pattern eth / ipv4 / udp / \ > + %s teid is %s / end actions %s / queue index %d / end' > + % (tunnel_pkt, correct_teid, port, queue)) > + for nomatch_pkt in range(2): It's not clear about each loop will be validated. Suggest to use meaningful name, like "for nomatch_opt in ['matched', 'not matched']". > + teid = correct_teid > + pkts = [] > + for cycles in range(2): Why here need these two round test? > + chk = '' > + for chktimes in range(2): > + pkts = self.gtp_packets( > + type, tunnel_pkt, inner_L3, nomatch_pkt, chk, teid) > + for packet_type in pkts.keys(): > + self.tester.scapy_append( > + 'sendp([%s], iface="%s")' > + % (pkts[packet_type], self.tester_intf)) > + self.tester.scapy_execute() > + if port is 'pf': > + out = self.dut.get_session_output(timeout=2) > + else: > + out = self.vm0_dut.get_session_output(timeout=2) > + self.verify( > + "port 0/queue %d" % queue in out, > + "Failed to receive packet in this queue!!!") > + > + if port is 'pf': > + layerparams = ['L3_', 'TUNNEL_', > + 'INNER_L3_', 'INNER_L4_'] > + ptypes = packet_type.split('/') > + endparams = ['_EXT_UNKNOWN', '', > + '_EXT_UNKNOWN', ''] > + for layerparam, ptype, endparam in zip( > + layerparams, ptypes, endparams): > + layer_type = layerparam + ptype + endparam > + self.verify( > + layer_type in out, > + "Failed to output ptype information!!!") > + if queue != 0 and type is 'fdir': > + self.verify("PKT_RX_FDIR" in out, > + "Failed to test flow director!!!") > + if teid == wrong_teid or nomatch_pkt == 1: > + break > + chk = 'chksum=0x1234,' > + if nomatch_pkt == 1: > + break > + queue = 0 > + teid = wrong_teid > + > + def test_fdir_gtpc_pf(self): > + """ > + GTP is supported by NVM with profile updated. Select flow director to > + do classfication, send gtpc packet to PF, check PF could receive > + packet using configured queue, checksum is good. > + """ > + self.gtp_test( > + type='fdir', port='pf', tunnel_pkt='gtpc', inner_L3=None) > + > + def test_fdir_gtpu_pf(self): > + """ > + GTP is supported by NVM with profile updated. Select flow director to > + do classfication, send gtpu packet to PF, check PF could receive > + packet using configured queue, checksum is good. > + """ > + self.gtp_test( > + type='fdir', port='pf', tunnel_pkt='gtpu', inner_L3=None) > + self.gtp_test( > + type='fdir', port='pf', tunnel_pkt='gtpu', inner_L3='ipv4') > + self.gtp_test( > + type='fdir', port='pf', tunnel_pkt='gtpu', inner_L3='ipv6') > + > + def test_clfter_gtpc_pf(self): > + """ > + GTP is supported by NVM with profile updated. Select cloud filter, > + send gtpc packet to PF, check PF could receive packet using > + configured queue, checksum is good. > + """ > + self.gtp_test( > + type='clfter', port='pf', tunnel_pkt='gtpc', inner_L3=None) > + > + def test_clfter_gtpu_pf(self): > + """ > + GTP is supported by NVM with profile updated. Select cloud filter, > + send gtpu packet to PF, check PF could receive packet using configured > + queue, checksum is good. > + """ > + self.gtp_test( > + type='clfter', port='pf', tunnel_pkt='gtpu', inner_L3=None) > + self.gtp_test( > + type='clfter', port='pf', tunnel_pkt='gtpu', inner_L3='ipv4') > + self.gtp_test( > + type='clfter', port='pf', tunnel_pkt='gtpu', inner_L3='ipv6') > + > + def test_clfter_gtpc_vf(self): > + """ > + GTP is supported by NVM with profile updated. Select cloud filter, > + send gtpc packet to VF, check PF could receive packet using configured > + queue, checksum is good. > + """ > + self.gtp_test( > + type='clfter', port='vf id 0', tunnel_pkt='gtpc', inner_L3=None) > + > + def test_clfter_gtpu_vf(self): > + """ > + GTP is supported by NVM with profile updated. Select cloud filter, > + send gtpu packet to VF, check PF could receive packet using configured > + queue, checksum is good. > + """ > + self.gtp_test( > + type='clfter', port='vf id 0', tunnel_pkt='gtpu', inner_L3=None) > + self.gtp_test( > + type='clfter', port='vf id 0', tunnel_pkt='gtpu', inner_L3='ipv4') > + self.gtp_test( > + type='clfter', port='vf id 0', tunnel_pkt='gtpu', inner_L3='ipv6') > + > + def tear_down(self): > + if self.vm0_testpmd: > + self.dut_testpmd.execute_cmd('write reg 0 0xb8190 1') > + self.dut_testpmd.execute_cmd('write reg 0 0xb8190 2') > + self.vm0_testpmd.quit() > + self.dut_testpmd.quit() > + > + def tear_down_all(self): > + self.destroy_vm_env()