<div dir="ltr"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><snip> </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="gmail-im" style="color:rgb(80,0,80)">+This test suite ensures proper and expected behavior of Allowlist <span class="gmail-il">filtering</span> via <span class="gmail-il">mac</span><br>+addresses on devices bound to the Poll Mode Driver. If a packet received on a device<br>+contains a <span class="gmail-il">mac</span> address not contained with its <span class="gmail-il">mac</span> address pool, the packet should<br>+be dropped. Alternatively, if a packet is received that contains a destination <span class="gmail-il">mac</span><br>+within the devices address pool, the packet should be accepted and forwarded. This<br>+behavior should remain consistent across all packets, namely those containing dot1q<br>+tags or otherwise.<br></span></blockquote><div><br></div><div>This is pretty minor but you might want to change "with its <span class="gmail-il">mac</span> address pool" to "within", just</div><div>to stay consistent with the wording in the rest of the suite</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><snip><span class="gmail-im" style="color:rgb(80,0,80)"><br>+        received_packets = [<br>+            packets<br>+            for packets in self.send_packet_and_capture(packet, adjust_addresses=False)<br>+            if hasattr(packets, "load") and "X" * 22 in str(packets.load)<br>+        ]<br></span></blockquote><div><br></div><div>Also Jeremy said he mentioned Juraj's opinion on using Jeremy's method of turning off</div><div>adjust addresses, if you end up doing that just make it depend on this patch:</div><div>patch-1142113 ("add send_packets to test suites and rework<br>packet addressing")<br></div><div> </div><div>Reviewed-by: Dean Marx <<a href="mailto:dmarx@iol.unh.edu" target="_blank">dmarx@iol.unh.edu</a>></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Jul 18, 2024 at 3:40 PM Nicholas Pratte <<a href="mailto:npratte@iol.unh.edu">npratte@iol.unh.edu</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The mac address filter test suite, whose test cases are based on old<br>
DTS's test cases, has been refactored to interface with the new DTS<br>
framework.<br>
<br>
In porting over this test suite into the new framework, some<br>
adjustments were made, namely in the EAL and TestPMD parameter provided<br>
before executing the application. While the original test plan was<br>
referenced, by and large, only for the individual test cases, I'll leave<br>
the parameters the original test plan was asking for below for the sake<br>
of discussion:<br>
<br>
--burst=1 --rxpt=0 --rxht=0 --rxwt=0 --txpt=36 --txht=0 --txwt=0<br>
--txfreet=32 --rxfreet=64 --mbcache=250 --portmask=0x3<br>
<br>
Bugzilla ID: 1454<br>
Signed-off-by: Nicholas Pratte <<a href="mailto:npratte@iol.unh.edu" target="_blank">npratte@iol.unh.edu</a>><br>
<br>
---<br>
v2:<br>
 * Refactored the address pool capacity tests to use all available<br>
   octets in the mac address.<br>
 * Change the payload to 'X' characters instead of 'P' characters.<br>
---<br>
 dts/framework/config/conf_yaml_schema.json |   3 +-<br>
 dts/tests/TestSuite_mac_filter.py          | 223 +++++++++++++++++++++<br>
 2 files changed, 225 insertions(+), 1 deletion(-)<br>
 create mode 100644 dts/tests/TestSuite_mac_filter.py<br>
