Add transmit and receive offload support using the virtio-net header
that is exchanged with the kernel TAP device.
Tx offloads:
- UDP and TCP checksum offload: set VIRTIO_NET_HDR_F_NEEDS_CSUM
with appropriate csum_start and csum_offset fields
- TCP segmentation offload (TSO): set gso_type and gso_size
Rx offloads:
- Parse virtio-net header flags to determine checksum status
- Handle NEEDS_CSUM by either marking L4_CKSUM_NONE for known
protocols or computing the checksum in software for tunnels
- Handle DATA_VALID flag to mark L4_CKSUM_GOOD
- Parse GSO headers to populate LRO metadata
Configure kernel-side offloads via TUNSETOFFLOAD in dev_configure
based on the requested rx offload flags.
Report offload capabilities in dev_info.
Signed-off-by: Stephen Hemminger <[email protected]>
---
doc/guides/nics/features/rtap.ini | 2 ++
drivers/net/rtap/rtap_ethdev.c | 30 +++++++++++++++++++++++++++++-
2 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/rtap.ini
b/doc/guides/nics/features/rtap.ini
index ce0804d795..b8eaa805fe 100644
--- a/doc/guides/nics/features/rtap.ini
+++ b/doc/guides/nics/features/rtap.ini
@@ -11,6 +11,8 @@ Allmulticast mode = Y
Scattered Rx = P
Basic stats = Y
Stats per queue = Y
+TSO = Y
+L4 checksum offload = Y
Linux = Y
ARMv7 = Y
ARMv8 = Y
diff --git a/drivers/net/rtap/rtap_ethdev.c b/drivers/net/rtap/rtap_ethdev.c
index 591fe91eac..277a280772 100644
--- a/drivers/net/rtap/rtap_ethdev.c
+++ b/drivers/net/rtap/rtap_ethdev.c
@@ -31,6 +31,16 @@
#define RTAP_DEFAULT_IFNAME "rtap%d"
+#define RTAP_TX_OFFLOAD (RTE_ETH_TX_OFFLOAD_MULTI_SEGS | \
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_CKSUM | \
+ RTE_ETH_TX_OFFLOAD_TCP_TSO)
+
+#define RTAP_RX_OFFLOAD (RTE_ETH_RX_OFFLOAD_UDP_CKSUM | \
+ RTE_ETH_RX_OFFLOAD_TCP_CKSUM | \
+ RTE_ETH_RX_OFFLOAD_TCP_LRO | \
+ RTE_ETH_RX_OFFLOAD_SCATTER)
+
#define RTAP_DEFAULT_BURST 64
#define RTAP_NUM_BUFFERS 1024
#define RTAP_MAX_QUEUES 128
@@ -317,7 +327,21 @@ rtap_dev_configure(struct rte_eth_dev *dev)
if (dev->data->nb_rx_queues != dev->data->nb_tx_queues)
return -EINVAL;
- if (ioctl(pmd->keep_fd, TUNSETOFFLOAD, 0) != 0) {
+ /*
+ * Set offload flags visible on the kernel network interface.
+ * This controls whether kernel will use checksum offload etc.
+ * Note: kernel transmit is DPDK receive.
+ */
+ const struct rte_eth_rxmode *rx_mode = &dev->data->dev_conf.rxmode;
+ unsigned int offload = 0;
+ if (rx_mode->offloads & RTE_ETH_RX_OFFLOAD_CHECKSUM) {
+ offload |= TUN_F_CSUM;
+
+ if (rx_mode->offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO)
+ offload |= TUN_F_TSO4 | TUN_F_TSO6 | TUN_F_TSO_ECN;
+ }
+
+ if (ioctl(pmd->keep_fd, TUNSETOFFLOAD, offload) != 0) {
PMD_LOG(ERR, "ioctl(TUNSETOFFLOAD) failed: %s",
strerror(errno));
return -1;
}
@@ -336,6 +360,10 @@ rtap_dev_info(struct rte_eth_dev *dev, struct
rte_eth_dev_info *dev_info)
dev_info->min_rx_bufsize = RTAP_MIN_RX_BUFSIZE;
dev_info->max_rx_queues = RTAP_MAX_QUEUES;
dev_info->max_tx_queues = RTAP_MAX_QUEUES;
+ dev_info->rx_queue_offload_capa = RTAP_RX_OFFLOAD;
+ dev_info->rx_offload_capa = dev_info->rx_queue_offload_capa;
+ dev_info->tx_queue_offload_capa = RTAP_TX_OFFLOAD;
+ dev_info->tx_offload_capa = dev_info->tx_queue_offload_capa;
dev_info->default_rxportconf = (struct rte_eth_dev_portconf) {
.burst_size = RTAP_DEFAULT_BURST,
--
2.51.0