DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH v1 0/2] dts: port over unified packet type suite
@ 2024-08-23 19:34 Dean Marx
  2024-08-23 19:34 ` [PATCH v1 1/2] dts: add VXLAN port method to testpmd shell Dean Marx
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Dean Marx @ 2024-08-23 19:34 UTC (permalink / raw)
  To: probb, npratte, jspewock, luca.vizzarro, yoan.picchi,
	Honnappa.Nagarahalli, paul.szczepanek, juraj.linkes
  Cc: dev, Dean Marx

Port over unified packet type flag testing suite from old DTS.
According to DPDK documentation, each Poll Mode Driver should reserve 32
bits of packet headers for unified packet type flags. These flags serve
as an identifier for user applications, and are divided into 
subcategories: L2, L3, L4, tunnel, inner L2, inner L3, and inner L4 types.
This suite verifies the ability of the driver to recognize these types.

v1:
*Removed NVGRE test cases due to lack of SCAPY support
*Removed redundant packet flag verification in certain test cases

Dean Marx (2):
  dts: add VXLAN port method to testpmd shell
  dts: port over unified packet suite

 dts/framework/config/conf_yaml_schema.json    |   3 +-
 dts/framework/remote_session/testpmd_shell.py |  47 ++++
 dts/tests/TestSuite_uni_pkt.py                | 230 +++++++++++++++++-
 3 files changed, 266 insertions(+), 14 deletions(-)

-- 
2.44.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v1 1/2] dts: add VXLAN port method to testpmd shell
  2024-08-23 19:34 [PATCH v1 0/2] dts: port over unified packet type suite Dean Marx
@ 2024-08-23 19:34 ` Dean Marx
  2024-08-23 19:34 ` [PATCH v1 2/2] dts: port over unified packet suite Dean Marx
  2024-08-23 20:22 ` [PATCH v2 0/2] dts: port over unified packet type suite Dean Marx
  2 siblings, 0 replies; 8+ messages in thread
From: Dean Marx @ 2024-08-23 19:34 UTC (permalink / raw)
  To: probb, npratte, jspewock, luca.vizzarro, yoan.picchi,
	Honnappa.Nagarahalli, paul.szczepanek, juraj.linkes
  Cc: dev, Dean Marx

Add rx_vxlan_port add/rm method to testpmd shell for adding
or removing a vxlan id to the specified port filter list.
Port over set_verbose method from queue start/stop suite.

Signed-off-by: Dean Marx <dmarx@iol.unh.edu>
---
 dts/framework/remote_session/testpmd_shell.py | 47 +++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py
index 7d0b5a374c..d802338d59 100644
--- a/dts/framework/remote_session/testpmd_shell.py
+++ b/dts/framework/remote_session/testpmd_shell.py
@@ -1207,6 +1207,53 @@ def extract_verbose_output(output: str) -> list[TestPmdVerbosePacket]:
             out.append(TestPmdVerbosePacket.parse(f"{prev_header}\n{match.group('PACKET')}"))
         return out
 
+    def set_verbose(self, level: int, verify: bool = True) -> None:
+        """Set debug verbosity level.
+
+        Args:
+            level:
+                0: silent except for error.
+                1: fully verbose except for Tx packets.
+                2: fully verbose except for Rx packets.
+                >2: fully verbose.
+            verify: if :data:`True` an additional command will be sent to verify that verbose level
+                is properly set. Defaults to :data:`True`.
+
+        Raises:
+            InteractiveCommandExecutionError: If `verify` is :data:`True` and verbose level
+            is not correctly set.
+        """
+        verbose_output = self.send_command(f"set verbose {level}")
+        if verify:
+            if "Change verbose level" not in verbose_output:
+                self._logger.debug(f"Failed to set verbose level to {level}: \n{verbose_output}")
+                raise InteractiveCommandExecutionError(
+                    f"Testpmd failed to set verbose level to {level}."
+                )
+
+    def rx_vxlan(self, vxlan_id: int, port_id: int, add: bool, verify: bool = True) -> None:
+        """Add or remove vxlan id to filter list.
+
+        Args:
+            vxlan_id: Number of VXLAN ID to add to port filter list.
+            port_id: Number of port to add VXLAN ID to.
+            add: If :data:`True`, adds specified VXLAN ID, otherwise removes it.
+            verify: If :data:`True`, the output of the command is checked to verify
+                the VXLAN ID was successfully added/removed from the port.
+
+        Raises:
+            InteractiveCommandExecutionError: If `verify` is :data:`True` and VXLAN ID
+                is not successfully added or removed.
+        """
+        action = "add" if add else "rm"
+        vxlan_output = self.send_command(f"rx_vxlan_port {action} {vxlan_id} {port_id}")
+        if verify:
+            if "udp tunneling add error" in vxlan_output:
+                self._logger.debug(f"Failed to set VXLAN:\n{vxlan_output}")
+                raise InteractiveCommandExecutionError(
+                    f"Failed to set VXLAN:\n{vxlan_output}"
+                )
+
     def _close(self) -> None:
         """Overrides :meth:`~.interactive_shell.close`."""
         self.stop()
