From a568f936c212096c1d7a9d2bf1b2787a08abecce Mon Sep 17 00:00:00 2001 From: liweigang Date: Wed, 13 Aug 2025 14:11:01 +0800 Subject: [PATCH] merge origin/openEuler-24.03-LTS-SP2 to openEuler-25.09 and modify patch number --- 0095-net-hns3-fix-CRC-data-segment.patch | 60 ++ ...-hns3-fix-Rx-packet-without-CRC-data.patch | 395 ++++++++++++ ...se-of-Rx-vector-mode-with-VLAN-filte.patch | 38 ++ ...-Tx-vector-when-fast-free-not-enable.patch | 42 ++ ...3-check-requirement-for-hardware-GRO.patch | 56 ++ 0100-net-add-tunnel-packet-type-parsing.patch | 193 ++++++ ...-testpmd-use-packet-type-parsing-API.patch | 594 ++++++++++++++++++ ...-fix-VLAN-parsing-in-checksum-engine.patch | 67 ++ ...-fix-offset-in-GENEVE-packet-parsing.patch | 37 ++ ...-app-testpmd-fix-packet-type-parsing.patch | 51 ++ 0105-net-fix-GTP-packet-parsing.patch | 43 ++ ...-tunnel-length-in-UDP-tunnel-parsing.patch | 78 +++ 0107-app-testpmd-fix-tunnel-inner-info.patch | 41 ++ ...b_uio-fix-build-error-in-kernel-6.12.patch | 0 dpdk.spec | 76 ++- 15 files changed, 1751 insertions(+), 20 deletions(-) create mode 100644 0095-net-hns3-fix-CRC-data-segment.patch create mode 100644 0096-net-hns3-fix-Rx-packet-without-CRC-data.patch create mode 100644 0097-net-hns3-allow-use-of-Rx-vector-mode-with-VLAN-filte.patch create mode 100644 0098-net-hns3-allow-use-of-Tx-vector-when-fast-free-not-enable.patch create mode 100644 0099-net-hns3-check-requirement-for-hardware-GRO.patch create mode 100644 0100-net-add-tunnel-packet-type-parsing.patch create mode 100644 0101-app-testpmd-use-packet-type-parsing-API.patch create mode 100644 0102-app-testpmd-fix-VLAN-parsing-in-checksum-engine.patch create mode 100644 0103-net-fix-offset-in-GENEVE-packet-parsing.patch create mode 100644 0104-app-testpmd-fix-packet-type-parsing.patch create mode 100644 0105-net-fix-GTP-packet-parsing.patch create mode 100644 0106-net-add-tunnel-length-in-UDP-tunnel-parsing.patch create mode 100644 0107-app-testpmd-fix-tunnel-inner-info.patch rename 0095-linux-igb_uio-fix-build-error-in-kernel-6.12.patch => 0108-linux-igb_uio-fix-build-error-in-kernel-6.12.patch (100%) diff --git a/0095-net-hns3-fix-CRC-data-segment.patch b/0095-net-hns3-fix-CRC-data-segment.patch new file mode 100644 index 0000000..53348c3 --- /dev/null +++ b/0095-net-hns3-fix-CRC-data-segment.patch @@ -0,0 +1,60 @@ +From 7a99b6ca9d079e9364ba61d3fe802a4761739c8f Mon Sep 17 00:00:00 2001 +From: Dengdui Huang +Date: Fri, 16 May 2025 15:15:18 +0800 +Subject: [PATCH] net/hns3: fix CRC data segment + +[ upstream commit 7a99b6ca9d079e9364ba61d3fe802a4761739c8f ] + +When the packet is received into a multisegment mbuf and +the last segment contains only CRC data, the driver should +not release this segment. Otherwise, the application cannot +look the CRC data. This patch fixes it. + +Fixes: 8973d7c4ca12 ("net/hns3: support keeping CRC") +Cc: stable@dpdk.org + +Signed-off-by: Dengdui Huang +--- + drivers/net/hns3/hns3_rxtx.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index bb7ffee12c..49b6f16ccd 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -2386,18 +2386,16 @@ hns3_rxd_to_vlan_tci(struct hns3_rx_queue *rxq, struct rte_mbuf *mb, + } + + static inline void +-recalculate_data_len(struct rte_mbuf *first_seg, struct rte_mbuf *last_seg, +- struct rte_mbuf *rxm, struct hns3_rx_queue *rxq, +- uint16_t data_len) ++recalculate_data_len(struct rte_mbuf *last_seg, struct rte_mbuf *rxm, ++ struct hns3_rx_queue *rxq) + { ++ uint16_t data_len = rxm->data_len; + uint8_t crc_len = rxq->crc_len; + + if (data_len <= crc_len) { +- rte_pktmbuf_free_seg(rxm); +- first_seg->nb_segs--; ++ rxm->data_len = 0; + last_seg->data_len = (uint16_t)(last_seg->data_len - + (crc_len - data_len)); +- last_seg->next = NULL; + } else + rxm->data_len = (uint16_t)(data_len - crc_len); + } +@@ -2728,8 +2726,7 @@ hns3_recv_scattered_pkts(void *rx_queue, + rxm->next = NULL; + if (unlikely(rxq->crc_len > 0)) { + first_seg->pkt_len -= rxq->crc_len; +- recalculate_data_len(first_seg, last_seg, rxm, rxq, +- rxm->data_len); ++ recalculate_data_len(last_seg, rxm, rxq); + } + + first_seg->port = rxq->port_id; +-- +2.25.1 + diff --git a/0096-net-hns3-fix-Rx-packet-without-CRC-data.patch b/0096-net-hns3-fix-Rx-packet-without-CRC-data.patch new file mode 100644 index 0000000..834956b --- /dev/null +++ b/0096-net-hns3-fix-Rx-packet-without-CRC-data.patch @@ -0,0 +1,395 @@ +From b5f814a62ba322111a7df79c019709c5ab0ef3b5 Mon Sep 17 00:00:00 2001 +From: Dengdui Huang +Date: Fri, 16 May 2025 15:15:19 +0800 +Subject: [PATCH] net/hns3: fix Rx packet without CRC data + +[ upstream commit 99c065da47c432e9529f761b457cde1fd8c89f20 ] + +When KEEP_CRC offload is enabled, the CRC data is still stripped +in following cases: +1. For HIP08 network engine, the packet type is TCP and the length + is less than or equal to 60B. +2. For HIP09 network engine, the packet type is IP and the length + is less than or equal to 60B. + +So driver has to recaculate packet CRC for this rare scenarios. + +In addition, to avoid impacting performance, KEEP_CRC is not +supported when NEON or SVE algorithm is used. + +Fixes: 8973d7c4ca12 ("net/hns3: support keeping CRC") +Cc: stable@dpdk.org + +Signed-off-by: Dengdui Huang +Acked-by: Huisong Li +Acked-by: Jie Hai +--- + drivers/net/hns3/hns3_ethdev.c | 2 + + drivers/net/hns3/hns3_ethdev.h | 23 +++++ + drivers/net/hns3/hns3_rxtx.c | 119 +++++++++++++++++++++----- + drivers/net/hns3/hns3_rxtx.h | 3 + + drivers/net/hns3/hns3_rxtx_vec.c | 3 +- + drivers/net/hns3/hns3_rxtx_vec_neon.h | 19 ---- + drivers/net/hns3/hns3_rxtx_vec_sve.c | 3 +- + 7 files changed, 128 insertions(+), 44 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index e8d449a..9e82f41 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2743,6 +2743,7 @@ hns3_get_capability(struct hns3_hw *hw) + hw->udp_cksum_mode = HNS3_SPECIAL_PORT_SW_CKSUM_MODE; + pf->support_multi_tc_pause = false; + hw->rx_dma_addr_align = HNS3_RX_DMA_ADDR_ALIGN_64; ++ hw->strip_crc_ptype = HNS3_STRIP_CRC_PTYPE_TCP; + return 0; + } + +@@ -2764,6 +2765,7 @@ hns3_get_capability(struct hns3_hw *hw) + hw->udp_cksum_mode = HNS3_SPECIAL_PORT_HW_CKSUM_MODE; + pf->support_multi_tc_pause = true; + hw->rx_dma_addr_align = HNS3_RX_DMA_ADDR_ALIGN_128; ++ hw->strip_crc_ptype = HNS3_STRIP_CRC_PTYPE_IP; + + return 0; + } +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 00d226d..0ce4974 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -54,6 +54,10 @@ + #define HNS3_SPECIAL_PORT_SW_CKSUM_MODE 0 + #define HNS3_SPECIAL_PORT_HW_CKSUM_MODE 1 + ++#define HNS3_STRIP_CRC_PTYPE_NONE 0 ++#define HNS3_STRIP_CRC_PTYPE_TCP 1 ++#define HNS3_STRIP_CRC_PTYPE_IP 2 ++ + #define HNS3_UC_MACADDR_NUM 128 + #define HNS3_VF_UC_MACADDR_NUM 48 + #define HNS3_MC_MACADDR_NUM 128 +@@ -655,6 +659,25 @@ struct hns3_hw { + */ + uint8_t udp_cksum_mode; + ++ /* ++ * When KEEP_CRC offload is enabled, the CRC data of some type packets ++ * whose length is less than or equal to HNS3_KEEP_CRC_OK_MIN_PKT_LEN ++ * is still be stripped on some network engine. So here has to use this ++ * field to distinguish the difference between different network engines. ++ * value range: ++ * - HNS3_STRIP_CRC_PTYPE_TCP ++ * This value for HIP08 network engine. ++ * Indicates that only the IP-TCP packet type is stripped. ++ * ++ * - HNS3_STRIP_CRC_PTYPE_IP ++ * This value for HIP09 network engine. ++ * Indicates that all IP packet types are stripped. ++ * ++ * - HNS3_STRIP_CRC_PTYPE_NONE ++ * Indicates that all packet types are not stripped. ++ */ ++ uint8_t strip_crc_ptype; ++ + struct hns3_port_base_vlan_config port_base_vlan_cfg; + + pthread_mutex_t flows_lock; /* rte_flow ops lock */ +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 32f2a41..2beef77 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #if defined(RTE_ARCH_ARM64) + #include + #include +@@ -1766,8 +1767,9 @@ hns3_rx_buf_len_calc(struct rte_mempool *mp, uint16_t *rx_buf_len) + } + + static int +-hns3_rxq_conf_runtime_check(struct hns3_hw *hw, uint16_t buf_size, +- uint16_t nb_desc) ++hns3_rxq_conf_runtime_check(struct hns3_hw *hw, ++ const struct rte_eth_rxconf *conf, ++ uint16_t buf_size, uint16_t nb_desc) + { + struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id]; + eth_rx_burst_t pkt_burst = dev->rx_pkt_burst; +@@ -1800,6 +1802,14 @@ hns3_rxq_conf_runtime_check(struct hns3_hw *hw, uint16_t buf_size, + return -EINVAL; + } + } ++ ++ if ((conf->offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC) && ++ pkt_burst != hns3_recv_pkts_simple && ++ pkt_burst != hns3_recv_scattered_pkts) { ++ hns3_err(hw, "KEEP_CRC offload is not supported with the current Rx function."); ++ return -EINVAL; ++ } ++ + return 0; + } + +@@ -1836,7 +1846,7 @@ hns3_rx_queue_conf_check(struct hns3_hw *hw, const struct rte_eth_rxconf *conf, + } + + if (hw->data->dev_started) { +- ret = hns3_rxq_conf_runtime_check(hw, *buf_size, nb_desc); ++ ret = hns3_rxq_conf_runtime_check(hw, conf, *buf_size, nb_desc); + if (ret) { + hns3_err(hw, "Rx queue runtime setup fail."); + return ret; +@@ -1957,6 +1967,8 @@ hns3_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc, + else + rxq->crc_len = 0; + ++ rxq->keep_crc_fail_ptype = hw->strip_crc_ptype; ++ + rxq->bulk_mbuf_num = 0; + + rte_spinlock_lock(&hw->lock); +@@ -2430,6 +2442,55 @@ hns3_rx_ptp_timestamp_handle(struct hns3_rx_queue *rxq, struct rte_mbuf *mbuf, + pf->rx_timestamp = timestamp; + } + ++static inline bool ++hns3_need_recalculate_crc(struct hns3_rx_queue *rxq, struct rte_mbuf *m) ++{ ++ uint32_t ptype = m->packet_type; ++ ++ if (rxq->keep_crc_fail_ptype == HNS3_STRIP_CRC_PTYPE_NONE) ++ return false; ++ ++ if (m->pkt_len > HNS3_KEEP_CRC_OK_MIN_PKT_LEN) ++ return false; ++ ++ if (!(RTE_ETH_IS_IPV4_HDR(ptype) || RTE_ETH_IS_IPV6_HDR(ptype))) ++ return false; ++ ++ if (rxq->keep_crc_fail_ptype == HNS3_STRIP_CRC_PTYPE_TCP) ++ return (ptype & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_TCP; ++ ++ return true; ++} ++ ++/* ++ * The hns3 driver requires that mbuf size must be at least 512B. ++ * When CRC is stripped by hardware, the pkt_len must be less than ++ * or equal to 60B. Therefore, the space of the mbuf is enough ++ * to insert the CRC. ++ */ ++static_assert(HNS3_KEEP_CRC_OK_MIN_PKT_LEN < HNS3_MIN_BD_BUF_SIZE, ++ "buffer size too small to insert CRC"); ++ ++static inline void ++hns3_recalculate_crc(struct rte_mbuf *m) ++{ ++ char *append_data; ++ uint32_t crc; ++ ++ crc = rte_net_crc_calc(rte_pktmbuf_mtod(m, void *), ++ m->data_len, RTE_NET_CRC32_ETH); ++ ++ /* ++ * After CRC is stripped by hardware, pkt_len and data_len do not ++ * contain the CRC length. Therefore, after CRC data is appended ++ * by PMD again. ++ */ ++ append_data = rte_pktmbuf_append(m, RTE_ETHER_CRC_LEN); ++ ++ /* CRC data is binary data and does not care about the byte order. */ ++ memcpy(append_data, &crc, RTE_ETHER_CRC_LEN); ++} ++ + uint16_t + hns3_recv_pkts_simple(void *rx_queue, + struct rte_mbuf **rx_pkts, +@@ -2500,8 +2561,7 @@ hns3_recv_pkts_simple(void *rx_queue, + rxdp->rx.bd_base_info = 0; + + rxm->data_off = RTE_PKTMBUF_HEADROOM; +- rxm->pkt_len = (uint16_t)(rte_le_to_cpu_16(rxd.rx.pkt_len)) - +- rxq->crc_len; ++ rxm->pkt_len = (uint16_t)(rte_le_to_cpu_16(rxd.rx.pkt_len)); + rxm->data_len = rxm->pkt_len; + rxm->port = rxq->port_id; + rxm->hash.rss = rte_le_to_cpu_32(rxd.rx.rss_hash); +@@ -2526,6 +2586,12 @@ hns3_recv_pkts_simple(void *rx_queue, + if (rxm->packet_type == RTE_PTYPE_L2_ETHER_TIMESYNC) + rxm->ol_flags |= RTE_MBUF_F_RX_IEEE1588_PTP; + ++ if (unlikely(rxq->crc_len > 0) && ++ hns3_need_recalculate_crc(rxq, rxm)) ++ hns3_recalculate_crc(rxm); ++ rxm->pkt_len -= rxq->crc_len; ++ rxm->data_len -= rxq->crc_len; ++ + hns3_rxd_to_vlan_tci(rxq, rxm, l234_info, &rxd); + + /* Increment bytes counter */ +@@ -2692,10 +2758,10 @@ hns3_recv_scattered_pkts(void *rx_queue, + + rxm->data_off = RTE_PKTMBUF_HEADROOM; + rxm->data_len = rte_le_to_cpu_16(rxd.rx.size); ++ rxm->next = NULL; + + if (!(bd_base_info & BIT(HNS3_RXD_FE_B))) { + last_seg = rxm; +- rxm->next = NULL; + continue; + } + +@@ -2710,22 +2776,6 @@ hns3_recv_scattered_pkts(void *rx_queue, + */ + first_seg->pkt_len = rte_le_to_cpu_16(rxd.rx.pkt_len); + +- /* +- * This is the last buffer of the received packet. If the CRC +- * is not stripped by the hardware: +- * - Subtract the CRC length from the total packet length. +- * - If the last buffer only contains the whole CRC or a part +- * of it, free the mbuf associated to the last buffer. If part +- * of the CRC is also contained in the previous mbuf, subtract +- * the length of that CRC part from the data length of the +- * previous mbuf. +- */ +- rxm->next = NULL; +- if (unlikely(rxq->crc_len > 0)) { +- first_seg->pkt_len -= rxq->crc_len; +- recalculate_data_len(last_seg, rxm, rxq); +- } +- + first_seg->port = rxq->port_id; + first_seg->hash.rss = rte_le_to_cpu_32(rxd.rx.rss_hash); + first_seg->ol_flags |= RTE_MBUF_F_RX_RSS_HASH; +@@ -2754,6 +2804,31 @@ hns3_recv_scattered_pkts(void *rx_queue, + + if (first_seg->packet_type == RTE_PTYPE_L2_ETHER_TIMESYNC) + rxm->ol_flags |= RTE_MBUF_F_RX_IEEE1588_PTP; ++ /* ++ * This is the last buffer of the received packet. If the CRC ++ * is not stripped by the hardware: ++ * - Subtract the CRC length from the total packet length. ++ * - If the last buffer only contains the whole CRC or a part ++ * of it, free the mbuf associated to the last buffer. If part ++ * of the CRC is also contained in the previous mbuf, subtract ++ * the length of that CRC part from the data length of the ++ * previous mbuf. ++ * ++ * In addition, the CRC is still stripped for a kind of packets ++ * in hns3 NIC: ++ * 1. All IP-TCP packet whose the length is less than and equal ++ * to 60 Byte (no CRC) on HIP08 network engine. ++ * 2. All IP packet whose the length is less than and equal to ++ * 60 Byte (no CRC) on HIP09 network engine. ++ * In this case, the PMD calculates the CRC and appends it to ++ * mbuf. ++ */ ++ if (unlikely(rxq->crc_len > 0)) { ++ if (hns3_need_recalculate_crc(rxq, first_seg)) ++ hns3_recalculate_crc(first_seg); ++ first_seg->pkt_len -= rxq->crc_len; ++ recalculate_data_len(last_seg, rxm, rxq); ++ } + + hns3_rxd_to_vlan_tci(rxq, first_seg, l234_info, &rxd); + +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index 18dcc75..1c784fd 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -178,6 +178,8 @@ + (HNS3_TXD_VLD_CMD | HNS3_TXD_FE_CMD | HNS3_TXD_DEFAULT_BDTYPE) + #define HNS3_TXD_SEND_SIZE_SHIFT 16 + ++#define HNS3_KEEP_CRC_OK_MIN_PKT_LEN 60 ++ + enum hns3_pkt_l2t_type { + HNS3_L2_TYPE_UNICAST, + HNS3_L2_TYPE_MULTICAST, +@@ -341,6 +343,7 @@ struct hns3_rx_queue { + */ + uint8_t pvid_sw_discard_en:1; + uint8_t ptype_en:1; /* indicate if the ptype field enabled */ ++ uint8_t keep_crc_fail_ptype:2; + + uint64_t mbuf_initializer; /* value to init mbufs used with vector rx */ + /* offset_table: used for vector, to solve execute re-order problem */ +diff --git a/drivers/net/hns3/hns3_rxtx_vec.c b/drivers/net/hns3/hns3_rxtx_vec.c +index 9708ec6..bf37ce5 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec.c ++++ b/drivers/net/hns3/hns3_rxtx_vec.c +@@ -185,7 +185,8 @@ hns3_rx_check_vec_support(struct rte_eth_dev *dev) + struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode; + uint64_t offloads_mask = RTE_ETH_RX_OFFLOAD_TCP_LRO | + RTE_ETH_RX_OFFLOAD_VLAN | +- RTE_ETH_RX_OFFLOAD_TIMESTAMP; ++ RTE_ETH_RX_OFFLOAD_TIMESTAMP | ++ RTE_ETH_RX_OFFLOAD_KEEP_CRC; + + if (dev->data->scattered_rx) + return -ENOTSUP; +diff --git a/drivers/net/hns3/hns3_rxtx_vec_neon.h b/drivers/net/hns3/hns3_rxtx_vec_neon.h +index 0dc6b9f..60ec501 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec_neon.h ++++ b/drivers/net/hns3/hns3_rxtx_vec_neon.h +@@ -148,14 +148,6 @@ hns3_recv_burst_vec(struct hns3_rx_queue *__restrict rxq, + 8, 9, 10, 11, /* rx.rss_hash to rte_mbuf.hash.rss */ + }; + +- uint16x8_t crc_adjust = { +- 0, 0, /* ignore pkt_type field */ +- rxq->crc_len, /* sub crc on pkt_len */ +- 0, /* ignore high-16bits of pkt_len */ +- rxq->crc_len, /* sub crc on data_len */ +- 0, 0, 0, /* ignore non-length fields */ +- }; +- + /* compile-time verifies the shuffle mask */ + RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, pkt_len) != + offsetof(struct rte_mbuf, rx_descriptor_fields1) + 4); +@@ -171,7 +163,6 @@ hns3_recv_burst_vec(struct hns3_rx_queue *__restrict rxq, + uint8x16_t pkt_mb1, pkt_mb2, pkt_mb3, pkt_mb4; + uint64x2_t mbp1, mbp2; + uint16x4_t bd_vld = {0}; +- uint16x8_t tmp; + uint64_t stat; + + /* calc how many bd valid */ +@@ -225,16 +216,6 @@ hns3_recv_burst_vec(struct hns3_rx_queue *__restrict rxq, + pkt_mb3 = vqtbl2q_u8(pkt_mbuf3, shuf_desc_fields_msk); + pkt_mb4 = vqtbl2q_u8(pkt_mbuf4, shuf_desc_fields_msk); + +- /* 4 packets remove crc */ +- tmp = vsubq_u16(vreinterpretq_u16_u8(pkt_mb1), crc_adjust); +- pkt_mb1 = vreinterpretq_u8_u16(tmp); +- tmp = vsubq_u16(vreinterpretq_u16_u8(pkt_mb2), crc_adjust); +- pkt_mb2 = vreinterpretq_u8_u16(tmp); +- tmp = vsubq_u16(vreinterpretq_u16_u8(pkt_mb3), crc_adjust); +- pkt_mb3 = vreinterpretq_u8_u16(tmp); +- tmp = vsubq_u16(vreinterpretq_u16_u8(pkt_mb4), crc_adjust); +- pkt_mb4 = vreinterpretq_u8_u16(tmp); +- + /* save packet info to rx_pkts mbuf */ + vst1q_u8((void *)&sw_ring[pos + 0].mbuf->rx_descriptor_fields1, + pkt_mb1); +diff --git a/drivers/net/hns3/hns3_rxtx_vec_sve.c b/drivers/net/hns3/hns3_rxtx_vec_sve.c +index 8aa4448..67c87f5 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec_sve.c ++++ b/drivers/net/hns3/hns3_rxtx_vec_sve.c +@@ -36,8 +36,7 @@ hns3_desc_parse_field_sve(struct hns3_rx_queue *rxq, + /* init rte_mbuf.rearm_data last 64-bit */ + rx_pkts[i]->ol_flags = RTE_MBUF_F_RX_RSS_HASH; + rx_pkts[i]->hash.rss = rxdp[i].rx.rss_hash; +- rx_pkts[i]->pkt_len = rte_le_to_cpu_16(rxdp[i].rx.pkt_len) - +- rxq->crc_len; ++ rx_pkts[i]->pkt_len = rte_le_to_cpu_16(rxdp[i].rx.pkt_len); + rx_pkts[i]->data_len = rx_pkts[i]->pkt_len; + + l234_info = rxdp[i].rx.l234_info; +-- +2.33.0 + diff --git a/0097-net-hns3-allow-use-of-Rx-vector-mode-with-VLAN-filte.patch b/0097-net-hns3-allow-use-of-Rx-vector-mode-with-VLAN-filte.patch new file mode 100644 index 0000000..84c3364 --- /dev/null +++ b/0097-net-hns3-allow-use-of-Rx-vector-mode-with-VLAN-filte.patch @@ -0,0 +1,38 @@ +From 2a8fb6711326225d4589e5b4aceb27be5e2e6068 Mon Sep 17 00:00:00 2001 +From: Dengdui Huang +Date: Mon, 9 Jun 2025 21:06:51 +0800 +Subject: [PATCH] net/hns3: allow use of Rx vector mode with VLAN filter + +[ upstream commit 4d345eb5ef9827aec1547d7dfc9afcf363359b46 ] + +When the RTE_ETH_RX_OFFLOAD_VLAN_FILTER offload flag was set, +the driver would not select the Rx vector algorithm. +But VLAN filtering does not impact data layout so it +is possible to use Rx vector algorithm in this case. + +Fixes: a3d4f4d291d7 ("net/hns3: support NEON Rx") +Cc: stable@dpdk.org + +Signed-off-by: Dengdui Huang +--- + drivers/net/hns3/hns3_rxtx_vec.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_rxtx_vec.c b/drivers/net/hns3/hns3_rxtx_vec.c +index bf37ce5..a910104 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec.c ++++ b/drivers/net/hns3/hns3_rxtx_vec.c +@@ -184,7 +184,9 @@ hns3_rx_check_vec_support(struct rte_eth_dev *dev) + { + struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode; + uint64_t offloads_mask = RTE_ETH_RX_OFFLOAD_TCP_LRO | +- RTE_ETH_RX_OFFLOAD_VLAN | ++ RTE_ETH_RX_OFFLOAD_VLAN_STRIP | ++ RTE_ETH_RX_OFFLOAD_VLAN_EXTEND | ++ RTE_ETH_RX_OFFLOAD_QINQ_STRIP | + RTE_ETH_RX_OFFLOAD_TIMESTAMP | + RTE_ETH_RX_OFFLOAD_KEEP_CRC; + +-- +2.25.1 + diff --git a/0098-net-hns3-allow-use-of-Tx-vector-when-fast-free-not-enable.patch b/0098-net-hns3-allow-use-of-Tx-vector-when-fast-free-not-enable.patch new file mode 100644 index 0000000..f6d84e2 --- /dev/null +++ b/0098-net-hns3-allow-use-of-Tx-vector-when-fast-free-not-enable.patch @@ -0,0 +1,42 @@ +From 13599c6475a5a76359b8ab6837895f46c0640441 Mon Sep 17 00:00:00 2001 +From: Dengdui Huang +Date: Mon, 9 Jun 2025 21:06:50 +0800 +Subject: [PATCH] net/hns3: allow use of Tx vector when fast free not enabled + +[ upstream commit e05cb702ca70aecdf01041274cd6ffc9233a726d ] + +Currently, the Tx vector algorithm is only enabled +when tx_offload is RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE. +If no offloads are enabled, then vector algorithm can also be used. +The vector algorithm does not support other transmit offloads. + +Fixes: e31f123db06b ("net/hns3: support NEON Tx") +Cc: stable@dpdk.org + +Signed-off-by: Dengdui Huang +--- + drivers/net/hns3/hns3_rxtx_vec.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx_vec.c b/drivers/net/hns3/hns3_rxtx_vec.c +index a910104..daadd7e 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec.c ++++ b/drivers/net/hns3/hns3_rxtx_vec.c +@@ -16,11 +16,11 @@ + int + hns3_tx_check_vec_support(struct rte_eth_dev *dev) + { +- struct rte_eth_txmode *txmode = &dev->data->dev_conf.txmode; ++ uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads; + struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode; + +- /* Only support RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE */ +- if (txmode->offloads != RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) ++ /* Only support when Tx offloads is RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE or 0. */ ++ if (tx_offloads != RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE && tx_offloads != 0) + return -ENOTSUP; + + /* +-- +2.25.1 + diff --git a/0099-net-hns3-check-requirement-for-hardware-GRO.patch b/0099-net-hns3-check-requirement-for-hardware-GRO.patch new file mode 100644 index 0000000..452fa1b --- /dev/null +++ b/0099-net-hns3-check-requirement-for-hardware-GRO.patch @@ -0,0 +1,56 @@ +From ae68b5d91c632a1dde839123f27b0317cf094170 Mon Sep 17 00:00:00 2001 +From: Dengdui Huang +Date: Mon, 9 Jun 2025 21:06:49 +0800 +Subject: [PATCH] net/hns3: check requirement for hardware GRO + +[ upstream commit ae68b5d91c632a1dde839123f27b0317cf094170 ] + +The HIP08 platform requires that data address be 64-byte aligned +for the GRO feature. + +Most applications already use 64-byte aligned. So a check is added +to avoid using the GRO function when 64-byte aligned is used. + +Fixes: d14c995b775a ("net/hns3: check Rx DMA address alignmnent") +Cc: stable@dpdk.org + +Signed-off-by: Dengdui Huang +--- + drivers/net/hns3/hns3_rxtx.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index bde46733b0..f9fde3948a 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -281,12 +281,25 @@ hns3_free_all_queues(struct rte_eth_dev *dev) + static int + hns3_check_rx_dma_addr(struct hns3_hw *hw, uint64_t dma_addr) + { ++ uint64_t rx_offload = hw->data->dev_conf.rxmode.offloads; + uint64_t rem; + + rem = dma_addr & (hw->rx_dma_addr_align - 1); + if (rem > 0) { +- hns3_err(hw, "The IO address of the beginning of the mbuf data " +- "must be %u-byte aligned", hw->rx_dma_addr_align); ++ hns3_err(hw, ++ "mbuf DMA address must be %u-byte aligned", ++ hw->rx_dma_addr_align); ++ return -EINVAL; ++ } ++ ++ /* ++ * This check is for HIP08 network engine. The GRO function ++ * requires that mbuf DMA address is 64-byte aligned. ++ */ ++ rem = dma_addr & (HNS3_RX_DMA_ADDR_ALIGN_128 - 1); ++ if ((rx_offload & RTE_ETH_RX_OFFLOAD_TCP_LRO) && rem > 0) { ++ hns3_err(hw, ++ "GRO requires that mbuf DMA address be 64-byte aligned"); + return -EINVAL; + } + return 0; +-- +2.25.1 + diff --git a/0100-net-add-tunnel-packet-type-parsing.patch b/0100-net-add-tunnel-packet-type-parsing.patch new file mode 100644 index 0000000..f58ef82 --- /dev/null +++ b/0100-net-add-tunnel-packet-type-parsing.patch @@ -0,0 +1,193 @@ +From ab320703aaf1d586c8dd1eaa5d8bffeb11d27f02 Mon Sep 17 00:00:00 2001 +From: Jie Hai +Date: Fri, 14 Feb 2025 09:56:37 +0800 +Subject: [PATCH] net: add tunnel packet type parsing + +[ upstream commit 64ed7f854cf445829b525df7b27ed00a9bcc9b16 ] + +Add packet types parse for vxlan/vxlan-gpe/gtp/geneve packets. + +Signed-off-by: Jie Hai +--- + lib/net/rte_net.c | 110 ++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 102 insertions(+), 8 deletions(-) + +diff --git a/lib/net/rte_net.c b/lib/net/rte_net.c +index d680acc..0c32e78 100644 +--- a/lib/net/rte_net.c ++++ b/lib/net/rte_net.c +@@ -14,6 +14,9 @@ + #include + #include + #include ++#include ++#include ++#include + #include + #include + +@@ -126,7 +129,7 @@ ptype_inner_l4(uint8_t proto) + + /* get the tunnel packet type if any, update proto and off. */ + static uint32_t +-ptype_tunnel(uint16_t *proto, const struct rte_mbuf *m, ++ptype_tunnel_without_udp(uint16_t *proto, const struct rte_mbuf *m, + uint32_t *off) + { + switch (*proto) { +@@ -172,6 +175,92 @@ ptype_tunnel(uint16_t *proto, const struct rte_mbuf *m, + } + } + ++/* get the tunnel packet type with UDP port if any, update proto and off. */ ++static uint32_t ++ptype_tunnel_with_udp(uint16_t *proto, const struct rte_mbuf *m, ++ uint32_t *off, struct rte_net_hdr_lens *hdr_lens) ++{ ++ const struct rte_udp_hdr *uh; ++ struct rte_udp_hdr uh_copy; ++ uint16_t port_no; ++ ++ uh = rte_pktmbuf_read(m, *off, sizeof(*uh), &uh_copy); ++ if (unlikely(uh == NULL)) ++ return 0; ++ ++ *off += sizeof(*uh); ++ if (rte_be_to_cpu_16(uh->src_port) == RTE_GTPC_UDP_PORT) ++ port_no = rte_be_to_cpu_16(uh->src_port); ++ else ++ port_no = rte_be_to_cpu_16(uh->dst_port); ++ switch (port_no) { ++ case RTE_VXLAN_DEFAULT_PORT: { ++ *off += sizeof(struct rte_vxlan_hdr); ++ hdr_lens->inner_l2_len = RTE_ETHER_VXLAN_HLEN; ++ *proto = RTE_VXLAN_GPE_TYPE_ETH; /* just for eth header parse. */ ++ return RTE_PTYPE_TUNNEL_VXLAN; ++ } ++ case RTE_VXLAN_GPE_DEFAULT_PORT: { ++ const struct rte_vxlan_gpe_hdr *vgh; ++ struct rte_vxlan_gpe_hdr vgh_copy; ++ vgh = rte_pktmbuf_read(m, *off, sizeof(*vgh), &vgh_copy); ++ if (unlikely(vgh == NULL)) ++ return 0; ++ *off += sizeof(struct rte_vxlan_gpe_hdr); ++ hdr_lens->inner_l2_len = RTE_ETHER_VXLAN_GPE_HLEN; ++ *proto = vgh->proto; ++ ++ return RTE_PTYPE_TUNNEL_VXLAN_GPE; ++ } ++ case RTE_GTPC_UDP_PORT: ++ case RTE_GTPU_UDP_PORT: { ++ const struct rte_gtp_hdr *gh; ++ struct rte_gtp_hdr gh_copy; ++ uint8_t gtp_len; ++ uint8_t ip_ver; ++ gh = rte_pktmbuf_read(m, *off, sizeof(*gh), &gh_copy); ++ if (unlikely(gh == NULL)) ++ return 0; ++ gtp_len = sizeof(*gh); ++ if (gh->e || gh->s || gh->pn) ++ gtp_len += sizeof(struct rte_gtp_hdr_ext_word); ++ /* ++ * Check message type. If message type is 0xff, it is ++ * a GTP data packet. If not, it is a GTP control packet ++ */ ++ if (gh->msg_type == 0xff) { ++ ip_ver = *(const uint8_t *)((const char *)gh + gtp_len); ++ *proto = (ip_ver) & 0xf0; ++ } else { ++ *proto = 0; ++ } ++ *off += gtp_len; ++ hdr_lens->inner_l2_len = gtp_len + sizeof(struct rte_udp_hdr); ++ if (port_no == RTE_GTPC_UDP_PORT) ++ return RTE_PTYPE_TUNNEL_GTPC; ++ else if (port_no == RTE_GTPU_UDP_PORT) ++ return RTE_PTYPE_TUNNEL_GTPU; ++ return 0; ++ } ++ case RTE_GENEVE_DEFAULT_PORT: { ++ const struct rte_geneve_hdr *gnh; ++ struct rte_geneve_hdr gnh_copy; ++ uint16_t geneve_len; ++ gnh = rte_pktmbuf_read(m, *off, sizeof(*gnh), &gnh_copy); ++ if (unlikely(gnh == NULL)) ++ return 0; ++ geneve_len = sizeof(*gnh) + gnh->opt_len * 4; ++ *off = geneve_len; ++ *proto = gnh->proto; ++ if (gnh->proto == 0) ++ *proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); ++ return RTE_PTYPE_TUNNEL_GENEVE; ++ } ++ default: ++ return 0; ++ } ++} ++ + /* parse ipv6 extended headers, update offset and return next proto */ + int + rte_net_skip_ip6_ext(uint16_t proto, const struct rte_mbuf *m, uint32_t *off, +@@ -352,7 +441,9 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m, + + if ((pkt_type & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_UDP) { + hdr_lens->l4_len = sizeof(struct rte_udp_hdr); +- return pkt_type; ++ if ((layers & RTE_PTYPE_TUNNEL_MASK) == 0) ++ return pkt_type; ++ pkt_type |= ptype_tunnel_with_udp(&proto, m, &off, hdr_lens); + } else if ((pkt_type & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_TCP) { + const struct rte_tcp_hdr *th; + struct rte_tcp_hdr th_copy; +@@ -374,7 +465,7 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m, + if ((layers & RTE_PTYPE_TUNNEL_MASK) == 0) + return pkt_type; + +- pkt_type |= ptype_tunnel(&proto, m, &off); ++ pkt_type |= ptype_tunnel_without_udp(&proto, m, &off); + hdr_lens->tunnel_len = off - prev_off; + } + +@@ -384,15 +475,16 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m, + if ((layers & RTE_PTYPE_INNER_L2_MASK) == 0) + return pkt_type; + +- hdr_lens->inner_l2_len = 0; +- if (proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_TEB)) { ++ if (proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_TEB) || ++ proto == rte_cpu_to_be_16(RTE_GENEVE_TYPE_ETH) || ++ proto == RTE_VXLAN_GPE_TYPE_ETH) { + eh = rte_pktmbuf_read(m, off, sizeof(*eh), &eh_copy); + if (unlikely(eh == NULL)) + return pkt_type; + pkt_type |= RTE_PTYPE_INNER_L2_ETHER; + proto = eh->ether_type; + off += sizeof(*eh); +- hdr_lens->inner_l2_len = sizeof(*eh); ++ hdr_lens->inner_l2_len += sizeof(*eh); + } + + if (proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN)) { +@@ -425,7 +517,8 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m, + if ((layers & RTE_PTYPE_INNER_L3_MASK) == 0) + return pkt_type; + +- if (proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)) { ++ if (proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4) || ++ proto == RTE_VXLAN_GPE_TYPE_IPV4) { + const struct rte_ipv4_hdr *ip4h; + struct rte_ipv4_hdr ip4h_copy; + +@@ -448,7 +541,8 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m, + } + proto = ip4h->next_proto_id; + pkt_type |= ptype_inner_l4(proto); +- } else if (proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6)) { ++ } else if (proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6) || ++ proto == RTE_VXLAN_GPE_TYPE_IPV6) { + const struct rte_ipv6_hdr *ip6h; + struct rte_ipv6_hdr ip6h_copy; + int frag = 0; +-- +2.25.1 + diff --git a/0101-app-testpmd-use-packet-type-parsing-API.patch b/0101-app-testpmd-use-packet-type-parsing-API.patch new file mode 100644 index 0000000..385254f --- /dev/null +++ b/0101-app-testpmd-use-packet-type-parsing-API.patch @@ -0,0 +1,594 @@ +From f220b230f88e45f8671d82243e4add6250e53131 Mon Sep 17 00:00:00 2001 +From: Jie Hai +Date: Fri, 14 Feb 2025 09:56:38 +0800 +Subject: [PATCH] app/testpmd: use packet type parsing API + +[ upstream commit 76730c7b9b5a35d1a74d45a08153a03bdb1b26f8 ] + +1. Use rte_net_get_ptype() to parse packets instead. +2. Support TSO for packets with IPv6 extension header. + +Signed-off-by: Jie Hai +--- + app/test-pmd/csumonly.c | 522 ++++++++++------------------------------ + 1 file changed, 128 insertions(+), 394 deletions(-) + +diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c +index 21210af..4b3be71 100644 +--- a/app/test-pmd/csumonly.c ++++ b/app/test-pmd/csumonly.c +@@ -46,6 +46,7 @@ + #include + #endif + #include ++#include + + #include "testpmd.h" + +@@ -104,88 +105,6 @@ get_udptcp_checksum(struct rte_mbuf *m, void *l3_hdr, uint16_t l4_off, + return rte_ipv6_udptcp_cksum_mbuf(m, l3_hdr, l4_off); + } + +-/* Parse an IPv4 header to fill l3_len, l4_len, and l4_proto */ +-static void +-parse_ipv4(struct rte_ipv4_hdr *ipv4_hdr, struct testpmd_offload_info *info) +-{ +- struct rte_tcp_hdr *tcp_hdr; +- +- info->l3_len = rte_ipv4_hdr_len(ipv4_hdr); +- info->l4_proto = ipv4_hdr->next_proto_id; +- +- /* only fill l4_len for TCP, it's useful for TSO */ +- if (info->l4_proto == IPPROTO_TCP) { +- tcp_hdr = (struct rte_tcp_hdr *) +- ((char *)ipv4_hdr + info->l3_len); +- info->l4_len = (tcp_hdr->data_off & 0xf0) >> 2; +- } else if (info->l4_proto == IPPROTO_UDP) +- info->l4_len = sizeof(struct rte_udp_hdr); +- else +- info->l4_len = 0; +-} +- +-/* Parse an IPv6 header to fill l3_len, l4_len, and l4_proto */ +-static void +-parse_ipv6(struct rte_ipv6_hdr *ipv6_hdr, struct testpmd_offload_info *info) +-{ +- struct rte_tcp_hdr *tcp_hdr; +- +- info->l3_len = sizeof(struct rte_ipv6_hdr); +- info->l4_proto = ipv6_hdr->proto; +- +- /* only fill l4_len for TCP, it's useful for TSO */ +- if (info->l4_proto == IPPROTO_TCP) { +- tcp_hdr = (struct rte_tcp_hdr *) +- ((char *)ipv6_hdr + info->l3_len); +- info->l4_len = (tcp_hdr->data_off & 0xf0) >> 2; +- } else if (info->l4_proto == IPPROTO_UDP) +- info->l4_len = sizeof(struct rte_udp_hdr); +- else +- info->l4_len = 0; +-} +- +-/* +- * Parse an ethernet header to fill the ethertype, l2_len, l3_len and +- * ipproto. This function is able to recognize IPv4/IPv6 with optional VLAN +- * headers. The l4_len argument is only set in case of TCP (useful for TSO). +- */ +-static void +-parse_ethernet(struct rte_ether_hdr *eth_hdr, struct testpmd_offload_info *info) +-{ +- struct rte_ipv4_hdr *ipv4_hdr; +- struct rte_ipv6_hdr *ipv6_hdr; +- struct rte_vlan_hdr *vlan_hdr; +- +- info->l2_len = sizeof(struct rte_ether_hdr); +- info->ethertype = eth_hdr->ether_type; +- +- while (info->ethertype == _htons(RTE_ETHER_TYPE_VLAN) || +- info->ethertype == _htons(RTE_ETHER_TYPE_QINQ)) { +- vlan_hdr = (struct rte_vlan_hdr *) +- ((char *)eth_hdr + info->l2_len); +- info->l2_len += sizeof(struct rte_vlan_hdr); +- info->ethertype = vlan_hdr->eth_proto; +- } +- +- switch (info->ethertype) { +- case _htons(RTE_ETHER_TYPE_IPV4): +- ipv4_hdr = (struct rte_ipv4_hdr *) +- ((char *)eth_hdr + info->l2_len); +- parse_ipv4(ipv4_hdr, info); +- break; +- case _htons(RTE_ETHER_TYPE_IPV6): +- ipv6_hdr = (struct rte_ipv6_hdr *) +- ((char *)eth_hdr + info->l2_len); +- parse_ipv6(ipv6_hdr, info); +- break; +- default: +- info->l4_len = 0; +- info->l3_len = 0; +- info->l4_proto = 0; +- break; +- } +-} +- + /* Fill in outer layers length */ + static void + update_tunnel_outer(struct testpmd_offload_info *info) +@@ -195,262 +114,7 @@ update_tunnel_outer(struct testpmd_offload_info *info) + info->outer_l2_len = info->l2_len; + info->outer_l3_len = info->l3_len; + info->outer_l4_proto = info->l4_proto; +-} +- +-/* +- * Parse a GTP protocol header. +- * No optional fields and next extension header type. +- */ +-static void +-parse_gtp(struct rte_udp_hdr *udp_hdr, +- struct testpmd_offload_info *info) +-{ +- struct rte_ipv4_hdr *ipv4_hdr; +- struct rte_ipv6_hdr *ipv6_hdr; +- struct rte_gtp_hdr *gtp_hdr; +- uint8_t gtp_len = sizeof(*gtp_hdr); +- uint8_t ip_ver; +- +- /* Check udp destination port. */ +- if (udp_hdr->dst_port != _htons(RTE_GTPC_UDP_PORT) && +- udp_hdr->src_port != _htons(RTE_GTPC_UDP_PORT) && +- udp_hdr->dst_port != _htons(RTE_GTPU_UDP_PORT)) +- return; +- +- update_tunnel_outer(info); +- info->l2_len = 0; +- +- gtp_hdr = (struct rte_gtp_hdr *)((char *)udp_hdr + +- sizeof(struct rte_udp_hdr)); +- if (gtp_hdr->e || gtp_hdr->s || gtp_hdr->pn) +- gtp_len += sizeof(struct rte_gtp_hdr_ext_word); +- /* +- * Check message type. If message type is 0xff, it is +- * a GTP data packet. If not, it is a GTP control packet +- */ +- if (gtp_hdr->msg_type == 0xff) { +- ip_ver = *(uint8_t *)((char *)gtp_hdr + gtp_len); +- ip_ver = (ip_ver) & 0xf0; +- +- if (ip_ver == RTE_GTP_TYPE_IPV4) { +- ipv4_hdr = (struct rte_ipv4_hdr *)((char *)gtp_hdr + +- gtp_len); +- info->ethertype = _htons(RTE_ETHER_TYPE_IPV4); +- parse_ipv4(ipv4_hdr, info); +- } else if (ip_ver == RTE_GTP_TYPE_IPV6) { +- ipv6_hdr = (struct rte_ipv6_hdr *)((char *)gtp_hdr + +- gtp_len); +- info->ethertype = _htons(RTE_ETHER_TYPE_IPV6); +- parse_ipv6(ipv6_hdr, info); +- } +- } else { +- info->ethertype = 0; +- info->l4_len = 0; +- info->l3_len = 0; +- info->l4_proto = 0; +- } +- +- info->l2_len += gtp_len + sizeof(*udp_hdr); +-} +- +-/* Parse a vxlan header */ +-static void +-parse_vxlan(struct rte_udp_hdr *udp_hdr, +- struct testpmd_offload_info *info) +-{ +- struct rte_ether_hdr *eth_hdr; +- +- /* check udp destination port, RTE_VXLAN_DEFAULT_PORT (4789) is the +- * default vxlan port (rfc7348) or that the rx offload flag is set +- * (i40e only currently) +- */ +- if (udp_hdr->dst_port != _htons(RTE_VXLAN_DEFAULT_PORT)) +- return; +- +- update_tunnel_outer(info); +- +- eth_hdr = (struct rte_ether_hdr *)((char *)udp_hdr + +- sizeof(struct rte_udp_hdr) + +- sizeof(struct rte_vxlan_hdr)); +- +- parse_ethernet(eth_hdr, info); +- info->l2_len += RTE_ETHER_VXLAN_HLEN; /* add udp + vxlan */ +-} +- +-/* Parse a vxlan-gpe header */ +-static void +-parse_vxlan_gpe(struct rte_udp_hdr *udp_hdr, +- struct testpmd_offload_info *info) +-{ +- struct rte_ether_hdr *eth_hdr; +- struct rte_ipv4_hdr *ipv4_hdr; +- struct rte_ipv6_hdr *ipv6_hdr; +- struct rte_vxlan_gpe_hdr *vxlan_gpe_hdr; +- uint8_t vxlan_gpe_len = sizeof(*vxlan_gpe_hdr); +- +- /* Check udp destination port. */ +- if (udp_hdr->dst_port != _htons(vxlan_gpe_udp_port)) +- return; +- +- vxlan_gpe_hdr = (struct rte_vxlan_gpe_hdr *)((char *)udp_hdr + +- sizeof(struct rte_udp_hdr)); +- +- if (!vxlan_gpe_hdr->proto || vxlan_gpe_hdr->proto == +- RTE_VXLAN_GPE_TYPE_IPV4) { +- update_tunnel_outer(info); +- +- ipv4_hdr = (struct rte_ipv4_hdr *)((char *)vxlan_gpe_hdr + +- vxlan_gpe_len); +- +- parse_ipv4(ipv4_hdr, info); +- info->ethertype = _htons(RTE_ETHER_TYPE_IPV4); +- info->l2_len = 0; +- +- } else if (vxlan_gpe_hdr->proto == RTE_VXLAN_GPE_TYPE_IPV6) { +- update_tunnel_outer(info); +- +- ipv6_hdr = (struct rte_ipv6_hdr *)((char *)vxlan_gpe_hdr + +- vxlan_gpe_len); +- +- info->ethertype = _htons(RTE_ETHER_TYPE_IPV6); +- parse_ipv6(ipv6_hdr, info); +- info->l2_len = 0; +- +- } else if (vxlan_gpe_hdr->proto == RTE_VXLAN_GPE_TYPE_ETH) { +- update_tunnel_outer(info); +- +- eth_hdr = (struct rte_ether_hdr *)((char *)vxlan_gpe_hdr + +- vxlan_gpe_len); +- +- parse_ethernet(eth_hdr, info); +- } else +- return; +- +- info->l2_len += RTE_ETHER_VXLAN_GPE_HLEN; +-} +- +-/* Parse a geneve header */ +-static void +-parse_geneve(struct rte_udp_hdr *udp_hdr, +- struct testpmd_offload_info *info) +-{ +- struct rte_ether_hdr *eth_hdr; +- struct rte_ipv4_hdr *ipv4_hdr; +- struct rte_ipv6_hdr *ipv6_hdr; +- struct rte_geneve_hdr *geneve_hdr; +- uint16_t geneve_len; +- +- /* Check udp destination port. */ +- if (udp_hdr->dst_port != _htons(geneve_udp_port)) +- return; +- +- geneve_hdr = (struct rte_geneve_hdr *)((char *)udp_hdr + +- sizeof(struct rte_udp_hdr)); +- geneve_len = sizeof(struct rte_geneve_hdr) + geneve_hdr->opt_len * 4; +- if (!geneve_hdr->proto || geneve_hdr->proto == +- _htons(RTE_ETHER_TYPE_IPV4)) { +- update_tunnel_outer(info); +- ipv4_hdr = (struct rte_ipv4_hdr *)((char *)geneve_hdr + +- geneve_len); +- parse_ipv4(ipv4_hdr, info); +- info->ethertype = _htons(RTE_ETHER_TYPE_IPV4); +- info->l2_len = 0; +- } else if (geneve_hdr->proto == _htons(RTE_ETHER_TYPE_IPV6)) { +- update_tunnel_outer(info); +- ipv6_hdr = (struct rte_ipv6_hdr *)((char *)geneve_hdr + +- geneve_len); +- info->ethertype = _htons(RTE_ETHER_TYPE_IPV6); +- parse_ipv6(ipv6_hdr, info); +- info->l2_len = 0; +- +- } else if (geneve_hdr->proto == _htons(RTE_GENEVE_TYPE_ETH)) { +- update_tunnel_outer(info); +- eth_hdr = (struct rte_ether_hdr *)((char *)geneve_hdr + +- geneve_len); +- parse_ethernet(eth_hdr, info); +- } else +- return; +- +- info->l2_len += +- (sizeof(struct rte_udp_hdr) + sizeof(struct rte_geneve_hdr) + +- ((struct rte_geneve_hdr *)geneve_hdr)->opt_len * 4); +-} +- +-/* Parse a gre header */ +-static void +-parse_gre(struct simple_gre_hdr *gre_hdr, struct testpmd_offload_info *info) +-{ +- struct rte_ether_hdr *eth_hdr; +- struct rte_ipv4_hdr *ipv4_hdr; +- struct rte_ipv6_hdr *ipv6_hdr; +- uint8_t gre_len = 0; +- +- gre_len += sizeof(struct simple_gre_hdr); +- +- if (gre_hdr->flags & _htons(GRE_KEY_PRESENT)) +- gre_len += GRE_EXT_LEN; +- if (gre_hdr->flags & _htons(GRE_SEQUENCE_PRESENT)) +- gre_len += GRE_EXT_LEN; +- if (gre_hdr->flags & _htons(GRE_CHECKSUM_PRESENT)) +- gre_len += GRE_EXT_LEN; +- +- if (gre_hdr->proto == _htons(RTE_ETHER_TYPE_IPV4)) { +- update_tunnel_outer(info); +- +- ipv4_hdr = (struct rte_ipv4_hdr *)((char *)gre_hdr + gre_len); +- +- parse_ipv4(ipv4_hdr, info); +- info->ethertype = _htons(RTE_ETHER_TYPE_IPV4); +- info->l2_len = 0; +- +- } else if (gre_hdr->proto == _htons(RTE_ETHER_TYPE_IPV6)) { +- update_tunnel_outer(info); +- +- ipv6_hdr = (struct rte_ipv6_hdr *)((char *)gre_hdr + gre_len); +- +- info->ethertype = _htons(RTE_ETHER_TYPE_IPV6); +- parse_ipv6(ipv6_hdr, info); +- info->l2_len = 0; +- +- } else if (gre_hdr->proto == _htons(RTE_ETHER_TYPE_TEB)) { +- update_tunnel_outer(info); +- +- eth_hdr = (struct rte_ether_hdr *)((char *)gre_hdr + gre_len); +- +- parse_ethernet(eth_hdr, info); +- } else +- return; +- +- info->l2_len += gre_len; +-} +- +- +-/* Parse an encapsulated ip or ipv6 header */ +-static void +-parse_encap_ip(void *encap_ip, struct testpmd_offload_info *info) +-{ +- struct rte_ipv4_hdr *ipv4_hdr = encap_ip; +- struct rte_ipv6_hdr *ipv6_hdr = encap_ip; +- uint8_t ip_version; +- +- ip_version = (ipv4_hdr->version_ihl & 0xf0) >> 4; +- +- if (ip_version != 4 && ip_version != 6) +- return; +- +- info->is_tunnel = 1; +- info->outer_ethertype = info->ethertype; +- info->outer_l2_len = info->l2_len; +- info->outer_l3_len = info->l3_len; +- +- if (ip_version == 4) { +- parse_ipv4(ipv4_hdr, info); +- info->ethertype = _htons(RTE_ETHER_TYPE_IPV4); +- } else { +- parse_ipv6(ipv6_hdr, info); +- info->ethertype = _htons(RTE_ETHER_TYPE_IPV6); +- } +- info->l2_len = 0; ++ info->l4_proto = 0; + } + + /* if possible, calculate the checksum of a packet in hw or sw, +@@ -810,6 +474,109 @@ pkts_ip_csum_recalc(struct rte_mbuf **pkts_burst, const uint16_t nb_pkts, uint64 + } + #endif + ++static uint32_t ++get_ethertype_by_ptype(struct rte_ether_hdr *eth_hdr, uint32_t ptype) ++{ ++ struct rte_vlan_hdr *vlan_hdr; ++ uint16_t ethertype; ++ ++ switch (ptype) { ++ case RTE_PTYPE_L3_IPV4: ++ case RTE_PTYPE_L3_IPV4_EXT: ++ case RTE_PTYPE_L3_IPV4_EXT_UNKNOWN: ++ case RTE_PTYPE_INNER_L3_IPV4: ++ case RTE_PTYPE_INNER_L3_IPV4_EXT: ++ case RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN: ++ return _htons(RTE_ETHER_TYPE_IPV4); ++ case RTE_PTYPE_L3_IPV6: ++ case RTE_PTYPE_L3_IPV6_EXT: ++ case RTE_PTYPE_L3_IPV6_EXT_UNKNOWN: ++ case RTE_PTYPE_INNER_L3_IPV6: ++ case RTE_PTYPE_INNER_L3_IPV6_EXT: ++ case RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN: ++ return _htons(RTE_ETHER_TYPE_IPV6); ++ default: ++ ethertype = eth_hdr->ether_type; ++ while (eth_hdr->ether_type == _htons(RTE_ETHER_TYPE_VLAN) || ++ eth_hdr->ether_type == _htons(RTE_ETHER_TYPE_QINQ)) { ++ vlan_hdr = (struct rte_vlan_hdr *) ++ ((char *)eth_hdr + sizeof(*eth_hdr)); ++ ethertype = vlan_hdr->eth_proto; ++ } ++ return ethertype; ++ } ++} ++ ++static uint64_t ++get_tunnel_ol_flags_by_ptype(uint32_t ptype) ++{ ++ switch ((ptype & RTE_PTYPE_TUNNEL_MASK)) { ++ case RTE_PTYPE_TUNNEL_GTPC: ++ case RTE_PTYPE_TUNNEL_GTPU: ++ return RTE_MBUF_F_TX_TUNNEL_GTP; ++ case RTE_PTYPE_TUNNEL_VXLAN_GPE: ++ return RTE_MBUF_F_TX_TUNNEL_VXLAN_GPE; ++ case RTE_PTYPE_TUNNEL_VXLAN: ++ return RTE_MBUF_F_TX_TUNNEL_VXLAN; ++ case RTE_PTYPE_TUNNEL_GENEVE: ++ return RTE_MBUF_F_TX_TUNNEL_GENEVE; ++ case RTE_PTYPE_TUNNEL_NVGRE: ++ case RTE_PTYPE_TUNNEL_GRE: ++ return RTE_MBUF_F_TX_TUNNEL_GRE; ++ case RTE_PTYPE_TUNNEL_IP: ++ return RTE_MBUF_F_TX_TUNNEL_IPIP; ++ default: ++ printf("unrecognized tunnel ptype: %x\n", ++ (ptype & RTE_PTYPE_TUNNEL_MASK)); ++ return 0; ++ } ++} ++ ++static void ++parse_inner_l4_proto(void *outer_l3_hdr, ++ struct testpmd_offload_info *info) ++{ ++ struct rte_ipv4_hdr *ipv4_hdr = outer_l3_hdr; ++ struct rte_ipv6_hdr *ipv6_hdr = outer_l3_hdr; ++ if (info->ethertype == _htons(RTE_ETHER_TYPE_IPV4)) ++ info->l4_proto = ipv4_hdr->next_proto_id; ++ else ++ info->l4_proto = ipv6_hdr->proto; ++} ++ ++static uint8_t ++parse_l4_proto(const struct rte_mbuf *m, uint32_t off, uint32_t ptype) ++{ ++ int frag = 0, ret; ++ ++ if (RTE_ETH_IS_IPV4_HDR(ptype)) { ++ const struct rte_ipv4_hdr *ip4h; ++ struct rte_ipv4_hdr ip4h_copy; ++ ip4h = rte_pktmbuf_read(m, off, sizeof(*ip4h), &ip4h_copy); ++ if (unlikely(ip4h == NULL)) ++ return 0; ++ ++ return ip4h->next_proto_id; ++ } else if (RTE_ETH_IS_IPV6_HDR(ptype)) { ++ const struct rte_ipv6_hdr *ip6h; ++ struct rte_ipv6_hdr ip6h_copy; ++ ip6h = rte_pktmbuf_read(m, off, sizeof(*ip6h), &ip6h_copy); ++ if (unlikely(ip6h == NULL)) ++ return 0; ++ ++ if ((ptype & RTE_PTYPE_INNER_L3_MASK) == ++ RTE_PTYPE_INNER_L3_IPV6_EXT) { ++ ret = rte_net_skip_ip6_ext(ip6h->proto, m, &off, &frag); ++ if (ret < 0) ++ return 0; ++ return ret; ++ } ++ ++ return ip6h->proto; ++ } ++ return 0; ++} ++ + /* + * Receive a burst of packets, and for each packet: + * - parse packet, and try to recognize a supported packet type (1) +@@ -867,6 +634,8 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) + uint32_t rx_bad_outer_l4_csum; + uint32_t rx_bad_outer_ip_csum; + struct testpmd_offload_info info; ++ struct rte_net_hdr_lens hdr_lens = {0}; ++ uint32_t ptype; + + /* receive a burst of packet */ + nb_rx = common_fwd_stream_receive(fs, pkts_burst, nb_pkt_per_burst); +@@ -923,70 +692,35 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) + rte_ether_addr_copy(&ports[fs->tx_port].eth_addr, + ð_hdr->src_addr); + } +- parse_ethernet(eth_hdr, &info); +- l3_hdr = (char *)eth_hdr + info.l2_len; + ++ ptype = rte_net_get_ptype(m, &hdr_lens, RTE_PTYPE_ALL_MASK); ++ info.l2_len = hdr_lens.l2_len; ++ info.l3_len = hdr_lens.l3_len; ++ info.l4_len = hdr_lens.l4_len; ++ info.ethertype = get_ethertype_by_ptype(eth_hdr, ++ ptype & RTE_PTYPE_L3_MASK); ++ info.l4_proto = parse_l4_proto(m, info.l2_len, ptype); ++ ++ l3_hdr = (char *)eth_hdr + info.l2_len; + /* check if it's a supported tunnel */ +- if (txp->parse_tunnel) { +- if (info.l4_proto == IPPROTO_UDP) { +- struct rte_udp_hdr *udp_hdr; +- +- udp_hdr = (struct rte_udp_hdr *) +- ((char *)l3_hdr + info.l3_len); +- parse_gtp(udp_hdr, &info); +- if (info.is_tunnel) { +- tx_ol_flags |= RTE_MBUF_F_TX_TUNNEL_GTP; +- goto tunnel_update; +- } +- parse_vxlan_gpe(udp_hdr, &info); +- if (info.is_tunnel) { +- tx_ol_flags |= +- RTE_MBUF_F_TX_TUNNEL_VXLAN_GPE; +- goto tunnel_update; +- } +- parse_vxlan(udp_hdr, &info); +- if (info.is_tunnel) { +- tx_ol_flags |= +- RTE_MBUF_F_TX_TUNNEL_VXLAN; +- goto tunnel_update; +- } +- parse_geneve(udp_hdr, &info); +- if (info.is_tunnel) { +- tx_ol_flags |= +- RTE_MBUF_F_TX_TUNNEL_GENEVE; +- goto tunnel_update; +- } +- /* Always keep last. */ +- if (unlikely(RTE_ETH_IS_TUNNEL_PKT( +- m->packet_type) != 0)) { +- TESTPMD_LOG(DEBUG, "Unknown tunnel packet. UDP dst port: %hu", +- udp_hdr->dst_port); +- } +- } else if (info.l4_proto == IPPROTO_GRE) { +- struct simple_gre_hdr *gre_hdr; +- +- gre_hdr = (struct simple_gre_hdr *) +- ((char *)l3_hdr + info.l3_len); +- parse_gre(gre_hdr, &info); +- if (info.is_tunnel) +- tx_ol_flags |= RTE_MBUF_F_TX_TUNNEL_GRE; +- } else if (info.l4_proto == IPPROTO_IPIP) { +- void *encap_ip_hdr; +- +- encap_ip_hdr = (char *)l3_hdr + info.l3_len; +- parse_encap_ip(encap_ip_hdr, &info); +- if (info.is_tunnel) +- tx_ol_flags |= RTE_MBUF_F_TX_TUNNEL_IPIP; +- } ++ if (txp->parse_tunnel && RTE_ETH_IS_TUNNEL_PKT(ptype) != 0) { ++ info.is_tunnel = 1; ++ update_tunnel_outer(&info); ++ info.l2_len = hdr_lens.inner_l2_len + hdr_lens.tunnel_len; ++ info.l3_len = hdr_lens.inner_l3_len; ++ info.l4_len = hdr_lens.inner_l4_len; ++ eth_hdr = (struct rte_ether_hdr *)(char *)l3_hdr + ++ info.outer_l3_len + hdr_lens.tunnel_len; ++ info.ethertype = get_ethertype_by_ptype(eth_hdr, ++ ptype & RTE_PTYPE_INNER_L3_MASK); ++ tx_ol_flags |= get_tunnel_ol_flags_by_ptype(ptype); + } +- +-tunnel_update: + /* update l3_hdr and outer_l3_hdr if a tunnel was parsed */ + if (info.is_tunnel) { + outer_l3_hdr = l3_hdr; + l3_hdr = (char *)l3_hdr + info.outer_l3_len + info.l2_len; ++ parse_inner_l4_proto(l3_hdr, &info); + } +- + /* step 2: depending on user command line configuration, + * recompute checksum either in software or flag the + * mbuf to offload the calculation to the NIC. If TSO +-- +2.25.1 + diff --git a/0102-app-testpmd-fix-VLAN-parsing-in-checksum-engine.patch b/0102-app-testpmd-fix-VLAN-parsing-in-checksum-engine.patch new file mode 100644 index 0000000..ca6a617 --- /dev/null +++ b/0102-app-testpmd-fix-VLAN-parsing-in-checksum-engine.patch @@ -0,0 +1,67 @@ +From c2a19057ed633a50c9a682dde72a65233891273e Mon Sep 17 00:00:00 2001 +From: Raslan Darawsheh +Date: Mon, 24 Mar 2025 11:33:49 +0200 +Subject: [PATCH] app/testpmd: fix VLAN parsing in checksum engine +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 8bit + +[ upstream commit 3e00b30e9b208092f896672046a3ae39b878955b ] + +When processing VLAN or QinQ packets, an infinite loop occurred, +preventing the csum forward engine from proceeding and causing +testpmd to hang during shutdown attempts. + +Updated the `get_ethertype_by_ptype` function to correctly parse +VLAN headers. + +Fixes: 76730c7b9b5a ("app/testpmd: use packet type parsing API") + +Signed-off-by: Raslan Darawsheh +Reviewed-by: Morten Brørup +--- + app/test-pmd/csumonly.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c +index 4b3be71..f2fd63b 100644 +--- a/app/test-pmd/csumonly.c ++++ b/app/test-pmd/csumonly.c +@@ -59,6 +59,8 @@ + #define GRE_SUPPORTED_FIELDS (GRE_CHECKSUM_PRESENT | GRE_KEY_PRESENT |\ + GRE_SEQUENCE_PRESENT) + ++#define MAX_VLAN_HEADERS 8 ++ + /* We cannot use rte_cpu_to_be_16() on a constant in a switch/case */ + #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN + #define _htons(x) ((uint16_t)((((x) & 0x00ffU) << 8) | (((x) & 0xff00U) >> 8))) +@@ -477,7 +479,7 @@ pkts_ip_csum_recalc(struct rte_mbuf **pkts_burst, const uint16_t nb_pkts, uint64 + static uint32_t + get_ethertype_by_ptype(struct rte_ether_hdr *eth_hdr, uint32_t ptype) + { +- struct rte_vlan_hdr *vlan_hdr; ++ struct rte_vlan_hdr *vlan_hdr, *max_vlans; + uint16_t ethertype; + + switch (ptype) { +@@ -497,10 +499,12 @@ get_ethertype_by_ptype(struct rte_ether_hdr *eth_hdr, uint32_t ptype) + return _htons(RTE_ETHER_TYPE_IPV6); + default: + ethertype = eth_hdr->ether_type; +- while (eth_hdr->ether_type == _htons(RTE_ETHER_TYPE_VLAN) || +- eth_hdr->ether_type == _htons(RTE_ETHER_TYPE_QINQ)) { +- vlan_hdr = (struct rte_vlan_hdr *) +- ((char *)eth_hdr + sizeof(*eth_hdr)); ++ vlan_hdr = RTE_PTR_ADD(eth_hdr, offsetof(struct rte_ether_hdr, ether_type)); ++ max_vlans = vlan_hdr + MAX_VLAN_HEADERS; ++ while ((ethertype == _htons(RTE_ETHER_TYPE_VLAN) || ++ ethertype == _htons(RTE_ETHER_TYPE_QINQ)) && ++ vlan_hdr < max_vlans) { ++ vlan_hdr++; + ethertype = vlan_hdr->eth_proto; + } + return ethertype; +-- +2.25.1 + diff --git a/0103-net-fix-offset-in-GENEVE-packet-parsing.patch b/0103-net-fix-offset-in-GENEVE-packet-parsing.patch new file mode 100644 index 0000000..9dc52d3 --- /dev/null +++ b/0103-net-fix-offset-in-GENEVE-packet-parsing.patch @@ -0,0 +1,37 @@ +From 461025d95ad3687f062915d22310db7c72a2e1a6 Mon Sep 17 00:00:00 2001 +From: Sunil Kumar Kori +Date: Wed, 21 May 2025 10:41:42 +0530 +Subject: [PATCH] net: fix offset in GENEVE packet parsing + +[ upstream commit 0a70cf3308f99bd3c32925e5fb0ec465ad4390e8 ] + +While parsing packet headers, offset must be added to get next +header but for geneve header parsing offset is overwritten. +Also inner_l2_len is not set in case of geneve packets. + +Fixes: 64ed7f854cf4 ("net: add tunnel packet type parsing") +Cc: stable@dpdk.org + +Signed-off-by: Sunil Kumar Kori +Acked-by: Dengdui Huang +--- + lib/net/rte_net.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/lib/net/rte_net.c b/lib/net/rte_net.c +index 0c32e78..12fdee0 100644 +--- a/lib/net/rte_net.c ++++ b/lib/net/rte_net.c +@@ -250,7 +250,8 @@ ptype_tunnel_with_udp(uint16_t *proto, const struct rte_mbuf *m, + if (unlikely(gnh == NULL)) + return 0; + geneve_len = sizeof(*gnh) + gnh->opt_len * 4; +- *off = geneve_len; ++ *off += geneve_len; ++ hdr_lens->inner_l2_len = sizeof(struct rte_udp_hdr) + geneve_len; + *proto = gnh->proto; + if (gnh->proto == 0) + *proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); +-- +2.25.1 + diff --git a/0104-app-testpmd-fix-packet-type-parsing.patch b/0104-app-testpmd-fix-packet-type-parsing.patch new file mode 100644 index 0000000..a6cdc90 --- /dev/null +++ b/0104-app-testpmd-fix-packet-type-parsing.patch @@ -0,0 +1,51 @@ +From 19fa302e172b430c706dd6d196fc82e103ca3fa2 Mon Sep 17 00:00:00 2001 +From: Sunil Kumar Kori +Date: Wed, 21 May 2025 10:41:43 +0530 +Subject: [PATCH] app/testpmd: fix packet type parsing + +[ upstream commit 2e0f1e6ec53d5360e8bb7b9dcbfe63839d8a6d9d ] + +hdr_lens is used to maintain header lengths after parsing packets. +When port receives different type of packets (say first is VXLAN +packet and second is GRE packet). + +For first packet, L2/L3/L4 lengths are set for inner and outer header +alongwith tunnel_len. + +Now for second packet, tunnel_len is added more than its size it +contains stale value which further leads to wrong header pointers. + +Hence clearing stale information before processing each packet. + +Fixes: 76730c7b9b5a ("app/testpmd: use packet type parsing API") +Cc: stable@dpdk.org + +Signed-off-by: Sunil Kumar Kori +--- + app/test-pmd/csumonly.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c +index f2fd63b..7fe3d0f 100644 +--- a/app/test-pmd/csumonly.c ++++ b/app/test-pmd/csumonly.c +@@ -638,7 +638,6 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) + uint32_t rx_bad_outer_l4_csum; + uint32_t rx_bad_outer_ip_csum; + struct testpmd_offload_info info; +- struct rte_net_hdr_lens hdr_lens = {0}; + uint32_t ptype; + + /* receive a burst of packet */ +@@ -665,6 +664,8 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) + #endif + + for (i = 0; i < nb_rx; i++) { ++ struct rte_net_hdr_lens hdr_lens = {0}; ++ + if (likely(i < nb_rx - 1)) + rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i + 1], + void *)); +-- +2.25.1 + diff --git a/0105-net-fix-GTP-packet-parsing.patch b/0105-net-fix-GTP-packet-parsing.patch new file mode 100644 index 0000000..4b51b9b --- /dev/null +++ b/0105-net-fix-GTP-packet-parsing.patch @@ -0,0 +1,43 @@ +From 4f00c80258d2061b7288a6431571d013757b4569 Mon Sep 17 00:00:00 2001 +From: Dengdui Huang +Date: Tue, 3 Jun 2025 20:06:22 +0800 +Subject: [PATCH] net: fix GTP packet parsing + +[ upstream commit b1f3a7a8c375fbb66be48aed078222686d16fdb5 ] + +After parsing the GTP packet header, the next protocol type should +be converted from RTE_GTP_TYPE_IPV4/IPV6 to RTE_ETHER_TYPE_IPV4/IPV6. +Otherwise, the next protocol cannot be parsed. + +Bugzilla ID: 1672 +Fixes: 64ed7f854cf4 ("net: add tunnel packet type parsing") +Cc: stable@dpdk.org + +Signed-off-by: Dengdui Huang +Acked-by: Jie Hai +--- + lib/net/rte_net.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/lib/net/rte_net.c b/lib/net/rte_net.c +index 12fdee0..61f9585 100644 +--- a/lib/net/rte_net.c ++++ b/lib/net/rte_net.c +@@ -230,7 +230,13 @@ ptype_tunnel_with_udp(uint16_t *proto, const struct rte_mbuf *m, + */ + if (gh->msg_type == 0xff) { + ip_ver = *(const uint8_t *)((const char *)gh + gtp_len); +- *proto = (ip_ver) & 0xf0; ++ ip_ver = (ip_ver) & 0xf0; ++ if (ip_ver == RTE_GTP_TYPE_IPV4) ++ *proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); ++ else if (ip_ver == RTE_GTP_TYPE_IPV6) ++ *proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); ++ else ++ *proto = 0; + } else { + *proto = 0; + } +-- +2.25.1 + diff --git a/0106-net-add-tunnel-length-in-UDP-tunnel-parsing.patch b/0106-net-add-tunnel-length-in-UDP-tunnel-parsing.patch new file mode 100644 index 0000000..0a14fcb --- /dev/null +++ b/0106-net-add-tunnel-length-in-UDP-tunnel-parsing.patch @@ -0,0 +1,78 @@ +From 4a357e0a748e15abb2647fd48e33ed8f899b7178 Mon Sep 17 00:00:00 2001 +From: Dengdui Huang +Date: Mon, 16 Jun 2025 16:27:01 +0800 +Subject: [PATCH] net: add tunnel length in UDP tunnel parsing + +[ upstream commit a5854045c38865c44459446565dc749aa29dffba ] + +Currently, the tunnel length info is not available when +get the tunnel packet type with UDP port. This patch +adds the parsing of the tunnel length info. + +Additionally, adding comments for the inner_l2_len field +and the tunnel_len field would help in understanding their. + +Fixes: 64ed7f854cf4 ("net: add tunnel packet type parsing") +Cc: stable@dpdk.org + +Signed-off-by: Dengdui Huang +--- + lib/net/rte_net.c | 4 ++++ + lib/net/rte_net.h | 2 ++ + 2 files changed, 6 insertions(+) + +diff --git a/lib/net/rte_net.c b/lib/net/rte_net.c +index 61f9585..1339613 100644 +--- a/lib/net/rte_net.c ++++ b/lib/net/rte_net.c +@@ -196,6 +196,7 @@ ptype_tunnel_with_udp(uint16_t *proto, const struct rte_mbuf *m, + switch (port_no) { + case RTE_VXLAN_DEFAULT_PORT: { + *off += sizeof(struct rte_vxlan_hdr); ++ hdr_lens->tunnel_len = sizeof(struct rte_vxlan_hdr); + hdr_lens->inner_l2_len = RTE_ETHER_VXLAN_HLEN; + *proto = RTE_VXLAN_GPE_TYPE_ETH; /* just for eth header parse. */ + return RTE_PTYPE_TUNNEL_VXLAN; +@@ -207,6 +208,7 @@ ptype_tunnel_with_udp(uint16_t *proto, const struct rte_mbuf *m, + if (unlikely(vgh == NULL)) + return 0; + *off += sizeof(struct rte_vxlan_gpe_hdr); ++ hdr_lens->tunnel_len = sizeof(struct rte_vxlan_gpe_hdr); + hdr_lens->inner_l2_len = RTE_ETHER_VXLAN_GPE_HLEN; + *proto = vgh->proto; + +@@ -242,6 +244,7 @@ ptype_tunnel_with_udp(uint16_t *proto, const struct rte_mbuf *m, + } + *off += gtp_len; + hdr_lens->inner_l2_len = gtp_len + sizeof(struct rte_udp_hdr); ++ hdr_lens->tunnel_len = gtp_len; + if (port_no == RTE_GTPC_UDP_PORT) + return RTE_PTYPE_TUNNEL_GTPC; + else if (port_no == RTE_GTPU_UDP_PORT) +@@ -257,6 +260,7 @@ ptype_tunnel_with_udp(uint16_t *proto, const struct rte_mbuf *m, + return 0; + geneve_len = sizeof(*gnh) + gnh->opt_len * 4; + *off += geneve_len; ++ hdr_lens->tunnel_len = geneve_len; + hdr_lens->inner_l2_len = sizeof(struct rte_udp_hdr) + geneve_len; + *proto = gnh->proto; + if (gnh->proto == 0) +diff --git a/lib/net/rte_net.h b/lib/net/rte_net.h +index ef3ff4c..a925fe0 100644 +--- a/lib/net/rte_net.h ++++ b/lib/net/rte_net.h +@@ -19,9 +19,11 @@ extern "C" { + */ + struct rte_net_hdr_lens { + uint8_t l2_len; ++ /* Outer_L4_len + ... + inner L2_len for tunneling pkt. */ + uint8_t inner_l2_len; + uint16_t l3_len; + uint16_t inner_l3_len; ++ /* Protocol header of tunnel packets */ + uint16_t tunnel_len; + uint8_t l4_len; + uint8_t inner_l4_len; +-- +2.25.1 + diff --git a/0107-app-testpmd-fix-tunnel-inner-info.patch b/0107-app-testpmd-fix-tunnel-inner-info.patch new file mode 100644 index 0000000..785580d --- /dev/null +++ b/0107-app-testpmd-fix-tunnel-inner-info.patch @@ -0,0 +1,41 @@ +From 22777c820ca639786fae895aafa6209a36d08070 Mon Sep 17 00:00:00 2001 +From: Dengdui Huang +Date: Mon, 16 Jun 2025 16:27:02 +0800 +Subject: [PATCH] app/testpmd: fix tunnel inner info + +[ upstream commit a738c43ffaee9ba5d8eccb0e881e7c816d3c6415 ] + +The l2_len field of tunnel packets already includes the tunnel_len field. +Additionally, the current offset used for the internal Ethernet header is +incorrect. This patch fixes these issues. + +Fixes: 76730c7b9b5a ("app/testpmd: use packet type parsing API") +Cc: stable@dpdk.org + +Signed-off-by: Dengdui Huang +--- + app/test-pmd/csumonly.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c +index 7fe3d0f..4891cb8 100644 +--- a/app/test-pmd/csumonly.c ++++ b/app/test-pmd/csumonly.c +@@ -711,11 +711,11 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) + if (txp->parse_tunnel && RTE_ETH_IS_TUNNEL_PKT(ptype) != 0) { + info.is_tunnel = 1; + update_tunnel_outer(&info); +- info.l2_len = hdr_lens.inner_l2_len + hdr_lens.tunnel_len; ++ info.l2_len = hdr_lens.inner_l2_len; + info.l3_len = hdr_lens.inner_l3_len; + info.l4_len = hdr_lens.inner_l4_len; +- eth_hdr = (struct rte_ether_hdr *)(char *)l3_hdr + +- info.outer_l3_len + hdr_lens.tunnel_len; ++ eth_hdr = (struct rte_ether_hdr *)((char *)l3_hdr + ++ hdr_lens.l3_len + hdr_lens.l4_len + hdr_lens.tunnel_len); + info.ethertype = get_ethertype_by_ptype(eth_hdr, + ptype & RTE_PTYPE_INNER_L3_MASK); + tx_ol_flags |= get_tunnel_ol_flags_by_ptype(ptype); +-- +2.25.1 + diff --git a/0095-linux-igb_uio-fix-build-error-in-kernel-6.12.patch b/0108-linux-igb_uio-fix-build-error-in-kernel-6.12.patch similarity index 100% rename from 0095-linux-igb_uio-fix-build-error-in-kernel-6.12.patch rename to 0108-linux-igb_uio-fix-build-error-in-kernel-6.12.patch diff --git a/dpdk.spec b/dpdk.spec index 851ae3d..540cc92 100644 --- a/dpdk.spec +++ b/dpdk.spec @@ -11,25 +11,25 @@ Name: dpdk Version: 23.11 -Release: 33 +Release: 36 URL: http://dpdk.org Source: https://fast.dpdk.org/rel/dpdk-%{version}.tar.xz # upstream patch number is 6xxx # self developed patch number is 9xxx # And the name number of two types patch are numbered together -Patch9001: 0001-add-igb_uio.patch -Patch9002: 0002-dpdk-add-secure-compile-option-and-fPIC-option.patch -Patch9003: 0003-dpdk-bugfix-the-deadlock-in-rte_eal_init.patch -Patch9004: 0004-dpdk-master-core-donot-set-affinity-in-libstorage.patch -Patch9005: 0005-dpdk-change-the-log-level-in-prepare_numa.patch -Patch9006: 0006-dpdk-fix-dpdk-coredump-problem.patch -Patch9007: 0007-dpdk-fix-cpu-flag-error-in-Intel-R-Xeon-R-CPU-E5-262.patch -Patch9008: 0008-reinit-support-return-ok.patch -Patch9009: 0009-gro-fix-gro-with-tcp-push-flag.patch -Patch9010: 0010-example-l3fwd-masking-wrong-warning-array-subscript-.patch -Patch9011: 0011-dpdk-add-support-for-gazellle.patch -Patch9012: 0012-lstack-need-skip-rte_bus_probe-when-use-ltran-mode.patch +Patch6001: 0001-add-igb_uio.patch +Patch6002: 0002-dpdk-add-secure-compile-option-and-fPIC-option.patch +Patch6003: 0003-dpdk-bugfix-the-deadlock-in-rte_eal_init.patch +Patch6004: 0004-dpdk-master-core-donot-set-affinity-in-libstorage.patch +Patch6005: 0005-dpdk-change-the-log-level-in-prepare_numa.patch +Patch6006: 0006-dpdk-fix-dpdk-coredump-problem.patch +Patch6007: 0007-dpdk-fix-cpu-flag-error-in-Intel-R-Xeon-R-CPU-E5-262.patch +Patch6008: 0008-reinit-support-return-ok.patch +Patch6009: 0009-gro-fix-gro-with-tcp-push-flag.patch +Patch6010: 0010-example-l3fwd-masking-wrong-warning-array-subscript-.patch +Patch6011: 0011-dpdk-add-support-for-gazellle.patch +Patch6012: 0012-lstack-need-skip-rte_bus_probe-when-use-ltran-mode.patch Patch6013: 0013-maintainers-update-for-DMA-device-performance-tool.patch Patch6014: 0014-dmadev-add-telemetry-capability-for-m2d-auto-free.patch @@ -50,7 +50,7 @@ Patch6028: 0028-net-hns3-remove-QinQ-insert-support-for-VF.patch Patch6029: 0029-net-hns3-support-power-monitor.patch Patch6030: 0030-app-testpmd-fix-crash-in-multi-process-forwarding.patch -Patch9013: 0031-add-rte_eth_bond_link_monitoring_get-in-map.patch +Patch6031: 0031-add-rte_eth_bond_link_monitoring_get-in-map.patch Patch6032: 0032-ethdev-fix-strict-aliasing-lead-to-link-cannot-be-up.patch @@ -58,7 +58,7 @@ Patch6033: 0033-net-hns3-enable-PFC-for-all-user-priorities.patch Patch6034: 0034-app-testpmd-fix-RSS-algorithm-choice.patch Patch6035: 0035-net-hns3-support-new-device.patch -Patch9036: 0036-require-at-least-two-segs-per-memseg-lists-in-map-pe.patch +Patch6036: 0036-require-at-least-two-segs-per-memseg-lists-in-map-pe.patch Patch6037: 0037-net-hns3-fix-offload-flag-of-IEEE-1588.patch Patch6038: 0038-net-hns3-fix-read-Rx-timestamp-handle.patch @@ -67,7 +67,7 @@ Patch6040: 0040-net-hns3-fix-variable-overflow.patch Patch6041: 0041-net-hns3-disable-SCTP-verification-tag-for-RSS-hash-input.patch Patch6042: 0042-dma-hisilicon-remove-support-for-HIP09-platform.patch -Patch9037: 0043-remove-symbol-for-examples-and-app.patch +Patch6043: 0043-remove-symbol-for-examples-and-app.patch Patch6044: 0044-net-hns3-support-more-VLAN-fields-matching.patch Patch6045: 0045-net-hns3-add-Rx-DMA-address-align-check.patch @@ -104,9 +104,9 @@ Patch6074: 0074-net-hns3-fix-error-code-for-repeatedly-create-counter.patch Patch6075: 0075-net-hns3-fix-fully-use-hardware-flow-director-table.patch Patch6076: 0076-CVE-2024-11614-net-virtio-fix-Rx-checksum-calculation.patch -Patch9077: 0077-config-arm-adapt-RTE_MAX_LCORE-to-640.patch +Patch6077: 0077-config-arm-adapt-RTE_MAX_LCORE-to-640.patch -Patch1078: 0078-dpdk-add-sw_64-support.patch +Patch6078: 0078-dpdk-add-sw_64-support.patch Patch6079: 0079-net-xsc-add-xsc-PMD.patch @@ -127,7 +127,20 @@ Patch6093: 0093-net-hns3-fix-unrelease-some-resources-on-reset-case.patch Patch6094: 0094-net-xsc-optimize-rx.patch -Patch9095: 0095-linux-igb_uio-fix-build-error-in-kernel-6.12.patch +Patch6095: 0095-net-hns3-fix-CRC-data-segment.patch +Patch6096: 0096-net-hns3-fix-Rx-packet-without-CRC-data.patch +Patch6097: 0097-net-hns3-allow-use-of-Rx-vector-mode-with-VLAN-filte.patch +Patch6098: 0098-net-hns3-allow-use-of-Tx-vector-when-fast-free-not-enable.patch +Patch6099: 0099-net-hns3-check-requirement-for-hardware-GRO.patch +Patch6100: 0100-net-add-tunnel-packet-type-parsing.patch +Patch6101: 0101-app-testpmd-use-packet-type-parsing-API.patch +Patch6102: 0102-app-testpmd-fix-VLAN-parsing-in-checksum-engine.patch +Patch6103: 0103-net-fix-offset-in-GENEVE-packet-parsing.patch +Patch6104: 0104-app-testpmd-fix-packet-type-parsing.patch +Patch6105: 0105-net-fix-GTP-packet-parsing.patch +Patch6106: 0106-net-add-tunnel-length-in-UDP-tunnel-parsing.patch +Patch6107: 0107-app-testpmd-fix-tunnel-inner-info.patch +Patch6108: 0108-linux-igb_uio-fix-build-error-in-kernel-6.12.patch BuildRequires: meson BuildRequires: python3-pyelftools @@ -332,9 +345,32 @@ fi /usr/sbin/depmod %changelog -* Wed Jul 30 2025 yangchen - 23.11-33 +* Wed Aug 13 2025 liweigang - 23.11-36 +- patch number modify + +* Wed Jul 30 2025 yangchen - 23.11-35 - linux/igb_uio: fix build error in kernel-6.12 +* Tue Jul 15 2025 huangdengdui - 23.11-34 + Sync some patches about support TSO for packets with + IPv6 extension header and modifications are as follow: + - net: add tunnel packet type parsing + - app/testpmd: use packet type parsing API + - app/testpmd: fix VLAN parsing in checksum engine + - net: fix offset in GENEVE packet parsing + - app/testpmd: fix packet type parsing + - net: fix GTP packet parsing + - net: add tunnel length in UDP tunnel parsing + - app/testpmd: fix tunnel inner info + +* Thu Jun 12 2025 huangdengdui - 23.11-33 + Sync some bugfixes for hns3 pmd and modifications are as follow: + - net/hns3: fix Rx packet without CRC data + - net/hns3: fix CRC data segment + - net/hns3: check requirement for hardware GRO + - net/hns3: allow use of Tx vector when fast free not enabled + - net/hns3: allow use of Rx vector mode with VLAN filter + * Tue May 27 2025 qianrong - 23.11-32 - optimize xsc rx -- Gitee