AF_XDP TX 元数据

本文档描述了如何在使用 AF_XDP 发送数据包时启用卸载。有关如何在接收端访问类似元数据的信息,请参阅 XDP RX 元数据

通用设计

通过 tx_metadata_lenstruct xdp_umem_reg 中的 XDP_UMEM_TX_METADATA_LEN 标志来保留元数据的预留空间。因此,对于共享相同 umem 的每个套接字,元数据长度都是相同的。元数据布局是固定的 UAPI,请参阅 include/uapi/linux/if_xdp.h 中的 union xsk_tx_metadata。因此,一般来说,上面的 tx_metadata_len 字段应包含 sizeof(union xsk_tx_metadata)

请注意,在原始实现中,XDP_UMEM_TX_METADATA_LEN 标志不是必需的。应用程序可能会尝试先使用标志创建 umem,如果失败,则尝试不使用标志进行另一次尝试。

预留空间和元数据本身应位于 umem 帧中 xdp_desc->addr 的正前方。在一个帧内,元数据布局如下

       tx_metadata_len
 /                         \
+-----------------+---------+----------------------------+
| xsk_tx_metadata | padding |          payload           |
+-----------------+---------+----------------------------+
                            ^
                            |
                      xdp_desc->addr

AF_XDP 应用程序可以请求大于 sizeof(struct xsk_tx_metadata) 的预留空间。内核将忽略填充(并且仍将使用 xdp_desc->addr - tx_metadata_len 来定位 xsk_tx_metadata)。对于不应携带任何元数据的帧(即,不具有 XDP_TX_METADATA 选项的帧),内核也会忽略元数据区域。

flags 字段启用特定的卸载

  • XDP_TXMD_FLAGS_TIMESTAMP: 请求设备将传输时间戳放入 union xsk_tx_metadatatx_timestamp 字段。

  • XDP_TXMD_FLAGS_CHECKSUM: 请求设备计算 L4 校验和。csum_start 指定校验和应从哪里开始的字节偏移量,csum_offset 指定设备应将计算出的校验和存储在哪里的字节偏移量。

除了上述标志之外,为了触发卸载,第一个数据包的 struct xdp_desc 描述符应在 options 字段中设置 XDP_TX_METADATA 位。另请注意,在多缓冲区数据包中,只有第一个块应携带元数据。

软件 TX 校验和

出于开发和测试目的,可以将 XDP_UMEM_TX_SW_CSUM 标志传递给 XDP_UMEM_REG UMEM 注册调用。在这种情况下,当以 XDK_COPY 模式运行时,TX 校验和在 CPU 上计算。不要在生产环境中启用此选项,因为它会负面影响性能。

查询设备功能

每个设备都通过 netlink netdev 系列导出其卸载功能。请参阅 Documentation/netlink/specs/netdev.yaml 中的 xsk-flags 功能位掩码。

  • tx-timestamp:设备支持 XDP_TXMD_FLAGS_TIMESTAMP

  • tx-checksum:设备支持 XDP_TXMD_FLAGS_CHECKSUM

请参阅 tools/net/ynl/samples/netdev.c,了解如何查询此信息。

示例

请参阅 tools/testing/selftests/bpf/xdp_hw_metadata.c,了解处理 TX 元数据的示例程序。另请参阅 https://github.com/fomichev/xskgen,了解更简洁的示例。