-- 
2.44.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v1 2/2] dts: port over unified packet suite
  2024-08-23 19:34 [PATCH v1 0/2] dts: port over unified packet type suite Dean Marx
  2024-08-23 19:34 ` [PATCH v1 1/2] dts: add VXLAN port method to testpmd shell Dean Marx
@ 2024-08-23 19:34 ` Dean Marx
  2024-08-23 20:22 ` [PATCH v2 0/2] dts: port over unified packet type suite Dean Marx
  2 siblings, 0 replies; 8+ messages in thread
From: Dean Marx @ 2024-08-23 19:34 UTC (permalink / raw)
  To: probb, npratte, jspewock, luca.vizzarro, yoan.picchi,
	Honnappa.Nagarahalli, paul.szczepanek, juraj.linkes
  Cc: dev, Dean Marx

Port over unified packet testing suite from old DTS. This suite
tests the ability of the PMD to recognize valid or invalid packet flags.

Depends-on: Patch-143033
("dts: add text parser for testpmd verbose output")
Depends-on: Patch-142691
("dts: add send_packets to test suites and rework
packet addressing")

Signed-off-by: Dean Marx <dmarx@iol.unh.edu>
---
 dts/framework/config/conf_yaml_schema.json |   3 +-
 dts/tests/TestSuite_uni_pkt.py             | 230 +++++++++++++++++++--
 2 files changed, 219 insertions(+), 14 deletions(-)

diff --git a/dts/framework/config/conf_yaml_schema.json b/dts/framework/config/conf_yaml_schema.json
index f02a310bb5..03ee0ce68a 100644
--- a/dts/framework/config/conf_yaml_schema.json
+++ b/dts/framework/config/conf_yaml_schema.json
@@ -187,7 +187,8 @@
       "enum": [
         "hello_world",
         "os_udp",
-        "pmd_buffer_scatter"
+        "pmd_buffer_scatter",
+        "uni_pkt"
       ]
     },
     "test_target": {
diff --git a/dts/tests/TestSuite_uni_pkt.py b/dts/tests/TestSuite_uni_pkt.py
index 11a856031c..78e0800092 100644
--- a/dts/tests/TestSuite_uni_pkt.py
+++ b/dts/tests/TestSuite_uni_pkt.py
@@ -3,24 +3,36 @@
 
 """Unified packet type flag testing suite.
 
-This suite verifies the ability of the PMD to recognize what
-type of packet is being sent to the DUT and print out the type
-for each layer in verbose output.
+According to DPDK documentation, each Poll Mode Driver should reserve 32 bits
+of packet headers for unified packet type flags. These flags serve as an
+identifier for user applications, and are divided into subcategories:
+L2, L3, L4, tunnel, inner L2, inner L3, and inner L4 types.
+This suite verifies the ability of the driver to recognize these types.
 
 """
 
-from typing import List
+from scapy.packet import Packet  # type: ignore[import-untyped]
+from scapy.layers.vxlan import VXLAN  # type: ignore[import-untyped]
+from scapy.contrib.nsh import NSH  # type: ignore[import-untyped]
+from scapy.layers.inet import IP, ICMP, TCP, UDP, GRE  # type: ignore[import-untyped]
+from scapy.layers.l2 import Ether, ARP  # type: ignore[import-untyped]
+from scapy.packet import Raw
+from scapy.layers.inet6 import IPv6, IPv6ExtHdrFragment  # type: ignore[import-untyped]
+from scapy.layers.sctp import SCTP, SCTPChunkData  # type: ignore[import-untyped]
 
-from scapy.packet import Packet
-from scapy.layers.inet import IP  # type: ignore[import-untyped]
-from scapy.layers.l2 import Ether  # type: ignore[import-untyped]
-from scapy.packet import Raw  # type: ignore[import-untyped]
-
-from framework.remote_session.testpmd_shell import SimpleForwardingModes, TestPmdShell
+from framework.remote_session.testpmd_shell import (SimpleForwardingModes, TestPmdShell,
+                                                    RtePTypes, TestPmdVerbosePacket)
 from framework.test_suite import TestSuite
 
+
 class TestUniPkt(TestSuite):
-    """DPDK Unified packet test suite."""
+    """DPDK Unified packet test suite.
+
+    This testing suite uses testpmd's verbose output hardware/software
+    packet type field to verify the ability of the driver to recognize
+    unified packet types when receiving different packets.
+
+    """
 
     def set_up_suite(self) -> None:
         """Set up the test suite.
@@ -30,5 +42,197 @@ def set_up_suite(self) -> None:
         """
         self.verify(len(self._port_links) > 1, "Not enough ports")
 
-    def send_packet_and_verify_flags(self, expected_flags: List[RtePTypes], packet: Packet) -> None:
-        """"""
\ No newline at end of file
+    def send_packet_and_verify_flags(self, expected_flags: list[RtePTypes],
+                                     packet: Packet, testpmd: TestPmdShell) -> None:
+        """Sends a packet to the DUT and verifies the verbose ptype flags."""
+        testpmd.start()
+        self.send_packet_and_capture(packet=packet)
+        verbose_output = testpmd.extract_verbose_output(testpmd.stop())
+        valid = self.check_for_matching_packet(output=verbose_output, flags=expected_flags)
+        self.verify(valid, f"Packet type flag did not match the expected flag: {expected_flags}.")
+
+    def check_for_matching_packet(self, output: list[TestPmdVerbosePacket],
+                                  flags: list[RtePTypes]) -> bool:
+        """Returns :data:`True` if the packet in verbose output contains all specified flags."""
+        for packet in output:
+            if packet.dst_mac == "00:00:00:00:00:01":
+                for flag in flags:
+                    if (flag not in packet.hw_ptype and flag not in packet.sw_ptype):
+                        return False
+        return True
+
+    def setup_session(self, testpmd: TestPmdShell) -> None:
+        """Sets the forwarding and verbose mode of each test case interactive shell session."""
+        testpmd.set_forward_mode(SimpleForwardingModes.rxonly)
+        testpmd.set_verbose(level=1)
+
+    def test_l2_packet_detect(self) -> None:
+        """Verify the correct flags are shown in verbose output when sending L2 packets."""
+        mac_id = "00:00:00:00:00:01"
+        packet_list = [
+            Ether(dst=mac_id, type=0x88f7) / Raw(),
+            Ether(dst=mac_id) / ARP() / Raw()
+        ]
+        flag_list = [
+            [RtePTypes.L2_ETHER_TIMESYNC],
+            [RtePTypes.L2_ETHER_ARP]
+        ]
+        with TestPmdShell(node=self.sut_node) as testpmd:
+            self.setup_session(testpmd=testpmd)
+            for i in range(0, len(packet_list)):
+                self.send_packet_and_verify_flags(expected_flags=flag_list[i],
+                                                  packet=packet_list[i], testpmd=testpmd)
+
+    def test_l3_l4_packet_detect(self) -> None:
+        """Verify correct flags are shown in the verbose output when sending IP/L4 packets."""
+        mac_id = "00:00:00:00:00:01"
+        packet_list = [
+            Ether(dst=mac_id) / IP() / Raw(),
+            Ether(dst=mac_id) / IP() / UDP() / Raw(),
+            Ether(dst=mac_id) / IP() / TCP() / Raw(),
+            Ether(dst=mac_id) / IP() / SCTP() / Raw(),
+            Ether(dst=mac_id) / IP() / ICMP() / Raw(),
+            Ether(dst=mac_id) / IP(frag=5) / TCP() / Raw(),
+        ]
+        flag_list = [
+            [RtePTypes.L3_IPV4, RtePTypes.L2_ETHER],
+            [RtePTypes.L4_UDP],
+            [RtePTypes.L4_TCP],
+            [RtePTypes.L4_SCTP],
+            [RtePTypes.L4_ICMP],
+            [RtePTypes.L4_FRAG, RtePTypes.L3_IPV4_EXT_UNKNOWN, RtePTypes.L2_ETHER]
+        ]
+        with TestPmdShell(node=self.sut_node) as testpmd:
+            self.setup_session(testpmd=testpmd)
+            for i in range(0, len(packet_list)):
+                self.send_packet_and_verify_flags(expected_flags=flag_list[i],
+                                                  packet=packet_list[i], testpmd=testpmd)
+
+    def test_ipv6_l4_packet_detect(self) -> None:
+        """Verify correct flags are shown in the verbose output when sending IPv6/L4 packets."""
+        mac_id = "00:00:00:00:00:01"
+        packet_list = [
+            Ether(dst=mac_id) / IPv6() / Raw(),
+            Ether(dst=mac_id) / IPv6() / UDP() / Raw(),
+            Ether(dst=mac_id) / IPv6() / TCP() / Raw(),
+            Ether(dst=mac_id) / IPv6() / IPv6ExtHdrFragment() / Raw()
+        ]
+        flag_list = [
+            [RtePTypes.L2_ETHER, RtePTypes.L3_IPV6],
+            [RtePTypes.L4_UDP],
+            [RtePTypes.L4_TCP],
+            [RtePTypes.L3_IPV6_EXT_UNKNOWN]
+        ]
+        with TestPmdShell(node=self.sut_node) as testpmd:
+            self.setup_session(testpmd=testpmd)
+            for i in range(0, len(packet_list)):
+                self.send_packet_and_verify_flags(expected_flags=flag_list[i],
+                                                  packet=packet_list[i], testpmd=testpmd)
+
+    def test_l3_tunnel_packet_detect(self) -> None:
+        """Verify correct flags are shown in the verbose output when sending IPv6/L4 packets."""
+        mac_id = "00:00:00:00:00:01"
+        packet_list = [
+            Ether(dst=mac_id) / IP() / IP(frag=5) / UDP() / Raw(),
+            Ether(dst=mac_id) / IP() / IP() / Raw(),
+            Ether(dst=mac_id) / IP() / IP() / UDP() / Raw(),
+            Ether(dst=mac_id) / IP() / IP() / TCP() / Raw(),
+            Ether(dst=mac_id) / IP() / IP() / SCTP() / Raw(),
+            Ether(dst=mac_id) / IP() / IP() / ICMP() / Raw(),
+            Ether(dst=mac_id) / IP() / IPv6() / IPv6ExtHdrFragment() / Raw()
+        ]
+        flag_list = [
+            [RtePTypes.TUNNEL_IP, RtePTypes.L3_IPV4_EXT_UNKNOWN, RtePTypes.INNER_L4_FRAG],
+            [RtePTypes.TUNNEL_IP, RtePTypes.INNER_L4_NONFRAG],
+            [RtePTypes.TUNNEL_IP, RtePTypes.INNER_L4_UDP],
+            [RtePTypes.TUNNEL_IP, RtePTypes.INNER_L4_TCP],
+            [RtePTypes.TUNNEL_IP, RtePTypes.INNER_L4_SCTP],
+            [RtePTypes.TUNNEL_IP, RtePTypes.INNER_L4_ICMP],
+            [RtePTypes.TUNNEL_IP, RtePTypes.INNER_L3_IPV6_EXT_UNKNOWN, RtePTypes.INNER_L4_FRAG]
+        ]
+        with TestPmdShell(node=self.sut_node) as testpmd:
+            self.setup_session(testpmd=testpmd)
+            for i in range(0, len(packet_list)):
+                self.send_packet_and_verify_flags(expected_flags=flag_list[i],
+                                                  packet=packet_list[i], testpmd=testpmd)
+
+    def test_gre_tunnel_packet_detect(self) -> None:
+        """Verify the correct flags are shown in the verbose output when sending GRE packets."""
+        mac_id = "00:00:00:00:00:01"
+        packet_list = [
+            Ether(dst=mac_id) / IP() / GRE() / IP(frag=5) / Raw(),
+            Ether(dst=mac_id) / IP() / GRE() / IP() / Raw(),
+            Ether(dst=mac_id) / IP() / GRE() / IP() / UDP() / Raw(),
+            Ether(dst=mac_id) / IP() / GRE() / IP() / TCP() / Raw(),
+            Ether(dst=mac_id) / IP() / GRE() / IP() / SCTP() / Raw(),
+            Ether(dst=mac_id) / IP() / GRE() / IP() / ICMP() / Raw()
+        ]
+        flag_list = [
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_FRAG, RtePTypes.INNER_L3_IPV4_EXT_UNKNOWN],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_NONFRAG],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_UDP],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_TCP],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_SCTP],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_ICMP]
+        ]
+        with TestPmdShell(node=self.sut_node) as testpmd:
+            self.setup_session(testpmd=testpmd)
+            for i in range(0, len(packet_list)):
+                self.send_packet_and_verify_flags(expected_flags=flag_list[i],
+                                                  packet=packet_list[i], testpmd=testpmd)
+
+    def test_vxlan_tunnel_packet_detect(self) -> None:
+        """Verify the correct flags are shown in the verbose output when sending VXLAN packets."""
+        mac_id = "00:00:00:00:00:01"
+        packet_list = [
+            Ether(dst=mac_id) / IP() / UDP() / VXLAN() / Ether() / IP(frag=5) / Raw(),
+            Ether(dst=mac_id) / IP() / UDP() / VXLAN() / Ether() / IP() / Raw(),
+            Ether(dst=mac_id) / IP() / UDP() / VXLAN() / Ether() / IP() / UDP() / Raw(),
+            Ether(dst=mac_id) / IP() / UDP() / VXLAN() / Ether() / IP() / TCP() / Raw(),
+            Ether(dst=mac_id) / IP() / UDP() / VXLAN() / Ether() / IP() / SCTP() / Raw(),
+            Ether(dst=mac_id) / IP() / UDP() / VXLAN() / Ether() / IP() / ICMP() / Raw(),
+            (Ether(dst=mac_id) / IP() / UDP() / VXLAN() / Ether()
+             / IPv6() / IPv6ExtHdrFragment() / Raw())
+        ]
+        flag_list = [
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_FRAG, RtePTypes.INNER_L3_IPV4_EXT_UNKNOWN],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_NONFRAG],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_UDP],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_TCP],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_SCTP],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_ICMP],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L3_IPV6_EXT_UNKNOWN, RtePTypes.INNER_L4_FRAG]
+        ]
+        with TestPmdShell(node=self.sut_node) as testpmd:
+            self.setup_session(testpmd=testpmd)
+            testpmd.rx_vxlan(vxlan_id=4789, port_id=0, add=True)
+            for i in range(0, len(packet_list)):
+                self.send_packet_and_verify_flags(expected_flags=flag_list[i],
+                                                  packet=packet_list[i], testpmd=testpmd)
+
+    def test_nsh_packet_detect(self) -> None:
+        """Verify the correct flags are shown in the verbose output when sending NSH packets."""
+        mac_id = "00:00:00:00:00:01"
+        packet_list = [
+            Ether(dst=mac_id, type=0x894f) / NSH() / IP(),
+            Ether(dst=mac_id, type=0x894f) / NSH() / IP() / ICMP(),
+            Ether(dst=mac_id, type=0x894f) / NSH() / IP(frag=1, flags="MF"),
+            Ether(dst=mac_id, type=0x894f) / NSH() / IP() / TCP(),
+            Ether(dst=mac_id, type=0x894f) / NSH() / IP() / UDP(),
+            Ether(dst=mac_id, type=0x894f) / NSH() / IP() / SCTP(tag=1) / SCTPChunkData(data='x'),
+            Ether(dst=mac_id, type=0x894f) / NSH() / IPv6()
+        ]
+        flag_list = [
+            [RtePTypes.L2_ETHER_NSH, RtePTypes.L3_IPV4_EXT_UNKNOWN, RtePTypes.L4_NONFRAG],
+            [RtePTypes.L2_ETHER_NSH, RtePTypes.L3_IPV4_EXT_UNKNOWN, RtePTypes.L4_ICMP],
+            [RtePTypes.L2_ETHER_NSH, RtePTypes.L3_IPV4_EXT_UNKNOWN, RtePTypes.L4_FRAG],
+            [RtePTypes.L2_ETHER_NSH, RtePTypes.L3_IPV4_EXT_UNKNOWN, RtePTypes.L4_TCP],
+            [RtePTypes.L2_ETHER_NSH, RtePTypes.L3_IPV4_EXT_UNKNOWN, RtePTypes.L4_UDP],
+            [RtePTypes.L2_ETHER_NSH, RtePTypes.L3_IPV4_EXT_UNKNOWN, RtePTypes.L4_SCTP],
+            [RtePTypes.L2_ETHER_NSH, RtePTypes.L3_IPV6_EXT_UNKNOWN, RtePTypes.L4_NONFRAG],
+        ]
+        with TestPmdShell(node=self.sut_node) as testpmd:
+            self.setup_session(testpmd=testpmd)
+            for i in range(0, len(packet_list)):
+                self.send_packet_and_verify_flags(expected_flags=flag_list[i],
+                                                  packet=packet_list[i], testpmd=testpmd)
-- 
2.44.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 0/2] dts: port over unified packet type suite
  2024-08-23 19:34 [PATCH v1 0/2] dts: port over unified packet type suite Dean Marx
  2024-08-23 19:34 ` [PATCH v1 1/2] dts: add VXLAN port method to testpmd shell Dean Marx
  2024-08-23 19:34 ` [PATCH v1 2/2] dts: port over unified packet suite Dean Marx
@ 2024-08-23 20:22 ` Dean Marx
  2024-08-23 20:22   ` [PATCH v2 1/2] dts: add VXLAN port method to testpmd shell Dean Marx
  2024-08-23 20:22   ` [PATCH v2 2/2] dts: port over unified packet suite Dean Marx
  2 siblings, 2 replies; 8+ messages in thread
