Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/121779/?format=api
https://patches.dpdk.org/api/patches/121779/?format=api", "web_url": "https://patches.dpdk.org/project/dts/patch/20230110164431.19390-8-hongbox.li@intel.com/", "project": { "id": 3, "url": "https://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": "<20230110164431.19390-8-hongbox.li@intel.com>", "list_archive_url": "https://inbox.dpdk.org/dts/20230110164431.19390-8-hongbox.li@intel.com", "date": "2023-01-10T16:44:30", "name": "[V3,7/8] tests/checksum_offload: split performance plan and suite", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "6b1bc80e6cc4b328c1c7e7a1474aa138ef111d5c", "submitter": { "id": 2804, "url": "https://patches.dpdk.org/api/people/2804/?format=api", "name": "Li, HongboX", "email": "hongbox.li@intel.com" }, "delegate": null, "mbox": "https://patches.dpdk.org/project/dts/patch/20230110164431.19390-8-hongbox.li@intel.com/mbox/", "series": [ { "id": 26458, "url": "https://patches.dpdk.org/api/series/26458/?format=api", "web_url": "https://patches.dpdk.org/project/dts/list/?series=26458", "date": "2023-01-10T16:44:23", "name": "split performance plan and suite", "version": 3, "mbox": "https://patches.dpdk.org/series/26458/mbox/" } ], "comments": "https://patches.dpdk.org/api/patches/121779/comments/", "check": "pending", "checks": "https://patches.dpdk.org/api/patches/121779/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 EAADD423A1;\n\tTue, 10 Jan 2023 09:25:07 +0100 (CET)", "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id E3FA242D1F;\n\tTue, 10 Jan 2023 09:25:07 +0100 (CET)", "from mga07.intel.com (mga07.intel.com [134.134.136.100])\n by mails.dpdk.org (Postfix) with ESMTP id 2D95C40689\n for <dts@dpdk.org>; Tue, 10 Jan 2023 09:25:06 +0100 (CET)", "from fmsmga001.fm.intel.com ([10.253.24.23])\n by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 10 Jan 2023 00:25:05 -0800", "from unknown (HELO cvl_100g_103.icx.intel.com) ([10.239.252.93])\n by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 10 Jan 2023 00:25:03 -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=1673339106; x=1704875106;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=fLDSyPtkBNm45kT9mQoX9T4x6tSVbn1AKbv6GmIg01g=;\n b=kUhlQeRyWxWtMhLKWztR5TQM0FSyEA5VYi/UwooRX985qFAVl9gKE9Vi\n n7EVxDeV074U9pBlMiQ0viySf/GYe/NTc1VdzhA4Qce/9puQiU/eCJoU8\n zVCc7LojCpo9oPR/8vFOr7sqCzVmGciFVME4UclWg0jJUWi83Hxrsxz7t\n 2NB8rHlW1u5sSbLx60izbkGUGKmbhcmDrbkPQxMuKoXqG49weda8PZjFz\n E2hUt5VP3aU/6sykWwCIzL3rLSo0XQAlwqOu1Yh4o01fZGzbbfab8El0s\n rOXK12OqvgzzkSYRpa/z5Qm8xxTOe8XZKg0OfRL6xkiB2dkq+PPctKwML g==;", "X-IronPort-AV": [ "E=McAfee;i=\"6500,9779,10585\"; a=\"387543519\"", "E=Sophos;i=\"5.96,314,1665471600\"; d=\"scan'208\";a=\"387543519\"", "E=McAfee;i=\"6500,9779,10585\"; a=\"799339298\"", "E=Sophos;i=\"5.96,314,1665471600\"; d=\"scan'208\";a=\"799339298\"" ], "From": "Hongbo Li <hongbox.li@intel.com>", "To": "dts@dpdk.org", "Cc": "Hongbo Li <hongbox.li@intel.com>", "Subject": "[dts][PATCH V3 7/8] tests/checksum_offload: split performance plan\n and suite", "Date": "Wed, 11 Jan 2023 00:44:30 +0800", "Message-Id": "<20230110164431.19390-8-hongbox.li@intel.com>", "X-Mailer": "git-send-email 2.17.1", "In-Reply-To": "<20230110164431.19390-1-hongbox.li@intel.com>", "References": "<20230110164431.19390-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 tests/TestSuite_checksum_offload.py | 54 --\n tests/TestSuite_perf_checksum_offload.py | 624 +++++++++++++++++++++++\n 2 files changed, 624 insertions(+), 54 deletions(-)\n create mode 100644 tests/TestSuite_perf_checksum_offload.py", "diff": "diff --git a/tests/TestSuite_checksum_offload.py b/tests/TestSuite_checksum_offload.py\nindex 0214231c..9ba06a19 100644\n--- a/tests/TestSuite_checksum_offload.py\n+++ b/tests/TestSuite_checksum_offload.py\n@@ -756,60 +756,6 @@ class TestChecksumOffload(TestCase):\n \n self.result_table_add(result)\n \n- def test_perf_checksum_throughtput(self):\n- \"\"\"\n- Test checksum offload performance.\n- \"\"\"\n- # Verify that enough ports are available\n- self.verify(len(self.dut_ports) >= 2, \"Insufficient ports for testing\")\n- self.dut.send_expect(\"quit\", \"#\")\n-\n- # sizes = [64, 128, 256, 512, 1024]\n- sizes = [64, 128]\n- pkts = {\n- \"IP/UDP\": 'Ether(dst=\"%s\", src=\"52:00:00:00:00:00\")/IP()/UDP()/(\"X\"*(%d-46))',\n- \"IP/TCP\": 'Ether(dst=\"%s\", src=\"52:00:00:00:00:00\")/IP()/TCP()/(\"X\"*(%d-58))',\n- \"IP/SCTP\": 'Ether(dst=\"%s\", src=\"52:00:00:00:00:00\")/IP()/SCTP()/(\"X\"*(%d-50+2))',\n- \"IPv6/UDP\": 'Ether(dst=\"%s\", src=\"52:00:00:00:00:00\")/IPv6()/UDP()/(\"X\"* (lambda x: x - 66 if x > 66 else 0)(%d))',\n- \"IPv6/TCP\": 'Ether(dst=\"%s\", src=\"52:00:00:00:00:00\")/IPv6()/TCP()/(\"X\"* (lambda x: x - 78 if x > 78 else 0)(%d))',\n- }\n-\n- if self.kdriver in DRIVER_TEST_LACK_CAPA[\"sctp_tx_offload\"]:\n- del pkts[\"IP/SCTP\"]\n-\n- lcore = \"1S/2C/1T\"\n- portMask = utils.create_mask([self.dut_ports[0], self.dut_ports[1]])\n- for mode in [\"sw\", \"hw\"]:\n- self.logger.info(\"%s performance\" % mode)\n- tblheader = [\"Ports\", \"S/C/T\", \"Packet Type\", \"Mode\"]\n- for size in sizes:\n- tblheader.append(\"%sB mpps\" % str(size))\n- tblheader.append(\"%sB %% \" % str(size))\n- self.result_table_create(tblheader)\n- self.pmdout.start_testpmd(\n- lcore,\n- \"--portmask=%s\" % self.portMask\n- + \" --enable-rx-cksum \"\n- + \"--port-topology=loop\",\n- socket=self.ports_socket,\n- )\n-\n- self.dut.send_expect(\"set fwd csum\", \"testpmd> \")\n- if mode == \"hw\":\n- self.checksum_enablehw(self.dut_ports[0])\n- self.checksum_enablehw(self.dut_ports[1])\n- else:\n- self.checksum_enablesw(self.dut_ports[0])\n- self.checksum_enablesw(self.dut_ports[1])\n-\n- self.dut.send_expect(\"start\", \"testpmd> \", 3)\n- for ptype in list(pkts.keys()):\n- self.benchmark(lcore, ptype, mode, pkts[ptype], sizes, self.nic)\n-\n- self.dut.send_expect(\"stop\", \"testpmd> \")\n- self.dut.send_expect(\"quit\", \"#\", 10)\n- self.result_table_print()\n-\n def test_hardware_checksum_check_ip_rx(self):\n self.tester.send_expect(\"scapy\", \">>>\")\n self.checksum_enablehw(self.dut_ports[0])\ndiff --git a/tests/TestSuite_perf_checksum_offload.py b/tests/TestSuite_perf_checksum_offload.py\nnew file mode 100644\nindex 00000000..a2288613\n--- /dev/null\n+++ b/tests/TestSuite_perf_checksum_offload.py\n@@ -0,0 +1,624 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2010-2014 Intel Corporation\n+# Copyright(c) 2018-2019 The University of New Hampshire\n+#\n+\n+\"\"\"\n+DPDK Test suite.\n+\n+Test support of RX/TX Checksum Offload Features by Poll Mode Drivers.\n+\n+\"\"\"\n+\n+import os\n+import re\n+import subprocess\n+import time\n+from typing import List, Pattern, Tuple, Union\n+\n+from scapy.layers.inet import IP, TCP, UDP\n+from scapy.layers.inet6 import IPv6\n+from scapy.layers.l2 import GRE, Ether\n+from scapy.layers.sctp import SCTP\n+from scapy.layers.vxlan import VXLAN\n+from scapy.packet import Raw\n+from scapy.utils import rdpcap, wrpcap\n+\n+import framework.packet as packet\n+import framework.utils as utils\n+from framework.exception import VerifyFailure\n+from framework.pktgen import PacketGeneratorHelper\n+from framework.pmd_output import PmdOutput\n+from framework.rst import RstReport\n+from framework.settings import FOLDERS\n+from framework.test_capabilities import DRIVER_TEST_LACK_CAPA\n+from framework.test_case import TestCase\n+\n+l3_proto_classes = [IP, IPv6]\n+\n+l4_proto_classes = [\n+ UDP,\n+ TCP,\n+]\n+\n+tunnelling_proto_classes = [\n+ VXLAN,\n+ GRE,\n+]\n+\n+l3_protos = [\"IP\", \"IPv6\"]\n+\n+l4_protos = [\n+ \"UDP\",\n+ \"TCP\",\n+ \"SCTP\",\n+]\n+\n+\n+class TestChecksumOffload(TestCase):\n+ def set_up_all(self):\n+ \"\"\"\n+ Run at the start of each test suite.\n+ Checksum offload prerequisites.\n+ \"\"\"\n+ # Based on h/w type, choose how many ports to use\n+ self.dut_ports = self.dut.get_ports(self.nic)\n+ # Verify that enough ports are available\n+ self.verify(len(self.dut_ports) >= 1, \"Insufficient ports for testing\")\n+ self.pmdout: PmdOutput = PmdOutput(self.dut)\n+ self.portMask = utils.create_mask([self.dut_ports[0]])\n+ self.ports_socket = self.dut.get_numa_id(self.dut_ports[0])\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+ # log debug used\n+ self.count = 0\n+\n+ def set_up(self):\n+ \"\"\"\n+ Run before each test case.\n+ \"\"\"\n+ self.pmdout.start_testpmd(\n+ \"Default\",\n+ \"--portmask=%s \" % (self.portMask)\n+ + \" --enable-rx-cksum \"\n+ + \"--port-topology=loop\",\n+ socket=self.ports_socket,\n+ )\n+ self.dut.send_expect(\"set verbose 1\", \"testpmd>\")\n+ self.dut.send_expect(\"set fwd csum\", \"testpmd>\")\n+ self.dut.send_expect(\"csum mac-swap off 0\", \"testpmd>\")\n+\n+ def checksum_enablehw(self, port):\n+ self.dut.send_expect(\"port stop all\", \"testpmd>\")\n+ self.dut.send_expect(\"rx_vxlan_port add 4789 0 \", \"testpmd>\")\n+ self.dut.send_expect(\"csum set ip hw %d\" % port, \"testpmd>\")\n+ self.dut.send_expect(\"csum set udp hw %d\" % port, \"testpmd>\")\n+ self.dut.send_expect(\"csum set tcp hw %d\" % port, \"testpmd>\")\n+ self.dut.send_expect(\"csum set sctp hw %d\" % port, \"testpmd>\")\n+ self.dut.send_expect(\"csum set outer-ip hw %d\" % port, \"testpmd>\")\n+ self.dut.send_expect(\"csum set outer-udp hw %d\" % port, \"testpmd>\")\n+ self.dut.send_expect(\"csum parse-tunnel on %d\" % port, \"testpmd>\")\n+ self.dut.send_expect(\"port start all\", \"testpmd>\")\n+\n+ def checksum_enablesw(self, port):\n+ self.dut.send_expect(\"port stop all\", \"testpmd>\")\n+ self.dut.send_expect(\"csum set ip sw %d\" % port, \"testpmd>\")\n+ self.dut.send_expect(\"csum set udp sw %d\" % port, \"testpmd>\")\n+ self.dut.send_expect(\"csum set tcp sw %d\" % port, \"testpmd>\")\n+ self.dut.send_expect(\"csum set sctp sw %d\" % port, \"testpmd>\")\n+ self.dut.send_expect(\"port start all\", \"testpmd>\")\n+\n+ def get_chksum_values(self, packets_expected):\n+ \"\"\"\n+ Validate the checksum flags.\n+ \"\"\"\n+ checksum_pattern = re.compile(\"chksum.*=.*(0x[0-9a-z]+)\")\n+\n+ chksum = dict()\n+\n+ self.tester.send_expect(\"scapy\", \">>> \")\n+\n+ for packet_type in list(packets_expected.keys()):\n+ self.tester.send_expect(\"p = %s\" % packets_expected[packet_type], \">>>\")\n+ out = self.tester.send_command(\"p.show2()\", timeout=1)\n+ chksums = checksum_pattern.findall(out)\n+ chksum[packet_type] = chksums\n+\n+ self.tester.send_expect(\"exit()\", \"#\")\n+\n+ return chksum\n+\n+ def checksum_valid_flags(self, packets_sent, flag):\n+ \"\"\"\n+ Sends packets and check the checksum valid-flags.\n+ \"\"\"\n+ self.dut.send_expect(\"start\", \"testpmd>\")\n+ tx_interface = self.tester.get_interface(\n+ self.tester.get_local_port(self.dut_ports[0])\n+ )\n+ for packet_type in list(packets_sent.keys()):\n+ self.pkt = packet.Packet(pkt_str=packets_sent[packet_type])\n+ self.pkt.send_pkt(self.tester, tx_interface, count=4)\n+ out = self.dut.get_session_output(timeout=1)\n+ lines = out.split(\"\\r\\n\")\n+\n+ # collect the checksum result\n+ for line in lines:\n+ line = line.strip()\n+ if len(line) != 0 and line.startswith(\"rx\"):\n+ # IPv6 don't be checksum, so always show \"GOOD\"\n+ if packet_type.startswith(\"IPv6\"):\n+ if \"RTE_MBUF_F_RX_L4_CKSUM\" not in line:\n+ self.verify(0, \"There is no checksum flags appeared!\")\n+ else:\n+ if flag == 1:\n+ self.verify(\n+ \"RTE_MBUF_F_RX_L4_CKSUM_GOOD\" in line,\n+ \"Packet Rx L4 checksum valid-flags error!\",\n+ )\n+ elif flag == 0:\n+ self.verify(\n+ \"RTE_MBUF_F_RX_L4_CKSUM_BAD\" in line\n+ or \"RTE_MBUF_F_RX_L4_CKSUM_UNKNOWN\" in line,\n+ \"Packet Rx L4 checksum valid-flags error!\",\n+ )\n+ else:\n+ if \"RTE_MBUF_F_RX_L4_CKSUM\" not in line:\n+ self.verify(0, \"There is no L4 checksum flags appeared!\")\n+ elif \"RTE_MBUF_F_RX_IP_CKSUM\" not in line:\n+ self.verify(0, \"There is no IP checksum flags appeared!\")\n+ else:\n+ if flag == 1:\n+ self.verify(\n+ \"RTE_MBUF_F_RX_L4_CKSUM_GOOD\" in line,\n+ \"Packet Rx L4 checksum valid-flags error!\",\n+ )\n+ self.verify(\n+ \"RTE_MBUF_F_RX_IP_CKSUM_GOOD\" in line,\n+ \"Packet Rx IP checksum valid-flags error!\",\n+ )\n+ elif flag == 0:\n+ self.verify(\n+ \"RTE_MBUF_F_RX_L4_CKSUM_BAD\" in line\n+ or \"RTE_MBUF_F_RX_L4_CKSUM_UNKNOWN\" in line,\n+ \"Packet Rx L4 checksum valid-flags error!\",\n+ )\n+ self.verify(\n+ \"RTE_MBUF_F_RX_IP_CKSUM_BAD\" in line,\n+ \"Packet Rx IP checksum valid-flags error!\",\n+ )\n+\n+ self.dut.send_expect(\"stop\", \"testpmd>\")\n+\n+ def checksum_validate(self, packets_sent, packets_expected):\n+ \"\"\"\n+ Validate the checksum.\n+ \"\"\"\n+ tx_interface = self.tester.get_interface(\n+ self.tester.get_local_port(self.dut_ports[0])\n+ )\n+ rx_interface = self.tester.get_interface(\n+ self.tester.get_local_port(self.dut_ports[0])\n+ )\n+\n+ sniff_src = \"52:00:00:00:00:00\"\n+ result = dict()\n+\n+ chksum = self.get_chksum_values(packets_expected)\n+ inst = self.tester.tcpdump_sniff_packets(\n+ intf=rx_interface,\n+ count=len(packets_sent) * 4,\n+ filters=[{\"layer\": \"ether\", \"config\": {\"src\": sniff_src}}],\n+ )\n+\n+ self.pkt = packet.Packet()\n+ for packet_type in list(packets_sent.keys()):\n+ self.pkt.append_pkt(packets_sent[packet_type])\n+ self.pkt.send_pkt(crb=self.tester, tx_port=tx_interface, count=4)\n+\n+ p = self.tester.load_tcpdump_sniff_packets(inst)\n+ nr_packets = len(p)\n+ print(p)\n+ packets_received = [\n+ p[i].sprintf(\"%IP.chksum%;%TCP.chksum%;%UDP.chksum%;%SCTP.chksum%\")\n+ for i in range(nr_packets)\n+ ]\n+ print(len(packets_sent), len(packets_received))\n+ self.verify(\n+ len(packets_sent) * 4 == len(packets_received), \"Unexpected Packets Drop\"\n+ )\n+\n+ for packet_received in packets_received:\n+ (\n+ ip_checksum,\n+ tcp_checksum,\n+ udp_checksum,\n+ sctp_checksum,\n+ ) = packet_received.split(\";\")\n+\n+ packet_type = \"\"\n+ l4_checksum = \"\"\n+ if tcp_checksum != \"??\":\n+ packet_type = \"TCP\"\n+ l4_checksum = tcp_checksum\n+ elif udp_checksum != \"??\":\n+ packet_type = \"UDP\"\n+ l4_checksum = udp_checksum\n+ elif sctp_checksum != \"??\":\n+ packet_type = \"SCTP\"\n+ l4_checksum = sctp_checksum\n+\n+ if ip_checksum != \"??\":\n+ packet_type = \"IP/\" + packet_type\n+ if chksum[packet_type] != [ip_checksum, l4_checksum]:\n+ result[packet_type] = packet_type + \" checksum error\"\n+ else:\n+ packet_type = \"IPv6/\" + packet_type\n+ if chksum[packet_type] != [l4_checksum]:\n+ result[packet_type] = packet_type + \" checksum error\"\n+\n+ return result\n+\n+ def send_scapy_packet(self, packet: str):\n+ itf = self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0]))\n+\n+ self.tester.scapy_foreground()\n+ self.tester.scapy_append(f'sendp({packet}, iface=\"{itf}\")')\n+ return self.tester.scapy_execute()\n+\n+ def get_pkt_rx_l4_cksum(self, testpmd_output: str) -> bool:\n+ return self.checksum_flags_are_good(\"RTE_MBUF_F_RX_L4_CKSUM_\", testpmd_output)\n+\n+ def get_pkt_rx_ip_cksum(self, testpmd_output: str) -> bool:\n+ return self.checksum_flags_are_good(\"RTE_MBUF_F_RX_IP_CKSUM_\", testpmd_output)\n+\n+ def send_pkt_expect_good_bad_from_flag(\n+ self, pkt_str: str, flag: str, test_name: str, should_pass: bool = True\n+ ):\n+ self.pmdout.get_output(timeout=1) # Remove any old output\n+ self.scapy_exec(f\"sendp({pkt_str}, iface=iface)\")\n+ testpmd_output: str = self.pmdout.get_output(timeout=1)\n+ self.verify(\n+ flag in testpmd_output,\n+ f\"Flag {flag[:-1]} not found for test {test_name}, please run test_rx_checksum_valid_flags.\",\n+ )\n+ self.verify(\n+ (flag + \"UNKNOWN\") not in testpmd_output,\n+ f\"Flag {flag[:-1]} was found to be unknown for test {test_name}, indicating a possible lack of support\",\n+ )\n+ if should_pass:\n+ if flag + \"GOOD\" in testpmd_output:\n+ return\n+ else: # flag + \"BAD\" in testpmd_output\n+ self.verify(\n+ False, f\"{flag}BAD was found in output, expecting {flag}GOOD.\"\n+ )\n+ else:\n+ if flag + \"BAD\" in testpmd_output:\n+ return\n+ else: # flag + \"GOOD\" in testpmd_output\n+ self.verify(\n+ False, f\"{flag}GOOD was found in output, expecting {flag}BAD.\"\n+ )\n+\n+ def send_pkt_expect_good_bad_from_flag_catch_failure(\n+ self, pkt_str: str, flag: str, test_name: str, should_pass: bool = True\n+ ) -> Union[VerifyFailure, None]:\n+ try:\n+ self.send_pkt_expect_good_bad_from_flag(\n+ pkt_str, flag, test_name, should_pass=should_pass\n+ )\n+ except VerifyFailure as vf:\n+ return vf\n+\n+ return None\n+\n+ def validate_checksum(self, pkt, pkt_type, inner_flag=False) -> bool:\n+ \"\"\"\n+ @param pkt: The packet to validate the checksum of.\n+ @return: Whether the checksum was valid.\n+ \"\"\"\n+ if pkt is None:\n+ return False\n+ for i in range(0, len(l3_protos)):\n+ if l3_protos[i] in pkt:\n+ l3 = l3_protos[i]\n+ for j in range(0, len(l4_protos)):\n+ if l4_protos[j] in pkt:\n+ layer = l4_proto_classes[j]\n+ csum = pkt[layer].chksum\n+ if csum is None:\n+ csum = 0\n+ del pkt[layer].chksum\n+ # Converting it to raw will calculate the checksum\n+ correct_csum = layer(bytes(Raw(pkt[layer]))).chksum\n+ if correct_csum == csum:\n+ # checksum value is correct\n+ return False\n+ else:\n+ if inner_flag:\n+ print(\n+ \"{} pkg[{}] VXLAN/{}/{} inner checksum {} is not correct {}\".format(\n+ pkt_type,\n+ self.count,\n+ l3,\n+ l4_protos[j],\n+ hex(correct_csum),\n+ hex(csum),\n+ )\n+ )\n+ else:\n+ print(\n+ \"{} pkg[{}] {}/{} outer checksum {} is not correct {}\".format(\n+ pkt_type,\n+ self.count,\n+ l3,\n+ l4_protos[j],\n+ hex(correct_csum),\n+ hex(csum),\n+ )\n+ )\n+ return True\n+ return False\n+\n+ def scapy_exec(self, cmd: str, timeout=1) -> str:\n+ return self.tester.send_expect(cmd, \">>>\", timeout=timeout)\n+\n+ def get_packets(self, dut_mac, tester_mac):\n+ eth = Ether(dst=dut_mac, src=tester_mac)\n+ packets = []\n+ checksum_options = (\n+ {},\n+ {\"chksum\": 0xF},\n+ )\n+ # Untunneled\n+ for l3 in l3_proto_classes:\n+ for l4 in l4_proto_classes:\n+ for chksum in checksum_options:\n+ # The packet's data can be used to identify how the packet was constructed so avoid any issues with\n+ # ordering\n+ pkt = eth / l3() / l4(**chksum) / (b\"X\" * 48)\n+ # Prevents the default behavior which adds DNS headers\n+ if l4 == UDP:\n+ pkt[UDP].dport, pkt[UDP].sport = 1001, 1001\n+ packets.append(pkt)\n+\n+ # Tunneled\n+ # VXLAN\n+ for l3 in l3_proto_classes:\n+ for l4 in l4_proto_classes:\n+ for outer_arg in checksum_options:\n+ for inner_arg in checksum_options:\n+ pkt = (\n+ eth\n+ / l3()\n+ / UDP(**outer_arg)\n+ / VXLAN()\n+ / Ether()\n+ / l3()\n+ / l4(**inner_arg)\n+ / (b\"Y\" * 48)\n+ )\n+ # Prevents the default behavior which adds DNS headers\n+ if l4 == UDP:\n+ pkt[VXLAN][UDP].dport, pkt[VXLAN][UDP].sport = 1001, 1001\n+ packets.append(pkt)\n+ # GRE\n+ for l3 in l3_proto_classes:\n+ for l4 in l4_proto_classes:\n+ for chksum in checksum_options:\n+ pkt = eth / l3() / GRE() / l3() / l4(**chksum) / (b\"Z\" * 48)\n+ # Prevents the default behavior which adds DNS headers\n+ if l4 == UDP:\n+ pkt[GRE][UDP].dport, pkt[GRE][UDP].sport = 1001, 1001\n+ packets.append(pkt)\n+\n+ return packets\n+\n+ def send_tx_package(\n+ self, packet_file_path, capture_file_path, packets, iface, dut_mac\n+ ):\n+ if os.path.isfile(capture_file_path):\n+ os.remove(capture_file_path)\n+ src_mac = \"52:00:00:00:00:00\"\n+ self.tester.send_expect(\n+ f\"tcpdump -i '{iface}' ether src {src_mac} -s 0 -w {capture_file_path} -Q in &\",\n+ \"# \",\n+ )\n+\n+ if os.path.isfile(packet_file_path):\n+ os.remove(packet_file_path)\n+ wrpcap(packet_file_path, packets)\n+ self.tester.session.copy_file_to(packet_file_path, packet_file_path)\n+\n+ # send packet\n+ self.tester.send_expect(\"scapy\", \">>>\")\n+ self.scapy_exec(f\"packets = rdpcap('{packet_file_path}')\")\n+ for i in range(0, len(packets)):\n+ self.scapy_exec(f\"packets[{i}].show\")\n+ self.scapy_exec(f\"sendp(packets[{i}], iface='{iface}')\")\n+ self.pmdout.get_output(timeout=0.5)\n+ self.dut.send_expect(\n+ \"show port stats {}\".format(self.dut_ports[0]), \"testpmd>\"\n+ )\n+ self.tester.send_expect(\"quit()\", \"# \")\n+\n+ time.sleep(1)\n+ self.tester.send_expect(\"killall tcpdump\", \"#\")\n+ time.sleep(1)\n+ self.tester.send_expect('echo \"Cleaning buffer\"', \"#\")\n+ time.sleep(1)\n+ return\n+\n+ def validate_packet_list_checksums(self, packets):\n+ error_messages = []\n+ untunnelled_error_message = (\n+ f\"un-tunneled checksum state for pkg[%s] with a invalid checksum.\"\n+ )\n+ vxlan_error_message = (\n+ f\"VXLAN tunnelled checksum state for pkg[%s] with a invalid checksum.\"\n+ )\n+ gre_error_message = (\n+ f\"GRE tunnelled checksum state for pkg[%s] with a invalid checksum.\"\n+ )\n+\n+ for packet in packets:\n+ self.count = self.count + 1\n+ payload: str\n+ # try:\n+ payload = packet[Raw].load.decode(\"utf-8\")\n+ # # This error usually happens with tunneling protocols, and means that an additional cast is needed\n+ # except UnicodeDecodeError:\n+ # for proto in tunnelling_proto_classes:\n+ if \"X\" in payload:\n+ if self.validate_checksum(packet, \"un-tunneled\"):\n+ error_messages.append(untunnelled_error_message % self.count)\n+ elif \"Y\" in payload:\n+ if self.validate_checksum(\n+ packet[VXLAN][Ether], \"VXLAN\", inner_flag=True\n+ ):\n+ error_messages.append(vxlan_error_message % self.count)\n+ # Intel® Ethernet 700 Series not support outer udp checksum\n+ if self.is_eth_series_nic(700):\n+ continue\n+ if self.validate_checksum(packet, \"VXLAN\"):\n+ error_messages.append(vxlan_error_message % self.count)\n+ elif \"Z\" in payload:\n+ if self.validate_checksum(packet, \"GRE\"):\n+ error_messages.append(gre_error_message % self.count)\n+ return error_messages\n+\n+ #\n+ #\n+ #\n+ # Test Cases\n+ #\n+ def benchmark(self, lcore, ptype, mode, flow_format, size_list, nic):\n+ \"\"\"\n+ Test ans report checksum offload performance for given parameters.\n+ \"\"\"\n+ Bps = dict()\n+ Pps = dict()\n+ Pct = dict()\n+ dmac = self.dut.get_mac_address(self.dut_ports[0])\n+ dmac1 = self.dut.get_mac_address(self.dut_ports[1])\n+\n+ result = [2, lcore, ptype, mode]\n+ for size in size_list:\n+ flow = flow_format % (dmac, size)\n+ pcap = os.sep.join([self.output_path, \"test.pcap\"])\n+ self.tester.scapy_append('wrpcap(\"%s\", [%s])' % (pcap, flow))\n+ self.tester.scapy_execute()\n+ flow = flow_format % (dmac1, size)\n+ pcap = os.sep.join([self.output_path, \"test1.pcap\"])\n+ self.tester.scapy_append('wrpcap(\"%s\", [%s])' % (pcap, flow))\n+ self.tester.scapy_execute()\n+\n+ tgenInput = []\n+ pcap = os.sep.join([self.output_path, \"test.pcap\"])\n+ tgenInput.append(\n+ (\n+ self.tester.get_local_port(self.dut_ports[0]),\n+ self.tester.get_local_port(self.dut_ports[1]),\n+ pcap,\n+ )\n+ )\n+ pcap = os.sep.join([self.output_path, \"test1.pcap\"])\n+ tgenInput.append(\n+ (\n+ self.tester.get_local_port(self.dut_ports[1]),\n+ self.tester.get_local_port(self.dut_ports[0]),\n+ pcap,\n+ )\n+ )\n+\n+ # clear streams before add new streams\n+ self.tester.pktgen.clear_streams()\n+ # create an instance to set stream field setting\n+ # Moved here because it messes with the ability of the functional tests to use scapy.\n+ self.pktgen_helper = PacketGeneratorHelper()\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+ self.verify(Pps[str(size)] > 0, \"No traffic detected\")\n+ Pps[str(size)] /= 1e6\n+ Pct[str(size)] = (Pps[str(size)] * 100) / self.wirespeed(self.nic, size, 2)\n+\n+ result.append(Pps[str(size)])\n+ result.append(Pct[str(size)])\n+\n+ self.result_table_add(result)\n+\n+ def test_perf_checksum_throughtput(self):\n+ \"\"\"\n+ Test checksum offload performance.\n+ \"\"\"\n+ # Verify that enough ports are available\n+ self.verify(len(self.dut_ports) >= 2, \"Insufficient ports for testing\")\n+ self.dut.send_expect(\"quit\", \"#\")\n+\n+ # sizes = [64, 128, 256, 512, 1024]\n+ sizes = [64, 128]\n+ pkts = {\n+ \"IP/UDP\": 'Ether(dst=\"%s\", src=\"52:00:00:00:00:00\")/IP()/UDP()/(\"X\"*(%d-46))',\n+ \"IP/TCP\": 'Ether(dst=\"%s\", src=\"52:00:00:00:00:00\")/IP()/TCP()/(\"X\"*(%d-58))',\n+ \"IP/SCTP\": 'Ether(dst=\"%s\", src=\"52:00:00:00:00:00\")/IP()/SCTP()/(\"X\"*(%d-50+2))',\n+ \"IPv6/UDP\": 'Ether(dst=\"%s\", src=\"52:00:00:00:00:00\")/IPv6()/UDP()/(\"X\"* (lambda x: x - 66 if x > 66 else 0)(%d))',\n+ \"IPv6/TCP\": 'Ether(dst=\"%s\", src=\"52:00:00:00:00:00\")/IPv6()/TCP()/(\"X\"* (lambda x: x - 78 if x > 78 else 0)(%d))',\n+ }\n+\n+ if self.kdriver in DRIVER_TEST_LACK_CAPA[\"sctp_tx_offload\"]:\n+ del pkts[\"IP/SCTP\"]\n+\n+ lcore = \"1S/2C/1T\"\n+ portMask = utils.create_mask([self.dut_ports[0], self.dut_ports[1]])\n+ for mode in [\"sw\", \"hw\"]:\n+ self.logger.info(\"%s performance\" % mode)\n+ tblheader = [\"Ports\", \"S/C/T\", \"Packet Type\", \"Mode\"]\n+ for size in sizes:\n+ tblheader.append(\"%sB mpps\" % str(size))\n+ tblheader.append(\"%sB %% \" % str(size))\n+ self.result_table_create(tblheader)\n+ self.pmdout.start_testpmd(\n+ lcore,\n+ \"--portmask=%s\" % self.portMask\n+ + \" --enable-rx-cksum \"\n+ + \"--port-topology=loop\",\n+ socket=self.ports_socket,\n+ )\n+\n+ self.dut.send_expect(\"set fwd csum\", \"testpmd> \")\n+ if mode == \"hw\":\n+ self.checksum_enablehw(self.dut_ports[0])\n+ self.checksum_enablehw(self.dut_ports[1])\n+ else:\n+ self.checksum_enablesw(self.dut_ports[0])\n+ self.checksum_enablesw(self.dut_ports[1])\n+\n+ self.dut.send_expect(\"start\", \"testpmd> \", 3)\n+ for ptype in list(pkts.keys()):\n+ self.benchmark(lcore, ptype, mode, pkts[ptype], sizes, self.nic)\n+\n+ self.dut.send_expect(\"stop\", \"testpmd> \")\n+ self.dut.send_expect(\"quit\", \"#\", 10)\n+ self.result_table_print()\n+\n+ def tear_down(self):\n+ \"\"\"\n+ Run after each test case.\n+ \"\"\"\n+ self.dut.send_expect(\"quit\", \"#\")\n+\n+ def tear_down_all(self):\n+ \"\"\"\n+ Run after each test suite.\n+ \"\"\"\n+ pass\n", "prefixes": [ "V3", "7/8" ] }{ "id": 121779, "url": "