From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id DC5D1A0548; Fri, 2 Apr 2021 12:36:09 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id CFD9D140E96; Fri, 2 Apr 2021 12:36:09 +0200 (CEST) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mails.dpdk.org (Postfix) with ESMTP id A1CD040141 for ; Fri, 2 Apr 2021 12:36:07 +0200 (CEST) IronPort-SDR: DCa1Qh+seu3tH8sPa+9dkOFds1yqum5I+KpPGSHpn1n5Z3OAwUzQ2hGDFUdPabFost2/b4D7Cl L3f1pMUPMDxg== X-IronPort-AV: E=McAfee;i="6000,8403,9941"; a="212720902" X-IronPort-AV: E=Sophos;i="5.81,299,1610438400"; d="scan'208";a="212720902" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Apr 2021 03:36:06 -0700 IronPort-SDR: ETvd0E4RE8mzTXGc/ml8sKNfQPM/8nFLhmP0YCCAqLsRIHRnA0JsJuawWNeYO68Q3guN0eY6mP UvzT66MvgXCw== X-IronPort-AV: E=Sophos;i="5.81,299,1610438400"; d="scan'208";a="419615548" Received: from unknown (HELO localhost.localdomain) ([10.240.183.222]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Apr 2021 03:36:02 -0700 From: Zhou Jun To: dts@dpdk.org Cc: Zhou Jun Date: Fri, 2 Apr 2021 18:34:33 +0800 Message-Id: <20210402103433.94545-1-junx.w.zhou@intel.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Subject: [dts] [PATCH V1] tests: add new suite cvl ecpri X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dts-bounces@dpdk.org Sender: "dts" ecpri only support by wireless pkg so split it to a new suite Signed-off-by: Zhou Jun --- tests/TestSuite_cvl_ecpri.py | 898 +++++++++++++++++++++++++++++++++++ 1 file changed, 898 insertions(+) create mode 100644 tests/TestSuite_cvl_ecpri.py diff --git a/tests/TestSuite_cvl_ecpri.py b/tests/TestSuite_cvl_ecpri.py new file mode 100644 index 00000000..af018ffd --- /dev/null +++ b/tests/TestSuite_cvl_ecpri.py @@ -0,0 +1,898 @@ +import re=0D +from packet import Packet=0D +from pmd_output import PmdOutput=0D +from test_case import TestCase=0D +import rte_flow_common as rfc=0D +import utils=0D +from utils import GREEN, RED=0D +import time=0D +=0D +Mac_list =3D ['00:11:22:33:44:55', '00:11:22:33:44:11', '00:11:22:33:44:22= ', '00:11:22:33:44:33']=0D +=0D +pkt_lst =3D ["Ether(dst=3D'{}')/IP()/UDP(dport=3D{})/Raw(\'\\x10\\x00\')",= =0D + "Ether(dst=3D'{}')/IP()/UDP(dport=3D{})/Raw(\'\\x10\\x02\')/R= aw('x'*11)/Raw(\'\\x00\')",=0D + "Ether(dst=3D'{}')/IP()/UDP(dport=3D{})/Raw(\'\\x10\\x02')/Ra= w('x'*11)/Raw(\'\\x01')",=0D + "Ether(dst=3D'{}')/IP()/UDP(dport=3D{})/Raw(\'\\x10\\x02\')/R= aw('x'*11)/Raw(\'\\x03\')",=0D + "Ether(dst=3D'{}')/IP()/UDP(dport=3D{})/Raw(\'\\x10\\x02\')/R= aw('x'*11)/Raw(\'\\x05\')",=0D + "Ether(dst=3D'{}')/IP()/UDP(dport=3D{})/Raw(\'\\x10\\x02\')/R= aw('x'*11)/Raw(\'\\x06\')",=0D + "Ether(dst=3D'{}')/IP()/UDP(dport=3D{})/Raw(\'\\x10\\x02\')/R= aw('x'*11)/Raw(\'\\x07\')",=0D + "Ether(dst=3D'{}')/IP()/UDP(dport=3D{})/Raw(\'\\x10\\x02\')/R= aw('x'*11)/Raw(\'\\x08\')",=0D + "Ether(dst=3D'{}')/IP()/UDP(dport=3D{})/Raw(\'\\x10\\x05\')",= =0D + "Ether(dst=3D'{}')/IP()/UDP(dport=3D{})/Raw(\'\\x10\\x06\')"= =0D + ]=0D +=0D +ptype_match_lst =3D ['ptype=3D' + str(i) for i in range(372, 382)]=0D +ptype_nomatch_lst =3D ['ptype=3D24'] * 10=0D +=0D +# eCPRI over Ethernet header data.=0D +eCPRI_over_Ethernet_rule =3D "flow create 1 ingress pattern eth / ecpri co= mmon type iq_data / end actions rss types ecpri end key_len 0 queues end / = end"=0D +over_eth_header_packets =3D {=0D + 'match': ["Ether(dst=3D'00:11:22:33:44:11', type=3D0xAEFE)/Raw(\'\\x10= \\x00\\x02\\x24\\x23\\x45\')"],=0D + 'unmatched': ["Ether(dst=3D'00:11:22:33:44:11', type=3D0xAEFE)/Raw(\'\= \x10\\x00\\x02\\x24\\x23\\x46\')"]=0D +}=0D +=0D +tv_over_eth_queue_index =3D {=0D + "name": "test_eth_queue_index",=0D + "rule": "flow create 1 ingress pattern eth / ecpri common type iq_data= pc_id is 0x2345 / end actions queue index 3 / mark id 1 / end",=0D + "scapy_str": over_eth_header_packets,=0D + "check_func": rfc.check_mark,=0D + "check_param": {"port_id": 1, "queue": 3, "mark_id": 1, 'rxq': 16},=0D + "send_port": {"port_id": 0}=0D +}=0D +=0D +tv_over_eth_rss_queues =3D {=0D + "name": "test_eth_rss_queues",=0D + "rule": "flow create 1 ingress pattern eth / ecpri common type iq_data= pc_id is 0x2345 / end actions rss queues 5 6 end / mark id 2 / end",=0D + "scapy_str": over_eth_header_packets,=0D + "check_func": rfc.check_mark,=0D + "check_param": {"port_id": 1, "queue": [5, 6], "mark_id": 2, 'rxq': 16= },=0D + "send_port": {"port_id": 0}=0D +}=0D +=0D +tv_over_eth_drop =3D {=0D + "name": "test_eth_drop",=0D + "rule": "flow create 1 ingress pattern eth / ecpri common type iq_data= pc_id is 0x2345 / end actions drop / end",=0D + "scapy_str": over_eth_header_packets,=0D + "check_func": rfc.check_mark,=0D + "check_param": {"port_id": 1, "drop": True, 'rxq': 16},=0D + "send_port": {"port_id": 0}=0D +}=0D +=0D +tv_over_eth_passthru =3D {=0D + "name": "test_eth_passthru",=0D + "rule": "flow create 1 ingress pattern eth / ecpri common type iq_data= pc_id is 0x2345 / end actions passthru / mark id 1 / end",=0D + "scapy_str": over_eth_header_packets,=0D + "check_func": rfc.check_mark,=0D + "check_param": {"port_id": 1, "rss": True, "mark_id": 1, 'rxq': 16},=0D + "send_port": {"port_id": 0}=0D +}=0D +=0D +tv_over_eth_mark_rss =3D {=0D + "name": "test_eth_mark_rss",=0D + "rule": "flow create 1 ingress pattern eth / ecpri common type iq_data= pc_id is 0x2345 / end actions mark / rss / end",=0D + "scapy_str": over_eth_header_packets,=0D + "check_func": rfc.check_mark,=0D + "check_param": {"port_id": 1, "mark_id": 0, "rss": True, 'rxq': 16},=0D + "send_port": {"port_id": 0}=0D +}=0D +=0D +tv_over_eth_mark =3D {=0D + "name": "test_eth_mark",=0D + "rule": "flow create 1 ingress pattern eth / ecpri common type iq_data= pc_id is 0x2345 / end actions mark / end",=0D + "scapy_str": over_eth_header_packets,=0D + "check_func": rfc.check_mark,=0D + "check_param": {"port_id": 1, "mark_id": 0, "rss": True, 'rxq': 16},=0D + "send_port": {"port_id": 0}=0D +}=0D +=0D +# eCPRI over IP/UDP header data.=0D +eCPRI_over_IP_UDP_rule =3D "flow create 1 ingress pattern eth / ipv4 / udp= / ecpri common type iq_data / end actions rss types ecpri end key_len 0 qu= eues end / end"=0D +over_ip_udp_header_packets =3D {=0D + 'match': ["Ether(dst=3D'00:11:22:33:44:11')/IP()/UDP(dport=3D0x5123)/R= aw(\'\\x10\\x00\\x02\\x24\\x23\\x45\')"],=0D + 'unmatched': ["Ether(dst=3D'00:11:22:33:44:11')/IP()/UDP(dport=3D0x512= 3)/Raw(\'\\x10\\x00\\x02\\x24\\x23\\x46\')"]=0D +}=0D +=0D +tv_over_ip_udp_queue_index =3D {=0D + "name": "test_ip_udp_queue_index",=0D + "rule": "flow create 1 ingress pattern eth / ipv4 / udp / ecpri common= type iq_data pc_id is 0x2345 / end actions queue index 2 / mark / end",=0D + "scapy_str": over_ip_udp_header_packets,=0D + "check_func": rfc.check_mark,=0D + "check_param": {"port_id": 1, "queue": 2, "mark_id": 0, 'rxq': 16},=0D + "send_port": {"port_id": 0}=0D +}=0D +=0D +tv_over_ip_udp_rss_queues =3D {=0D + "name": "test_ip_udp_rss_queues",=0D + "rule": "flow create 1 ingress pattern eth / ipv4 / udp / ecpri common= type iq_data pc_id is 0x2345 / end actions rss queues 5 6 end / mark id 2 = / end",=0D + "scapy_str": over_ip_udp_header_packets,=0D + "check_func": rfc.check_mark,=0D + "check_param": {"port_id": 1, "queue": [5, 6], "mark_id": 2, 'rxq': 16= },=0D + "send_port": {"port_id": 0}=0D +}=0D +=0D +tv_over_ip_udp_drop =3D {=0D + "name": "test_ip_udp_drop",=0D + "rule": "flow create 1 ingress pattern eth / ipv4 / udp / ecpri common= type iq_data pc_id is 0x2345 / end actions drop / end",=0D + "scapy_str": over_ip_udp_header_packets,=0D + "check_func": rfc.check_mark,=0D + "check_param": {"port_id": 1, "drop": True, 'rxq': 16},=0D + "send_port": {"port_id": 0}=0D +}=0D +=0D +tv_over_ip_udp_passthru =3D {=0D + "name": "test_ip_udp_passthru",=0D + "rule": "flow create 1 ingress pattern eth / ipv4 / udp / ecpri common= type iq_data pc_id is 0x2345 / end actions passthru / mark id 1 / end",=0D + "scapy_str": over_ip_udp_header_packets,=0D + "check_func": rfc.check_mark,=0D + "check_param": {"port_id": 1, "rss": True, "mark_id": 1, 'rxq': 16},=0D + "send_port": {"port_id": 0}=0D +}=0D +=0D +tv_over_ip_udp_mark_rss =3D {=0D + "name": "test_ip_udp_mark_rss",=0D + "rule": "flow create 1 ingress pattern eth / ipv4 / udp / ecpri common= type iq_data pc_id is 0x2345 / end actions mark / rss / end",=0D + "scapy_str": over_ip_udp_header_packets,=0D + "check_func": rfc.check_mark,=0D + "check_param": {"port_id": 1, "mark_id": 0, "rss": True, 'rxq': 16},=0D + "send_port": {"port_id": 0}=0D +}=0D +=0D +tv_over_ip_udp_mark =3D {=0D + "name": "test_ip_udp_mark",=0D + "rule": "flow create 1 ingress pattern eth / ipv4 / udp / ecpri common= type iq_data pc_id is 0x2345 / end actions mark / end",=0D + "scapy_str": over_ip_udp_header_packets,=0D + "check_func": rfc.check_mark,=0D + "check_param": {"port_id": 1, "mark_id": 0, "rss": True, 'rxq': 16},=0D + "send_port": {"port_id": 0}=0D +}=0D +=0D +tv_over_eth =3D [tv_over_eth_queue_index, tv_over_eth_rss_queues, tv_over_= eth_drop, tv_over_eth_passthru, tv_over_eth_mark_rss, tv_over_eth_mark]=0D +=0D +tv_over_ip_udp =3D [tv_over_ip_udp_queue_index, tv_over_ip_udp_rss_queues,= tv_over_ip_udp_drop, tv_over_ip_udp_passthru, tv_over_ip_udp_mark_rss, tv_= over_ip_udp_mark]=0D +=0D +class TestCVLEcpri(TestCase):=0D + def set_up_all(self):=0D + """=0D + Run at the start of each test suite.=0D + prerequisites.=0D + """=0D + # Based on h/w type, choose how many ports to use=0D + self.dut_ports =3D self.dut.get_ports(self.nic)=0D + self.verify(len(self.dut_ports) >=3D 2, "Insufficient ports for te= sting")=0D + # Verify that enough threads are available=0D + cores =3D self.dut.get_core_list("1S/4C/1T")=0D + self.verify(cores is not None, "Insufficient cores for speed testi= ng")=0D + self.ports_socket =3D self.dut.get_numa_id(self.dut_ports[0])=0D + self.tester_port0 =3D self.tester.get_local_port(self.dut_ports[0]= )=0D + self.tester_port1 =3D self.tester.get_local_port(self.dut_ports[1]= )=0D + self.tester_iface0 =3D self.tester.get_interface(self.tester_port0= )=0D + self.tester_iface1 =3D self.tester.get_interface(self.tester_port1= )=0D +=0D + self.used_dut_port =3D self.dut_ports[0]=0D + self.pf_interface =3D self.dut.ports_info[self.dut_ports[0]]['intf= ']=0D + self.file_path =3D './drivers/net/iavf/iavf_rxtx.c'=0D + self.compile_dpdk()=0D + self.vf_flag =3D False=0D + self.create_iavf()=0D +=0D + self.pass_flag =3D 'passed'=0D + self.fail_flag =3D 'failed'=0D + self.pkt =3D Packet()=0D + self.pmd_output =3D PmdOutput(self.dut)=0D + self.right_ecpri =3D '0x5123'=0D + self.wrong_ecpri =3D '0x5121'=0D +=0D + def set_up(self):=0D + """=0D + Run before each test case.=0D + """=0D + self.launch_testpmd()=0D + self.pkt =3D Packet()=0D +=0D + def create_iavf(self):=0D + if self.vf_flag is False:=0D + self.dut.bind_interfaces_linux('ice')=0D + self.dut.generate_sriov_vfs_by_port(self.used_dut_port, 4)=0D + self.sriov_vfs_port =3D self.dut.ports_info[self.used_dut_port= ]['vfs_port']=0D + self.vf_flag =3D True=0D +=0D + try:=0D + for i in range(len(self.sriov_vfs_port)):=0D + if i !=3D len(self.sriov_vfs_port):=0D + self.sriov_vfs_port[i].bind_driver(self.drivername= )=0D + self.dut.send_expect("ip link set %s vf %s mac %s" % (= self.pf_interface, i, Mac_list[i]), "# ")=0D +=0D + #self.vf0_prop =3D {'opt_host': self.sriov_vfs_port[0].pci= }=0D + #self.dut.send_expect("ifconfig %s up" % self.pf_interface= , "# ")=0D + self.dut.send_expect("ip link set %s vf 0 trust on" % self= .pf_interface, "# ")=0D + except Exception as e:=0D + self.destroy_iavf()=0D + raise Exception(e)=0D +=0D + def destroy_iavf(self):=0D + if self.vf_flag is True:=0D + self.dut.destroy_sriov_vfs_by_port(self.used_dut_port)=0D + self.vf_flag =3D False=0D +=0D + def launch_testpmd(self):=0D + eal_param =3D " -a {},cap=3Ddcf -a {} -a {}".format(self.sriov_vfs= _port[0].pci, self.sriov_vfs_port[1].pci,=0D + self.sr= iov_vfs_port[2].pci)=0D + param =3D " --rxq=3D16 --txq=3D16"=0D + out =3D self.pmd_output.start_testpmd(cores=3D[0, 1, 2, 3], eal_pa= ram=3Deal_param, param=3Dparam, socket=3Dself.ports_socket)=0D + # check the VF0 driver is net_ice_dcf=0D + self.check_dcf_status(out, stats=3DTrue)=0D + self.pmd_output.execute_cmd("set fwd rxonly")=0D + self.pmd_output.execute_cmd("set verbose 1")=0D + self.pmd_output.execute_cmd("start")=0D +=0D + def check_dcf_status(self, out_testpmd, stats=3DTrue):=0D + """=0D + check if request for DCF is accepted.=0D + """=0D + if stats:=0D + self.verify("Failed to init DCF parent adapter" not in out_tes= tpmd, "request for DCF is rejected.")=0D + out_portinfo =3D self.dut.send_expect("show port info 0", "tes= tpmd> ", 15)=0D + self.verify("net_ice_dcf" in out_portinfo, "request for DCF is= rejected.")=0D + else:=0D + self.verify("Failed to init DCF parent adapter" in out_testpmd= , "request for DCF is accepted.")=0D + out_portinfo =3D self.dut.send_expect("show port info 0", "tes= tpmd> ", 15)=0D + self.verify("net_ice_dcf" not in out_portinfo, "request for DC= F is accepted.")=0D +=0D + def test_add_and_delete_eCPRI_port_config_in_DCF(self):=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port add ecp= ri {}".format(self.right_ecpri))=0D + self.send_and_verify(Mac_list[1], self.right_ecpri, if_match=3DTru= e)=0D + self.send_and_verify(Mac_list[1], self.wrong_ecpri, if_match=3DFal= se)=0D + self.send_and_verify(Mac_list[2], self.right_ecpri, if_match=3DTru= e)=0D + # remove rule and test=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port rm ecpr= i {}".format(self.right_ecpri))=0D +=0D + self.send_and_verify(Mac_list[1], self.right_ecpri, if_match=3DFal= se)=0D +=0D + def test_add_and_delete_eCPRI_port_config_in_DCF(self):=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port add ecp= ri {}".format(self.right_ecpri))=0D + self.pmd_output.execute_cmd("quit", expected=3D"#")=0D + self.launch_testpmd()=0D + self.send_and_verify(Mac_list[1], self.right_ecpri, if_match=3DFal= se)=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port add ecp= ri {}".format(self.right_ecpri))=0D + # use new mac to test=0D + new_session =3D self.dut.create_session(name=3D"new_session")=0D + new_mac =3D "00:11:22:33:44:66"=0D + new_session.send_expect("ip link set {} vf 0 mac {}".format(self.p= f_interface, new_mac), "#", timeout=3D10)=0D + self.send_and_verify(Mac_list[1], self.right_ecpri, if_match=3DFal= se)=0D + self.pmd_output.execute_cmd("quit", expected=3D"#")=0D + # set port vf 0 trust off and test=0D + self.launch_testpmd()=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port add ecp= ri {}".format(self.right_ecpri))=0D + new_session.send_expect("ip link set {} vf 0 trust off".format(sel= f.pf_interface), "#", timeout=3D10)=0D + self.send_and_verify(Mac_list[1], self.right_ecpri, if_match=3DFal= se)=0D + new_session.close()=0D +=0D + def test_DCF_port_config_and_linux_port_config(self):=0D + new_session =3D self.dut.create_session(name=3D"new_session")=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port add ecp= ri {}".format(self.right_ecpri))=0D + new_session.send_expect("dmesg -c", "#")=0D + new_session.send_expect("ip link add vx0 type vxlan id 100 local 1= .1.1.1 remote "=0D + "2.2.2.2 dev {} dstport 0x1234".format(sel= f.pf_interface), "#")=0D + new_session.send_expect("ifconfig vx0 up", "#")=0D + new_session.send_expect("ifconfig vx0 down", "#")=0D + out =3D new_session.send_expect("dmesg", "#")=0D + self.verify("Cannot config tunnel, the capability is used by DCF" = in out, "port can used by another thread!")=0D + # delete eCPRI port config and test=0D + new_session.send_expect("dmesg -c", "#")=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port rm ecpr= i {}".format(self.right_ecpri))=0D + new_session.send_expect("ifconfig vx0 up", "#")=0D + new_session.send_expect("ifconfig vx0 down", "# ")=0D + out =3D new_session.send_expect("dmesg", "#")=0D + self.verify("Cannot config tunnel, the capability is used by DCF" = not in out, "port can't used by another thread!")=0D + self.pmd_output.execute_cmd("quit", "#")=0D + # do ecpri test=0D + self.launch_testpmd()=0D + new_session.send_expect("ip link add vx0 type vxlan id 100 local 1= .1.1.1 remote "=0D + "2.2.2.2 dev {} dstport 0x1234".format(sel= f.pf_interface), "#")=0D + new_session.send_expect("ifconfig vx0 up", "#")=0D + out =3D self.pmd_output.execute_cmd("port config 0 udp_tunnel_port= add ecpri {}".format(self.right_ecpri))=0D + self.verify("ice_dcf_send_aq_cmd(): No response (201 times) or ret= urn failure (desc: -63 / buff: -63)" in out,=0D + "test fail")=0D + # set vx0 down and test=0D + new_session.send_expect("ifconfig vx0 down", "#")=0D + out =3D self.pmd_output.execute_cmd("port config 0 udp_tunnel_port= add ecpri {}".format(self.right_ecpri))=0D + self.verify("ice_dcf_send_aq_cmd(): No response (201 times) or ret= urn failure (desc: -63 / buff: -63)"=0D + not in out, "test fail")=0D + new_session.close()=0D +=0D + def test_negative_eCPRI_port_config_in_DCF(self):=0D + ecpri_and_expect_dic =3D {"1": "Operation not supported",=0D + "5": "Invalid port",=0D + "15": "Invalid port",=0D + "a": "Bad arguments"=0D + }=0D + # set wrong port to test=0D + for ecpri in ecpri_and_expect_dic.keys():=0D + out =3D self.pmd_output.execute_cmd("port config {} udp_tunnel= _port add ecpri {}".format(ecpri, self.right_ecpri))=0D + self.verify(ecpri_and_expect_dic[ecpri] in out, "test fail")=0D + # set an invalid ecpri to test=0D + ecpri_and_expect_dic =3D {"ffff": "Bad arguments",=0D + "65536": "Bad arguments"}=0D +=0D + for ecpri in ecpri_and_expect_dic.keys():=0D + out =3D self.pmd_output.execute_cmd("port config 0 udp_tunnel_= port add ecpri {}".format(ecpri))=0D + self.verify(ecpri_and_expect_dic[ecpri] in out, "test fail")=0D + if ecpri =3D=3D "0":=0D + # test remove an invalid ecpri=0D + out =3D self.pmd_output.execute_cmd("port config 0 udp_tun= nel_port rm ecpri {}".format(ecpri))=0D + self.verify("Operation not permitted" in out, "test fail")= =0D +=0D + def test_rss_for_udp_ecpri(self):=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port add ecp= ri {}".format(self.right_ecpri))=0D + self.pmd_output.execute_cmd("flow validate 1 ingress pattern eth /= ipv4 / udp / ecpri common type iq_data / "=0D + "end actions rss types ecpri end key_l= en 0 queues end / end")=0D + self.pmd_output.execute_cmd("flow create 1 ingress pattern eth / i= pv4 / udp / ecpri common type iq_data / "=0D + "end actions rss types ecpri end key_l= en 0 queues end / end")=0D + tag_lst =3D ['x45', 'x46', 'x47']=0D + pkt_str =3D "Ether(dst=3D'{}')/IP()/UDP(dport=3D0x5123)/Raw(\'\\x1= 0\\x00\\x02\\x24\\x23\\%s\')".format(=0D + Mac_list[1])=0D + data_lst =3D self.get_receive_lst(tag_lst, [pkt_str])=0D + hash_lst =3D [i.get('RSS hash') for i in data_lst]=0D + self.verify(len(set(hash_lst)) =3D=3D len(tag_lst) =3D=3D len(set(= [i.get('queue') for i in data_lst])), "test fail, RSS hash is same.")=0D + # destroy rule and test=0D + self.pmd_output.execute_cmd("flow destroy 1 rule 0")=0D + out =3D self.pmd_output.execute_cmd("flow list 1")=0D + data_lst =3D self.get_receive_lst(tag_lst, [pkt_str], stats=3DFals= e)=0D + hash_lst =3D [i.get('RSS hash') for i in data_lst]=0D + self.verify(len(hash_lst) =3D=3D 0 or len(set(hash_lst)) =3D=3D 1,= "test fail, rule still worked.")=0D +=0D + def test_rss_for_eth_ecpri(self):=0D + self.dut.send_expect("quit", "# ")=0D + eal_param =3D " -a {} -a {}".format(self.sriov_vfs_port[0].pci, se= lf.sriov_vfs_port[1].pci)=0D + param =3D " --rxq=3D16 --txq=3D16"=0D + self.pmd_output.start_testpmd(cores=3D[0, 1, 2, 3], eal_param=3Dea= l_param, param=3Dparam, socket=3Dself.ports_socket)=0D + self.pmd_output.execute_cmd("set fwd rxonly")=0D + self.pmd_output.execute_cmd("set verbose 1")=0D + self.pmd_output.execute_cmd("start")=0D + self.pmd_output.execute_cmd("flow validate 1 ingress pattern eth /= ecpri common type iq_data / "=0D + "end actions rss types ecpri end key_l= en 0 queues end / end")=0D + self.pmd_output.execute_cmd("flow create 1 ingress pattern eth / e= cpri common type iq_data / end actions "=0D + "rss types ecpri end key_len 0 queues = end / end")=0D + tag_lst =3D ['x45', 'x46', 'x47']=0D + pkt_str =3D "Ether(dst=3D'{}', type=3D0xAEFE)/Raw(\'\\x10\\x00\\x0= 2\\x24\\x23\\%s\')".format(Mac_list[1])=0D + data_lst =3D self.get_receive_lst(tag_lst, [pkt_str])=0D + hash_lst =3D [i.get('RSS hash') for i in data_lst]=0D + self.verify(len(set(hash_lst)) =3D=3D len(tag_lst), "test fail, RS= S hash is same.")=0D + # destroy rule and test=0D + self.pmd_output.execute_cmd("flow destroy 1 rule 0")=0D + self.pmd_output.execute_cmd("flow list 1")=0D + data_lst =3D self.get_receive_lst(tag_lst, [pkt_str], stats=3DFals= e)=0D + hash_lst =3D [i.get('RSS hash') for i in data_lst]=0D + self.verify(len(hash_lst) =3D=3D 0 or len(set(hash_lst)) =3D=3D 1,= "test fail, rule still worked.")=0D +=0D + def test_rss_multirules_multiports(self):=0D + dst_mac_lst =3D Mac_list[1:3]=0D + tag_lst =3D ['x45', 'x46']=0D + module_pkt_lst =3D ["Ether(dst=3D'{}')/IP()/UDP(dport=3D0x5123)/Ra= w(\'\\x10\\x00\\x02\\x24\\x23\\%s\')",=0D + "Ether(dst=3D'{}', type=3D0xAEFE)/Raw(\'\\x10\\x00\\x02= \\x24\\x23\\%s\')"]=0D + rule_lst =3D ["flow create 1 ingress pattern eth / ipv4 / udp / ec= pri common type iq_data / end actions rss "=0D + "types ecpri end key_len 0 queues end / end",=0D + "flow create 1 ingress pattern eth / ecpri common type= iq_data / end actions rss types ecpri end "=0D + "key_len 0 queues end / end",=0D + "flow create 2 ingress pattern eth / ipv4 / udp / ecpr= i common type iq_data / end actions rss types"=0D + " ecpri end key_len 0 queues end / end",=0D + "flow create 2 ingress pattern eth / ecpri common type= iq_data / end actions rss types ecpri end "=0D + "key_len 0 queues end / end"]=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port add ecp= ri 0x5123")=0D + for rule in rule_lst:=0D + self.pmd_output.execute_cmd(rule)=0D + out_data =3D {}=0D + for dst_mac in dst_mac_lst:=0D + pkt_lst =3D [pkt.format(dst_mac) for pkt in module_pkt_lst]=0D + reta_line =3D self.get_receive_lst(tag_lst, pkt_lst)=0D + out_data.setdefault(dst_mac, reta_line)=0D + # verify=0D + for key in out_data.keys():=0D + hash_lst =3D [i.get('RSS hash') for i in out_data[key]]=0D + self.verify(len(set(hash_lst)) =3D=3D 2 and None not in hash_l= st, 'test fail, RSS hash is same.')=0D +=0D + # destroy rule to test=0D + self.pmd_output.execute_cmd("flow destroy 1 rule 0")=0D + self.pmd_output.execute_cmd("flow destroy 1 rule 1")=0D + self.pmd_output.execute_cmd("flow list 1")=0D + self.pmd_output.execute_cmd("flow destroy 2 rule 0")=0D + self.pmd_output.execute_cmd("flow destroy 2 rule 1")=0D + self.pmd_output.execute_cmd("flow list 2")=0D + out_data =3D {}=0D + for dst_mac in dst_mac_lst:=0D + pkt_lst =3D [pkt.format(dst_mac) for pkt in module_pkt_lst]=0D + reta_line =3D self.get_receive_lst(tag_lst[:1], pkt_lst, stats= =3DFalse)=0D + out_data.setdefault(dst_mac, reta_line)=0D + # verify=0D + for key in out_data.keys():=0D + hash_lst =3D [i.get('RSS hash') for i in out_data[key]]=0D + self.verify(len(set(hash_lst)) =3D=3D 1, 'test fail, RSS hash = is same.')=0D +=0D + def test_rss_without_or_with_udp_port_set_for_udp_ecpri_rule(self):=0D + tag_lst =3D ['x45', 'x46', 'x47', 'x48']=0D + pkt =3D "Ether(dst=3D'{}')/IP()/UDP(dport=3D0x5123)/Raw(\'\\x10\\x= 00\\x02\\x24\\x23\\%s\')".format(Mac_list[1])=0D + self.pmd_output.execute_cmd("flow create 1 ingress pattern eth / i= pv4 / udp / ecpri common type iq_data / end "=0D + "actions rss types ecpri end key_len 0 queu= es end / end")=0D + out_data =3D self.get_receive_lst(tag_lst, [pkt])=0D + # verify=0D + hash_lst =3D [i.get('RSS hash') for i in out_data]=0D + self.verify(len(set(hash_lst)) =3D=3D 1, 'test fail, rule worked!'= )=0D + # set ecpri and test=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port add ecp= ri 0x5123")=0D + out_data =3D self.get_receive_lst(tag_lst[:2], [pkt])=0D + # verify=0D + hash_lst =3D [i.get('RSS hash') for i in out_data]=0D + self.verify(len(set(hash_lst)) =3D=3D 2 and None not in hash_lst, = 'test fail, rule not worked!')=0D +=0D + def test_DCF_reset_for_udp_ecpri_rss(self):=0D + tag_lst =3D ['x45', 'x46', 'x47']=0D + pkt =3D "Ether(dst=3D'{}')/IP()/UDP(dport=3D0x5123)/Raw(\'\\x10\\x= 00\\x02\\x24\\x23\\%s\')".format(Mac_list[1])=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port add ecp= ri 0x5123")=0D + self.pmd_output.execute_cmd("flow create 1 ingress pattern eth / i= pv4 / udp / ecpri common type iq_data / end "=0D + "actions rss types ecpri end key_len 0 queu= es end / end")=0D + out_data =3D self.get_receive_lst(tag_lst[:2], [pkt])=0D + # verify=0D + hash_lst =3D [i.get('RSS hash') for i in out_data]=0D + self.verify(len(set(hash_lst)) =3D=3D 2 and None not in hash_lst, = 'test fail, RSS hash is same')=0D +=0D + new_session =3D self.dut.create_session(name=3D"new_session")=0D + new_session.send_expect("ip link set {} vf 0 mac 00:11:22:33:44:66= ".format(self.pf_interface), "#")=0D + out_data =3D self.get_receive_lst(tag_lst, [pkt])=0D + # verify=0D + hash_lst =3D [i.get('RSS hash') for i in out_data]=0D + self.verify(len(set(hash_lst)) =3D=3D 1, 'test fail, RSS hash is n= ot same')=0D +=0D + # restart testpmd and test=0D + new_mac =3D "00:11:22:33:44:55"=0D + new_session.send_expect("ip link set {} vf 0 mac {}".format(self.p= f_interface, new_mac), "#")=0D + self.dut.send_expect("quit", "# ")=0D + self.launch_testpmd()=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port add ecp= ri 0x5123")=0D + self.pmd_output.execute_cmd("flow create 1 ingress pattern eth / i= pv4 / udp / ecpri common type iq_data / end "=0D + "actions rss types ecpri end key_len 0 queu= es end / end")=0D + out_data =3D self.get_receive_lst(tag_lst[:2], [pkt])=0D + # verify=0D + hash_lst =3D [i.get('RSS hash') for i in out_data]=0D + self.verify(len(set(hash_lst)) =3D=3D 2 and None not in hash_lst, = 'test fail, RSS hash is same')=0D +=0D + new_session.send_expect("ip link set {} vf 0 mac 00:11:22:33:44:66= ".format(self.pf_interface), "#")=0D + out_data =3D self.get_receive_lst(tag_lst, [pkt])=0D + # verify=0D + hash_lst =3D [i.get('RSS hash') for i in out_data]=0D + self.verify(len(set(hash_lst)) =3D=3D 1, 'test fail, RSS hash is n= ot same')=0D +=0D + self.dut.send_expect("quit", "# ")=0D + self.launch_testpmd()=0D + new_session.send_expect("ip link set {} vf 0 trust off".format(sel= f.pf_interface), "#")=0D + out_data =3D self.get_receive_lst(tag_lst, [pkt])=0D + # verify=0D + hash_lst =3D [i.get('RSS hash') for i in out_data]=0D + self.verify(len(set(hash_lst)) =3D=3D 1, 'test fail, RSS hash is n= ot same')=0D + new_session.send_expect("ip link set {} vf 0 trust on".format(self= .pf_interface), "#")=0D + new_session.close()=0D +=0D + def test_DCF_reset_for_eth_ecpri_rss(self):=0D + tag_lst =3D ['x45', 'x46', 'x47', 'x48']=0D + pkt =3D "Ether(dst=3D'{}', type=3D0xAEFE)/Raw(\'\\x10\\x00\\x02\\x= 24\\x23\\%s\')"=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port add ecp= ri 0x5123")=0D + self.pmd_output.execute_cmd("flow create 1 ingress pattern eth / e= cpri common type iq_data / end actions rss types"=0D + " ecpri end key_len 0 queues end / end= ")=0D +=0D + out_data =3D self.get_receive_lst(tag_lst[:2], [pkt])=0D + # verify=0D + hash_lst =3D [i.get('RSS hash') for i in out_data]=0D + self.verify(len(set(hash_lst)) =3D=3D 2 and None not in hash_lst, = 'test fail, RSS hash is same')=0D + new_session =3D self.dut.create_session(name=3D"new_session")=0D + new_session.send_expect("ip link set {} vf 0 mac 00:11:22:33:44:66= ".format(self.pf_interface), "#")=0D + out_data =3D self.get_receive_lst(tag_lst[1:], [pkt])=0D + # verify=0D + hash_lst =3D [i.get('RSS hash') for i in out_data]=0D + self.verify(len(set(hash_lst)) =3D=3D 3 and None not in hash_lst, = 'test fail, RSS hash is same')=0D +=0D + new_session.send_expect("ip link set {} vf 0 trust off".format(sel= f.pf_interface), "#")=0D + out_data =3D self.get_receive_lst(tag_lst[:2], [pkt])=0D + # verify=0D + hash_lst =3D [i.get('RSS hash') for i in out_data]=0D + self.verify(len(set(hash_lst)) =3D=3D 2 and None not in hash_lst, = 'test fail, RSS hash is same')=0D +=0D + new_session.send_expect("ip link set {} vf 0 mac 00:11:22:33:44:66= ".format(self.pf_interface), "#")=0D + out_data =3D self.get_receive_lst(tag_lst[1:], [pkt])=0D + # verify=0D + hash_lst =3D [i.get('RSS hash') for i in out_data]=0D + self.verify(len(set(hash_lst)) =3D=3D 3 and None not in hash_lst, = 'test fail, RSS hash is same')=0D +=0D + new_session.send_expect("ip link set {} vf 0 trust on".format(self= .pf_interface), "#")=0D + new_session.send_expect("ip link set {} vf 0 mac 00:11:22:33:44:55= ".format(self.pf_interface), "#")=0D + new_session.close()=0D +=0D + def test_DCF_exit_for_eth_ecpri_and_udp_ecpri_rss(self):=0D + self.dut.send_expect("quit", "# ")=0D + eal_param =3D " -a {},cap=3Ddcf".format(self.sriov_vfs_port[0].pci= )=0D + self.pmd_output.start_testpmd(cores=3Dlist(range(8)), eal_param=3D= eal_param, prefix=3D"test1", socket=3Dself.ports_socket)=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port add ecp= ri 0x5123")=0D + new_session =3D self.dut.create_session(name=3D"new_session")=0D + pmd_output1 =3D PmdOutput(self.dut, new_session)=0D + eal_param1 =3D " -a {} -a {}".format(self.sriov_vfs_port[1].pci, s= elf.sriov_vfs_port[2].pci)=0D + param =3D " --rxq=3D16 --txq=3D16"=0D + pmd_output1.start_testpmd(cores=3Dlist(range(8)), eal_param=3Deal_= param1, param=3Dparam, prefix=3D"test2",=0D + socket=3Dself.ports_socket)=0D + pmd_output1.execute_cmd("flow create 0 ingress pattern eth / ipv4 = / udp / ecpri common type iq_data / end "=0D + "actions rss types ecpri end key_len 0 que= ues end / end")=0D + pmd_output1.execute_cmd("flow create 1 ingress pattern eth / ecpri= common type iq_data / end actions rss "=0D + "types ecpri end key_len 0 queues end / en= d")=0D + pmd_output1.execute_cmd("set verbose 1")=0D + pmd_output1.execute_cmd("set fwd rxonly")=0D + pmd_output1.execute_cmd("start")=0D + tag_lst =3D ['x45', 'x46']=0D + pkt_lst =3D ["Ether(dst=3D'{}')/IP()/UDP(dport=3D0x5123)/Raw(\'\\x= 10\\x00\\x02\\x24\\x23\\%s')".format(Mac_list[1]),=0D + "Ether(dst=3D'{}', type=3D0xAEFE)/Raw(\'\\x10\\x00\\x02= \\x24\\x23\\%s\')".format(Mac_list[2])=0D + ]=0D + out_data =3D self.get_receive_lst(tag_lst, pkt_lst, pmd_output1)=0D + # verify=0D + hash_lst =3D [i.get('RSS hash') for i in out_data]=0D + self.verify(len(set(hash_lst)) =3D=3D 4 and None not in hash_lst, = 'test fail, Rss hash is same.')=0D + self.pmd_output.execute_cmd("quit", "#")=0D + out_data =3D self.get_receive_lst(tag_lst, pkt_lst, pmd_output1)=0D + # verify=0D + hash_lst =3D [i.get('RSS hash') for i in out_data]=0D + self.verify(hash_lst[0] =3D=3D hash_lst[2] and hash_lst[1] !=3D ha= sh_lst[3], 'test fail, hash value is wrong.')=0D + pmd_output1.execute_cmd("quit", '#')=0D + new_session.close()=0D +=0D + def create_fdir_rule(self, rule: (list, str), check_stats=3DNone, msg= =3DNone, validate=3DTrue):=0D + if validate:=0D + if isinstance(rule, list):=0D + validate_rule =3D [i.replace('create', 'validate') for i i= n rule]=0D + else:=0D + validate_rule =3D rule.replace('create', 'validate')=0D + self.validate_fdir_rule(validate_rule, check_stats=3Dcheck_sta= ts)=0D + p =3D re.compile(r"Flow rule #(\d+) created")=0D + rule_list =3D []=0D + if isinstance(rule, list):=0D + for i in rule:=0D + out =3D self.pmd_output.execute_cmd(i, timeout=3D1)=0D + if msg:=0D + self.verify(msg in out, "failed: expect %s in %s" % (m= sg, out))=0D + m =3D p.search(out)=0D + if m:=0D + rule_list.append(m.group(1))=0D + else:=0D + rule_list.append(False)=0D + elif isinstance(rule, str):=0D + out =3D self.pmd_output.execute_cmd(rule, timeout=3D1)=0D + if msg:=0D + self.verify(msg in out, "failed: expect %s in %s" % (msg, = out))=0D + m =3D p.search(out)=0D + if m:=0D + rule_list.append(m.group(1))=0D + else:=0D + rule_list.append(False)=0D + else:=0D + raise Exception("unsupported rule type, only accept list or st= r")=0D + if check_stats:=0D + self.verify(all(rule_list), "some rules create failed, result = %s" % rule_list)=0D + elif check_stats =3D=3D False:=0D + self.verify(not any(rule_list), "all rules should create faile= d, result %s" % rule_list)=0D + return rule_list=0D +=0D + def validate_fdir_rule(self, rule, check_stats=3DTrue, check_msg=3DNon= e):=0D + flag =3D 'Flow rule validated'=0D + if isinstance(rule, str):=0D + out =3D self.pmd_output.execute_cmd(rule, timeout=3D1)=0D + if check_stats:=0D + self.verify(flag in out.strip(), "rule %s validated failed= , result %s" % (rule, out))=0D + else:=0D + if check_msg:=0D + self.verify(flag not in out.strip() and check_msg in o= ut.strip(),=0D + "rule %s validate should failed with msg: = %s, but result %s" % (rule, check_msg, out))=0D + else:=0D + self.verify(flag not in out.strip(), "rule %s validate= should failed, result %s" % (rule, out))=0D + elif isinstance(rule, list):=0D + for r in rule:=0D + out =3D self.pmd_output.execute_cmd(r, timeout=3D1)=0D + if check_stats:=0D + self.verify(flag in out.strip(), "rule %s validated fa= iled, result %s" % (r, out))=0D + else:=0D + if not check_msg:=0D + self.verify(flag not in out.strip(), "rule %s vali= date should failed, result %s" % (r, out))=0D + else:=0D + self.verify(flag not in out.strip() and check_msg = in out.strip(),=0D + "rule %s should validate failed with m= sg: %s, but result %s" % (=0D + r, check_msg, out))=0D +=0D + def check_fdir_rule(self, port_id=3D0, stats=3DTrue, rule_list=3DNone)= :=0D + out =3D self.pmd_output.execute_cmd("flow list %s" % port_id)=0D + p =3D re.compile(r"ID\s+Group\s+Prio\s+Attr\s+Rule")=0D + matched =3D p.search(out)=0D + if stats:=0D + self.verify(matched, "flow rule on port %s is not existed" % p= ort_id)=0D + if rule_list:=0D + p =3D re.compile("^(\d+)\s")=0D + li =3D out.splitlines()=0D + res =3D list(filter(bool, list(map(p.match, li))))=0D + result =3D [i.group(1) for i in res]=0D + self.verify(sorted(result) =3D=3D sorted(rule_list),=0D + "check rule list failed. expect %s, result %s"= % (rule_list, result))=0D + else:=0D + if rule_list:=0D + p =3D re.compile("^(\d+)\s")=0D + li =3D out.splitlines()=0D + res =3D list(filter(bool, list(map(p.match, li))))=0D + result =3D [i.group(1) for i in res]=0D + self.verify(not [i for i in rule_list if i in result],=0D + "check rule list failed. flow rule %s on port = %s is existed" % (rule_list, port_id))=0D + else:=0D + self.verify(not matched, "flow rule on port %s is existed"= % port_id)=0D +=0D + def destroy_fdir_rule(self, port_id=3D0, rule_id=3DNone):=0D + if rule_id is None:=0D + rule_id =3D 0=0D + if isinstance(rule_id, list):=0D + for i in rule_id:=0D + out =3D self.dut.send_command("flow destroy %s rule %s" % = (port_id, i), timeout=3D1)=0D + p =3D re.compile(r"Flow rule #(\d+) destroyed")=0D + m =3D p.search(out)=0D + self.verify(m, "flow rule %s delete failed" % rule_id)=0D + else:=0D + out =3D self.dut.send_command("flow destroy %s rule %s" % (por= t_id, rule_id), timeout=3D1)=0D + p =3D re.compile(r"Flow rule #(\d+) destroyed")=0D + m =3D p.search(out)=0D + self.verify(m, "flow rule %s delete failed" % rule_id)=0D +=0D + def send_packets(self, packets, tx_port=3DNone, count=3D1):=0D + self.pkt.update_pkt(packets)=0D + tx_port =3D self.tester_iface0 if not tx_port else tx_port=0D + self.pkt.send_pkt(crb=3Dself.tester, tx_port=3Dtx_port, count=3Dco= unt)=0D +=0D + def send_pkts_getouput(self, pkts, port_id=3D0, count=3D1, drop=3DFals= e):=0D + tx_port =3D self.tester_iface0 if port_id =3D=3D 0 else self.teste= r_iface1=0D +=0D + time.sleep(1)=0D + if drop:=0D + self.pmd_output.execute_cmd("clear port stats all")=0D + time.sleep(0.5)=0D + self.send_packets(pkts, tx_port=3Dtx_port, count=3Dcount)=0D + out =3D self.pmd_output.execute_cmd("stop")=0D + self.pmd_output.execute_cmd("start")=0D + else:=0D + self.send_packets(pkts, tx_port=3Dtx_port, count=3Dcount)=0D + out =3D self.pmd_output.get_output()=0D + return out=0D +=0D + def _rte_flow_validate(self, vectors):=0D + test_results =3D {}=0D + for tv in vectors:=0D + try:=0D + count =3D 1=0D + port_id =3D tv["send_port"]["port_id"] if tv["send_port"].= get("port_id") is not None else 0=0D + dut_port_id =3D tv["check_param"]["port_id"] if tv["check_= param"].get("port_id") is not None else 0=0D + drop =3D tv["check_param"].get("drop")=0D + # create rule=0D + rule_li =3D self.create_fdir_rule(tv["rule"], check_stats= =3DTrue)=0D + # send and check match packets=0D + out1 =3D self.send_pkts_getouput(pkts=3Dtv["scapy_str"]["m= atch"], port_id=3Dport_id,=0D + count=3Dcount, drop=3Ddrop)= =0D + matched_queue =3D tv["check_func"](out1, pkt_num=3Dlen(tv[= "scapy_str"]["match"]),=0D + check_param=3Dtv["check_p= aram"])=0D + # send and check unmatched packets=0D + out2 =3D self.send_pkts_getouput(pkts=3Dtv["scapy_str"]["u= nmatched"], port_id=3Dport_id,=0D + count=3Dcount, drop=3Ddrop)= =0D + tv["check_func"](out2, pkt_num=3Dlen(tv["scapy_str"]["unma= tched"]), check_param=3Dtv["check_param"],=0D + stats=3DFalse)=0D + # list and destroy rule=0D + self.check_fdir_rule(port_id=3Dtv["check_param"]["port_id"= ], rule_list=3D['0'] + rule_li)=0D + self.destroy_fdir_rule(rule_id=3Drule_li, port_id=3Ddut_po= rt_id)=0D + # send matched packet=0D + out3 =3D self.send_pkts_getouput(pkts=3Dtv["scapy_str"]["m= atch"], port_id=3Dport_id,=0D + count=3Dcount, drop=3Ddrop)= =0D + matched_queue2 =3D tv["check_func"](out3, pkt_num=3Dlen(tv= ["scapy_str"]["match"]),=0D + check_param=3Dtv["check_= param"],=0D + stats=3DFalse)=0D + if tv["check_param"].get("rss"):=0D + self.verify(matched_queue =3D=3D matched_queue2 and No= ne not in matched_queue,=0D + "send twice matched packet, received in de= ferent queues")=0D + # check not rule exists=0D + self.check_fdir_rule(port_id=3Ddut_port_id, rule_list=3Dru= le_li, stats=3DFalse)=0D + test_results[tv["name"]] =3D True=0D + self.logger.info((GREEN("case passed: %s" % tv["name"])))= =0D + except Exception as e:=0D + self.logger.warning((RED(e)))=0D + self.dut.send_command("flow flush 0", timeout=3D1)=0D + self.dut.send_command("flow flush 1", timeout=3D1)=0D + test_results[tv["name"]] =3D False=0D + self.logger.info((GREEN("case failed: %s" % tv["name"])))= =0D + continue=0D + failed_cases =3D []=0D + for k, v in list(test_results.items()):=0D + if not v:=0D + failed_cases.append(k)=0D + self.verify(all(test_results.values()), "{} failed.".format(failed= _cases))=0D +=0D + def test_eCPRI_over_Ethernet_header_pattern_fdir(self):=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port add ecp= ri 0x5123")=0D + self.create_fdir_rule(rule=3DeCPRI_over_Ethernet_rule, check_stats= =3DTrue)=0D + self._rte_flow_validate(tv_over_eth)=0D +=0D + def test_eCPRI_over_IP_or_UDP_header_pattern_fdir(self):=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port add ecp= ri 0x5123")=0D + self.create_fdir_rule(rule=3DeCPRI_over_IP_UDP_rule, check_stats= =3DTrue)=0D + self._rte_flow_validate(tv_over_ip_udp)=0D +=0D + def test_ecpri_fdir_multirules(self):=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port add ecp= ri 0x5123")=0D + rule_lst =3D ["flow create 1 ingress pattern eth / ecpri common ty= pe iq_data / end actions rss types ecpri end "=0D + "key_len 0 queues end / end",=0D + "flow create 1 ingress pattern eth / ipv4 / udp / ecpr= i common type iq_data / end actions rss "=0D + "types ecpri end key_len 0 queues end / end",=0D + "flow create 2 ingress pattern eth / ecpri common type= iq_data / end actions rss types ecpri end "=0D + "key_len 0 queues end / end",=0D + "flow create 2 ingress pattern eth / ipv4 / udp / ecpr= i common type iq_data / end actions rss "=0D + "types ecpri end key_len 0 queues end / end",=0D + "flow create 1 ingress pattern eth / ipv4 / udp / ecpr= i common type iq_data pc_id is 0x2345 / end "=0D + "actions rss queues 5 6 end / mark id 0 / end",=0D + "flow create 1 ingress pattern eth / ipv4 / udp / ecpr= i common type iq_data pc_id is 0x2346 / end "=0D + "actions passthru / mark id 1 / end",=0D + "flow create 1 ingress pattern eth / ecpri common type= iq_data pc_id is 0x2345 / end actions "=0D + "drop / end",=0D + "flow create 1 ingress pattern eth / ecpri common type= iq_data pc_id is 0x2346 / end actions "=0D + "queue index 1 / mark id 2 / end",=0D + "flow create 2 ingress pattern eth / ecpri common type= iq_data pc_id is 0x2346 / end actions "=0D + "mark id 3 / end",=0D + "flow create 2 ingress pattern eth / ipv4 / udp / ecpr= i common type iq_data pc_id is 0x2346 / end "=0D + "actions mark / rss / end"]=0D + for rule in rule_lst:=0D + self.pmd_output.execute_cmd(rule)=0D + tag_lst =3D ['x45', 'x46']=0D + module_pkt_lst =3D ["Ether(dst=3D'{}')/IP()/UDP(dport=3D0x5123)/Ra= w(\'\\x10\\x00\\x02\\x24\\x23\\%s\')",=0D + "Ether(dst=3D'{}', type=3D0xAEFE)/Raw(\'\\x10\\x= 00\\x02\\x24\\x23\\%s\')"]=0D + pkt_lst =3D ["Ether(dst=3D'{}')/IP()/UDP(dport=3D0x5123)/Raw(\'\\x= 10\\x00\\x02\\x24\\x23\\%s\')".format(Mac_list[1])]=0D + data_lst =3D self.get_receive_lst(tag_lst[: 1], pkt_lst, stats=3DF= alse)=0D + queue =3D [data.get('queue') for data in data_lst]=0D + self.verify([i for i in queue if i in ['5', '6']], 'pkt go to wron= g queue!')=0D + self.verify([data.get('FDIR matched ID') for data in data_lst] =3D= =3D ['0x0'], 'pkt has wrong mark id!')=0D + data_lst =3D self.get_receive_lst(tag_lst[1: ], pkt_lst)=0D + self.verify([data.get('FDIR matched ID') for data in data_lst] =3D= =3D ['0x1'], 'pkt has wrong mark id!')=0D + pkt_lst =3D ["Ether(dst=3D'{}', type=3D0xAEFE)/Raw(\'\\x10\\x00\\x= 02\\x24\\x23\\%s\')".format(Mac_list[1])]=0D + data_lst =3D self.get_receive_lst(tag_lst, pkt_lst, stats=3DFalse)= =0D + self.verify([data.get('queue') for data in data_lst] =3D=3D [None,= '1'], 'pkt go to wrong queue!')=0D + self.verify([data.get('FDIR matched ID') for data in data_lst] =3D= =3D [None, '0x2'], 'pkt has wrong mark id!')=0D + pkt_lst =3D [pkt.format(Mac_list[2]) for pkt in module_pkt_lst]=0D + data_lst =3D self.get_receive_lst(tag_lst, pkt_lst)=0D + self.verify([data.get('FDIR matched ID') for data in data_lst] =3D= =3D [None, None, '0x0', '0x3'], 'pkt has wrong mark id!') =0D +=0D + def test_ecpri_fdir_negative_case(self):=0D + out =3D self.pmd_output.execute_cmd("flow create 1 ingress pattern= eth / ipv4 / udp / ecpri common type iq_data pc_id is "=0D + "0x2345 / end actions rss queues 5 6 end / = mark id 0 / end")=0D + self.verify("Failed to create parser engine.: Invalid argument" in= out, "test fail, bad rule set success.")=0D + out =3D self.pmd_output.execute_cmd("flow list 1")=0D + r =3D r'flow list 1(\s+)(.*)'=0D + m =3D re.match(r, out)=0D + self.verify(m.group(2) =3D=3D '', 'bad rule set successful!')=0D +=0D + def test_ecpri_fdir_when_DCF_reset(self):=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port add ecp= ri 0x5123")=0D + self.pmd_output.execute_cmd("flow create 1 ingress pattern eth / i= pv4 / udp / ecpri common type iq_data pc_id "=0D + "is 0x2345 / end actions queue index 1= / mark id 1 / end")=0D + self.pmd_output.execute_cmd("flow create 1 ingress pattern eth / e= cpri common type iq_data pc_id is "=0D + "0x2345 / end actions queue index 2 / = mark id 2 / end")=0D + pkt_lst =3D ["Ether(dst=3D'{}')/IP()/UDP(dport=3D0x5123)/Raw(\'\\x= 10\\x00\\x02\\x24\\x23\\%s\')".format(Mac_list[1]),=0D + "Ether(dst=3D'{}', type=3D0xAEFE)/Raw(\'\\x10\\x00\\x02= \\x24\\x23\\%s\')".format(Mac_list[1])]=0D + tag_lst =3D ['x45']=0D + data_lst =3D self.get_receive_lst(tag_lst, pkt_lst)=0D + # verify=0D + self.verify([data.get('queue') for data in data_lst] =3D=3D ['1', = '2'], "pkt to the wrong queue!")=0D + self.verify([data.get('FDIR matched ID') for data in data_lst] =3D= =3D ['0x1', '0x2'], "pkt with wrong FDIR matched ID!")=0D + new_session =3D self.dut.create_session(name=3D"new_session")=0D + new_session.send_expect('ip link set {} vf 0 mac 00:11:22:33:44:66= '.format(self.pf_interface), '#')=0D + data_lst =3D self.get_receive_lst(tag_lst, pkt_lst)=0D + # verify=0D + self.verify(data_lst[1].get('queue') =3D=3D '2', "pkt to the wrong= queue!")=0D + self.verify([data.get('FDIR matched ID') for data in data_lst] =3D= =3D [None, '0x2'], "pkt with wrong FDIR matched ID!")=0D + self.dut.send_expect("quit", "#")=0D + self.launch_testpmd()=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port add ecp= ri 0x5123")=0D + self.pmd_output.execute_cmd("flow create 1 ingress pattern eth / i= pv4 / udp / ecpri common type iq_data pc_id "=0D + "is 0x2345 / end actions queue index 1= / mark id 1 / end")=0D + self.pmd_output.execute_cmd("flow create 1 ingress pattern eth / e= cpri common type iq_data pc_id is "=0D + "0x2345 / end actions queue index 2 / = mark id 2 / end")=0D + data_lst =3D self.get_receive_lst(tag_lst, pkt_lst)=0D + self.verify([data.get('queue') for data in data_lst] =3D=3D ['1', = '2'], "pkt to the wrong queue!")=0D + self.verify([data.get('FDIR matched ID') for data in data_lst] =3D= =3D ['0x1', '0x2'], "pkt with wrong FDIR matched ID!")=0D + new_session.send_expect("ip link set {} vf 0 trust off".format(sel= f.pf_interface), "#")=0D + data_lst =3D self.get_receive_lst(tag_lst, pkt_lst)=0D + self.verify(data_lst[1].get('queue') =3D=3D '2', "pkt to the wrong= queue!")=0D + self.verify([data.get('FDIR matched ID') for data in data_lst] =3D= =3D [None, '0x2'], "pkt with wrong FDIR matched ID!")=0D + new_session.close()=0D +=0D + def test_ecpri_fdir_when_DCF_exit(self):=0D + self.dut.send_expect("quit", "#")=0D + eal_param =3D " -a {},cap=3Ddcf".format(self.sriov_vfs_port[0].pci= )=0D + self.pmd_output.start_testpmd(cores=3Dlist(range(8)), eal_param=3D= eal_param, prefix=3D"test1",=0D + socket=3Dself.ports_socket)=0D + self.pmd_output.execute_cmd("port config 0 udp_tunnel_port add ecp= ri 0x5123")=0D + new_session =3D self.dut.create_session(name=3D"new_session")=0D + pmd_output1 =3D PmdOutput(self.dut, new_session)=0D + eal_param1 =3D " -a {} -a {}".format(self.sriov_vfs_port[1].pci, s= elf.sriov_vfs_port[2].pci)=0D + param =3D " --rxq=3D16 --txq=3D16"=0D + pmd_output1.start_testpmd(cores=3Dlist(range(8)), eal_param=3Deal_= param1, param=3Dparam, prefix=3D"test2",=0D + socket=3Dself.ports_socket)=0D + pmd_output1.execute_cmd("flow create 0 ingress pattern eth / ipv4 = / udp / ecpri common type iq_data pc_id "=0D + "is 0x2345 / end actions queue index 1 / m= ark id 1 / end")=0D + pmd_output1.execute_cmd("flow create 0 ingress pattern eth / ecpri= common type iq_data pc_id is 0x2345 / end "=0D + "actions queue index 2 / mark id 2 / end")= =0D + pmd_output1.execute_cmd("set verbose 1")=0D + pmd_output1.execute_cmd("set fwd rxonly")=0D + pmd_output1.execute_cmd("start")=0D + pkt_lst =3D ["Ether(dst=3D'{}')/IP()/UDP(dport=3D0x5123)/Raw(\'\\x= 10\\x00\\x02\\x24\\x23\\%s\')".format(Mac_list[1]),=0D + "Ether(dst=3D'{}', type=3D0xAEFE)/Raw(\'\\x10\\x00\\x02= \\x24\\x23\\%s\')".format(Mac_list[1])]=0D + tag_lst =3D ['x45']=0D + data_lst =3D self.get_receive_lst(tag_lst, pkt_lst, pmd_output=3Dp= md_output1)=0D + # verify=0D + self.verify([data.get('FDIR matched ID') for data in data_lst] =3D= =3D ['0x1', '0x2'] and [data.get('queue') for data in data_lst] =3D=3D ['1'= , '2'], 'mark id or queue wrong!')=0D +=0D + self.dut.send_expect("quit", "#")=0D + data_lst =3D self.get_receive_lst(tag_lst, pkt_lst, pmd_output=3Dp= md_output1)=0D + # verify=0D + self.verify([data.get('FDIR matched ID') for data in data_lst] =3D= =3D [None, '0x2'] and data_lst[1].get('queue') =3D=3D '2', 'mark id or queu= e wrong!')=0D +=0D + def get_receive_lst(self, tag_lst=3D[], pkt_lst=3D[], pmd_output=3D'',= stats=3DTrue):=0D + data_lst =3D []=0D + for tag in tag_lst:=0D + for pkt in pkt_lst:=0D + pkt_str =3D pkt % tag=0D + out =3D self.send_pkt(pkt_str=3Dpkt_str, pmd_output=3Dpmd_= output)=0D + rfc.verify_directed_by_rss(out, rxq=3D16, stats=3Dstats) = =0D + reta_line =3D self.get_receive_data(out)=0D + data_lst.append(reta_line)=0D + return data_lst=0D +=0D + def get_receive_data(self, out):=0D + reta_line =3D {}=0D + lines =3D out.split("\r\n")=0D + for line in lines:=0D + line =3D line.strip()=0D + if len(line) !=3D 0 and line.strip().startswith("port "):=0D + reta_line =3D {}=0D + rexp =3D r"port (\d)/queue (\d{1,2}): received (\d) packet= s"=0D + m =3D re.match(rexp, line.strip())=0D + if m:=0D + reta_line["port"] =3D m.group(1)=0D + reta_line["queue"] =3D m.group(2)=0D +=0D + elif len(line) !=3D 0 and line.startswith(("src=3D",)):=0D + for item in line.split("-"):=0D + item =3D item.strip()=0D + if item.startswith("RSS hash"):=0D + name, value =3D item.split("=3D", 1)=0D + reta_line[name.strip()] =3D value.strip()=0D + elif item.startswith("FDIR matched ID"):=0D + name, value =3D item.split("=3D", 1)=0D + reta_line[name.strip()] =3D value.strip()=0D + return reta_line=0D +=0D + def compile_dpdk(self):=0D + cmd_lst =3D [r"sed -i '/iavf_flex_rxd_to_vlan_tci(rxm, &rxd, rxq->= rx_flags);/i\printf(\"++++++++++++ptype=3D%u\\n\",IAVF_RX_FLEX_DESC_PTYPE_M= & rte_le_to_cpu_16(rxd.wb.ptype_flex_flags0));' ",=0D + r"sed -i '/IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_privat= e);/{:a;n;s/ifdef RTE_ARCH_X86/if 0/g;/struct iavf_rx_queue/!ba}' ",=0D + r"sed -i '/rx_pkt_burst =3D iavf_recv_pkts;/{n;s/\}/\}d= ev->rx_pkt_burst =3D iavf_recv_pkts_flex_rxd;\n/g}' "]=0D + for cmd in cmd_lst:=0D + self.dut.send_expect(cmd + self.file_path, "#")=0D + self.dut.build_install_dpdk(self.target)=0D +=0D + def send_and_verify(self, dts_mac, ecpri, if_match=3DTrue):=0D + ptype_lst =3D ptype_match_lst if if_match else ptype_nomatch_lst=0D + for i in range(len(pkt_lst)):=0D + out =3D self.send_pkt(pkt_lst[i], dts_mac=3Ddts_mac, ecpri=3De= cpri)=0D + self.verify(ptype_lst[i] in out, 'ptype is error, expect {}'.f= ormat(ptype_lst[i]))=0D +=0D + def send_pkt(self, pkt_str=3D'', dts_mac=3D'00:11:22:33:44:11', ecpri= =3D'0x5123', pmd_output=3D''):=0D + self.pkt.append_pkt(pkt_str.format(dts_mac, ecpri))=0D + self.pkt.send_pkt(crb=3Dself.tester, tx_port=3Dself.tester_iface0,= count=3D1)=0D + out =3D pmd_output.get_output() if pmd_output else self.pmd_output= .get_output()=0D + self.pkt.update_pkt([])=0D + return out=0D +=0D + def tear_down(self):=0D + self.dut.kill_all()=0D +=0D + def tear_down_all(self):=0D + self.dut.kill_all()=0D --=20 2.25.1