From: Dean Marx @ 2024-08-23 20:22 UTC (permalink / raw)
  To: probb, npratte, jspewock, luca.vizzarro, yoan.picchi,
	Honnappa.Nagarahalli, paul.szczepanek, juraj.linkes
  Cc: dev, Dean Marx

Port over unified packet type flag testing suite from old DTS.
According to DPDK documentation, each Poll Mode Driver should reserve 32
bits of packet headers for unified packet type flags. These flags serve
as an identifier for user applications, and are divided into 
subcategories: L2, L3, L4, tunnel, inner L2, inner L3, and inner L4 types.
This suite verifies the ability of the driver to recognize these types.

-------
v1:
*Removed NVGRE test cases due to lack of SCAPY support
*Removed redundant packet flag verification in certain test cases

v2:
*Fixed git history issue causing apply patch failure
*Removed set_verbose duplication and added dependency

Dean Marx (2):
  dts: add VXLAN port method to testpmd shell
  dts: port over unified packet suite

 dts/framework/remote_session/testpmd_shell.py |  23 ++
 dts/tests/TestSuite_uni_pkt.py                | 239 ++++++++++++++++++
 2 files changed, 262 insertions(+)
 create mode 100644 dts/tests/TestSuite_uni_pkt.py

-- 
2.44.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/2] dts: add VXLAN port method to testpmd shell
  2024-08-23 20:22 ` [PATCH v2 0/2] dts: port over unified packet type suite Dean Marx
@ 2024-08-23 20:22   ` Dean Marx
  2024-09-04 19:23     ` Jeremy Spewock
  2024-08-23 20:22   ` [PATCH v2 2/2] dts: port over unified packet suite Dean Marx
  1 sibling, 1 reply; 8+ messages in thread
