[PATCH v10 2/3] dts: add Tx offload capabilities to NIC capabilities

Patrick Robb probb at iol.unh.edu
Mon Oct 27 17:15:25 CET 2025


On Mon, Oct 27, 2025 at 9:02 AM Andrew Bailey <abailey at iol.unh.edu> wrote:

> Currently, there is no support for tracking tx_offload capabilities and
> there is no separation between port capabilities and queue
> capabilities. This is an issue if a test case requires a tx_offload
> capability or if a test case requires that a card supports a capability
> on a queue. This causes test cases with said requirements to not be
> skipped when appropriate. Add tx_offload capabilities and distinguish
> capabilities between ports and queues.
>
> Signed-off-by: Andrew Bailey <abailey at iol.unh.edu>
> Signed-off-by: Jeremy Spewock <jspewock at iol.unh.edu>
> ---
>  dts/api/capabilities.py                   | 126 ++++++++++--
>  dts/api/testpmd/__init__.py               |  97 ++++++++-
>  dts/api/testpmd/types.py                  | 227 +++++++++++++++-------
>  dts/framework/parser.py                   |  30 +++
>  dts/framework/testbed_model/capability.py | 109 +++++++++--
>  dts/tests/TestSuite_checksum_offload.py   |  10 +-
>  dts/tests/TestSuite_pmd_buffer_scatter.py |   4 +-
>  dts/tests/TestSuite_vlan.py               |   4 +-
>  8 files changed, 489 insertions(+), 118 deletions(-)
>
> diff --git a/dts/api/capabilities.py b/dts/api/capabilities.py
> index 1a79413f6f..243759668f 100644
> --- a/dts/api/capabilities.py
> +++ b/dts/api/capabilities.py
> @@ -77,45 +77,65 @@ class NicCapability(IntEnum):
>      #: Scattered packets Rx enabled.
>      SCATTERED_RX_ENABLED = 0
>      #: Device supports VLAN stripping.
> -    RX_OFFLOAD_VLAN_STRIP = auto()
> +    PORT_RX_OFFLOAD_VLAN_STRIP = auto()
> +    QUEUE_RX_OFFLOAD_VLAN_STRIP = auto()
>      #: Device supports L3 checksum offload.
> -    RX_OFFLOAD_IPV4_CKSUM = auto()
> +    PORT_RX_OFFLOAD_IPV4_CKSUM = auto()
> +    QUEUE_RX_OFFLOAD_IPV4_CKSUM = auto()
>      #: Device supports L4 checksum offload.
> -    RX_OFFLOAD_UDP_CKSUM = auto()
> +    PORT_RX_OFFLOAD_UDP_CKSUM = auto()
> +    QUEUE_RX_OFFLOAD_UDP_CKSUM = auto()
>      #: Device supports L4 checksum offload.
> -    RX_OFFLOAD_TCP_CKSUM = auto()
> +    PORT_RX_OFFLOAD_TCP_CKSUM = auto()
> +    QUEUE_RX_OFFLOAD_TCP_CKSUM = auto()
>      #: Device supports Large Receive Offload.
> -    RX_OFFLOAD_TCP_LRO = auto()
> +    PORT_RX_OFFLOAD_TCP_LRO = auto()
> +    QUEUE_RX_OFFLOAD_TCP_LRO = auto()
>      #: Device supports QinQ (queue in queue) offload.
> -    RX_OFFLOAD_QINQ_STRIP = auto()
> +    PORT_RX_OFFLOAD_QINQ_STRIP = auto()
> +    QUEUE_RX_OFFLOAD_QINQ_STRIP = auto()
>      #: Device supports inner packet L3 checksum.
> -    RX_OFFLOAD_OUTER_IPV4_CKSUM = auto()
> +    PORT_RX_OFFLOAD_OUTER_IPV4_CKSUM = auto()
> +    QUEUE_RX_OFFLOAD_OUTER_IPV4_CKSUM = auto()
>      #: Device supports MACsec.
> -    RX_OFFLOAD_MACSEC_STRIP = auto()
> +    PORT_RX_OFFLOAD_MACSEC_STRIP = auto()
> +    QUEUE_RX_OFFLOAD_MACSEC_STRIP = auto()
>      #: Device supports filtering of a VLAN Tag identifier.
> -    RX_OFFLOAD_VLAN_FILTER = auto()
> +    PORT_RX_OFFLOAD_VLAN_FILTER = auto()
> +    QUEUE_RX_OFFLOAD_VLAN_FILTER = auto()
>      #: Device supports VLAN offload.
> -    RX_OFFLOAD_VLAN_EXTEND = auto()
> +    PORT_RX_OFFLOAD_VLAN_EXTEND = auto()
> +    QUEUE_RX_OFFLOAD_VLAN_EXTEND = auto()
>      #: Device supports receiving segmented mbufs.
> -    RX_OFFLOAD_SCATTER = auto()
> +    PORT_RX_OFFLOAD_SCATTER = auto()
> +    QUEUE_RX_OFFLOAD_SCATTER = auto()
>      #: Device supports Timestamp.
> -    RX_OFFLOAD_TIMESTAMP = auto()
> +    PORT_RX_OFFLOAD_TIMESTAMP = auto()
> +    QUEUE_RX_OFFLOAD_TIMESTAMP = auto()
>      #: Device supports crypto processing while packet is received in NIC.
> -    RX_OFFLOAD_SECURITY = auto()
> +    PORT_RX_OFFLOAD_SECURITY = auto()
> +    QUEUE_RX_OFFLOAD_SECURITY = auto()
>      #: Device supports CRC stripping.
> -    RX_OFFLOAD_KEEP_CRC = auto()
> +    PORT_RX_OFFLOAD_KEEP_CRC = auto()
> +    QUEUE_RX_OFFLOAD_KEEP_CRC = auto()
>      #: Device supports L4 checksum offload.
> -    RX_OFFLOAD_SCTP_CKSUM = auto()
> +    PORT_RX_OFFLOAD_SCTP_CKSUM = auto()
> +    QUEUE_RX_OFFLOAD_SCTP_CKSUM = auto()
>      #: Device supports inner packet L4 checksum.
> -    RX_OFFLOAD_OUTER_UDP_CKSUM = auto()
> +    PORT_RX_OFFLOAD_OUTER_UDP_CKSUM = auto()
> +    QUEUE_RX_OFFLOAD_OUTER_UDP_CKSUM = auto()
>      #: Device supports RSS hashing.
> -    RX_OFFLOAD_RSS_HASH = auto()
> +    PORT_RX_OFFLOAD_RSS_HASH = auto()
> +    QUEUE_RX_OFFLOAD_RSS_HASH = auto()
>      #: Device supports scatter Rx packets to segmented mbufs.
> -    RX_OFFLOAD_BUFFER_SPLIT = auto()
> +    PORT_RX_OFFLOAD_BUFFER_SPLIT = auto()
> +    QUEUE_RX_OFFLOAD_BUFFER_SPLIT = auto()
>      #: Device supports all checksum capabilities.
> -    RX_OFFLOAD_CHECKSUM = auto()
> +    PORT_RX_OFFLOAD_CHECKSUM = auto()
> +    QUEUE_RX_OFFLOAD_CHECKSUM = auto()
>      #: Device supports all VLAN capabilities.
> -    RX_OFFLOAD_VLAN = auto()
> +    PORT_RX_OFFLOAD_VLAN = auto()
> +    QUEUE_RX_OFFLOAD_VLAN = auto()
>      #: Device supports Rx queue setup after device started.
>      RUNTIME_RX_QUEUE_SETUP = auto()
>      #: Device supports Tx queue setup after device started.
> @@ -132,6 +152,72 @@ class NicCapability(IntEnum):
>      FLOW_CTRL = auto()
>      #: Device is running on a physical function.
>      PHYSICAL_FUNCTION = auto()
> +    #:
> +    PORT_TX_OFFLOAD_VLAN_INSERT = auto()
> +    QUEUE_TX_OFFLOAD_VLAN_INSERT = auto()
> +    #:
> +    PORT_TX_OFFLOAD_IPV4_CKSUM = auto()
> +    QUEUE_TX_OFFLOAD_IPV4_CKSUM = auto()
> +    #:
> +    PORT_TX_OFFLOAD_UDP_CKSUM = auto()
> +    QUEUE_TX_OFFLOAD_UDP_CKSUM = auto()
> +    #:
> +    PORT_TX_OFFLOAD_TCP_CKSUM = auto()
> +    QUEUE_TX_OFFLOAD_TCP_CKSUM = auto()
> +    #:
> +    PORT_TX_OFFLOAD_SCTP_CKSUM = auto()
> +    QUEUE_TX_OFFLOAD_SCTP_CKSUM = auto()
> +    #:
> +    PORT_TX_OFFLOAD_TCP_TSO = auto()
> +    QUEUE_TX_OFFLOAD_TCP_TSO = auto()
> +    #:
> +    PORT_TX_OFFLOAD_UDP_TSO = auto()
> +    QUEUE_TX_OFFLOAD_UDP_TSO = auto()
> +    #:
> +    PORT_TX_OFFLOAD_OUTER_IPV4_CKSUM = auto()
> +    QUEUE_TX_OFFLOAD_OUTER_IPV4_CKSUM = auto()
> +    #:
> +    PORT_TX_OFFLOAD_QINQ_INSERT = auto()
> +    QUEUE_TX_OFFLOAD_QINQ_INSERT = auto()
> +    #:
> +    PORT_TX_OFFLOAD_VXLAN_TNL_TSO = auto()
> +    QUEUE_TX_OFFLOAD_VXLAN_TNL_TSO = auto()
> +    #:
> +    PORT_TX_OFFLOAD_GRE_TNL_TSO = auto()
> +    QUEUE_TX_OFFLOAD_GRE_TNL_TSO = auto()
> +    #:
> +    PORT_TX_OFFLOAD_IPIP_TNL_TSO = auto()
> +    QUEUE_TX_OFFLOAD_IPIP_TNL_TSO = auto()
> +    #:
> +    PORT_TX_OFFLOAD_GENEVE_TNL_TSO = auto()
> +    QUEUE_TX_OFFLOAD_GENEVE_TNL_TSO = auto()
> +    #:
> +    PORT_TX_OFFLOAD_MACSEC_INSERT = auto()
> +    QUEUE_TX_OFFLOAD_MACSEC_INSERT = auto()
> +    #:
> +    PORT_TX_OFFLOAD_MT_LOCKFREE = auto()
> +    QUEUE_TX_OFFLOAD_MT_LOCKFREE = auto()
> +    #:
> +    PORT_TX_OFFLOAD_MULTI_SEGS = auto()
> +    QUEUE_TX_OFFLOAD_MULTI_SEGS = auto()
> +    #:
> +    PORT_TX_OFFLOAD_MBUF_FAST_FREE = auto()
> +    QUEUE_TX_OFFLOAD_MBUF_FAST_FREE = auto()
> +    #:
> +    PORT_TX_OFFLOAD_SECURITY = auto()
> +    QUEUE_TX_OFFLOAD_SECURITY = auto()
> +    #:
> +    PORT_TX_OFFLOAD_UDP_TNL_TSO = auto()
> +    QUEUE_TX_OFFLOAD_UDP_TNL_TSO = auto()
> +    #:
> +    PORT_TX_OFFLOAD_IP_TNL_TSO = auto()
> +    QUEUE_TX_OFFLOAD_IP_TNL_TSO = auto()
> +    #:
> +    PORT_TX_OFFLOAD_OUTER_UDP_CKSUM = auto()
> +    QUEUE_TX_OFFLOAD_OUTER_UDP_CKSUM = auto()
> +    #:
> +    PORT_TX_OFFLOAD_SEND_ON_TIMESTAMP = auto()
> +    QUEUE_TX_OFFLOAD_SEND_ON_TIMESTAMP = auto()
>
>
>  def requires_link_topology(
> diff --git a/dts/api/testpmd/__init__.py b/dts/api/testpmd/__init__.py
> index 9e9cbaf495..aadb7f4e70 100644
> --- a/dts/api/testpmd/__init__.py
> +++ b/dts/api/testpmd/__init__.py
> @@ -39,6 +39,8 @@
>      FlowRule,
>      RxOffloadCapabilities,
>      RxOffloadCapability,
> +    RxOffloadConfiguration,
> +    RxTxLiteralSwitch,
>      TestPmdDevice,
>      TestPmdPort,
>      TestPmdPortFlowCtrl,
> @@ -46,6 +48,9 @@
>      TestPmdQueueInfo,
>      TestPmdRxqInfo,
>      TestPmdVerbosePacket,
> +    TxOffloadCapabilities,
> +    TxOffloadCapability,
> +    TxOffloadConfiguration,
>      VLANOffloadFlag,
>  )
>  from framework.context import get_ctx
> @@ -1190,13 +1195,14 @@ def _update_capabilities_from_flag(
>          unsupported_capabilities: MutableSet["NicCapability"],
>          flag_class: type[Flag],
>          supported_flags: Flag,
> +        prefix: str = "",
>      ) -> None:
>          """Divide all flags from `flag_class` into supported and
> unsupported."""
>          for flag in flag_class:
>              if flag in supported_flags:
> -                supported_capabilities.add(NicCapability[str(flag.name)])
> +                supported_capabilities.add(NicCapability[f"{prefix}{
> flag.name}"])
>              else:
> -                unsupported_capabilities.add(NicCapability[str(flag.name
> )])
> +                unsupported_capabilities.add(NicCapability[f"{prefix}{
> flag.name}"])
>
>      @_requires_started_ports
>      def get_capabilities_rxq_info(
> @@ -1293,6 +1299,55 @@ def get_capabilities_physical_function(
>          else:
>              unsupported_capabilities.add(NicCapability.PHYSICAL_FUNCTION)
>
> +    @staticmethod
> +    def get_offload_capabilities_func(
> +        rxtx: RxTxLiteralSwitch,
> +    ) -> Callable[["TestPmd", MutableSet["NicCapability"],
> MutableSet["NicCapability"]], None]:
> +        """High-order function that returns a method for gathering Rx/Tx
> offload capabilities.
> +
> +        Args:
> +            rxtx: whether to gather the rx or tx capabilities in the
> returned method.
> +
> +        Returns:
> +            A method for gathering Rx/Tx offload capabilities that meets
> the required structure.
> +        """
> +
> +        def get_capabilities(
> +            self: "TestPmd",
> +            supported_capabilities: MutableSet["NicCapability"],
> +            unsupported_capabilities: MutableSet["NicCapability"],
> +        ) -> None:
> +            """Get all rx/tx offload capabilities and divide them into
> supported and unsupported.
> +
> +            Args:
> +                self: The shell instance to get the capabilities from.
> +                supported_capabilities: Supported capabilities will be
> added to this set.
> +                unsupported_capabilities: Unsupported capabilities will
> be added to this set.
> +            """
> +            self._logger.info(f"Getting {rxtx} offload capabilities.")
> +            command = f"show port {self.ports[0].id} {rxtx}_offload
> capabilities"
> +            offload_capabilities_out = self.send_command(command)
> +
> +            capabilities = TxOffloadCapabilities if rxtx == "tx" else
> RxOffloadCapabilities
> +            offload_capabilities =
> capabilities.parse(offload_capabilities_out)
> +
> +            self._update_capabilities_from_flag(
> +                supported_capabilities,
> +                unsupported_capabilities,
> +                TxOffloadCapability if rxtx == "tx" else
> RxOffloadCapability,
> +                offload_capabilities.per_port |
> offload_capabilities.per_queue,
> +                prefix=f"PORT_{rxtx.upper()}_OFFLOAD_",
> +            )
> +            self._update_capabilities_from_flag(
> +                supported_capabilities,
> +                unsupported_capabilities,
> +                TxOffloadCapability if rxtx == "tx" else
> RxOffloadCapability,
> +                offload_capabilities.per_queue,
> +                prefix=f"QUEUE_{rxtx.upper()}_OFFLOAD_",
> +            )
> +
> +        return get_capabilities
> +
>      @_requires_stopped_ports
>      def set_port_mbuf_fast_free(
>          self,
> @@ -1352,3 +1407,41 @@ def set_queue_mbuf_fast_free(
>              raise InteractiveCommandExecutionError(
>                  f"Failed to get offload config on port {port_id}, queue
> {queue_id}:\n{output}"
>              )
> +
> +    @_requires_started_ports
> +    def get_offload_config(
> +        self,
> +        port_id: int,
> +        rxtx: RxTxLiteralSwitch,
> +        /,
> +        verify: bool = True,
> +    ) -> RxOffloadConfiguration | TxOffloadConfiguration:
> +        """Get the Rx or Tx offload configuration of the queues from the
> given port.
> +
> +        Args:
> +            port_id: The port ID that contains the desired queues.
> +            rxtx: Whether to get the Rx or Tx configuration of the given
> queues.
> +            verify: If :data:`True` the output of the command will be
> scanned in an attempt to
> +                verify that the offload configuration was retrieved
> successfully on all queues.
> +
> +        Returns:
> +            An offload configuration containing the capabilities of the
> port and queues.
> +
> +        Raises:
> +            InteractiveCommandExecutionError: If all queue offload
> configurations could not be
> +                retrieved.
> +        """
> +        config_output = self.send_command(f"show port {port_id}
> {rxtx}_offload configuration")
> +        if verify:
> +            if (
> +                f"Rx Offloading Configuration of port {port_id}" not in
> config_output
> +                and f"Tx Offloading Configuration of port {port_id}" not
> in config_output
> +            ):
> +                self._logger.debug(f"Get port offload config
> error\n{config_output}")
> +                raise InteractiveCommandExecutionError(
> +                    f"Failed to get offload config on port
> {port_id}:\n{config_output}"
> +                )
> +        if rxtx == "rx":
> +            return RxOffloadConfiguration.parse(config_output)
> +        else:
> +            return TxOffloadConfiguration.parse(config_output)
> diff --git a/dts/api/testpmd/types.py b/dts/api/testpmd/types.py
> index d1ebf6f2d1..7e28235b18 100644
> --- a/dts/api/testpmd/types.py
> +++ b/dts/api/testpmd/types.py
> @@ -18,6 +18,8 @@
>  from framework.parser import ParserFn, TextParser
>  from framework.utils import REGEX_FOR_MAC_ADDRESS, StrEnum
>
> +RxTxLiteralSwitch = Literal["rx", "tx"]
> +
>
>  class TestPmdDevice:
>      """The data of a device that testpmd can recognize.
> @@ -1246,7 +1248,99 @@ class TestPmdVerbosePacket(TextParser):
>      )
>
>
> -class RxOffloadCapability(Flag):
> +class OffloadCapability(Flag):
> +    """Flags generated from RxOffloadCapabilites and
> TxOffloadCapabilities classes."""
> +
> +    @classmethod
> +    def from_string(cls, line: str) -> Self:
> +        """Make an instance from a string containing the flag names
> separated with a space.
> +
> +        Args:
> +            line: The line to parse.
> +
> +        Returns:
> +            A new instance containing all found flags.
> +        """
> +        flag = cls(0)
> +        for flag_name in line.split():
> +            flag |= cls[flag_name]
> +        return flag
> +
> +    @classmethod
> +    def from_list(cls, lines: list[str]) -> list[Self]:
> +        """Gather capabilities from a list of strings.
> +
> +        Args:
> +            lines: The list of capabilities to make flags from.
> +        """
> +        return [cls.from_string(line) for line in lines]
> +
> +    @classmethod
> +    def make_parser(
> +        cls, port_or_queue: Literal["port", "queue"], /, find_multiple:
> bool = False
> +    ) -> ParserFn:
> +        """Make a parser function.
> +
> +        Args:
> +            port_or_queue: If :data:`True`, will return capabilities per
> port. If :data:`False`,
> +                will return capabilities per queue.
> +            find_multiple: If :data:`True`, will use
> :func:`TextParser.find_all` to find all
> +                matches for the regex query and return a list of
> instances based on those matches.
> +                If :data:`False`, will return a single instance of the
> flag based off a single
> +                match.
> +
> +        Returns:
> +            ParserFn: A dictionary for the `dataclasses.field` metadata
> argument containing a
> +                parser function that makes an instance of this flag from
> text.
> +        """
> +        granularity = port_or_queue.capitalize()
> +        regex = rf"{granularity}[\s\[\]\d]+:(.*)$"
> +        if find_multiple:
> +            return TextParser.wrap(TextParser.find_all(regex,
> re.MULTILINE), cls.from_list)
> +        return TextParser.wrap(TextParser.find(regex, re.MULTILINE),
> cls.from_string)
> +
> +
> +class TxOffloadCapability(OffloadCapability):
> +    """Tx offload capabilities of a device.
> +
> +    The flags are taken from ``lib/ethdev/rte_ethdev.h``.
> +    They're prefixed with ``RTE_ETH_TX_OFFLOAD`` in
> ``lib/ethdev/rte_ethdev.h``
> +    instead of ``TX_OFFLOAD``, which is what testpmd changes the prefix
> to.
> +
> +    The ``TX_OFFLOAD`` prefix has been preserved so that the same flag
> names can be used
> +    in :class:`NicCapability`. The prefix is needed in
> :class:`NicCapability` since there's
> +    no other qualifier which would sufficiently distinguish it from other
> capabilities.
> +
> +    References:
> +        DPDK lib: ``lib/ethdev/rte_ethdev.h``
> +        testpmd display function:
> ``app/test-pmd/cmdline.c:print_rx_offloads()``
> +    """
> +
> +    VLAN_INSERT = auto()
> +    IPV4_CKSUM = auto()
> +    UDP_CKSUM = auto()
> +    TCP_CKSUM = auto()
> +    SCTP_CKSUM = auto()
> +    TCP_TSO = auto()
> +    UDP_TSO = auto()
> +    OUTER_IPV4_CKSUM = auto()
> +    QINQ_INSERT = auto()
> +    VXLAN_TNL_TSO = auto()
> +    GRE_TNL_TSO = auto()
> +    IPIP_TNL_TSO = auto()
> +    GENEVE_TNL_TSO = auto()
> +    MACSEC_INSERT = auto()
> +    MT_LOCKFREE = auto()
> +    MULTI_SEGS = auto()
> +    MBUF_FAST_FREE = auto()
> +    SECURITY = auto()
> +    UDP_TNL_TSO = auto()
> +    IP_TNL_TSO = auto()
> +    OUTER_UDP_CKSUM = auto()
> +    SEND_ON_TIMESTAMP = auto()
> +
> +
> +class RxOffloadCapability(OffloadCapability):
>      """Rx offload capabilities of a device.
>
>      The flags are taken from ``lib/ethdev/rte_ethdev.h``.
> @@ -1265,102 +1359,103 @@ class RxOffloadCapability(Flag):
>      """
>
>      #:
> -    RX_OFFLOAD_VLAN_STRIP = auto()
> +    VLAN_STRIP = auto()
>      #: Device supports L3 checksum offload.
> -    RX_OFFLOAD_IPV4_CKSUM = auto()
> +    IPV4_CKSUM = auto()
>      #: Device supports L4 checksum offload.
> -    RX_OFFLOAD_UDP_CKSUM = auto()
> +    UDP_CKSUM = auto()
>      #: Device supports L4 checksum offload.
> -    RX_OFFLOAD_TCP_CKSUM = auto()
> +    TCP_CKSUM = auto()
>      #: Device supports Large Receive Offload.
> -    RX_OFFLOAD_TCP_LRO = auto()
> +    TCP_LRO = auto()
>      #: Device supports QinQ (queue in queue) offload.
> -    RX_OFFLOAD_QINQ_STRIP = auto()
> +    QINQ_STRIP = auto()
>      #: Device supports inner packet L3 checksum.
> -    RX_OFFLOAD_OUTER_IPV4_CKSUM = auto()
> +    OUTER_IPV4_CKSUM = auto()
>      #: Device supports MACsec.
> -    RX_OFFLOAD_MACSEC_STRIP = auto()
> +    MACSEC_STRIP = auto()
>      #: Device supports filtering of a VLAN Tag identifier.
> -    RX_OFFLOAD_VLAN_FILTER = 1 << 9
> +    VLAN_FILTER = 1 << 9
>      #: Device supports VLAN offload.
> -    RX_OFFLOAD_VLAN_EXTEND = auto()
> +    VLAN_EXTEND = auto()
>      #: Device supports receiving segmented mbufs.
> -    RX_OFFLOAD_SCATTER = 1 << 13
> +    SCATTER = 1 << 13
>      #: Device supports Timestamp.
> -    RX_OFFLOAD_TIMESTAMP = auto()
> +    TIMESTAMP = auto()
>      #: Device supports crypto processing while packet is received in NIC.
> -    RX_OFFLOAD_SECURITY = auto()
> +    SECURITY = auto()
>      #: Device supports CRC stripping.
> -    RX_OFFLOAD_KEEP_CRC = auto()
> +    KEEP_CRC = auto()
>      #: Device supports L4 checksum offload.
> -    RX_OFFLOAD_SCTP_CKSUM = auto()
> +    SCTP_CKSUM = auto()
>      #: Device supports inner packet L4 checksum.
> -    RX_OFFLOAD_OUTER_UDP_CKSUM = auto()
> +    OUTER_UDP_CKSUM = auto()
>      #: Device supports RSS hashing.
> -    RX_OFFLOAD_RSS_HASH = auto()
> +    RSS_HASH = auto()
>      #: Device supports
> -    RX_OFFLOAD_BUFFER_SPLIT = auto()
> +    BUFFER_SPLIT = auto()
>      #: Device supports all checksum capabilities.
> -    RX_OFFLOAD_CHECKSUM = RX_OFFLOAD_IPV4_CKSUM | RX_OFFLOAD_UDP_CKSUM |
> RX_OFFLOAD_TCP_CKSUM
> +    CHECKSUM = IPV4_CKSUM | UDP_CKSUM | TCP_CKSUM
>      #: Device supports all VLAN capabilities.
> -    RX_OFFLOAD_VLAN = (
> -        RX_OFFLOAD_VLAN_STRIP
> -        | RX_OFFLOAD_VLAN_FILTER
> -        | RX_OFFLOAD_VLAN_EXTEND
> -        | RX_OFFLOAD_QINQ_STRIP
> -    )
> +    VLAN = VLAN_STRIP | VLAN_FILTER | VLAN_EXTEND | QINQ_STRIP
>
> -    @classmethod
> -    def from_string(cls, line: str) -> Self:
> -        """Make an instance from a string containing the flag names
> separated with a space.
>
> -        Args:
> -            line: The line to parse.
> + at dataclass
> +class OffloadCapabilities(TextParser):
> +    """The result of testpmd's ``show port <port_id> rx/tx_offload
> capabilities`` command."""
>
> -        Returns:
> -            A new instance containing all found flags.
> -        """
> -        flag = cls(0)
> -        for flag_name in line.split():
> -            flag |= cls[f"RX_OFFLOAD_{flag_name}"]
> -        return flag
> +    port_id: int = field(metadata=TextParser.find_int(r"Offloading
> Capabilities of port (\d+) :"))
> +    #: Per-queue offload capabilities.
> +    per_queue: OffloadCapability
> +    #: Capabilities other than per-queue offload capabilities.
> +    per_port: OffloadCapability
>
> -    @classmethod
> -    def make_parser(cls, per_port: bool) -> ParserFn:
> -        """Make a parser function.
>
> -        Args:
> -            per_port: If :data:`True`, will return capabilities per port.
> If :data:`False`,
> -                will return capabilities per queue.
> + at dataclass
> +class RxOffloadCapabilities(OffloadCapabilities):
> +    """Extends :class:`OffloadCapabilities` with Rx specific
> functionality."""
>
> -        Returns:
> -            ParserFn: A dictionary for the `dataclasses.field` metadata
> argument containing a
> -                parser function that makes an instance of this flag from
> text.
> -        """
> -        granularity = "Port" if per_port else "Queue"
> -        return TextParser.wrap(
> -            TextParser.find(rf"Per {granularity}\s+:(.*)$", re.MULTILINE),
> -            cls.from_string,
> -        )
> +    per_queue: OffloadCapability =
> field(metadata=RxOffloadCapability.make_parser("queue"))
> +    per_port: OffloadCapability =
> field(metadata=RxOffloadCapability.make_parser("port"))
>
>
>  @dataclass
> -class RxOffloadCapabilities(TextParser):
> -    """The result of testpmd's ``show port <port_id> rx_offload
> capabilities`` command.
> +class TxOffloadCapabilities(OffloadCapabilities):
> +    """Extends :class:`OffloadCapabilities` with Tx specific
> functionality."""
>
> -    References:
> -        testpmd command function:
> ``app/test-pmd/cmdline.c:cmd_rx_offload_get_capa()``
> -        testpmd display function:
> ``app/test-pmd/cmdline.c:cmd_rx_offload_get_capa_parsed()``
> -    """
> +    per_queue: OffloadCapability =
> field(metadata=TxOffloadCapability.make_parser("queue"))
> +    per_port: OffloadCapability =
> field(metadata=TxOffloadCapability.make_parser("port"))
>
> -    #:
> -    port_id: int = field(
> -        metadata=TextParser.find_int(r"Rx Offloading Capabilities of port
> (\d+) :")
> +
> + at dataclass
> +class OffloadConfiguration(TextParser):
> +    """The result of testpmd's ``show port <port_id> rx/tx_offload
> configuration`` command."""
> +
> +    port_id: int = field(metadata=TextParser.find_int(r"Offloading
> Configuration of port (\d+) :"))
> +    #: Queue offload configurations.
> +    queues: list[OffloadCapability]
> +    #: Port offload configuration.
> +    port: OffloadCapability
>

One final nit - I think attribute names queue_configs and port_config would
read more clearly. What do you think?

Reviewed-by: Patrick Robb <probb at iol.unh.edu>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mails.dpdk.org/archives/dev/attachments/20251027/9dc0a85f/attachment-0001.htm>


More information about the dev mailing list