[PATCH] net/hns3: fix L4 checksum incorrect for tunnel packets
Xingui Yang
yangxingui at huawei.com
Sat May 9 08:36:56 CEST 2026
In HIP09 simple BD mode, the driver incorrectly calculates L4_START
position for tunnel packets. The current implementation only uses
l2_len + l3_len without considering outer header lengths (outer_l2_len
and outer_l3_len), causing hardware to calculate checksum from wrong
offset.
For a typical NvGRE tunnel packet with structure:
Outer Eth(14) + Outer IPv6(40) + NvGRE(8) + Inner Eth(14) +
Inner IPv6(40) + TCP(20)
Expected L4_START: 116 bytes (from packet start to inner TCP header)
Actual calculation: 62 bytes (missing outer headers)
This results in incorrect TCP/UDP checksum for all tunnel packets when
using simple BD mode, including NvGRE, VxLAN, GRE, GENEVE tunnels.
Fix by adding outer_l2_len and outer_l3_len to L4_START calculation
when RTE_MBUF_F_TX_TUNNEL_MASK flag is set.
Fixes: 6393fc0b823 ("net/hns3: simplify hardware checksum offloading")
Cc: stable at dpdk.org
Signed-off-by: Xingui Yang <yangxingui at huawei.com>
---
drivers/net/hns3/hns3_rxtx.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index 573604b0cd..4d48cbdc11 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -3982,6 +3982,7 @@ hns3_handle_simple_bd(struct hns3_tx_queue *txq, struct hns3_desc *desc,
{
#define HNS3_TCP_CSUM_OFFSET 16
#define HNS3_UDP_CSUM_OFFSET 6
+ uint32_t l4_start;
/*
* In HIP09, NIC HW support Tx simple BD mode that the HW will
@@ -4003,9 +4004,13 @@ hns3_handle_simple_bd(struct hns3_tx_queue *txq, struct hns3_desc *desc,
((m->ol_flags & RTE_MBUF_F_TX_L4_MASK) == RTE_MBUF_F_TX_TCP_CKSUM ||
(m->ol_flags & RTE_MBUF_F_TX_L4_MASK) == RTE_MBUF_F_TX_UDP_CKSUM)) {
/* set checksum start and offset, defined in 2 Bytes */
+ l4_start = m->l2_len + m->l3_len;
+ if (m->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK)
+ l4_start += m->outer_l2_len + m->outer_l3_len;
+
hns3_set_field(desc->tx.type_cs_vlan_tso_len,
HNS3_TXD_L4_START_M, HNS3_TXD_L4_START_S,
- (m->l2_len + m->l3_len) >> HNS3_SIMPLE_BD_UNIT);
+ l4_start >> HNS3_SIMPLE_BD_UNIT);
hns3_set_field(desc->tx.ol_type_vlan_len_msec,
HNS3_TXD_L4_CKS_OFFSET_M, HNS3_TXD_L4_CKS_OFFSET_S,
(m->ol_flags & RTE_MBUF_F_TX_L4_MASK) ==
--
2.33.0
More information about the dev
mailing list