From: Dean Marx @ 2024-08-23 20:22 UTC (permalink / raw)
  To: probb, npratte, jspewock, luca.vizzarro, yoan.picchi,
	Honnappa.Nagarahalli, paul.szczepanek, juraj.linkes
  Cc: dev, Dean Marx

Add rx_vxlan_port add/rm method to testpmd shell for adding
or removing a vxlan id to the specified port filter list.

Signed-off-by: Dean Marx <dmarx@iol.unh.edu>
---
 dts/framework/remote_session/testpmd_shell.py | 23 +++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py
index 43e9f56517..00b75954ef 100644
--- a/dts/framework/remote_session/testpmd_shell.py
+++ b/dts/framework/remote_session/testpmd_shell.py
@@ -806,6 +806,29 @@ def show_port_stats(self, port_id: int) -> TestPmdPortStats:
 
         return TestPmdPortStats.parse(output)
 
+    def rx_vxlan(self, vxlan_id: int, port_id: int, add: bool, verify: bool = True) -> None:
+        """Add or remove vxlan id to filter list.
+
+        Args:
+            vxlan_id: Number of VXLAN ID to add to port filter list.
+            port_id: Number of port to add VXLAN ID to.
+            add: If :data:`True`, adds specified VXLAN ID, otherwise removes it.
+            verify: If :data:`True`, the output of the command is checked to verify
+                the VXLAN ID was successfully added/removed from the port.
+
+        Raises:
+            InteractiveCommandExecutionError: If `verify` is :data:`True` and VXLAN ID
+                is not successfully added or removed.
+        """
+        action = "add" if add else "rm"
+        vxlan_output = self.send_command(f"rx_vxlan_port {action} {vxlan_id} {port_id}")
+        if verify:
+            if "udp tunneling add error" in vxlan_output:
+                self._logger.debug(f"Failed to set VXLAN:\n{vxlan_output}")
+                raise InteractiveCommandExecutionError(
+                    f"Failed to set VXLAN:\n{vxlan_output}"
+                )
+
     def _close(self) -> None:
         """Overrides :meth:`~.interactive_shell.close`."""
         self.stop()
-- 
2.44.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 2/2] dts: port over unified packet suite
  2024-08-23 20:22 ` [PATCH v2 0/2] dts: port over unified packet type suite Dean Marx
  2024-08-23 20:22   ` [PATCH v2 1/2] dts: add VXLAN port method to testpmd shell Dean Marx
@ 2024-08-23 20:22   ` Dean Marx
  2024-09-04 19:23     ` Jeremy Spewock
  1 sibling, 1 reply; 8+ messages in thread
From: Dean Marx @ 2024-08-23 20:22 UTC (permalink / raw)
  To: probb, npratte, jspewock, luca.vizzarro, yoan.picchi,
	Honnappa.Nagarahalli, paul.szczepanek, juraj.linkes
  Cc: dev, Dean Marx

Port over unified packet testing suite from old DTS. This suite
tests the ability of the PMD to recognize valid or invalid packet flags.

