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 D638F45743; Mon, 5 Aug 2024 19:13:24 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 985B140685; Mon, 5 Aug 2024 19:13:18 +0200 (CEST) Received: from mail-qv1-f50.google.com (mail-qv1-f50.google.com [209.85.219.50]) by mails.dpdk.org (Postfix) with ESMTP id D75874066A for ; Mon, 5 Aug 2024 19:13:17 +0200 (CEST) Received: by mail-qv1-f50.google.com with SMTP id 6a1803df08f44-6bb8a12e9e3so6044606d6.0 for ; Mon, 05 Aug 2024 10:13:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iol.unh.edu; s=unh-iol; t=1722877997; x=1723482797; 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=+Ujs7j/8qs/NAqJ0pIVqXnQypG0Tv8toqOCuQqALkPc=; b=Qo0tDC2pGfpXTLi9/9XL47xeH/0GmRNXVhDbAJbIchAjXKRr7o4YAGSNRXVU3CO3SN 8FjUheiPz4xXaAEabgXm43fmruchkrgSguBCPUKFKTDnRnM2TVU9KBp6p+8WL3XeasT6 7V4rlPFmMPCF/eh8EKQddR+RlLXSgKipaOjdo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722877997; x=1723482797; 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=+Ujs7j/8qs/NAqJ0pIVqXnQypG0Tv8toqOCuQqALkPc=; b=CHCnb+Ju4RkmDMC2fSaWQVnXufQfw2UyKFnsDa0MzgT6FUzyHy7WW7IqZyTBZX52Dt fIuQSHCXqYRzBh19WVVnsGhvzGmn/TbONqA/pZiuxyrXkf33j9uc9mMqtGioUIV0wskH OAou2lOBDzdb2kJxToVqwK8LSYxbSEUP54slbkocT4Xqgt7zUFkBWq1Vf8vTzcWGPTfW OaBybCu9Q8ppzDaxbtcgwvPUj/mvU7sxY8mdTgk8Gz7njNv/byLWjrMo2rcsqleB9ydE PhgpKF56bmUCY2+tLBV6+m6JQ4pyrviT3Nu7br5ihlMO+vF5c1BeuAThWe4AYvx0FAf+ iPHQ== X-Gm-Message-State: AOJu0YyLNV6h80hkFtEBpb9eIj/Yb/N/bOqTsxAntHrASsq844bNjKVk aHaYNMx4LJCbV05Y9VDGl5sAzI3L2L/BmUB8e/4neMDsKEk10/jDhvISa/QL4wQ= X-Google-Smtp-Source: AGHT+IEx9b0IgaIHz11XAh/4EwxBILN4Fy1czH7pvK7QAQtOrtLyslqFGWJ5+yXKW/HU4nPeode3vA== X-Received: by 2002:ac8:5883:0:b0:44e:cff7:6260 with SMTP id d75a77b69052e-45189298fa6mr92970471cf.8.1722877996898; Mon, 05 Aug 2024 10:13:16 -0700 (PDT) Received: from localhost.unh.edu ([2606:4100:3880:1271:e2f8:4ec3:8bf3:864c]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-4519ed14bf8sm19517331cf.3.2024.08.05.10.13.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Aug 2024 10:13:16 -0700 (PDT) From: Nicholas Pratte To: Honnappa.Nagarahalli@arm.com, yoan.picchi@foss.arm.com, paul.szczepanek@arm.com, juraj.linkes@pantheon.tech, luca.vizzarro@arm.com, probb@iol.unh.edu, dmarx@iol.unh.edu, jspewock@iol.unh.edu Cc: dev@dpdk.org, Nicholas Pratte Subject: [RFC v1 2/2] dts: port ethertype ethdev api test suite to new dts framework Date: Mon, 5 Aug 2024 13:12:46 -0400 Message-ID: <20240805171246.18580-3-npratte@iol.unh.edu> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240805171246.18580-1-npratte@iol.unh.edu> References: <20240805171246.18580-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 Based off the test cases from the old DTS test suite, the following test suite assess the behavior of ethertype configuration options found within the ethdev api. Bugzilla-ID: 1505 depends-on: 142696 ("dts: add VLAN methods to testpmd shell") depends-on: 142762 ("dts: add text parser for testpmd verbose output") depends-on: 139227 ("dts: skip test cases based on capabilities") Signed-off-by: Nicholas Pratte --- dts/framework/config/conf_yaml_schema.json | 3 +- dts/tests/TestSuite_ethertype_config.py | 381 +++++++++++++++++++++ 2 files changed, 383 insertions(+), 1 deletion(-) create mode 100644 dts/tests/TestSuite_ethertype_config.py diff --git a/dts/framework/config/conf_yaml_schema.json b/dts/framework/config/conf_yaml_schema.json index f02a310bb5..b5a9bcdf2a 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", + "ethertype_config" ] }, "test_target": { diff --git a/dts/tests/TestSuite_ethertype_config.py b/dts/tests/TestSuite_ethertype_config.py new file mode 100644 index 0000000000..4b3e99a081 --- /dev/null +++ b/dts/tests/TestSuite_ethertype_config.py @@ -0,0 +1,381 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2023-2024 University of New Hampshire + +"""VLAN tpid ethdev api assessment test suite. + +Assesses the behavior of Poll Mode Drivers as it relates to their ability to adequately interface +with VLAN tpid functionalities within the ethdev api. Associated test cases within this suite may +check and analyse both verbose output within testpmd and/or forwarding behaviors within a paired +topology. An ethernet device should detect and forward packets as expected when using different +tpids for both standard VLAN and extended QinQ networking. Moreover, if a Poll Mode Driver is +configured with a different tpid, then packets with a corresponding tpid should be read properly +within testpmd verbose output, and packets should be forwarded and not dropped. +""" + +from scapy.layers.inet import IP # type: ignore[import-untyped] +from scapy.layers.l2 import Dot1Q, Ether # type: ignore[import-untyped] +from scapy.packet import Packet, Raw # type: ignore[import-untyped] + +from framework.params.testpmd import SimpleForwardingModes +from framework.remote_session.testpmd_shell import ( + NicCapability, + TestPmdShell, + VLANOffloadFlag, +) +from framework.test_suite import TestSuite, requires + + +class TestEthertypeConfig(TestSuite): + """The vlan tpid configuration ethdev test suite for DPDK PMDs.""" + + def send_packet_and_verify(self, packet: Packet, should_receive: bool) -> None: + """Sends a specified packet and verify both reception and tpid values. + + Sends a specified packet across a paired topology, and if a packet is to be received, check + that said packet is within the list of received packets and verify that the tpid is + unchanged. Otherwise, check that the specified packet was not received. + + Args: + packet: The packet to be sent across the topology. + should_receive: If :data:`True', ensure that the packet was received and the Dot1Q tpid + is unchanged. + """ + received_packets = [ + packets + for packets in self.send_packet_and_capture(packet) + if hasattr(packets, "load") and str(packets.load) == "X" * 80 + ] + if should_receive: + self.verify(len(received_packets) == 1, "Packet should be received.") + self.verify( + received_packets[0][Ether].type == packet[Ether].type, + "tpid value changed during transmission", + ) + else: + self.verify(not received_packets, "Packet should not be received.") + + def verify_verbose_output( + self, testpmd_shell: TestPmdShell, packet: Packet, expected_output: str + ) -> None: + """Send a specified packet and analyse verbose testpmd output for vlan information. + + Sends a specified packet across a paired topology. Forwarding is not checked, but verbose + output is analysed to ensure that the packet's ptype matches the expected output parameter + which, with respect to this test suite, will either check for standard VLAN or QinQ + tagging information. + + Args: + testpmd_shell: A test case's associated testpmd shell. This is needed to stop the + testpmd shell and gather verbose output for assessment. + packet: The packet to be sent across the topology. + expected_output: Output to be checked for within testpmd verbose output after a packet + has been forwarded. + """ + self.send_packet_and_capture(packet) + verbose_output = testpmd_shell.extract_verbose_output(testpmd_shell.stop()) + try: + self.verify( + ( + any( + self._sut_port_egress.mac_address in packets.src_mac + for queues in verbose_output + for packets in queues.packets + ) + ), + "Packet not discovered in verbose output.", + ) + self.verify( + ( + any( + self._sut_port_egress.mac_address in packets.src_mac + and expected_output in packets.sw_ptype + for queues in verbose_output + for packets in queues.packets + ) + ), + f"{expected_output} not found in verbose output.", + ) + finally: + testpmd_shell.start() + + def test_change_vlan_tpid(self) -> None: + """Set PMD's default tpid and assess testpmd verbose output for VLAN information. + + Check that a PMD can properly detect that a Dot1Q layer is present on a received packet + when its tpid is changed to a different value. + + Test: + Start testpmd with rxonly forwarding mode enabled. + Set testpmd verbose level to 3. + Send a VLAN enabled packet with a tpid value of 0xA100 across the testbed. + Assess that the packet's verbose output within testpmd contains 'L2_ETHER_VLAN'. + """ + with TestPmdShell(self.sut_node, forward_mode=SimpleForwardingModes.rxonly) as testpmd: + testpmd.start() + testpmd.set_verbose(3) + testpmd.set_vlan_tpid(0, 0xA100, inner_id=False) + + # Send a basic packet and verify the TPID changes. + packet = Ether(type=0xA100) / Dot1Q() / IP() / Raw(load="X" * 80) + self.verify_verbose_output(testpmd, packet, "L2_ETHER_VLAN") + + @requires(NicCapability.vlan_filter) + @requires(NicCapability.vlan_extended) + def test_vlan_filtering_on_off(self) -> None: + """Test VLAN filter offload with variable tpid values. + + Assesses VLAN filtering behavior when a packet is sent with both an identical and different + tpid from what is set on a PMD. Behavior is validated via packet forwarding. Packets with a + different tpid from the PMD should be dropped, and packet with an identical tpid should be + forwarded across the testbed. + + Test: + Start testpmd with mac forwarding mode enabled. + Enable both filter and extend VLAN offloading options. + Send a packet with a nondefault tpid (0xA100) and verify that it was not received. + Use the ethdev api to change the default tpid on the device to 0xA100. + Send a packet with tpid 0xA100, and verify that it was forwarded across the testbed. + """ + with TestPmdShell( + self.sut_node, + forward_mode=SimpleForwardingModes.mac, + ) as testpmd: + testpmd.set_vlan_offload_option(0, VLANOffloadFlag.FILTER, on=True) + testpmd.set_vlan_offload_option(0, VLANOffloadFlag.EXTEND, on=True) + testpmd.start() + + packet = Ether(type=0xA100) / Dot1Q(vlan=16) / IP() / Raw("X" * 80) + self.send_packet_and_verify(packet, should_receive=False) + + testpmd.set_vlan_offload_option(0, VLANOffloadFlag.FILTER, on=False) + testpmd.set_vlan_tpid(0, 0xA100, inner_id=False) + self.send_packet_and_verify(packet, should_receive=True) + + @requires(NicCapability.vlan_extended) + @requires(NicCapability.vlan_strip) + @requires(NicCapability.vlan_filter) + def test_adding_vlan_tag_identifier_with_changing_vlan_tpid(self) -> None: + """Test VLAN filter offload with vlan tagging and variable tpid values. + + Assess VLAN filtering on tagged vlan packets with both differing and identical tpid values. + Behavior is validated via packet forwarding within the testbed. A packet with a differing + tpid value the device should be dropped, and packets with identical tpid values should be + forwarded, regardless of any VLAN tag present. Moreover, packets with VLAN tags should + perform as expected. Packets with differing VLAN tags from a device filter should be + dropped, and packets with accepted VLAN tags should be forwarded. + + Test: + Start testpmd with mac forwarding mode enabled. + Enable filter, strip and extend offloading features within testpmd. + Add VLAN tag value 16 to the rx VLAN filter on testpmd. + Send a packet with default tpid value (0x8100) and vlan tag 16, verify that the packet + has been received. + Use the ethdev api to change the device's tpid value to 0xA100. + Send a packet with VLAN tag of 16 and a tpid of 0xA100 to the SUT, and verify that + the packet was received. + Remove VLAN tag value 16 from the rx VLAN filter on testpmd. + Send a packet with VLAN tag 16 and tpid value 0xA100 and verify that it was not + received. + """ + with TestPmdShell( + self.sut_node, + forward_mode=SimpleForwardingModes.mac, + ) as testpmd: + testpmd.set_vlan_offload_option(0, VLANOffloadFlag.FILTER, on=True) + testpmd.set_vlan_offload_option(0, VLANOffloadFlag.STRIP, on=False) + testpmd.set_vlan_offload_option(0, VLANOffloadFlag.EXTEND, on=True) + testpmd.start() + + testpmd.rx_vlan(16, 0, add=True) + packet = Ether() / Dot1Q(vlan=16) / IP() / Raw(load="X" * 80) + self.send_packet_and_verify(packet, should_receive=True) + + testpmd.set_vlan_tpid(0, 0xA100, inner_id=False) + packet[Ether].type = 0xA100 + self.send_packet_and_verify(packet, should_receive=True) + + testpmd.rx_vlan(16, 0, add=False) + self.send_packet_and_verify(packet, should_receive=False) + + @requires(NicCapability.vlan_filter) + @requires(NicCapability.vlan_strip) + def test_vlan_header_stripping_with_changing_vlan_tpid(self) -> None: + """Test VLAN stripping offload with changing VLAN tpid. + + Changing tpid values should not affect the expected behavior of the VLAN stripping offload + functionality. Thus, the following test case assesses that vlan tags are properly stripped + despite the change in VLAN tpid values. + + Test: + Start testpmd with mac forwarding mode enabled. + Enable filter and strip offloading options within testpmd. + Send a VLAN tagged packet and verify it was received with Dot1Q layer removed across + the testbed when VLAN filtering offload is turned off and stipping is turned on. + Use the ethdev api to change the device default tpid to 0xA100. + Send a packet with vlan tag value 16 and tpid value 0xA100 across the testbed and + verify that it was received with Dot1Q layer removed when filter offload is + disable and stripping enabled. + Turn off VLAN strip offload option in testpmd. + Send a packet with vlan tag value 16 and tpid value 0xA100 and verify that is + received across the testbed with Dot1Q layer present. + """ + with TestPmdShell( + self.sut_node, + forward_mode=SimpleForwardingModes.mac, + ) as testpmd: + testpmd.set_vlan_offload_option(0, VLANOffloadFlag.FILTER, on=False) + testpmd.set_vlan_offload_option(0, VLANOffloadFlag.STRIP, on=True) + testpmd.start() + + # Test that packets are received without VLAN filter + packet = Ether() / Dot1Q(vlan=16) / IP() / Raw(load="X" * 80) + received_packets = [ + packets + for packets in self.send_packet_and_capture(packet) + if hasattr(packets, "load") and str(packets.load) == "X" * 80 + ] + self.verify(len(received_packets) > 0, "Expected packet not received during strip") + self.verify(Dot1Q not in received_packets[0], "Dot1Q tag not stripped during transfer.") + + testpmd.set_vlan_tpid(0, 0xA100, inner_id=False) + packet[Ether].type = 0xA100 + received_packets = [ + packets + for packets in self.send_packet_and_capture(packet) + if hasattr(packets, "load") and str(packets.load) == "X" * 80 + ] + self.verify(len(received_packets) > 0, "Expected packet not received during strip") + self.verify(Dot1Q not in received_packets[0], "Dot1Q tag not stripped during transfer.") + + testpmd.set_vlan_offload_option(0, VLANOffloadFlag.STRIP, on=False) + received_packets = [ + packets + for packets in self.send_packet_and_capture(packet) + if hasattr(packets, "load") and str(packets.load) == "X" * 80 + ] + self.verify(len(received_packets) > 0, "Expected packet not received during strip") + self.verify(Dot1Q in received_packets[0], "Dot1Q tag was stripped during transfer.") + + @requires(NicCapability.vlan_filter) + @requires(NicCapability.vlan_strip) + def test_vlan_header_inserting_with_changing_vlan_tpid(self) -> None: + """Test tx VLAN behavior with varying tpid values. + + Test tx Dot1Q layer insertion behavior when the default tpid value is changed using the + ethdev api. An ethernet device should insert Dot1Q layers on egressing packet regardless of + the tpid value set, and egressing packets should contain the tpid value that was explicitly + set. + + Test: + Start testpmd with mac forwarding mode enabled. + Add tx VLAN value of 16 using testpmd. + Send a packet without a Dot1Q layer across the testbed, and verify that the packet was + received with a Dot1Q layer present, a VLAN tag value of 16, and a tpid value of + 0x8100. + Use the ethdev api to change the default device tpid value to 0xA100 + Send a packet without a Dot1Q layer across the testbed, and verify that the packet was + received with a Dot1Q layer present, a VLAN tag value of 16, and a tpid value of + 0xA100. + Reset tx VLAN options to its default state using testpmd. + Send a packet without a Dot1Q layer across the testbed and verify that it is received + without a Dot1Q layer present. + """ + with TestPmdShell(self.sut_node, forward_mode=SimpleForwardingModes.mac) as testpmd: + testpmd.set_vlan_offload_option(0, VLANOffloadFlag.FILTER, on=False) + testpmd.set_vlan_offload_option(0, VLANOffloadFlag.STRIP, on=False) + testpmd.start() + + testpmd.tx_vlan_set(1, vlan=16) + packet = Ether() / IP() / Raw(load="X" * 80) + received_packets = list( + packets + for packets in self.send_packet_and_capture(packet) + if hasattr(packets, "load") and str(packets.load) == "X" * 80 + ) + self.verify(len(received_packets) > 0, "Expected packets not received.") + # Separate verifications for easier debugging. + self.verify(Dot1Q in received_packets[0], "Expected Dot1Q layer not found.") + self.verify( + received_packets[0][Ether].type == 0x8100, "Ethertype changed during transmission." + ) + self.verify( + received_packets[0][Dot1Q].vlan == 16, + "Vlan tag number changed during transmission.", + ) + + testpmd.set_vlan_tpid(1, 0xA100, inner_id=False) + received_packets = [ + packets + for packets in self.send_packet_and_capture(packet) + if hasattr(packets, "load") and str(packets.load) == "X" * 80 + ] + self.verify(len(received_packets) > 0, "Expected packets not received.") + # Separate verifications for easier debugging. + self.verify(Dot1Q in received_packets[0], "Expected Dot1Q layer not found.") + self.verify( + received_packets[0][Ether].type == 0xA100, "Ethertype changed during transmission." + ) + self.verify( + received_packets[0][Dot1Q].vlan == 16, + "Vlan tag number changed during transmission.", + ) + + testpmd.tx_vlan_reset(1) + received_packets = [ + packets + for packets in self.send_packet_and_capture(packet) + if hasattr(packets, "load") and str(packets.load) == "X" * 80 + ] + self.verify(len(received_packets) > 0, "Expected packets not received.") + self.verify( + Dot1Q not in received_packets[0].layers(), "Dot1q detected in received packet." + ) + + @requires(NicCapability.qinq_strip) + def change_stag_and_ctag_within_qinq(self) -> None: + """Assess QinQ packet recognition with varying c_tag and s_tag values. + + Assesses testpmd verbose output to validate the proper functionality of QinQ packets when + inner and outer tpid values are changed. If a sent QinQ packet's tpid values are changed to + correspond to the values that are set within testpmd, then that sent packet should be + acknowledged and the expected standard VLAN and QinQ verbose output should be present + within testpmd. + + Test: + Start testpmd with rxonly forwarding mode enabled. + Enable qinq_strip VLAN offload option within testpmd. + Set testpmd verbose level to 3. + Use the ethdev api to set the default outer tpid value to 0x88A8. + Use the ethdev api to set the default inner tpid value to 0x8100. + Send a QinQ packet with an outer tpid value of 0x88A8 and an inner tpid value of 0x8100 + and verify that 'L2_ETHER_VLAN INNER_L2_ETHER_QINQ' is present in verbose output. + Use the ethdev api to set the default outer tpid value to 0x9100. + Use the ethdev api to set the default inner tpid value to 0xA100. + Send a QinQ packet with an outer tpid value of 0x9100 and an inner tpid value of 0xA100 + and verify that 'L2_ETHER_VLAN INNER_L2_ETHER_QINQ' is present in verbose output. + Use the ethdev api to set the default outer tpid value to 0x8100. + Use the ethdev api to set the default inner tpid value to 0x8100. + Send a QinQ packet with an outer tpid value of 0x8100 and an inner tpid value of 0x8100 + and verify that 'L2_ETHER_VLAN INNER_L2_ETHER_QINQ' is present in verbose output. + """ + with TestPmdShell(self.sut_node, forward_mode=SimpleForwardingModes.rxonly) as testpmd: + testpmd.set_vlan_offload_option(0, VLANOffloadFlag.QINQ_STRIP, on=True) + testpmd.set_verbose(3) + testpmd.start() + + testpmd.set_vlan_tpid(0, 0x88A8, inner_id=False) + testpmd.set_vlan_tpid(0, 0x8100, inner_id=True) + packet = Ether(type=0x88A8) / Dot1Q(type=0x8100) / Dot1Q() / IP() / Raw(load="X" * 80) + self.verify_verbose_output(testpmd, packet, "L2_ETHER_VLAN INNER_L2_ETHER_QINQ") + + testpmd.set_vlan_tpid(0, 0x9100, inner_id=False) + testpmd.set_vlan_tpid(0, 0xA100, inner_id=True) + packet[Ether].type = 0x9100 + packet[Dot1Q][0].type = 0xA100 + self.verify_verbose_output(testpmd, packet, "L2_ETHER_VLAN INNER_L2_ETHER_QINQ") + + testpmd.set_vlan_tpid(0, 0x8100, inner_id=False) + testpmd.set_vlan_tpid(0, 0x8100, inner_id=True) + packet[Ether].type = 0x8100 + packet[Dot1Q][0].type = 0x8100 + self.verify_verbose_output(testpmd, packet, "L2_ETHER_VLAN INNER_L2_ETHER_QINQ") -- 2.44.0