xref: /dpdk/dts/tests/TestSuite_pmd_buffer_scatter.py (revision 7e1388637b560e8a6211f4651fbd29e9437d988e)
1*7e138863SJeremy Spewock# SPDX-License-Identifier: BSD-3-Clause
2*7e138863SJeremy Spewock# Copyright(c) 2023-2024 University of New Hampshire
3*7e138863SJeremy Spewock
4*7e138863SJeremy Spewock"""Multi-segment packet scattering testing suite.
5*7e138863SJeremy Spewock
6*7e138863SJeremy SpewockThis testing suite tests the support of transmitting and receiving scattered packets.
7*7e138863SJeremy SpewockThis is shown by the Poll Mode Driver being able to forward
8*7e138863SJeremy Spewockscattered multi-segment packets composed of multiple non-contiguous memory buffers.
9*7e138863SJeremy SpewockTo ensure the receipt of scattered packets,
10*7e138863SJeremy Spewockthe DMA rings of the port's Rx queues must be configured
11*7e138863SJeremy Spewockwith mbuf data buffers whose size is less than the maximum length.
12*7e138863SJeremy Spewock
13*7e138863SJeremy SpewockIf it is the case that the Poll Mode Driver can forward scattered packets which it receives,
14*7e138863SJeremy Spewockthen this suffices to show the Poll Mode Driver is capable of both receiving and transmitting
15*7e138863SJeremy Spewockscattered packets.
16*7e138863SJeremy Spewock"""
17*7e138863SJeremy Spewock
18*7e138863SJeremy Spewockimport struct
19*7e138863SJeremy Spewock
20*7e138863SJeremy Spewockfrom scapy.layers.inet import IP  # type: ignore[import]
21*7e138863SJeremy Spewockfrom scapy.layers.l2 import Ether  # type: ignore[import]
22*7e138863SJeremy Spewockfrom scapy.packet import Raw  # type: ignore[import]
23*7e138863SJeremy Spewockfrom scapy.utils import hexstr  # type: ignore[import]
24*7e138863SJeremy Spewock
25*7e138863SJeremy Spewockfrom framework.remote_session.testpmd_shell import TestPmdForwardingModes, TestPmdShell
26*7e138863SJeremy Spewockfrom framework.test_suite import TestSuite
27*7e138863SJeremy Spewock
28*7e138863SJeremy Spewock
29*7e138863SJeremy Spewockclass TestPmdBufferScatter(TestSuite):
30*7e138863SJeremy Spewock    """DPDK PMD packet scattering test suite.
31*7e138863SJeremy Spewock
32*7e138863SJeremy Spewock    Configure the Rx queues to have mbuf data buffers
33*7e138863SJeremy Spewock    whose sizes are smaller than the maximum packet size.
34*7e138863SJeremy Spewock    Specifically, set mbuf data buffers to have a size of 2048
35*7e138863SJeremy Spewock    to fit a full 1512-byte (CRC included) ethernet frame in a mono-segment packet.
36*7e138863SJeremy Spewock    The testing of scattered packets is done by sending a packet
37*7e138863SJeremy Spewock    whose length is greater than the size of the configured size of mbuf data buffers.
38*7e138863SJeremy Spewock    There are a total of 5 packets sent within test cases
39*7e138863SJeremy Spewock    which have lengths less than, equal to, and greater than the mbuf size.
40*7e138863SJeremy Spewock    There are multiple packets sent with lengths greater than the mbuf size
41*7e138863SJeremy Spewock    in order to test cases such as:
42*7e138863SJeremy Spewock
43*7e138863SJeremy Spewock    1. A single byte of the CRC being in a second buffer
44*7e138863SJeremy Spewock       while the remaining 3 bytes are stored in the first buffer alongside packet data.
45*7e138863SJeremy Spewock    2. The entire CRC being stored in a second buffer
46*7e138863SJeremy Spewock       while all of the packet data is stored in the first.
47*7e138863SJeremy Spewock    3. Most of the packet data being stored in the first buffer
48*7e138863SJeremy Spewock       and a single byte of packet data stored in a second buffer alongside the CRC.
49*7e138863SJeremy Spewock    """
50*7e138863SJeremy Spewock
51*7e138863SJeremy Spewock    def set_up_suite(self) -> None:
52*7e138863SJeremy Spewock        """Set up the test suite.
53*7e138863SJeremy Spewock
54*7e138863SJeremy Spewock        Setup:
55*7e138863SJeremy Spewock            Verify that we have at least 2 port links in the current execution
56*7e138863SJeremy Spewock            and increase the MTU of both ports on the traffic generator to 9000
57*7e138863SJeremy Spewock            to support larger packet sizes.
58*7e138863SJeremy Spewock        """
59*7e138863SJeremy Spewock        self.verify(
60*7e138863SJeremy Spewock            len(self._port_links) > 1,
61*7e138863SJeremy Spewock            "There must be at least two port links to run the scatter test suite",
62*7e138863SJeremy Spewock        )
63*7e138863SJeremy Spewock
64*7e138863SJeremy Spewock        self.tg_node.main_session.configure_port_mtu(9000, self._tg_port_egress)
65*7e138863SJeremy Spewock        self.tg_node.main_session.configure_port_mtu(9000, self._tg_port_ingress)
66*7e138863SJeremy Spewock
67*7e138863SJeremy Spewock    def scatter_pktgen_send_packet(self, pktsize: int) -> str:
68*7e138863SJeremy Spewock        """Generate and send a packet to the SUT then capture what is forwarded back.
69*7e138863SJeremy Spewock
70*7e138863SJeremy Spewock        Generate an IP packet of a specific length and send it to the SUT,
71*7e138863SJeremy Spewock        then capture the resulting received packet and extract its payload.
72*7e138863SJeremy Spewock        The desired length of the packet is met by packing its payload
73*7e138863SJeremy Spewock        with the letter "X" in hexadecimal.
74*7e138863SJeremy Spewock
75*7e138863SJeremy Spewock        Args:
76*7e138863SJeremy Spewock            pktsize: Size of the packet to generate and send.
77*7e138863SJeremy Spewock
78*7e138863SJeremy Spewock        Returns:
79*7e138863SJeremy Spewock            The payload of the received packet as a string.
80*7e138863SJeremy Spewock        """
81*7e138863SJeremy Spewock        packet = Ether() / IP() / Raw()
82*7e138863SJeremy Spewock        packet.getlayer(2).load = ""
83*7e138863SJeremy Spewock        payload_len = pktsize - len(packet) - 4
84*7e138863SJeremy Spewock        payload = ["58"] * payload_len
85*7e138863SJeremy Spewock        # pack the payload
86*7e138863SJeremy Spewock        for X_in_hex in payload:
87*7e138863SJeremy Spewock            packet.load += struct.pack("=B", int("%s%s" % (X_in_hex[0], X_in_hex[1]), 16))
88*7e138863SJeremy Spewock        received_packets = self.send_packet_and_capture(packet)
89*7e138863SJeremy Spewock        self.verify(len(received_packets) > 0, "Did not receive any packets.")
90*7e138863SJeremy Spewock        load = hexstr(received_packets[0].getlayer(2), onlyhex=1)
91*7e138863SJeremy Spewock
92*7e138863SJeremy Spewock        return load
93*7e138863SJeremy Spewock
94*7e138863SJeremy Spewock    def pmd_scatter(self, mbsize: int) -> None:
95*7e138863SJeremy Spewock        """Testpmd support of receiving and sending scattered multi-segment packets.
96*7e138863SJeremy Spewock
97*7e138863SJeremy Spewock        Support for scattered packets is shown by sending 5 packets of differing length
98*7e138863SJeremy Spewock        where the length of the packet is calculated by taking mbuf-size + an offset.
99*7e138863SJeremy Spewock        The offsets used in the test are -1, 0, 1, 4, 5 respectively.
100*7e138863SJeremy Spewock
101*7e138863SJeremy Spewock        Test:
102*7e138863SJeremy Spewock            Start testpmd and run functional test with preset mbsize.
103*7e138863SJeremy Spewock        """
104*7e138863SJeremy Spewock        testpmd = self.sut_node.create_interactive_shell(
105*7e138863SJeremy Spewock            TestPmdShell,
106*7e138863SJeremy Spewock            app_parameters=(
107*7e138863SJeremy Spewock                "--mbcache=200 "
108*7e138863SJeremy Spewock                f"--mbuf-size={mbsize} "
109*7e138863SJeremy Spewock                "--max-pkt-len=9000 "
110*7e138863SJeremy Spewock                "--port-topology=paired "
111*7e138863SJeremy Spewock                "--tx-offloads=0x00008000"
112*7e138863SJeremy Spewock            ),
113*7e138863SJeremy Spewock            privileged=True,
114*7e138863SJeremy Spewock        )
115*7e138863SJeremy Spewock        testpmd.set_forward_mode(TestPmdForwardingModes.mac)
116*7e138863SJeremy Spewock        testpmd.start()
117*7e138863SJeremy Spewock
118*7e138863SJeremy Spewock        for offset in [-1, 0, 1, 4, 5]:
119*7e138863SJeremy Spewock            recv_payload = self.scatter_pktgen_send_packet(mbsize + offset)
120*7e138863SJeremy Spewock            self._logger.debug(f"Payload of scattered packet after forwarding: \n{recv_payload}")
121*7e138863SJeremy Spewock            self.verify(
122*7e138863SJeremy Spewock                ("58 " * 8).strip() in recv_payload,
123*7e138863SJeremy Spewock                f"Payload of scattered packet did not match expected payload with offset {offset}.",
124*7e138863SJeremy Spewock            )
125*7e138863SJeremy Spewock        testpmd.stop()
126*7e138863SJeremy Spewock
127*7e138863SJeremy Spewock    def test_scatter_mbuf_2048(self) -> None:
128*7e138863SJeremy Spewock        """Run the :meth:`pmd_scatter` test with `mbsize` set to 2048."""
129*7e138863SJeremy Spewock        self.pmd_scatter(mbsize=2048)
130*7e138863SJeremy Spewock
131*7e138863SJeremy Spewock    def tear_down_suite(self) -> None:
132*7e138863SJeremy Spewock        """Tear down the test suite.
133*7e138863SJeremy Spewock
134*7e138863SJeremy Spewock        Teardown:
135*7e138863SJeremy Spewock            Set the MTU of the tg_node back to a more standard size of 1500.
136*7e138863SJeremy Spewock        """
137*7e138863SJeremy Spewock        self.tg_node.main_session.configure_port_mtu(1500, self._tg_port_egress)
138*7e138863SJeremy Spewock        self.tg_node.main_session.configure_port_mtu(1500, self._tg_port_ingress)
139