Depends-on: Patch-143033
("dts: add text parser for testpmd verbose output")
Depends-on: Patch-142691
("dts: add send_packets to test suites and rework
packet addressing")
Depends-on: Patch-143005
("dts: add functions to testpmd shell")

Signed-off-by: Dean Marx <dmarx@iol.unh.edu>
---
 dts/tests/TestSuite_uni_pkt.py | 239 +++++++++++++++++++++++++++++++++
 1 file changed, 239 insertions(+)
 create mode 100644 dts/tests/TestSuite_uni_pkt.py

diff --git a/dts/tests/TestSuite_uni_pkt.py b/dts/tests/TestSuite_uni_pkt.py
new file mode 100644
index 0000000000..90a8f35fa1
--- /dev/null
+++ b/dts/tests/TestSuite_uni_pkt.py
@@ -0,0 +1,239 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2024 University of New Hampshire
+
+"""Unified packet type flag testing suite.
+
+According to DPDK documentation, each Poll Mode Driver should reserve 32 bits
+of packet headers for unified packet type flags. These flags serve as an
+identifier for user applications, and are divided into subcategories:
+L2, L3, L4, tunnel, inner L2, inner L3, and inner L4 types.
+This suite verifies the ability of the driver to recognize these types.
+
+"""
+
+from scapy.packet import Packet  # type: ignore[import-untyped]
+from scapy.layers.vxlan import VXLAN  # type: ignore[import-untyped]
+from scapy.contrib.nsh import NSH  # type: ignore[import-untyped]
+from scapy.layers.inet import IP, ICMP, TCP, UDP, GRE  # type: ignore[import-untyped]
+from scapy.layers.l2 import Ether, ARP  # type: ignore[import-untyped]
+from scapy.packet import Raw
+from scapy.layers.inet6 import IPv6, IPv6ExtHdrFragment  # type: ignore[import-untyped]
+from scapy.layers.sctp import SCTP, SCTPChunkData  # type: ignore[import-untyped]
+
+from framework.remote_session.testpmd_shell import (SimpleForwardingModes, TestPmdShell,
+                                                    RtePTypes, TestPmdVerbosePacket)
+from framework.test_suite import TestSuite
+
+
+class TestUniPkt(TestSuite):
+    """DPDK Unified packet test suite.
+
+    This testing suite uses testpmd's verbose output hardware/software
+    packet type field to verify the ability of the driver to recognize
+    unified packet types when receiving different packets.
+
+    """
+
+    def set_up_suite(self) -> None:
+        """Set up the test suite.
+
+        Setup:
+            Verify that at least two ports are open for session.
+        """
+        self.verify(len(self._port_links) > 1, "Not enough ports")
+
+    def send_packet_and_verify_flags(self, expected_flags: list[RtePTypes],
+                                     packet: Packet, testpmd: TestPmdShell) -> None:
+        """Sends a packet to the DUT and verifies the verbose ptype flags."""
+        testpmd.start()
+        self.send_packet_and_capture(packet=packet)
+        verbose_output = testpmd.extract_verbose_output(testpmd.stop())
+        valid = self.check_for_matching_packet(output=verbose_output, flags=expected_flags)
+        self.verify(valid, f"Packet type flag did not match the expected flag: {expected_flags}.")
+
+    def check_for_matching_packet(self, output: list[TestPmdVerbosePacket],
+                                  flags: list[RtePTypes]) -> bool:
+        """Returns :data:`True` if the packet in verbose output contains all specified flags."""
+        for packet in output:
+            if packet.dst_mac == "00:00:00:00:00:01":
+                for flag in flags:
+                    if (flag not in packet.hw_ptype and flag not in packet.sw_ptype):
+                        return False
+        return True
+
+    def setup_session(self, testpmd: TestPmdShell) -> None:
+        """Sets the forwarding and verbose mode of each test case interactive shell session."""
+        testpmd.set_forward_mode(SimpleForwardingModes.rxonly)
+        testpmd.set_verbose(level=1)
+
+    def test_l2_packet_detect(self) -> None:
+        """Verify the correct flags are shown in verbose output when sending L2 packets."""
+        mac_id = "00:00:00:00:00:01"
+        packet_list = [
+            Ether(dst=mac_id, type=0x88f7) / Raw(),
+            Ether(dst=mac_id) / ARP() / Raw()
+        ]
+        flag_list = [
+            [RtePTypes.L2_ETHER_TIMESYNC],
+            [RtePTypes.L2_ETHER_ARP]
+        ]
+        with TestPmdShell(node=self.sut_node) as testpmd:
+            self.setup_session(testpmd=testpmd)
+            for i in range(0, len(packet_list)):
+                self.send_packet_and_verify_flags(expected_flags=flag_list[i],
+                                                  packet=packet_list[i], testpmd=testpmd)
+
+
+    def test_l3_l4_packet_detect(self) -> None:
+        """Verify correct flags are shown in the verbose output when sending IP/L4 packets."""
+        mac_id = "00:00:00:00:00:01"
+        packet_list = [
+            Ether(dst=mac_id) / IP() / Raw(),
+            Ether(dst=mac_id) / IP() / UDP() / Raw(),
+            Ether(dst=mac_id) / IP() / TCP() / Raw(),
+            Ether(dst=mac_id) / IP() / SCTP() / Raw(),
+            Ether(dst=mac_id) / IP() / ICMP() / Raw(),
+            Ether(dst=mac_id) / IP(frag=5) / TCP() / Raw(),
+        ]
+        flag_list = [
+            [RtePTypes.L3_IPV4, RtePTypes.L2_ETHER],
+            [RtePTypes.L4_UDP],
+            [RtePTypes.L4_TCP],
+            [RtePTypes.L4_SCTP],
+            [RtePTypes.L4_ICMP],
+            [RtePTypes.L4_FRAG, RtePTypes.L3_IPV4_EXT_UNKNOWN, RtePTypes.L2_ETHER]
+        ]
+        with TestPmdShell(node=self.sut_node) as testpmd:
+            self.setup_session(testpmd=testpmd)
+            for i in range(0, len(packet_list)):
+                self.send_packet_and_verify_flags(expected_flags=flag_list[i],
+                                                  packet=packet_list[i], testpmd=testpmd)
+
+    def test_ipv6_l4_packet_detect(self) -> None:
+        """Verify correct flags are shown in the verbose output when sending IPv6/L4 packets."""
+        mac_id = "00:00:00:00:00:01"
+        packet_list = [
+            Ether(dst=mac_id) / IPv6() / Raw(),
+            Ether(dst=mac_id) / IPv6() / UDP() / Raw(),
+            Ether(dst=mac_id) / IPv6() / TCP() / Raw(),
+            Ether(dst=mac_id) / IPv6() / IPv6ExtHdrFragment() / Raw()
+        ]
+        flag_list = [
+            [RtePTypes.L2_ETHER, RtePTypes.L3_IPV6],
+            [RtePTypes.L4_UDP],
+            [RtePTypes.L4_TCP],
+            [RtePTypes.L3_IPV6_EXT_UNKNOWN]
+        ]
+        with TestPmdShell(node=self.sut_node) as testpmd:
+            self.setup_session(testpmd=testpmd)
+            for i in range(0, len(packet_list)):
+                self.send_packet_and_verify_flags(expected_flags=flag_list[i],
+                                                  packet=packet_list[i], testpmd=testpmd)
+
+    def test_l3_tunnel_packet_detect(self) -> None:
+        """Verify correct flags are shown in the verbose output when sending IPv6/L4 packets."""
+        mac_id = "00:00:00:00:00:01"
+        packet_list = [
+            Ether(dst=mac_id) / IP() / IP(frag=5) / UDP() / Raw(),
+            Ether(dst=mac_id) / IP() / IP() / Raw(),
+            Ether(dst=mac_id) / IP() / IP() / UDP() / Raw(),
+            Ether(dst=mac_id) / IP() / IP() / TCP() / Raw(),
+            Ether(dst=mac_id) / IP() / IP() / SCTP() / Raw(),
+            Ether(dst=mac_id) / IP() / IP() / ICMP() / Raw(),
+            Ether(dst=mac_id) / IP() / IPv6() / IPv6ExtHdrFragment() / Raw()
+        ]
+        flag_list = [
+            [RtePTypes.TUNNEL_IP, RtePTypes.L3_IPV4_EXT_UNKNOWN, RtePTypes.INNER_L4_FRAG],
+            [RtePTypes.TUNNEL_IP, RtePTypes.INNER_L4_NONFRAG],
+            [RtePTypes.TUNNEL_IP, RtePTypes.INNER_L4_UDP],
+            [RtePTypes.TUNNEL_IP, RtePTypes.INNER_L4_TCP],
+            [RtePTypes.TUNNEL_IP, RtePTypes.INNER_L4_SCTP],
+            [RtePTypes.TUNNEL_IP, RtePTypes.INNER_L4_ICMP],
+            [RtePTypes.TUNNEL_IP, RtePTypes.INNER_L3_IPV6_EXT_UNKNOWN, RtePTypes.INNER_L4_FRAG]
+        ]
+        with TestPmdShell(node=self.sut_node) as testpmd:
+            self.setup_session(testpmd=testpmd)
+            for i in range(0, len(packet_list)):
+                self.send_packet_and_verify_flags(expected_flags=flag_list[i],
+                                                  packet=packet_list[i], testpmd=testpmd)
+
+    def test_gre_tunnel_packet_detect(self) -> None:
+        """Verify the correct flags are shown in the verbose output when sending GRE packets."""
+        mac_id = "00:00:00:00:00:01"
+        packet_list = [
+            Ether(dst=mac_id) / IP() / GRE() / IP(frag=5) / Raw(),
+            Ether(dst=mac_id) / IP() / GRE() / IP() / Raw(),
+            Ether(dst=mac_id) / IP() / GRE() / IP() / UDP() / Raw(),
+            Ether(dst=mac_id) / IP() / GRE() / IP() / TCP() / Raw(),
+            Ether(dst=mac_id) / IP() / GRE() / IP() / SCTP() / Raw(),
+            Ether(dst=mac_id) / IP() / GRE() / IP() / ICMP() / Raw()
+        ]
+        flag_list = [
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_FRAG, RtePTypes.INNER_L3_IPV4_EXT_UNKNOWN],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_NONFRAG],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_UDP],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_TCP],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_SCTP],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_ICMP]
+        ]
+        with TestPmdShell(node=self.sut_node) as testpmd:
+            self.setup_session(testpmd=testpmd)
+            for i in range(0, len(packet_list)):
+                self.send_packet_and_verify_flags(expected_flags=flag_list[i],
+                                                  packet=packet_list[i], testpmd=testpmd)
+
+    def test_vxlan_tunnel_packet_detect(self) -> None:
+        """Verify the correct flags are shown in the verbose output when sending VXLAN packets."""
+        mac_id = "00:00:00:00:00:01"
+        packet_list = [
+            Ether(dst=mac_id) / IP() / UDP() / VXLAN() / Ether() / IP(frag=5) / Raw(),
+            Ether(dst=mac_id) / IP() / UDP() / VXLAN() / Ether() / IP() / Raw(),
+            Ether(dst=mac_id) / IP() / UDP() / VXLAN() / Ether() / IP() / UDP() / Raw(),
+            Ether(dst=mac_id) / IP() / UDP() / VXLAN() / Ether() / IP() / TCP() / Raw(),
+            Ether(dst=mac_id) / IP() / UDP() / VXLAN() / Ether() / IP() / SCTP() / Raw(),
+            Ether(dst=mac_id) / IP() / UDP() / VXLAN() / Ether() / IP() / ICMP() / Raw(),
+            (Ether(dst=mac_id) / IP() / UDP() / VXLAN() / Ether()
+             / IPv6() / IPv6ExtHdrFragment() / Raw())
+        ]
+        flag_list = [
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_FRAG, RtePTypes.INNER_L3_IPV4_EXT_UNKNOWN],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_NONFRAG],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_UDP],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_TCP],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_SCTP],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L4_ICMP],
+            [RtePTypes.TUNNEL_GRENAT, RtePTypes.INNER_L3_IPV6_EXT_UNKNOWN, RtePTypes.INNER_L4_FRAG]
+        ]
+        with TestPmdShell(node=self.sut_node) as testpmd:
+            self.setup_session(testpmd=testpmd)
+            testpmd.rx_vxlan(vxlan_id=4789, port_id=0, add=True)
+            for i in range(0, len(packet_list)):
+                self.send_packet_and_verify_flags(expected_flags=flag_list[i],
+                                                  packet=packet_list[i], testpmd=testpmd)
+
+    def test_nsh_packet_detect(self) -> None:
+        """Verify the correct flags are shown in the verbose output when sending NSH packets."""
+        mac_id = "00:00:00:00:00:01"
+        packet_list = [
+            Ether(dst=mac_id, type=0x894f) / NSH() / IP(),
+            Ether(dst=mac_id, type=0x894f) / NSH() / IP() / ICMP(),
+            Ether(dst=mac_id, type=0x894f) / NSH() / IP(frag=1, flags="MF"),
+            Ether(dst=mac_id, type=0x894f) / NSH() / IP() / TCP(),
+            Ether(dst=mac_id, type=0x894f) / NSH() / IP() / UDP(),
+            Ether(dst=mac_id, type=0x894f) / NSH() / IP() / SCTP(tag=1) / SCTPChunkData(data='x'),
+            Ether(dst=mac_id, type=0x894f) / NSH() / IPv6()
+        ]
+        flag_list = [
+            [RtePTypes.L2_ETHER_NSH, RtePTypes.L3_IPV4_EXT_UNKNOWN, RtePTypes.L4_NONFRAG],
+            [RtePTypes.L2_ETHER_NSH, RtePTypes.L3_IPV4_EXT_UNKNOWN, RtePTypes.L4_ICMP],
+            [RtePTypes.L2_ETHER_NSH, RtePTypes.L3_IPV4_EXT_UNKNOWN, RtePTypes.L4_FRAG],
+            [RtePTypes.L2_ETHER_NSH, RtePTypes.L3_IPV4_EXT_UNKNOWN, RtePTypes.L4_TCP],
+            [RtePTypes.L2_ETHER_NSH, RtePTypes.L3_IPV4_EXT_UNKNOWN, RtePTypes.L4_UDP],
+            [RtePTypes.L2_ETHER_NSH, RtePTypes.L3_IPV4_EXT_UNKNOWN, RtePTypes.L4_SCTP],
+            [RtePTypes.L2_ETHER_NSH, RtePTypes.L3_IPV6_EXT_UNKNOWN, RtePTypes.L4_NONFRAG],
+        ]
+        with TestPmdShell(node=self.sut_node) as testpmd:
+            self.setup_session(testpmd=testpmd)
+            for i in range(0, len(packet_list)):
+                self.send_packet_and_verify_flags(expected_flags=flag_list[i],
+                                                  packet=packet_list[i], testpmd=testpmd)
-- 
2.44.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/2] dts: add VXLAN port method to testpmd shell
  2024-08-23 20:22   ` [PATCH v2 1/2] dts: add VXLAN port method to testpmd shell Dean Marx
@ 2024-09-04 19:23     ` Jeremy Spewock
  0 siblings, 0 replies; 8+ messages in thread