<br>
diff --git a/dts/framework/config/conf_yaml_schema.json b/dts/framework/config/conf_yaml_schema.json<br>
index f02a310bb5..ad1f3757f7 100644<br>
--- a/dts/framework/config/conf_yaml_schema.json<br>
+++ b/dts/framework/config/conf_yaml_schema.json<br>
@@ -187,7 +187,8 @@<br>
       "enum": [<br>
         "hello_world",<br>
         "os_udp",<br>
-        "pmd_buffer_scatter"<br>
+        "pmd_buffer_scatter",<br>
+        "mac_filter"<br>
       ]<br>
     },<br>
     "test_target": {<br>
diff --git a/dts/tests/TestSuite_mac_filter.py b/dts/tests/TestSuite_mac_filter.py<br>
new file mode 100644<br>
index 0000000000..53a3331224<br>
--- /dev/null<br>
+++ b/dts/tests/TestSuite_mac_filter.py<br>
@@ -0,0 +1,223 @@<br>
+# SPDX-License-Identifier: BSD-3-Clause<br>
+# Copyright(c) 2023-2024 University of New Hampshire<br>
+"""Mac address filtering test suite.<br>
+<br>
+This test suite ensures proper and expected behavior of Allowlist filtering via mac<br>
+addresses on devices bound to the Poll Mode Driver. If a packet received on a device<br>
+contains a mac address not contained with its mac address pool, the packet should<br>
+be dropped. Alternatively, if a packet is received that contains a destination mac<br>
+within the devices address pool, the packet should be accepted and forwarded. This<br>
+behavior should remain consistent across all packets, namely those containing dot1q<br>
+tags or otherwise.<br>
+<br>
+The following test suite assesses behaviors based on the aforementioned logic.<br>
+Additionally, testing is done within the PMD itself to ensure that the mac address<br>
+allow list is behaving as expected.<br>
+"""<br>
+<br>
+from time import sleep<br>
+<br>
+from scapy.layers.inet import IP  # type: ignore[import-untyped]<br>
+from scapy.layers.l2 import Dot1Q, Ether  # type: ignore[import-untyped]<br>
+from scapy.packet import Raw  # type: ignore[import-untyped]<br>
+<br>
+from framework.exception import InteractiveCommandExecutionError<br>
+from framework.remote_session.testpmd_shell import TestPmdShell<br>
+from framework.test_suite import TestSuite<br>
+<br>
+<br>
+class TestMacFilter(TestSuite):<br>
+    """Mac address allowlist filtering test suite.<br>
+<br>
+    Configure mac address filtering on a given port, and test the port's filtering behavior<br>
+    using both a given port's hardware address as well as dummy addresses. If a port accepts<br>
+    a packet that is not contained within its mac address allowlist, then a given test case<br>
+    fails. Alternatively, if a port drops a packet that is designated within its mac address<br>
+    allowlist, a given test case will fail.<br>
+<br>
+    Moreover, a given port should demonstrate proper behavior when bound to the Poll Mode<br>
+    Driver. A port should not have a mac address allowlist that exceeds its designated size.<br>
+    A port's default hardware address should not be removed from its address pool, and invalid<br>
+    addresses should not be included in the allowlist. If a port abides by the above rules, the<br>
+    test case passes.<br>
+    """<br>
+<br>
+    def send_packet_and_verify(<br>
+        self,<br>
+        mac_address: str,<br>
+        add_vlan: bool = False,<br>
+        should_receive: bool = True,<br>
+    ) -> None:<br>
+        """Generate, send, and verify a packet based on specified parameters.<br>
+<br>
+        Test cases within this suite utilize this method to create, send, and verify<br>
+        packets based on criteria relating to the packet's destination mac address,<br>
+        vlan tag, and whether or not the packet should be received or not. Packets<br>
+        are verified using an inserted payload. Assuming the test case expects to<br>
+        receive a specified packet, if the list of received packets contains this<br>
+        payload within any of its packets, the test case passes. Alternatively, if<br>
+        the designed packet should not be received, and the packet payload is not,<br>
+        received, then the test case fails. Each call with this method sends exactly<br>
+        one packet.<br>
+<br>
+        Args:<br>
+            mac_address: The destination mac address of the packet being sent.<br>
+            add_vlan: If :data:'True', add a vlan tag to the packet being sent. The<br>
+                vlan tag will be :data:'2' if the packet should be received and<br>
+                :data:'1' if the packet should not be received but requires a vlan tag.<br>
+            should_receive: If :data:'True', assert whether or not the sent packet<br>
+                has been received. If :data:'False', assert that the send packet was not<br>
+                received. :data:'True' by default<br>
+        """<br>
+        if add_vlan:<br>
+            packet = Ether() / Dot1Q(vlan=2 if should_receive else 1) / IP() / Raw(load="X" * 22)<br>
+        else:<br>
+            packet = Ether() / IP() / Raw(load="X" * 22)<br>
+        packet.dst = mac_address<br>
+        received_packets = [<br>
+            packets<br>
+            for packets in self.send_packet_and_capture(packet, adjust_addresses=False)<br>
+            if hasattr(packets, "load") and "X" * 22 in str(packets.load)<br>
+        ]<br>
+        if should_receive:<br>
+            self.verify(len(received_packets) == 1, "Expected packet not received")<br>
+        else:<br>
+            self.verify(len(received_packets) == 0, "Expected packet received")<br>
+<br>
+    def test_add_remove_mac_addresses(self) -> None:<br>
+        """Assess basic mac addressing filtering functionalities.<br>
+<br>
+        This test case validates for proper behavior of mac address filtering with both<br>
+        a port's default, burned-in mac address, as well as additional mac addresses<br>
+        added to the PMD. Packets should either be received or not received depending on<br>
+        the properties applied to the PMD at any given time.<br>
+<br>
+        Test:<br>
+            Start TestPMD with promiscuous mode.<br>
+            Send a packet with the port's default mac address. (Should receive)<br>
+            Send a packet with fake mac address. (Should not receive)<br>
+            Add fake mac address to the PMD's address pool.<br>
+            Send a packet with the fake mac address to the PMD. (Should receive)<br>
+            Remove the fake mac address from the PMD's address pool.<br>
+            Sent a packet with the fake mac address to the PMD. (Should not receive)<br>
+        """<br>
+        testpmd = TestPmdShell(self.sut_node)<br>
+        testpmd.set_promisc(0, on=False)<br>
+        testpmd.start()<br>
+        mac_address = self._sut_port_ingress.mac_address<br>
+<br>
+        # Send a packet with NIC default mac address<br>
+        self.send_packet_and_verify(mac_address=mac_address, should_receive=True)<br>
+        # Send a packet with different mac address<br>
+        fake_address = "00:00:00:00:00:01"<br>
+        self.send_packet_and_verify(mac_address=fake_address, should_receive=False)<br>
+<br>
+        # Add mac address to pool and rerun tests<br>
+        testpmd.set_mac_addr(0, mac_address=fake_address, add=True)<br>
+        self.send_packet_and_verify(mac_address=fake_address, should_receive=True)<br>
+        testpmd.set_mac_addr(0, mac_address=fake_address, add=False)<br>
+        self.send_packet_and_verify(mac_address=fake_address, should_receive=False)<br>
+        testpmd.close()<br>
+        sleep(6)<br>
+<br>
+    def test_invalid_address(self) -> None:<br>
+        """Assess the behavior of a NIC mac address pool while bound to the PMD.<br>
+<br>
+        An assessment of a NIC's behavior when mounted to a PMD as it relates to mac addresses<br>
+        and address pooling. Devices should not be able to use invalid mac addresses, remove their<br>
+        built-in hardware address, or exceed their address pools.<br>
+<br>
+        Test:<br>
+            Start TestPMD.<br>
+            Attempt to add an invalid mac address. (Should fail)<br>
+            Attempt to remove the device's hardware address with no additional addresses in the<br>
+                address pool. (Should fail)<br>
+            Add a fake mac address to the pool twice in succession. (Should not create any errors)<br>
+            Attempt to remove the device's hardware address with other addresses in the address<br>
+                pool. (Should fail)<br>
+            Determine the device's mac address pool size, and fill the pool with fake addresses.<br>
+            Attempt to add another fake mac address, overloading the address pool. (Should fail)<br>
+        """<br>
+        testpmd = TestPmdShell(self.sut_node)<br>
+        testpmd.start()<br>
+        mac_address = self._sut_port_ingress.mac_address<br>
+        try:<br>
+            testpmd.set_mac_addr(0, "00:00:00:00:00:00", add=True)<br>
+            self.verify(False, "Invalid mac address added.")<br>
+        except InteractiveCommandExecutionError:<br>
+            pass<br>
+        try:<br>
+            testpmd.set_mac_addr(0, mac_address, add=False)<br>
+            self.verify(False, "Default mac address removed.")<br>
+        except InteractiveCommandExecutionError:<br>
+            pass<br>
+        # Should be no errors adding this twice<br>
+        testpmd.set_mac_addr(0, "1" + mac_address[1:], add=True)<br>
+        testpmd.set_mac_addr(0, "1" + mac_address[1:], add=True)<br>
+        # Double check to see if default mac address can be removed<br>
+        try:<br>
+            testpmd.set_mac_addr(0, mac_address, add=False)<br>
+            self.verify(False, "Default mac address removed.")<br>
+        except InteractiveCommandExecutionError:<br>
+            pass<br>
+<br>
+        for i in range(testpmd.show_port_info(0).max_mac_addresses_num - 1):<br>
+            # A0 fake address based on the index 'i'.<br>
+            fake_address = str(hex(i)[2:].zfill(12))<br>
+            # Insert ':' characters every two indexes to create a fake mac address.<br>
+            fake_address = ":".join(fake_address[x : x + 2] for x in range(0, len(fake_address), 2))<br>
+            testpmd.set_mac_addr(0, fake_address, add=True, verify=False)<br>
+        try:<br>
+            testpmd.set_mac_addr(0, "F" + mac_address[1:], add=True)<br>
+            self.verify(False, "Mac address limit exceeded.")<br>
+        except InteractiveCommandExecutionError:<br>
+            pass<br>
+        testpmd.close()<br>
+        sleep(6)<br>
+<br>
+    def test_multicast_filter(self) -> None:<br>
+        """Assess basic multicast address filtering functionalities.<br>
+<br>
+        Ensure that multicast filtering performs as intended when a given device is bound<br>
+        to the PMD, with and without dot1q vlan tagging.<br>
+<br>
+        Test:<br>
+            Start TestPMD with promiscuous mode.<br>
+            Add a fake multicast address to the PMD's multicast address pool.<br>
+            Send a packet with the fake multicast address to the PMD. (Should receive)<br>
+            Set vlan filtering on the PMD, and add vlan ID to the PMD.<br>
+            Send a packet with the fake multicast address and vlan ID to the PMD. (Should receive)<br>
+            Send a packet with the fake multicast address and a different vlan ID to the PMD.<br>
+                (Should not receive)<br>
+            Remove the vlan tag from the PMD, and turn vlan filtering off on the PMD.<br>
+            Send a packet with the fake multicast address and no vlan tag to the PMD.<br>
+                (Should receive)<br>
+            Remove the fake multicast address from the PMDs multicast address filter.<br>
+            Send a packet with the fake multicast address to the PMD. (Should not receive)<br>
+        """<br>
+        testpmd = TestPmdShell(self.sut_node)<br>
+        testpmd.start()<br>
+        testpmd.set_promisc(0, on=False)<br>
+        multicast_address = "01:00:5E:00:00:00"<br>
+        vlan_id = 2<br>
+<br>
+        testpmd.set_multicast_mac_addr(0, multi_addr=multicast_address, add=True)<br>
+        self.send_packet_and_verify(multicast_address, should_receive=True)<br>
+<br>
+        # Test vlan filtering on multicast addressing.<br>
+        # Verify vlan functionality for debugging purposes.<br>
+        testpmd.vlan_filter_set_on(port=0)<br>
+        testpmd.rx_vlan_add(vlan_id, 0)<br>
+        self.send_packet_and_verify(multicast_address, should_receive=True, add_vlan=True)<br>
+        self.send_packet_and_verify(multicast_address, should_receive=False, add_vlan=True)<br>
+<br>
+        # Remove vlan tag and filtering and run basic multicast addr test.<br>
+        testpmd.rx_vlan_rm(vlan_id, 0)<br>
+        testpmd.vlan_filter_set_off(port=0)<br>
+        self.send_packet_and_verify(multicast_address, should_receive=True)<br>
+<br>
+        # Remove multicast filter and verify the packet was not received.<br>
+        testpmd.set_multicast_mac_addr(0, multicast_address, add=False)<br>
+        self.send_packet_and_verify(multicast_address, should_receive=False)<br>
+        testpmd.close()<br>
+        sleep(6)<br>
-- <br>
2.44.0<br>
<br>
</blockquote></div>