get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/121754/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 121754,
    "url": "http://patches.dpdk.org/api/patches/121754/?format=api",
    "web_url": "http://patches.dpdk.org/project/dts/patch/20230110145719.18052-6-hongbox.li@intel.com/",
    "project": {
        "id": 3,
        "url": "http://patches.dpdk.org/api/projects/3/?format=api",
        "name": "DTS",
        "link_name": "dts",
        "list_id": "dts.dpdk.org",
        "list_email": "dts@dpdk.org",
        "web_url": "",
        "scm_url": "git://dpdk.org/tools/dts",
        "webscm_url": "http://git.dpdk.org/tools/dts/",
        "list_archive_url": "https://inbox.dpdk.org/dts",
        "list_archive_url_format": "https://inbox.dpdk.org/dts/{}",
        "commit_url_format": ""
    },
    "msgid": "<20230110145719.18052-6-hongbox.li@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dts/20230110145719.18052-6-hongbox.li@intel.com",
    "date": "2023-01-10T14:57:16",
    "name": "[V2,5/8] tests/ipfrag: split performance plan and suite",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": false,
    "hash": "026ef40aed245d5049854dbc741a12ea2d76c032",
    "submitter": {
        "id": 2804,
        "url": "http://patches.dpdk.org/api/people/2804/?format=api",
        "name": "Li, HongboX",
        "email": "hongbox.li@intel.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dts/patch/20230110145719.18052-6-hongbox.li@intel.com/mbox/",
    "series": [
        {
            "id": 26450,
            "url": "http://patches.dpdk.org/api/series/26450/?format=api",
            "web_url": "http://patches.dpdk.org/project/dts/list/?series=26450",
            "date": "2023-01-10T14:57:11",
            "name": "split performance plan and suite",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/26450/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/121754/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/121754/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dts-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id C3C2B4239F;\n\tTue, 10 Jan 2023 07:38:13 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id C1B8841141;\n\tTue, 10 Jan 2023 07:38:13 +0100 (CET)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n by mails.dpdk.org (Postfix) with ESMTP id 9B8FC40F16\n for <dts@dpdk.org>; Tue, 10 Jan 2023 07:38:11 +0100 (CET)",
            "from fmsmga003.fm.intel.com ([10.253.24.29])\n by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 09 Jan 2023 22:37:53 -0800",
            "from unknown (HELO cvl_100g_103.icx.intel.com) ([10.239.252.93])\n by fmsmga003-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 09 Jan 2023 22:37:51 -0800"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1673332692; x=1704868692;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=nO2qM6m5DG8fxd8wYqrsSVTc7f8o5UeChbLpx8KoglE=;\n b=XZNddPm479c7978PMXTweHrkvJoilaUzc2hhWddaQAj/LGkXMdFLpse2\n d5unaAWBzP+aWjOuICP6xP6g6e9T/DLFiOnRSpQC2RLU0zr1DlA69aUIk\n cXLhcVcQv748p5EU4RntIxb96P6ubLNsCijR/bdtiFj82OuES9mrrZ2Hs\n uqTZa+E77vgdpbRqB0MhlVQRvnr0c7KKx5mLf2AiOAA1kuQ4uouf1C/kI\n UvgU8tUVW/M5feFgXZsn4c+jfNlI38+ZxbgXyFzL9pLM3L+EBWWeDKc2l\n 0XKZ9J3k7pSzgppWPxJhb3e9spzp857WgFo2o8tYfm4Ckkm90tw1LVo7+ A==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6500,9779,10585\"; a=\"310874999\"",
            "E=Sophos;i=\"5.96,314,1665471600\"; d=\"scan'208\";a=\"310874999\"",
            "E=McAfee;i=\"6500,9779,10585\"; a=\"745657680\"",
            "E=Sophos;i=\"5.96,314,1665471600\"; d=\"scan'208\";a=\"745657680\""
        ],
        "From": "Hongbo Li <hongbox.li@intel.com>",
        "To": "dts@dpdk.org",
        "Cc": "Hongbo Li <hongbox.li@intel.com>",
        "Subject": "[dts][PATCH V2 5/8] tests/ipfrag: split performance plan and suite",
        "Date": "Tue, 10 Jan 2023 22:57:16 +0800",
        "Message-Id": "<20230110145719.18052-6-hongbox.li@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20230110145719.18052-1-hongbox.li@intel.com>",
        "References": "<20230110145719.18052-1-hongbox.li@intel.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "X-BeenThere": "dts@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "test suite reviews and discussions <dts.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dts>,\n <mailto:dts-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dts/>",
        "List-Post": "<mailto:dts@dpdk.org>",
        "List-Help": "<mailto:dts-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dts>,\n <mailto:dts-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dts-bounces@dpdk.org"
    },
    "content": "split performance plan and suite\n\nSigned-off-by: Hongbo Li <hongbox.li@intel.com>\n---\n test_plans/ipfrag_test_plan.rst      |  33 +--\n test_plans/perf_ipfrag_test_plan.rst | 141 ++++++++++\n tests/TestSuite_ipfrag.py            |  21 --\n tests/TestSuite_perf_ipfrag.py       | 386 +++++++++++++++++++++++++++\n 4 files changed, 528 insertions(+), 53 deletions(-)\n create mode 100644 test_plans/perf_ipfrag_test_plan.rst\n create mode 100644 tests/TestSuite_perf_ipfrag.py",
    "diff": "diff --git a/test_plans/ipfrag_test_plan.rst b/test_plans/ipfrag_test_plan.rst\nindex e30a5961..17ea5c3c 100644\n--- a/test_plans/ipfrag_test_plan.rst\n+++ b/test_plans/ipfrag_test_plan.rst\n@@ -129,35 +129,4 @@ For each of them check that:\n \n #. Check number of output packets.\n #. Check header of each output packet: length, ID, fragment offset, flags.\n-#. Check payload: size and contents as expected, not corrupted.\n-\n-\n-\n-Test Case 4: Throughput test\n-============================\n-\n-The test report should provide the throughput rate measurements (in mpps and % of the line rate for 2x NIC ports)\n-for the following input frame sizes: 64 bytes, 1518 bytes, 1519 bytes, 2K, 9k.\n-\n-The following configurations should be tested:\n-\n-|\n-\n-+----------+-------------------------+----------------------+\n-|# of ports|  Socket/Core/HyperThread|Total # of sw threads |\n-+----------+-------------------------+----------------------+\n-|   2      |    1S/1C/1T             |          1           |\n-+----------+-------------------------+----------------------+\n-|   2      |    1S/1C/2T             |          2           |\n-+----------+-------------------------+----------------------+\n-|   2      |    1S/2C/1T             |          2           |\n-+----------+-------------------------+----------------------+\n-|   2      |    2S/1C/1T             |          2           |\n-+----------+-------------------------+----------------------+\n-\n-|\n-\n-Command line::\n-\n-   ./x86_64-native-linuxapp-gcc/examples/dpdk-ip_fragmentation -c <LCOREMASK> -n 4 -- [-P] -p PORTMASK\n-      -q <NUM_OF_PORTS_PER_THREAD>\n+#. Check payload: size and contents as expected, not corrupted.\n\\ No newline at end of file\ndiff --git a/test_plans/perf_ipfrag_test_plan.rst b/test_plans/perf_ipfrag_test_plan.rst\nnew file mode 100644\nindex 00000000..96dca62d\n--- /dev/null\n+++ b/test_plans/perf_ipfrag_test_plan.rst\n@@ -0,0 +1,141 @@\n+.. SPDX-License-Identifier: BSD-3-Clause\n+   Copyright(c) 2011-2017 Intel Corporation\n+\n+======================\n+IP fragmentation Tests\n+======================\n+\n+The IP fragmentation results are produced using ''ip_fragmentation'' application.\n+The test application should run with both IPv4 and IPv6 fragmentation.\n+\n+The suit support NIC: Intel® Ethernet 700 Series, Intel® Ethernet 800 Series, 82599 and igc driver NIC.\n+\n+Prerequisites\n+=============\n+\n+1. Hardware requirements:\n+\n+   - For each CPU socket, each memory channel should be populated with at least 1x DIMM\n+   - Board is populated with at least 2x 1GbE or 10GbE ports. Special PCIe restrictions may\n+     be required for performance. For example, the following requirements should be\n+     met for Intel 82599 NICs:\n+\n+       - NICs are plugged into PCIe Gen2 or Gen3 slots\n+       - For PCIe Gen2 slots, the number of lanes should be 8x or higher\n+       - A single port from each NIC should be used, so for 2x ports, 2x NICs should\n+         be used\n+\n+   - NIC ports connected to traffic generator. It is assumed that the NIC ports\n+     P0, P1, P2, P3 (as identified by the DPDK application) are connected to the\n+     traffic generator ports TG0, TG1, TG2, TG3. The application-side port mask of\n+     NIC ports P0, P1, P2, P3 is noted as PORTMASK in this section.\n+     Traffic generator should support sending jumbo frames with size up to 9K.\n+\n+2. BIOS requirements:\n+\n+   - Intel Hyper-Threading Technology is ENABLED\n+   - Hardware Prefetcher is DISABLED\n+   - Adjacent Cache Line Prefetch is DISABLED\n+   - Direct Cache Access is DISABLED\n+\n+3. Linux kernel requirements:\n+\n+   - Linux kernel has the following features enabled: huge page support, UIO, HPET\n+   - Appropriate number of huge pages are reserved at kernel boot time\n+   - The IDs of the hardware threads (logical cores) per each CPU socket can be\n+     determined by parsing the file /proc/cpuinfo. The naming convention for the\n+     logical cores is: C{x.y.z} = hyper-thread z of physical core y of CPU socket x,\n+     with typical values of x = 0 .. 3, y = 0 .. 7, z = 0 .. 1. Logical cores\n+     C{0.0.1} and C{0.0.1} should be avoided while executing the test, as they are\n+     used by the Linux kernel for running regular processes.\n+\n+4. Software application requirements\n+\n+5. If using vfio the kernel must be >= 3.6+ and VT-d must be enabled in bios.When\n+   using vfio, use the following commands to load the vfio driver and bind it\n+   to the device under test::\n+\n+      modprobe vfio\n+      modprobe vfio-pci\n+      usertools/dpdk-devbind.py --bind=vfio-pci device_bus_id\n+\n+   - The test can be run with IPv4 package. The LPM table used for IPv4 packet routing is:\n+\n+   +-------+-------------------------------------+-----------+\n+   |Entry #|LPM prefix (IP/length)               |Output port|\n+   +-------+-------------------------------------+-----------+\n+   |   0   |   100.10.0.0/16                     |     P2    |\n+   +-------+-------------------------------------+-----------+\n+   |   1   |   100.20.0.0/16                     |     P2    |\n+   +-------+-------------------------------------+-----------+\n+   |   2   |   100.30.0.0/16                     |     P0    |\n+   +-------+-------------------------------------+-----------+\n+   |   3   |   100.40.0.0/16                     |     P0    |\n+   +-------+-------------------------------------+-----------+\n+\n+\n+   - The test can be run with IPv6 package, which follows rules below.\n+\n+    - There is no support for Hop-by-Hop or Routing extension headers in the packet\n+      to be fragmented. All other optional headers, which are not part of the\n+      unfragmentable part of the IPv6 packet are supported.\n+\n+    - When a fragment is generated, its identification field in the IPv6\n+      fragmentation extension header is set to 0. This is not RFC compliant, but\n+      proper identification number generation is out of the scope of the application\n+      and routers in an IPv6 path are not allowed to fragment in the first place...\n+      Generating that identification number is the job of a proper IP stack.\n+\n+   - The LPM table used for IPv6 packet routing is:\n+\n+   +-------+-------------------------------------+-----------+\n+   |Entry #|LPM prefix (IP/length)               |Output port|\n+   +-------+-------------------------------------+-----------+\n+   |   0   |   101:101:101:101:101:101:101:101/48|     P2    |\n+   +-------+-------------------------------------+-----------+\n+   |   1   |   201:101:101:101:101:101:101:101/48|     P2    |\n+   +-------+-------------------------------------+-----------+\n+   |   2   |   301:101:101:101:101:101:101:101/48|     P0    |\n+   +-------+-------------------------------------+-----------+\n+   |   3   |   401:101:101:101:101:101:101:101/48|     P0    |\n+   +-------+-------------------------------------+-----------+\n+\n+   The following items are configured through the command line interface of the application:\n+\n+     - The set of one or several RX queues to be enabled for each NIC port\n+     - The set of logical cores to execute the packet forwarding task\n+     - Mapping of the NIC RX queues to logical cores handling them.\n+\n+6. Compile examples/ip_fragmentation::\n+\n+    meson configure -Dexamples=ip_fragmentation x86_64-native-linuxapp-gcc\n+    ninja -C x86_64-native-linuxapp-gcc\n+\n+Test Case 1: Throughput test\n+============================\n+\n+The test report should provide the throughput rate measurements (in mpps and % of the line rate for 2x NIC ports)\n+for the following input frame sizes: 64 bytes, 1518 bytes, 1519 bytes, 2K, 9k.\n+\n+The following configurations should be tested:\n+\n+|\n+\n++----------+-------------------------+----------------------+\n+|# of ports|  Socket/Core/HyperThread|Total # of sw threads |\n++----------+-------------------------+----------------------+\n+|   2      |    1S/1C/1T             |          1           |\n++----------+-------------------------+----------------------+\n+|   2      |    1S/1C/2T             |          2           |\n++----------+-------------------------+----------------------+\n+|   2      |    1S/2C/1T             |          2           |\n++----------+-------------------------+----------------------+\n+|   2      |    2S/1C/1T             |          2           |\n++----------+-------------------------+----------------------+\n+\n+|\n+\n+Command line::\n+\n+   ./x86_64-native-linuxapp-gcc/examples/dpdk-ip_fragmentation -c <LCOREMASK> -n 4 -- [-P] -p PORTMASK\n+      -q <NUM_OF_PORTS_PER_THREAD>\ndiff --git a/tests/TestSuite_ipfrag.py b/tests/TestSuite_ipfrag.py\nindex 95f99281..169df06b 100644\n--- a/tests/TestSuite_ipfrag.py\n+++ b/tests/TestSuite_ipfrag.py\n@@ -372,27 +372,6 @@ class TestIpfrag(TestCase):\n \n         self.dut.send_expect(\"^C\", \"#\")\n \n-    def test_perf_ipfrag_throughtput(self):\n-        \"\"\"\n-        Performance test for 64, 1518, 1519, 2k and 9k.\n-        \"\"\"\n-        sizes = [64, 1518, 1519, 2000, 9000]\n-\n-        tblheader = [\"Ports\", \"S/C/T\", \"SW threads\"]\n-        for size in sizes:\n-            tblheader.append(\"%dB Mpps\" % size)\n-            tblheader.append(\"%d\" % size)\n-\n-        self.result_table_create(tblheader)\n-\n-        lcores = [(\"1S/1C/1T\", 2), (\"1S/1C/2T\", 2), (\"1S/2C/1T\", 2), (\"2S/1C/1T\", 2)]\n-        index = 1\n-        for (lcore, numThr) in lcores:\n-            self.benchmark(index, lcore, numThr, sizes)\n-            index += 1\n-\n-        self.result_table_print()\n-\n     def tear_down(self):\n         \"\"\"\n         Run after each test case.\ndiff --git a/tests/TestSuite_perf_ipfrag.py b/tests/TestSuite_perf_ipfrag.py\nnew file mode 100644\nindex 00000000..030aa378\n--- /dev/null\n+++ b/tests/TestSuite_perf_ipfrag.py\n@@ -0,0 +1,386 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2010-2014 Intel Corporation\n+#\n+\n+\"\"\"\n+DPDK Test suite.\n+Test IPv4 fragmentation features in DPDK.\n+\"\"\"\n+\n+import os\n+import re\n+import string\n+import time\n+\n+import framework.utils as utils\n+from framework.packet import Packet\n+from framework.pktgen import PacketGeneratorHelper\n+from framework.settings import HEADER_SIZE\n+from framework.test_case import TestCase\n+\n+lpm_table_ipv6 = [\n+    \"{{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, 48, P1}\",\n+    \"{{2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, 48, P1}\",\n+    \"{{3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, 48, P0}\",\n+    \"{{4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, 48, P0}\",\n+    \"{{5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, 48, P1}\",\n+    \"{{6,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, 48, P1}\",\n+    \"{{7,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, 48, P0}\",\n+    \"{{8,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, 48, P0}\",\n+]\n+\n+\n+class TestIpfrag(TestCase):\n+    def portRepl(self, match):\n+        \"\"\"\n+        Function to replace P([0123]) pattern in tables\n+        \"\"\"\n+\n+        portid = match.group(1)\n+        self.verify(int(portid) in range(4), \"invalid port id\")\n+        return \"%s\" % eval(\"P\" + str(portid))\n+\n+    def set_up_all(self):\n+        \"\"\"\n+        ip_fragmentation Prerequisites\n+        \"\"\"\n+\n+        # Based on h/w type, choose how many ports to use\n+        self.ports = self.dut.get_ports()\n+\n+        # Verify that enough ports are available\n+        self.verify(len(self.ports) >= 2, \"Insufficient ports for testing\")\n+\n+        self.ports_socket = self.dut.get_numa_id(self.ports[0])\n+\n+        # Verify that enough threads are available\n+        cores = self.dut.get_core_list(\"1S/1C/1T\")\n+        self.verify(cores is not None, \"Insufficient cores for speed testing\")\n+\n+        global P0, P1\n+        P0 = self.ports[0]\n+        P1 = self.ports[1]\n+\n+        # make application\n+        out = self.dut.build_dpdk_apps(\"examples/ip_fragmentation\")\n+        self.verify(\"Error\" not in out, \"compilation error 1\")\n+        self.verify(\"No such file\" not in out, \"compilation error 2\")\n+\n+        self.eal_para = self.dut.create_eal_parameters(\n+            socket=self.ports_socket, ports=self.ports\n+        )\n+        portmask = utils.create_mask([P0, P1])\n+        numPortThread = len([P0, P1]) / len(cores)\n+\n+        # run ipv4_frag\n+        self.app_ip_fragmentation_path = self.dut.apps_name[\"ip_fragmentation\"]\n+        self.dut.send_expect(\n+            \"%s %s -- -p %s -q %s\"\n+            % (\n+                self.app_ip_fragmentation_path,\n+                self.eal_para,\n+                portmask,\n+                int(numPortThread),\n+            ),\n+            \"Link [Uu]p\",\n+            120,\n+        )\n+\n+        time.sleep(2)\n+        self.txItf = self.tester.get_interface(self.tester.get_local_port(P0))\n+        self.rxItf = self.tester.get_interface(self.tester.get_local_port(P1))\n+        self.dmac = self.dut.get_mac_address(P0)\n+\n+        # get dts output path\n+        if self.logger.log_path.startswith(os.sep):\n+            self.output_path = self.logger.log_path\n+        else:\n+            cur_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))\n+            self.output_path = os.sep.join([cur_path, self.logger.log_path])\n+        # create an instance to set stream field setting\n+        self.pktgen_helper = PacketGeneratorHelper()\n+\n+    def functional_check_ipv4(self, pkt_sizes, burst=1, flag=None):\n+        \"\"\"\n+        Perform functional fragmentation checks.\n+        \"\"\"\n+        for size in pkt_sizes[::burst]:\n+            # simulate to set TG properties\n+            if flag == \"frag\":\n+                # do fragment, each packet max length 1518 - 18 - 20 = 1480\n+                expPkts = int((size - HEADER_SIZE[\"eth\"] - HEADER_SIZE[\"ip\"]) / 1480)\n+                if (size - HEADER_SIZE[\"eth\"] - HEADER_SIZE[\"ip\"]) % 1480:\n+                    expPkts += 1\n+                val = 0\n+            elif flag == \"nofrag\":\n+                expPkts = 0\n+                val = 2\n+            else:\n+                expPkts = 1\n+                val = 2\n+\n+            inst = self.tester.tcpdump_sniff_packets(intf=self.rxItf)\n+            # send packet\n+            for times in range(burst):\n+                pkt_size = pkt_sizes[pkt_sizes.index(size) + times]\n+                pkt = Packet(pkt_type=\"UDP\", pkt_len=pkt_size)\n+                pkt.config_layer(\"ether\", {\"dst\": \"%s\" % self.dmac})\n+                pkt.config_layer(\n+                    \"ipv4\", {\"dst\": \"100.20.0.1\", \"src\": \"1.2.3.4\", \"flags\": val}\n+                )\n+                pkt.send_pkt(self.tester, tx_port=self.txItf)\n+\n+            # verify normal packet just by number, verify fragment packet by all elements\n+            pkts = self.tester.load_tcpdump_sniff_packets(inst)\n+            self.verify(\n+                len(pkts) == expPkts,\n+                \"in functional_check_ipv4(): failed on forward packet size \"\n+                + str(size),\n+            )\n+            if flag == \"frag\":\n+                idx = 1\n+                for i in range(len(pkts)):\n+                    pkt_id = pkts.strip_element_layer3(\"id\", p_index=i)\n+                    if idx == 1:\n+                        prev_idx = pkt_id\n+                    self.verify(\n+                        prev_idx == pkt_id, \"Fragmented packets index not match\"\n+                    )\n+                    prev_idx = pkt_id\n+\n+                    # last flags should be 0\n+                    flags = pkts.strip_element_layer3(\"flags\", p_index=i)\n+                    if idx == expPkts:\n+                        self.verify(\n+                            flags == 0, \"Fragmented last packet flags not match\"\n+                        )\n+                    else:\n+                        self.verify(flags == 1, \"Fragmented packets flags not match\")\n+\n+                    # fragment offset should be correct\n+                    frag = pkts.strip_element_layer3(\"frag\", p_index=i)\n+                    self.verify(\n+                        (frag == ((idx - 1) * 185)), \"Fragment packet frag not match\"\n+                    )\n+                    idx += 1\n+\n+    def functional_check_ipv6(self, pkt_sizes, burst=1, flag=None, funtion=None):\n+        \"\"\"\n+        Perform functional fragmentation checks.\n+        \"\"\"\n+        for size in pkt_sizes[::burst]:\n+            # simulate to set TG properties\n+            if flag == \"frag\":\n+                # each packet max len: 1518 - 18 (eth) - 40 (ipv6) - 8 (ipv6 ext hdr) = 1452\n+                expPkts = int((size - HEADER_SIZE[\"eth\"] - HEADER_SIZE[\"ipv6\"]) / 1452)\n+                if (size - HEADER_SIZE[\"eth\"] - HEADER_SIZE[\"ipv6\"]) % 1452:\n+                    expPkts += 1\n+                val = 0\n+            else:\n+                expPkts = 1\n+                val = 2\n+\n+            inst = self.tester.tcpdump_sniff_packets(intf=self.rxItf)\n+            # send packet\n+            for times in range(burst):\n+                pkt_size = pkt_sizes[pkt_sizes.index(size) + times]\n+                pkt = Packet(pkt_type=\"IPv6_UDP\", pkt_len=pkt_size)\n+                pkt.config_layer(\"ether\", {\"dst\": \"%s\" % self.dmac})\n+                pkt.config_layer(\n+                    \"ipv6\",\n+                    {\n+                        \"dst\": \"201:101:101:101:101:101:101:101\",\n+                        \"src\": \"ee80:ee80:ee80:ee80:ee80:ee80:ee80:ee80\",\n+                    },\n+                )\n+                pkt.send_pkt(self.tester, tx_port=self.txItf)\n+\n+            # verify normal packet just by number, verify fragment packet by all elements\n+            pkts = self.tester.load_tcpdump_sniff_packets(inst)\n+            self.verify(\n+                len(pkts) == expPkts,\n+                \"In functional_check_ipv6(): failed on forward packet size \"\n+                + str(size),\n+            )\n+            if flag == \"frag\":\n+                idx = 1\n+                for i in range(len(pkts)):\n+                    pkt_id = pkts.strip_element_layer4(\"id\", p_index=i)\n+                    if idx == 1:\n+                        prev_idx = pkt_id\n+                    self.verify(\n+                        prev_idx == pkt_id, \"Fragmented packets index not match\"\n+                    )\n+                    prev_idx = pkt_id\n+\n+                    # last flags should be 0\n+                    flags = pkts.strip_element_layer4(\"m\", p_index=i)\n+                    if idx == expPkts:\n+                        self.verify(\n+                            flags == 0, \"Fragmented last packet flags not match\"\n+                        )\n+                    else:\n+                        self.verify(flags == 1, \"Fragmented packets flags not match\")\n+\n+                    # fragment offset should be correct\n+                    frag = pkts.strip_element_layer4(\"offset\", p_index=i)\n+                    self.verify(\n+                        (frag == int((idx - 1) * 181)), \"Fragment packet frag not match\"\n+                    )\n+                    idx += 1\n+\n+    def set_up(self):\n+        \"\"\"\n+        Run before each test case.\n+        \"\"\"\n+        self.tester.send_expect(\n+            \"ifconfig %s mtu 9200\"\n+            % self.tester.get_interface(self.tester.get_local_port(P0)),\n+            \"#\",\n+        )\n+        self.tester.send_expect(\n+            \"ifconfig %s mtu 9200\"\n+            % self.tester.get_interface(self.tester.get_local_port(P1)),\n+            \"#\",\n+        )\n+\n+    def benchmark(self, index, lcore, num_pthreads, size_list):\n+        \"\"\"\n+        Just Test IPv4 Throughput for selected parameters.\n+        \"\"\"\n+\n+        Bps = dict()\n+        Pps = dict()\n+        Pct = dict()\n+\n+        if int(lcore[0]) == 1:\n+            eal_param = self.dut.create_eal_parameters(\n+                cores=lcore, socket=self.ports_socket, ports=self.ports\n+            )\n+        else:\n+            eal_param = self.dut.create_eal_parameters(cores=lcore, ports=self.ports)\n+        portmask = utils.create_mask([P0, P1])\n+        self.dut.send_expect(\"^c\", \"# \", 120)\n+        self.dut.send_expect(\n+            \"%s %s -- -p %s -q %s\"\n+            % (self.app_ip_fragmentation_path, eal_param, portmask, num_pthreads),\n+            \"IP_FRAG:\",\n+            120,\n+        )\n+        result = [2, lcore, num_pthreads]\n+        for size in size_list:\n+            dmac = self.dut.get_mac_address(P0)\n+            flows_p0 = [\n+                'Ether(dst=\"%s\")/IP(src=\"1.2.3.4\", dst=\"100.10.0.1\", flags=0)/(\"X\"*%d)'\n+                % (dmac, size - 38),\n+                'Ether(dst=\"%s\")/IP(src=\"1.2.3.4\", dst=\"100.20.0.1\", flags=0)/(\"X\"*%d)'\n+                % (dmac, size - 38),\n+                'Ether(dst=\"%s\")/IPv6(dst=\"101:101:101:101:101:101:101:101\",src=\"ee80:ee80:ee80:ee80:ee80:ee80:ee80:ee80\")/Raw(load=\"X\"*%d)'\n+                % (dmac, size - 58),\n+                'Ether(dst=\"%s\")/IPv6(dst=\"201:101:101:101:101:101:101:101\",src=\"ee80:ee80:ee80:ee80:ee80:ee80:ee80:ee80\")/Raw(load=\"X\"*%d)'\n+                % (dmac, size - 58),\n+            ]\n+\n+            # reserved for rx/tx bidirection test\n+            dmac = self.dut.get_mac_address(P1)\n+            flows_p1 = [\n+                'Ether(dst=\"%s\")/IP(src=\"1.2.3.4\", dst=\"100.30.0.1\", flags=0)/(\"X\"*%d)'\n+                % (dmac, size - 38),\n+                'Ether(dst=\"%s\")/IP(src=\"1.2.3.4\", dst=\"100.40.0.1\", flags=0)/(\"X\"*%d)'\n+                % (dmac, size - 38),\n+                'Ether(dst=\"%s\")/IPv6(dst=\"301:101:101:101:101:101:101:101\",src=\"ee80:ee80:ee80:ee80:ee80:ee80:ee80:ee80\")/Raw(load=\"X\"*%d)'\n+                % (dmac, size - 58),\n+                'Ether(dst=\"%s\")/IPv6(dst=\"401:101:101:101:101:101:101:101\",src=\"ee80:ee80:ee80:ee80:ee80:ee80:ee80:ee80\")/Raw(load=\"X\"*%d)'\n+                % (dmac, size - 58),\n+            ]\n+            flow_len = len(flows_p0)\n+            tgenInput = []\n+            for i in range(flow_len):\n+\n+                pcap0 = os.sep.join([self.output_path, \"p0_{}.pcap\".format(i)])\n+                self.tester.scapy_append('wrpcap(\"%s\", [%s])' % (pcap0, flows_p0[i]))\n+                pcap1 = os.sep.join([self.output_path, \"p1_{}.pcap\".format(i)])\n+                self.tester.scapy_append('wrpcap(\"%s\", [%s])' % (pcap1, flows_p1[i]))\n+                self.tester.scapy_execute()\n+\n+                tgenInput.append(\n+                    (\n+                        self.tester.get_local_port(P0),\n+                        self.tester.get_local_port(P1),\n+                        pcap0,\n+                    )\n+                )\n+                tgenInput.append(\n+                    (\n+                        self.tester.get_local_port(P1),\n+                        self.tester.get_local_port(P0),\n+                        pcap1,\n+                    )\n+                )\n+\n+            factor = (size + 1517) / 1518\n+            # wireSpd = 2 * 10000.0 / ((20 + size) * 8)\n+\n+            # clear streams before add new streams\n+            self.tester.pktgen.clear_streams()\n+            # run packet generator\n+            streams = self.pktgen_helper.prepare_stream_from_tginput(\n+                tgenInput, 100, None, self.tester.pktgen\n+            )\n+            Bps[str(size)], Pps[str(size)] = self.tester.pktgen.measure_throughput(\n+                stream_ids=streams\n+            )\n+\n+            self.verify(Pps[str(size)] > 0, \"No traffic detected\")\n+            Pps[str(size)] *= 1.0 / factor / 1000000\n+            Pct[str(size)] = (1.0 * Bps[str(size)] * 100) / (2 * 10000000000)\n+\n+            result.append(Pps[str(size)])\n+            result.append(Pct[str(size)])\n+\n+        self.result_table_add(result)\n+\n+        self.dut.send_expect(\"^C\", \"#\")\n+\n+    def test_perf_ipfrag_throughtput(self):\n+        \"\"\"\n+        Performance test for 64, 1518, 1519, 2k and 9k.\n+        \"\"\"\n+        sizes = [64, 1518, 1519, 2000, 9000]\n+\n+        tblheader = [\"Ports\", \"S/C/T\", \"SW threads\"]\n+        for size in sizes:\n+            tblheader.append(\"%dB Mpps\" % size)\n+            tblheader.append(\"%d\" % size)\n+\n+        self.result_table_create(tblheader)\n+\n+        lcores = [(\"1S/1C/1T\", 2), (\"1S/1C/2T\", 2), (\"1S/2C/1T\", 2), (\"2S/1C/1T\", 2)]\n+        index = 1\n+        for (lcore, numThr) in lcores:\n+            self.benchmark(index, lcore, numThr, sizes)\n+            index += 1\n+\n+        self.result_table_print()\n+\n+    def tear_down(self):\n+        \"\"\"\n+        Run after each test case.\n+        \"\"\"\n+        self.tester.send_expect(\n+            \"ifconfig %s mtu 1500\"\n+            % self.tester.get_interface(self.tester.get_local_port(P0)),\n+            \"#\",\n+        )\n+        self.tester.send_expect(\n+            \"ifconfig %s mtu 1500\"\n+            % self.tester.get_interface(self.tester.get_local_port(P1)),\n+            \"#\",\n+        )\n+\n+    def tear_down_all(self):\n+        \"\"\"\n+        Run after each test suite.\n+        \"\"\"\n+        self.dut.send_expect(\"^C\", \"#\")\n+        pass\n",
    "prefixes": [
        "V2",
        "5/8"
    ]
}