From: Jeremy Spewock @ 2024-09-04 19:23 UTC (permalink / raw)
  To: Dean Marx
  Cc: probb, npratte, luca.vizzarro, yoan.picchi, Honnappa.Nagarahalli,
	paul.szczepanek, juraj.linkes, dev

Just a few comments on doc-strings, otherwise:

Reviewed-by: Jeremy Spewock <jspewock@iol.unh.edu>

On Fri, Aug 23, 2024 at 4:22 PM Dean Marx <dmarx@iol.unh.edu> wrote:
>
> Add rx_vxlan_port add/rm method to testpmd shell for adding
> or removing a vxlan id to the specified port filter list.
>
> Signed-off-by: Dean Marx <dmarx@iol.unh.edu>
> ---
>  dts/framework/remote_session/testpmd_shell.py | 23 +++++++++++++++++++
>  1 file changed, 23 insertions(+)
>
> diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py
> index 43e9f56517..00b75954ef 100644
> --- a/dts/framework/remote_session/testpmd_shell.py
> +++ b/dts/framework/remote_session/testpmd_shell.py
> @@ -806,6 +806,29 @@ def show_port_stats(self, port_id: int) -> TestPmdPortStats:
>
>          return TestPmdPortStats.parse(output)
>
> +    def rx_vxlan(self, vxlan_id: int, port_id: int, add: bool, verify: bool = True) -> None:
> +        """Add or remove vxlan id to filter list.

It might read better if you replaced "to" here with "to/from".

> +
> +        Args:
> +            vxlan_id: Number of VXLAN ID to add to port filter list.

This is a little nit-picky, but it might be worth removing "Number of"
here and replacing "add to" with "add to/remove from" so it is "VXLAN
ID to add to/remove from port filter list." just so that it reflects
that you can both add and remove using this method.

> +            port_id: Number of port to add VXLAN ID to.

For this line I might be in favor of simplifying it down to something
like "ID of the port to modify VXLAN filter of." That way it doesn't
need all the slashes to account for both adding and removing.

> +            add: If :data:`True`, adds specified VXLAN ID, otherwise removes it.
> +            verify: If :data:`True`, the output of the command is checked to verify
> +                the VXLAN ID was successfully added/removed from the port.
> +
> +        Raises:
> +            InteractiveCommandExecutionError: If `verify` is :data:`True` and VXLAN ID
> +                is not successfully added or removed.
> +        """
> +        action = "add" if add else "rm"
> +        vxlan_output = self.send_command(f"rx_vxlan_port {action} {vxlan_id} {port_id}")
> +        if verify:
> +            if "udp tunneling add error" in vxlan_output:
> +                self._logger.debug(f"Failed to set VXLAN:\n{vxlan_output}")
> +                raise InteractiveCommandExecutionError(
> +                    f"Failed to set VXLAN:\n{vxlan_output}"
> +                )
> +
>      def _close(self) -> None:
>          """Overrides :meth:`~.interactive_shell.close`."""
>          self.stop()
> --
> 2.44.0
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 2/2] dts: port over unified packet suite
  2024-08-23 20:22   ` [PATCH v2 2/2] dts: port over unified packet suite Dean Marx
@ 2024-09-04 19:23     ` Jeremy Spewock
  0 siblings, 0 replies; 8+ messages in thread
