[dts] [PATCH v4] add dynamic flow type test suite

Xueqin Lin xueqin.lin at intel.com
Tue Nov 21 00:10:43 CET 2017


---
 tests/TestSuite_dynamic_flowtype.py | 293 ++++++++++++++++++++++++++++++++++++
 1 file changed, 293 insertions(+)
 create mode 100644 tests/TestSuite_dynamic_flowtype.py

diff --git a/tests/TestSuite_dynamic_flowtype.py b/tests/TestSuite_dynamic_flowtype.py
new file mode 100644
index 0000000..98baa31
--- /dev/null
+++ b/tests/TestSuite_dynamic_flowtype.py
@@ -0,0 +1,293 @@
+# <COPYRIGHT_TAG>
+
+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 TestDynamic_Flowtype(TestCase):
+
+    def set_up_all(self):
+        self.verify(self.nic in ['fortville_25g'],
+                    'dynamic flow type mapping can not support %s nic'
+                    % self.nic)
+        ports = self.dut.get_ports()
+        self.verify(len(ports) >= 1, "Insufficient ports for testing")
+        valports = [_ for _ in ports if self.tester.get_local_port(_) != -1]
+        self.dut_port = valports[0]
+        tester_port = self.tester.get_local_port(self.dut_port)
+        self.tester_intf = self.tester.get_interface(tester_port)
+        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'
+        self.PF_QUEUE = self.search_queue_number(PF_Q_strip)
+
+    def set_up(self):
+        """
+        Run before each test case.
+        """
+        self.dut_testpmd = PmdOutput(self.dut)
+        self.dut_testpmd.start_testpmd(
+            "Default", "--port-topology=chained --txq=%s --rxq=%s"
+            % (self.PF_QUEUE, self.PF_QUEUE))
+        self.load_profile()
+
+    def search_queue_number(self, Q_strip):
+        """
+        Search max queue number from configuration.
+        """
+        out = self.dut.send_expect("cat config/common_base", "]# ", 10)
+        pattern = "(%s=)(\d*)" % Q_strip
+        s = re.compile(pattern)
+        res = s.search(out)
+        if res is None:
+            print utils.RED('Search no queue number.')
+            return None
+        else:
+            queue = res.group(2)
+            return int(queue)
+
+    def load_profile(self):
+        """
+        Load profile to update FVL configuration tables, profile will be
+        stored in binary file and need to be passed to AQ to program FVL
+        during initialization stage.
+        """
+        self.dut_testpmd.execute_cmd('port stop all')
+        time.sleep(1)
+        out = self.dut_testpmd.execute_cmd('ddp get list 0')
+        self.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')
+
+    def gtp_packets(self, flowtype=26, match_opt='matched'):
+        """
+        Generate different GTP types according to different parameters.
+        I40e PCTYPEs are statically mapped to RTE_ETH_FLOW_* types in
+        DPDK, defined in rte_eth_ctrl.h, and flow types used to define
+        ETH_RSS_* offload types in rte_ethdev.h. RTE_ETH_FLOW_MAX is
+        defined now as 22, leaves 42 flow type unassigned.
+        Input:
+        flowtype: define flow type 26, 23, 24, 25 for GTP types as below
+                  table, check each layer type, tunnel packet includes
+                  GTPC and GTPU, GTPC has none inner L3, GTPU has none,
+                  IPV4 and IPV6 inner L3.
+        match_opt: PF or VSIs receive match packets to rss queue, but
+                   receive not match packets to queue 0.
+
+        +------------+------------+------------+
+        |Packet Type |   PCTYPEs  | Flow Types |
+        +------------+------------+------------+
+        |GTP-U IPv4  |    22      |   26       |
+        +------------+------ -----+------------+
+        |GTP-U IPv6  |    23      |   23       |
+        +------------+------------+------------+
+        |GTP-U PAY4  |    24      |   24       |
+        +------------+------------+------------+
+        |GTP-C PAY4  |    25      |   25       |
+        +------------+------------+------------+
+
+        """
+        pkts = []
+        pkts_ipv4 = {'IPV4': 'Ether()/IP()/Raw("X"*20)'}
+
+        pkts_gtpc_pay = {'IPV4/GTPC': 'Ether()/IP()/UDP(dport=2123)/GTP_U_Header()/Raw("X"*20)',
+                         'IPV6/GTPC': 'Ether()/IPv6()/UDP(dport=2123)/GTP_U_Header()/Raw("X"*20)'}
+
+        pkts_gtpu_pay = {'IPV4/GTPU': 'Ether()/IP()/UDP(dport=2152)/GTP_U_Header()/Raw("X"*20)',
+                         'IPV6/GTPU': 'Ether()/IPv6()/UDP(dport=2152)/GTP_U_Header()/Raw("X"*20)'}
+
+        pkts_gtpu_ipv4 = {'IPV4/GTPU/IPV4': 'Ether()/IP()/UDP(dport=2152)/GTP_U_Header()/IP()/Raw("X"*20)',
+                          'IPV4/GTPU/IPV4/FRAG': 'Ether()/IP()/UDP(dport=2152)/GTP_U_Header()/IP(frag=5)/Raw("X"*20)',
+                          'IPV4/GTPU/IPV4/UDP': 'Ether()/IP()/UDP(dport=2152)/GTP_U_Header()/IP()/UDP()/Raw("X"*20)',
+                          'IPV4/GTPU/IPV4/TCP': 'Ether()/IP()/UDP(dport=2152)/GTP_U_Header()/IP()/TCP()/Raw("X"*20)',
+                          'IPV4/GTPU/IPV4/SCTP': 'Ether()/IP()/UDP(dport=2152)/GTP_U_Header()/IP()/SCTP()/Raw("X"*20)',
+                          'IPV4/GTPU/IPV4/ICMP': 'Ether()/IP()/UDP(dport=2152)/GTP_U_Header()/IP()/ICMP()/Raw("X"*20)',
+                          'IPV6/GTPU/IPV4': 'Ether()/IPv6()/UDP(dport=2152)/GTP_U_Header()/IP()/Raw("X"*20)',
+                          'IPV6/GTPU/IPV4/FRAG': 'Ether()/IPv6()/UDP(dport=2152)/GTP_U_Header()/IP(frag=5)/Raw("X"*20)',
+                          'IPV6/GTPU/IPV4/UDP': 'Ether()/IPv6()/UDP(dport=2152)/GTP_U_Header()/IP()/UDP()/Raw("X"*20)',
+                          'IPV6/GTPU/IPV4/TCP': 'Ether()/IPv6()/UDP(dport=2152)/GTP_U_Header()/IP()/TCP()/Raw("X"*20)',
+                          'IPV6/GTPU/IPV4/SCTP': 'Ether()/IPv6()/UDP(dport=2152)/GTP_U_Header()/IP()/SCTP()/Raw("X"*20)',
+                          'IPV6/GTPU/IPV4/ICMP': 'Ether()/IPv6()/UDP(dport=2152)/GTP_U_Header()/IP()/ICMP()/Raw("X"*20)'}
+
+        pkts_gtpu_ipv6 = {'IPV4/GTPU/IPV6/FRAG': 'Ether()/IP()/UDP(dport=2152)/GTP_U_Header()/IPv6()/IPv6ExtHdrFragment()/Raw("X"*20)',
+                          'IPV4/GTPU/IPV6': 'Ether()/IP()/UDP(dport=2152)/GTP_U_Header()/IPv6()/Raw("X"*20)',
+                          'IPV4/GTPU/IPV6/UDP': 'Ether()/IP()/UDP(dport=2152)/GTP_U_Header()/IPv6()/UDP()/Raw("X"*20)',
+                          'IPV4/GTPU/IPV6/TCP': 'Ether()/IP()/UDP(dport=2152)/GTP_U_Header()/IPv6()/TCP()/Raw("X"*20)',
+                          'IPV4/GTPU/IPV6/SCTP': 'Ether()/IP()/UDP(dport=2152)/GTP_U_Header()/IPv6()/SCTP()/Raw("X"*20)',
+                          'IPV4/GTPU/IPV6/ICMP': 'Ether()/IP()/UDP(dport=2152)/GTP_U_Header()/IPv6(nh=58)/ICMP()/Raw("X"*20)',
+                          'IPV6/GTPU/IPV6/FRAG': 'Ether()/IPv6()/UDP(dport=2152)/GTP_U_Header()/IPv6()/IPv6ExtHdrFragment()/Raw("X"*20)',
+                          'IPV6/GTPU/IPV6': 'Ether()/IPv6()/UDP(dport=2152)/GTP_U_Header()/IPv6()/Raw("X"*20)',
+                          'IPV6/GTPU/IPV6/UDP': 'Ether()/IPv6()/UDP(dport=2152)/GTP_U_Header()/IPv6()/UDP()/Raw("X"*20)',
+                          'IPV6/GTPU/IPV6/TCP': 'Ether()/IPv6()/UDP(dport=2152)/GTP_U_Header()/IPv6()/TCP()/Raw("X"*20)',
+                          'IPV6/GTPU/IPV6/SCTP': 'Ether()/IPv6()/UDP(dport=2152)/GTP_U_Header()/IPv6()/SCTP()/Raw("X"*20)',
+                          'IPV6/GTPU/IPV6/ICMP': 'Ether()/IPv6()/UDP(dport=2152)/GTP_U_Header()/IPv6(nh=58)/ICMP()/Raw("X"*20)'}
+
+        if match_opt == 'matched':
+            # Define flow type for IPV4 as 2 in rte_eth_ctrl.h
+            if flowtype == 2:
+                pkts = pkts_ipv4
+            if flowtype == 23:
+                pkts = pkts_gtpu_ipv6
+            if flowtype == 24:
+                pkts = pkts_gtpu_pay
+            if flowtype == 25:
+                pkts = pkts_gtpc_pay
+            if flowtype == 26:
+                pkts = pkts_gtpu_ipv4
+
+        if match_opt == 'not matched':
+            if flowtype == 23:
+                pkts = dict(pkts_gtpc_pay.items() +
+                            pkts_gtpu_pay.items() +
+                            pkts_gtpu_ipv4.items())
+            if flowtype == 24:
+                pkts = dict(pkts_gtpc_pay.items() +
+                            pkts_gtpu_ipv4.items() +
+                            pkts_gtpu_ipv6.items())
+            if flowtype == 25:
+                pkts = dict(pkts_gtpu_pay.items() +
+                            pkts_gtpu_ipv4.items() +
+                            pkts_gtpu_ipv6.items())
+            if flowtype == 26:
+                pkts = dict(pkts_gtpc_pay.items() +
+                            pkts_gtpu_pay.items() +
+                            pkts_gtpu_ipv6.items())
+
+        return pkts
+
+    def packet_send_verify(self, flowtype=26, match_opt='matched'):
+        """
+        Send packet and verify rss function.
+        """
+        pkts = self.gtp_packets(flowtype, match_opt)
+        for packet_type in pkts.keys():
+            self.tester.scapy_append(
+                'sendp([%s], iface="%s")'
+                % (pkts[packet_type], self.tester_intf))
+            self.tester.scapy_execute()
+            out = self.dut.get_session_output(timeout=2)
+            if match_opt == 'matched':
+                self.verify("port 0/queue 0" not in out,
+                            "Failed to receive packet in rss queue!!!")
+                self.verify("PKT_RX_RSS_HASH" in out,
+                            "Failed to receive packet in rss queue!!!")
+            elif match_opt == 'not matched':
+                self.verify("port 0/queue 0" in out,
+                            "Failed to receive packet in queue 0!!!")
+                self.verify("PKT_RX_RSS_HASH" not in out,
+                            "Failed to receive packet in queue 0!!!")
+
+    def dynamic_flowtype_test(self, pctype=22, flowtype=26, reset=False):
+        """
+        Dynamic modify, return or reset the contents of flow type to pctype
+        dynamic mapping, enable rss hash for new protocal.
+        reset: If reset is true, reset the contents of flow type to pctype
+               mapping. If reset is false, enable rss hash for new protocal.
+        """
+        out = self.dut_testpmd.execute_cmd('show port 0 pctype mapping')
+        self.verify("pctype: 63  ->  flowtype: 14" in out,
+                    "Failed show flow type to pctype mapping!!!")
+        self.verify("pctype: %s  ->  flowtype: %s"
+                    % (pctype, flowtype) not in out,
+                    "Failed show flow type to pctype mapping!!!")
+        self.dut_testpmd.execute_cmd(
+            'port config 0 pctype mapping update %s %s' % (pctype, flowtype))
+        out = self.dut_testpmd.execute_cmd('show port 0 pctype mapping')
+        self.verify("pctype: %s  ->  flowtype: %s"
+                    % (pctype, flowtype) in out,
+                    "Failed update flow type to pctype mapping!!!")
+        if reset is False:
+            self.dut_testpmd.execute_cmd(
+                'set_hash_input_set 0 %s udp-key add' % flowtype)
+            self.dut_testpmd.execute_cmd('port config all rss %s' % flowtype)
+        else:
+            self.dut_testpmd.execute_cmd('port config 0 pctype mapping reset')
+            out = self.dut_testpmd.execute_cmd('show port 0 pctype mapping')
+            self.verify("pctype: %s  ->  flowtype: %s"
+                        % (pctype, flowtype) not in out,
+                        "Failed reset flow type to pctype mapping!!!")
+            """
+            Send normal ipv4 packet to test rss, rte_eth_ctrl.h defines flow
+            type for IPV4 is 2.
+            """
+            flowtype = 2
+        for match_opt in ['matched', 'not matched']:
+            if match_opt == 'not matched' and reset is True:
+                break
+            self.packet_send_verify(flowtype, match_opt)
+
+    def test_profile_correctness(self):
+        """
+        GTP is supported by NVM with profile updated. Check profile
+        information correctness, includes used protocols, packet
+        classification types, defined packet types and so on.
+        """
+        out = self.dut_testpmd.execute_cmd('ddp get info /tmp/gtp.pkgo')
+        self.verify("i40e Profile Version" in out,
+                    "Failed to verify profile version!!!")
+        self.verify("List of used protocols" in out,
+                    "Failed to verify profie used protocols!!!")
+        self.verify("List of defined packet classification types" in out,
+                    "Failed to verify profile packet classification types!!!")
+        self.verify("List of defined packet types" in out,
+                    "Failed to verify profile packet types!!!")
+
+    def test_dynamic_flowtype_reset(self):
+        """
+        Dynamic modify, reset and return the contents of flow type to pctype
+        dynamic mapping.
+        """
+        self.dynamic_flowtype_test(pctype=22, flowtype=26, reset=True)
+
+    def test_dynamic_flowtype_gtpu_ipv4(self):
+        """
+        Dynamic modify, return the contents of flow type to pctype dynamic
+        mapping, enable and verify rss for GTP-U IPV4 packets.
+        """
+        self.dynamic_flowtype_test(pctype=22, flowtype=26, reset=False)
+
+    def test_dynamic_flowtype_gtpu_ipv6(self):
+        """
+        Dynamic modify, return the contents of flow type to pctype dynamic
+        mapping, enable and verify rss for GTP-U IPV6 packets.
+        """
+        self.dynamic_flowtype_test(pctype=23, flowtype=23, reset=False)
+
+    def test_dynamic_flowtype_gtpu_pay(self):
+        """
+        Dynamic modify, return the contents of flow type to pctype dynamic
+        mapping, enable and verify rss for GTP-U PAY packets.
+        """
+        self.dynamic_flowtype_test(pctype=24, flowtype=24, reset=False)
+
+    def test_dynamic_flowtype_gtpc_pay(self):
+        """
+        Dynamic modify, return the contents of flow type to pctype dynamic
+        mapping, enable and verify rss for GTP-C PAY packets.
+        """
+        self.dynamic_flowtype_test(pctype=25, flowtype=25, reset=False)
+
+    def tear_down(self):
+        if self.dut_testpmd:
+            self.dut_testpmd.execute_cmd('write reg 0 0xb8190 1')
+            self.dut_testpmd.execute_cmd('write reg 0 0xb8190 2')
+            self.dut_testpmd.quit()
+
+    def tear_down_all(self):
+        self.dut.kill_all()
-- 
2.5.5



More information about the dts mailing list