From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9000F45B54; Wed, 16 Oct 2024 19:14:16 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 814E24065F; Wed, 16 Oct 2024 19:14:04 +0200 (CEST) Received: from mail-qv1-f47.google.com (mail-qv1-f47.google.com [209.85.219.47]) by mails.dpdk.org (Postfix) with ESMTP id D289540663 for ; Wed, 16 Oct 2024 19:14:02 +0200 (CEST) Received: by mail-qv1-f47.google.com with SMTP id 6a1803df08f44-6cbe53e370eso71996d6.2 for ; Wed, 16 Oct 2024 10:14:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iol.unh.edu; s=unh-iol; t=1729098842; x=1729703642; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=HoSzsNZf/4zQV7LIKgRqPEVParBbp2qUiet6rhkniYg=; b=jCRKmsxaSI91qvge5vJLxfq0Lcp28rm1aRQ4366KnUghaH2d5RazpD+SslA+ZRlr3s e0E4fAxVS35pK43G0tqNejVeHh6acAu7uyV00C/YTeeUwLf8uxuSGW7s1PhCR/SvG9XA 1h+kHGITmWlf1tFDItD1+YoUsH4ad4h0lwiE8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1729098842; x=1729703642; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=HoSzsNZf/4zQV7LIKgRqPEVParBbp2qUiet6rhkniYg=; b=mvph+k+4RLDlc79CA+bCaFBQGgeNKJHX6qtv1MhI4Vvt44yVteUGMkzJAN+aaSreAn +ajIeD/ahVLDrC0S3JMh8E2Ge3ghNTuaAhnEmjsAAt5e6jUDuLeMPuyTSj8HNrdcY2Bt hGis6u1tjRdjvYevtNZp7H21ayykCiK8TbEbL0zai+bOIJ+dkLGZIYlTCfPxNQ0XEryn KbhSjSnJW06AGACjBV+LKQB03oQs7YO6CJAyXzjW16DhUrldsuk6RuMKNtJZQMhkF+76 PC8SCgCQLOKWLREr+Wh8Fs7HoJysKWSeULis6Mi7f1PYg6UutdvVoKIpx1/ukVDcove6 Io1Q== X-Gm-Message-State: AOJu0YxBGVycBejdVdjmTgzYwqXKfRJZNYCmsz/cRR2PbnGI56OKD/sj dlstXCC3GJFCAfMG7UEpq6nm5T/JG2YKjcDlhU3id0pLqbIY+RbCeRzr0h0j722OSWP0Vsbbcs4 q X-Google-Smtp-Source: AGHT+IGm+goT+MNH8wIlRTilgoBv1zjfxhgvx+TUyfo47EVx7lgPbb4vyWltcsWTzTmQlNyfzRGsSA== X-Received: by 2002:a05:6214:cca:b0:6cb:f0f2:f56c with SMTP id 6a1803df08f44-6cc37aafe97mr1301436d6.6.1729098842019; Wed, 16 Oct 2024 10:14:02 -0700 (PDT) Received: from localhost.unh.edu ([2606:4100:3880:1271:e2f8:4ec3:8bf3:864c]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-6cc2291dbbbsm19738756d6.38.2024.10.16.10.14.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Oct 2024 10:14:00 -0700 (PDT) From: Nicholas Pratte To: dmarx@iol.unh.edu, probb@iol.unh.edu, luca.vizzarro@arm.com, Honnappa.Nagarahalli@arm.com, yoan.picchi@foss.arm.com, paul.szczepanek@arm.com Cc: dev@dpdk.org, Nicholas Pratte Subject: [PATCH v9 3/3] dts: mac filter test suite refactored for new dts Date: Wed, 16 Oct 2024 13:13:07 -0400 Message-ID: <20241016171307.18635-4-npratte@iol.unh.edu> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241016171307.18635-1-npratte@iol.unh.edu> References: <20240702192422.2480-2-npratte@iol.unh.edu> <20241016171307.18635-1-npratte@iol.unh.edu> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org The mac address filter test suite, whose test cases are based on old DTS's test cases, has been refactored to interface with the new DTS framework. The test suite assesses the behavior of ethdev api calls as it relates to mac address filtering using TestPMD. Specific test cases have been designed to be vendor agnostic. Bugzilla ID: 1454 Signed-off-by: Nicholas Pratte --- dts/framework/config/conf_yaml_schema.json | 3 +- dts/tests/TestSuite_mac_filter.py | 204 +++++++++++++++++++++ 2 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 dts/tests/TestSuite_mac_filter.py diff --git a/dts/framework/config/conf_yaml_schema.json b/dts/framework/config/conf_yaml_schema.json index df390e8ae2..ed89981edc 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", + "mac_filter" ] }, "test_target": { diff --git a/dts/tests/TestSuite_mac_filter.py b/dts/tests/TestSuite_mac_filter.py new file mode 100644 index 0000000000..8538550140 --- /dev/null +++ b/dts/tests/TestSuite_mac_filter.py @@ -0,0 +1,204 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2023-2024 University of New Hampshire +"""Mac address filtering test suite. + +This test suite ensures proper and expected behavior of Allowlist filtering via mac +addresses on devices bound to the Poll Mode Driver. If a packet received on a device +contains a mac address not contained within its mac address pool, the packet should +be dropped. Alternatively, if a packet is received that contains a destination mac +within the devices address pool, the packet should be accepted and forwarded. This +behavior should remain consistent across all packets, namely those containing dot1q +tags or otherwise. + +The following test suite assesses behaviors based on the aforementioned logic. +Additionally, testing is done within the PMD itself to ensure that the mac address +allow list is behaving as expected. +""" + +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.exception import InteractiveCommandExecutionError +from framework.remote_session.testpmd_shell import NicCapability, TestPmdShell +from framework.test_suite import TestSuite, func_test +from framework.testbed_model.capability import requires + + +class TestMacFilter(TestSuite): + """Mac address allowlist filtering test suite. + + Configure mac address filtering on a given port, and test the port's filtering behavior + using both a given port's hardware address as well as dummy addresses. If a port accepts + a packet that is not contained within its mac address allowlist, then a given test case + fails. Alternatively, if a port drops a packet that is designated within its mac address + allowlist, a given test case will fail. + + Moreover, a given port should demonstrate proper behavior when bound to the Poll Mode + Driver. A port should not have a mac address allowlist that exceeds its designated size. + A port's default hardware address should not be removed from its address pool, and invalid + addresses should not be included in the allowlist. If a port abides by the above rules, the + test case passes. + """ + + def send_packet_and_verify( + self, + mac_address: str, + should_receive: bool = True, + ) -> None: + """Generate, send, and verify a packet based on specified parameters. + + Test cases within this suite utilize this method to create, send, and verify + packets based on criteria relating to the packet's destination mac address, + and vlan tag. Packets are verified using an inserted payload. Assuming the test case + expects to receive a specified packet, if the list of received packets contains this + payload within any of its packets, the test case passes. Alternatively, if the designed + packet should not be received, and the packet payload is received, then the test case + fails. Each call with this method sends exactly one packet. + + Args: + mac_address: The destination mac address of the packet being sent. + add_vlan: If :data:'True', add a vlan tag to the packet being sent. The + vlan tag will be :data:'2' if the packet should be received and + :data:'1' if the packet should not be received but requires a vlan tag. + should_receive: If :data:'True', assert whether or not the sent packet + has been received. If :data:'False', assert that the send packet was not + received. :data:'True' by default + """ + packet = Ether() / IP() / Raw(load="X" * 22) + packet.dst = mac_address + received_packets = [ + packets + for packets in self.send_packet_and_capture(packet) + if hasattr(packets, "load") and "X" * 22 in str(packets.load) + ] + if should_receive: + self.verify( + len(received_packets) == 1, + "Packet sent by test case should be forwarded and received.", + ) + else: + self.verify( + len(received_packets) == 0, + "Packet sent by test case should not be forwarded and received.", + ) + + @func_test + def test_add_remove_mac_addresses(self) -> None: + """Assess basic mac addressing filtering functionalities. + + This test case validates for proper behavior of mac address filtering with both + a port's default, burned-in mac address, as well as additional mac addresses + added to the PMD. Packets should either be received or not received depending on + the properties applied to the PMD at any given time. + + Test: + Start TestPMD without promiscuous mode. + Send a packet with the port's default mac address. (Should receive) + Send a packet with fake mac address. (Should not receive) + Add fake mac address to the PMD's address pool. + Send a packet with the fake mac address to the PMD. (Should receive) + Remove the fake mac address from the PMD's address pool. + Send a packet with the fake mac address to the PMD. (Should not receive) + """ + with TestPmdShell(self.sut_node) as testpmd: + testpmd.set_promisc(0, enable=False) + testpmd.start() + mac_address = self._sut_port_ingress.mac_address + + # Send a packet with NIC default mac address + self.send_packet_and_verify(mac_address=mac_address, should_receive=True) + # Send a packet with different mac address + fake_address = "00:00:00:00:00:01" + self.send_packet_and_verify(mac_address=fake_address, should_receive=False) + + # Add mac address to pool and rerun tests + testpmd.set_mac_addr(0, mac_address=fake_address, add=True) + self.send_packet_and_verify(mac_address=fake_address, should_receive=True) + testpmd.set_mac_addr(0, mac_address=fake_address, add=False) + self.send_packet_and_verify(mac_address=fake_address, should_receive=False) + + @func_test + def test_invalid_address(self) -> None: + """Assess the behavior of a NIC mac address pool while bound to the PMD. + + An assessment of a NIC's behavior when mounted to a PMD as it relates to mac addresses + and address pooling. Devices should not be able to use invalid mac addresses, remove their + built-in hardware address, or exceed their address pools. + + Test: + Start TestPMD. + Attempt to add an invalid mac address. (Should fail) + Attempt to remove the device's hardware address with no additional addresses in the + address pool. (Should fail) + Add a fake mac address to the pool twice in succession. (Should not create any errors) + Attempt to remove the device's hardware address with other addresses in the address + pool. (Should fail) + Determine the device's mac address pool size, and fill the pool with fake addresses. + Attempt to add another fake mac address, overloading the address pool. (Should fail) + """ + with TestPmdShell(self.sut_node) as testpmd: + testpmd.start() + mac_address = self._sut_port_ingress.mac_address + try: + testpmd.set_mac_addr(0, "00:00:00:00:00:00", add=True) + self.verify(False, "Invalid mac address added.") + except InteractiveCommandExecutionError: + pass + try: + testpmd.set_mac_addr(0, mac_address, add=False) + self.verify(False, "Default mac address removed.") + except InteractiveCommandExecutionError: + pass + # Should be no errors adding this twice + testpmd.set_mac_addr(0, "1" + mac_address[1:], add=True) + testpmd.set_mac_addr(0, "1" + mac_address[1:], add=True) + # Double check to see if default mac address can be removed + try: + testpmd.set_mac_addr(0, mac_address, add=False) + self.verify(False, "Default mac address removed.") + except InteractiveCommandExecutionError: + pass + + for i in range(testpmd.show_port_info(0).max_mac_addresses_num - 1): + # A0 fake address based on the index 'i'. + fake_address = str(hex(i)[2:].zfill(12)) + # Insert ':' characters every two indexes to create a fake mac address. + fake_address = ":".join( + fake_address[x : x + 2] for x in range(0, len(fake_address), 2) + ) + testpmd.set_mac_addr(0, fake_address, add=True, verify=False) + try: + testpmd.set_mac_addr(0, "E" + mac_address[1:], add=True) + # We add an extra address to compensate for mac address pool inconsistencies. + testpmd.set_mac_addr(0, "F" + mac_address[1:], add=True) + self.verify(False, "Mac address limit exceeded.") + except InteractiveCommandExecutionError: + pass + + @requires(NicCapability.MCAST_FILTERING) + @func_test + def test_multicast_filter(self) -> None: + """Assess basic multicast address filtering functionalities. + + Ensure that multicast filtering performs as intended when a given device is bound + to the PMD. + + Test: + Start TestPMD without promiscuous mode. + Add a fake multicast address to the PMD's multicast address pool. + Send a packet with the fake multicast address to the PMD. (Should receive) + Remove the fake multicast address from the PMDs multicast address filter. + Send a packet with the fake multicast address to the PMD. (Should not receive) + """ + with TestPmdShell(self.sut_node) as testpmd: + testpmd.start() + testpmd.set_promisc(0, enable=False) + multicast_address = "01:00:5E:00:00:00" + + testpmd.set_multicast_mac_addr(0, multi_addr=multicast_address, add=True) + self.send_packet_and_verify(multicast_address, should_receive=True) + + # Remove multicast filter and verify the packet was not received. + testpmd.set_multicast_mac_addr(0, multicast_address, add=False) + self.send_packet_and_verify(multicast_address, should_receive=False) -- 2.44.0