From: Jeremy Spewock @ 2024-09-04 19:23 UTC (permalink / raw)
  To: Dean Marx
  Cc: probb, npratte, luca.vizzarro, yoan.picchi, Honnappa.Nagarahalli,
	paul.szczepanek, juraj.linkes, dev

I just left some general formatting comments and a few idea that I
thought might be helpful, but it looks good to me in general:

Reviewed-by: Jeremy Spewock <jspewock@iol.unh.edu>

On Fri, Aug 23, 2024 at 4:22 PM Dean Marx <dmarx@iol.unh.edu> wrote:
>
> Port over unified packet testing suite from old DTS. This suite
> tests the ability of the PMD to recognize valid or invalid packet flags.
>
> Depends-on: Patch-143033
> ("dts: add text parser for testpmd verbose output")
> Depends-on: Patch-142691
> ("dts: add send_packets to test suites and rework
> packet addressing")
> Depends-on: Patch-143005
> ("dts: add functions to testpmd shell")
>
> Signed-off-by: Dean Marx <dmarx@iol.unh.edu>
> ---
<snip>
> +
> +from scapy.packet import Packet  # type: ignore[import-untyped]
> +from scapy.layers.vxlan import VXLAN  # type: ignore[import-untyped]
> +from scapy.contrib.nsh import NSH  # type: ignore[import-untyped]
> +from scapy.layers.inet import IP, ICMP, TCP, UDP, GRE  # type: ignore[import-untyped]
> +from scapy.layers.l2 import Ether, ARP  # type: ignore[import-untyped]
> +from scapy.packet import Raw

I think this import also needs a type: ignore comment, but regardless
it is probably better to combine it with the other file that imports
from the `scapy.packet` library to keep things concise.

> +from scapy.layers.inet6 import IPv6, IPv6ExtHdrFragment  # type: ignore[import-untyped]
> +from scapy.layers.sctp import SCTP, SCTPChunkData  # type: ignore[import-untyped]
> +
> +from framework.remote_session.testpmd_shell import (SimpleForwardingModes, TestPmdShell,
> +                                                    RtePTypes, TestPmdVerbosePacket)

There isn't anything wrong with breaking lines like this, but it is a
little different than how the formatting script would separate it and
how it is done in other parts of the framework. It might be worth
putting the newline after the opening parenthesis to match how it is
done elsewhere.

> +from framework.test_suite import TestSuite
> +
> +
> +class TestUniPkt(TestSuite):
> +    """DPDK Unified packet test suite.
> +
> +    This testing suite uses testpmd's verbose output hardware/software
> +    packet type field to verify the ability of the driver to recognize
> +    unified packet types when receiving different packets.
> +
> +    """
> +
> +    def set_up_suite(self) -> None:
> +        """Set up the test suite.
> +
> +        Setup:
> +            Verify that at least two ports are open for session.
> +        """
> +        self.verify(len(self._port_links) > 1, "Not enough ports")
> +
> +    def send_packet_and_verify_flags(self, expected_flags: list[RtePTypes],
> +                                     packet: Packet, testpmd: TestPmdShell) -> None:

Same thing here as the comment above, generally these function
definitions elsewhere in the framework will break the lines at the
opening parenthesis and then again before the closing one.

Additionally, something that might save you some space/complexity in
this method is you can combine all of your flags into one rather than
storing them in a list, and compare the combinations rather than
looping through and comparing them one at a time. Since flag values
are really just bytes and combinations of flags are always unique, if
expected_flags were just the type RtePTypes, instead of looping
through all of the individual values you could have your boolean check
be something like:

any(packet.dst_mac == "00:00:00:00:00:01" and (expected_flags in
packet.hw_ptype or expected_flags in packet.sw_ptype) for packet in
verbose_output)

and that "in" statement will check for you that all of the flags that
are part of expected_flags are present in the sw_ptype and hw_ptype
flags.

> +        """Sends a packet to the DUT and verifies the verbose ptype flags."""
> +        testpmd.start()
> +        self.send_packet_and_capture(packet=packet)
> +        verbose_output = testpmd.extract_verbose_output(testpmd.stop())
> +        valid = self.check_for_matching_packet(output=verbose_output, flags=expected_flags)
> +        self.verify(valid, f"Packet type flag did not match the expected flag: {expected_flags}.")
> +
> +    def check_for_matching_packet(self, output: list[TestPmdVerbosePacket],
> +                                  flags: list[RtePTypes]) -> bool:
> +        """Returns :data:`True` if the packet in verbose output contains all specified flags."""
> +        for packet in output:
> +            if packet.dst_mac == "00:00:00:00:00:01":
> +                for flag in flags:
> +                    if (flag not in packet.hw_ptype and flag not in packet.sw_ptype):
> +                        return False
> +        return True

This might just be personal preference too, but I think it is a little
easier to read if methods are defined above the one where they are
used.

> +
> +    def setup_session(self, testpmd: TestPmdShell) -> None:
> +        """Sets the forwarding and verbose mode of each test case interactive shell session."""
> +        testpmd.set_forward_mode(SimpleForwardingModes.rxonly)
> +        testpmd.set_verbose(level=1)
> +
> +    def test_l2_packet_detect(self) -> None:
> +        """Verify the correct flags are shown in verbose output when sending L2 packets."""
> +        mac_id = "00:00:00:00:00:01"
> +        packet_list = [
> +            Ether(dst=mac_id, type=0x88f7) / Raw(),
> +            Ether(dst=mac_id) / ARP() / Raw()
> +        ]
> +        flag_list = [
> +            [RtePTypes.L2_ETHER_TIMESYNC],
> +            [RtePTypes.L2_ETHER_ARP]
> +        ]

I think this idea of having two lists where the indices line up is
very intuitive and I like how it makes things simple to pass to the
send and verify method. One thing that I thought of that could be
interesting (and feel free to not do it this way, I just thought it
was a cool idea so I figured I'd share) is you could make the packets
and the flags a tuple, and then you could just unpack the tuple when
you call the function. The only downside to this is the lines could
get a little long in some of the later test cases because the list of
flags is long, but you might be able to get around that by having a
variable for common flags that are present in items in the list,  and
then just appending to the end of that. Something like:

params_list = [
    (Ether(dst=mac_id, type=0x88f7) / Raw(), RtePTypes.L2_ETHER_TIMESYNC),
    ...
]
with TestPmdShell(node=self.sut_node) as testpmd:
            self.setup_session(testpmd=testpmd)
            for p in params_list:
                self.send_packet_and_verify_flags(*p, testpmd=testpmd)

> +        with TestPmdShell(node=self.sut_node) as testpmd:
> +            self.setup_session(testpmd=testpmd)
> +            for i in range(0, len(packet_list)):
> +                self.send_packet_and_verify_flags(expected_flags=flag_list[i],
> +                                                  packet=packet_list[i], testpmd=testpmd)
> +

Do you think it would be worth splitting this part of creating testpmd
and running the verify function into a helper method so that you don't
have to repeat yourself in these test cases? You could even put it all
in setup_testpmd and just rename it to something like
`run_flag_testing` and have it accept the two lists of packets and
flags as input.

> +
> +    def test_l3_l4_packet_detect(self) -> None:
> +        """Verify correct flags are shown in the verbose output when sending IP/L4 packets."""
> +        mac_id = "00:00:00:00:00:01"
> +        packet_list = [
> +            Ether(dst=mac_id) / IP() / Raw(),
> +            Ether(dst=mac_id) / IP() / UDP() / Raw(),
> +            Ether(dst=mac_id) / IP() / TCP() / Raw(),
> +            Ether(dst=mac_id) / IP() / SCTP() / Raw(),
> +            Ether(dst=mac_id) / IP() / ICMP() / Raw(),
> +            Ether(dst=mac_id) / IP(frag=5) / TCP() / Raw(),
> +        ]
> +        flag_list = [
> +            [RtePTypes.L3_IPV4, RtePTypes.L2_ETHER],

If you decided to make this a flag instead of a list like I had
mentioned above, this line would become:

RtePTypes.L3_IPV4 | RtePTypes.L2_ETHER,

> +            [RtePTypes.L4_UDP],
> +            [RtePTypes.L4_TCP],
> +            [RtePTypes.L4_SCTP],
> +            [RtePTypes.L4_ICMP],
> +            [RtePTypes.L4_FRAG, RtePTypes.L3_IPV4_EXT_UNKNOWN, RtePTypes.L2_ETHER]

And this one would be:

RtePTypes.L4_FRAG | RtePTypes.L3_IPV4_EXT_UNKNOWN | RtePTypes.L2_ETHER

> +        ]
> +        with TestPmdShell(node=self.sut_node) as testpmd:
> +            self.setup_session(testpmd=testpmd)
> +            for i in range(0, len(packet_list)):
> +                self.send_packet_and_verify_flags(expected_flags=flag_list[i],
> +                                                  packet=packet_list[i], testpmd=testpmd)
> +
<snip>
> 2.44.0
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-09-04 19:24 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-08-23 19:34 [PATCH v1 0/2] dts: port over unified packet type suite Dean Marx
2024-08-23 19:34 ` [PATCH v1 1/2] dts: add VXLAN port method to testpmd shell Dean Marx
2024-08-23 19:34 ` [PATCH v1 2/2] dts: port over unified packet suite Dean Marx
2024-08-23 20:22 ` [PATCH v2 0/2] dts: port over unified packet type suite Dean Marx
2024-08-23 20:22   ` [PATCH v2 1/2] dts: add VXLAN port method to testpmd shell Dean Marx
2024-09-04 19:23     ` Jeremy Spewock
2024-08-23 20:22   ` [PATCH v2 2/2] dts: port over unified packet suite Dean Marx
2024-09-04 19:23     ` Jeremy Spewock

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).