* [PATCH] app/testpmd: fix L4 protocol retrieval from L3 header
@ 2025-08-30 1:29 Dengdui Huang
2025-09-15 16:39 ` Stephen Hemminger
0 siblings, 1 reply; 3+ messages in thread
From: Dengdui Huang @ 2025-08-30 1:29 UTC (permalink / raw)
To: dev; +Cc: aman.deep.singh, stephen, lihuisong, fengchengwen, liuyonglong
Currently, when retrieving the L4 protocol from the L3 header,
the case of IPv6 with extension headers is not handled correctly.
This patch fixes it.
Fixes: 76730c7b9b5a ("app/testpmd: use packet type parsing API")
Cc: stable@dpdk.org
Signed-off-by: Dengdui Huang <huangdengdui@huawei.com>
---
app/test-pmd/csumonly.c | 39 ++++++++++++++++-----------------------
1 file changed, 16 insertions(+), 23 deletions(-)
diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index d355dbd8c0..a6e872e5a4 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -525,20 +525,8 @@ get_tunnel_ol_flags_by_ptype(uint32_t ptype)
}
}
-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)
+parse_l4_proto(const struct rte_mbuf *m, uint32_t off, uint32_t ptype, bool parse_inner)
{
int frag = 0, ret;
@@ -557,16 +545,19 @@ parse_l4_proto(const struct rte_mbuf *m, uint32_t off, uint32_t ptype)
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;
- }
+ if (!parse_inner && (ptype & RTE_PTYPE_L3_MASK) != RTE_PTYPE_L3_IPV6_EXT)
+ return ip6h->proto;
+
+ if (parse_inner && (ptype & RTE_PTYPE_INNER_L3_MASK) != RTE_PTYPE_INNER_L3_IPV6_EXT)
+ return ip6h->proto;
- return ip6h->proto;
+ off += sizeof(struct rte_ipv6_hdr);
+ ret = rte_net_skip_ip6_ext(ip6h->proto, m, &off, &frag);
+ if (ret < 0)
+ return 0;
+ return ret;
}
+
return 0;
}
@@ -705,7 +696,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
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);
+ info.l4_proto = parse_l4_proto(m, info.l2_len, ptype, false);
l3_hdr = (char *)eth_hdr + info.l2_len;
/* check if it's a supported tunnel */
@@ -723,9 +714,11 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
}
/* update l3_hdr and outer_l3_hdr if a tunnel was parsed */
if (info.is_tunnel) {
+ uint16_t l3_off = info.outer_l2_len + info.outer_l3_len + info.l2_len;
+
outer_l3_hdr = l3_hdr;
l3_hdr = (char *)l3_hdr + info.outer_l3_len + info.l2_len;
- parse_inner_l4_proto(l3_hdr, &info);
+ info.l4_proto = parse_l4_proto(m, l3_off, ptype, true);
}
/* step 2: depending on user command line configuration,
* recompute checksum either in software or flag the
--
2.33.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] app/testpmd: fix L4 protocol retrieval from L3 header
2025-08-30 1:29 [PATCH] app/testpmd: fix L4 protocol retrieval from L3 header Dengdui Huang
@ 2025-09-15 16:39 ` Stephen Hemminger
2025-09-16 6:34 ` huangdengdui
0 siblings, 1 reply; 3+ messages in thread
From: Stephen Hemminger @ 2025-09-15 16:39 UTC (permalink / raw)
To: Dengdui Huang; +Cc: dev, aman.deep.singh, lihuisong, fengchengwen, liuyonglong
On Sat, 30 Aug 2025 09:29:13 +0800
Dengdui Huang <huangdengdui@huawei.com> wrote:
> Currently, when retrieving the L4 protocol from the L3 header,
> the case of IPv6 with extension headers is not handled correctly.
> This patch fixes it.
>
> Fixes: 76730c7b9b5a ("app/testpmd: use packet type parsing API")
> Cc: stable@dpdk.org
>
> Signed-off-by: Dengdui Huang <huangdengdui@huawei.com>
> ---
> app/test-pmd/csumonly.c | 39 ++++++++++++++++-----------------------
> 1 file changed, 16 insertions(+), 23 deletions(-)
>
> diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
> index d355dbd8c0..a6e872e5a4 100644
> --- a/app/test-pmd/csumonly.c
> +++ b/app/test-pmd/csumonly.c
> @@ -525,20 +525,8 @@ get_tunnel_ol_flags_by_ptype(uint32_t ptype)
> }
> }
>
> -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)
> +parse_l4_proto(const struct rte_mbuf *m, uint32_t off, uint32_t ptype, bool parse_inner)
> {
> int frag = 0, ret;
>
> @@ -557,16 +545,19 @@ parse_l4_proto(const struct rte_mbuf *m, uint32_t off, uint32_t ptype)
> 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;
> - }
> + if (!parse_inner && (ptype & RTE_PTYPE_L3_MASK) != RTE_PTYPE_L3_IPV6_EXT)
> + return ip6h->proto;
> +
> + if (parse_inner && (ptype & RTE_PTYPE_INNER_L3_MASK) != RTE_PTYPE_INNER_L3_IPV6_EXT)
> + return ip6h->proto;
>
> - return ip6h->proto;
> + off += sizeof(struct rte_ipv6_hdr);
> + ret = rte_net_skip_ip6_ext(ip6h->proto, m, &off, &frag);
> + if (ret < 0)
> + return 0;
> + return ret;
> }
> +
> return 0;
> }
>
> @@ -705,7 +696,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
> 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);
> + info.l4_proto = parse_l4_proto(m, info.l2_len, ptype, false);
Setting parse_inner to false would cause l4_proto to be set to the extension
header type (rather than the real L4 protocol). Was this change intentional?
Looks like it would cause checksum to be computed incorrectly for simple
case of IPV6 with extension header and TCP.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] app/testpmd: fix L4 protocol retrieval from L3 header
2025-09-15 16:39 ` Stephen Hemminger
@ 2025-09-16 6:34 ` huangdengdui
0 siblings, 0 replies; 3+ messages in thread
From: huangdengdui @ 2025-09-16 6:34 UTC (permalink / raw)
To: Stephen Hemminger
Cc: dev, aman.deep.singh, lihuisong, fengchengwen, liuyonglong
On 2025/9/16 0:39, Stephen Hemminger wrote:
> On Sat, 30 Aug 2025 09:29:13 +0800
> Dengdui Huang <huangdengdui@huawei.com> wrote:
>
>> Currently, when retrieving the L4 protocol from the L3 header,
>> the case of IPv6 with extension headers is not handled correctly.
>> This patch fixes it.
>>
>> Fixes: 76730c7b9b5a ("app/testpmd: use packet type parsing API")
>> Cc: stable@dpdk.org
>>
>> Signed-off-by: Dengdui Huang <huangdengdui@huawei.com>
>> ---
>> app/test-pmd/csumonly.c | 39 ++++++++++++++++-----------------------
>> 1 file changed, 16 insertions(+), 23 deletions(-)
>>
>> diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
>> index d355dbd8c0..a6e872e5a4 100644
>> --- a/app/test-pmd/csumonly.c
>> +++ b/app/test-pmd/csumonly.c
>> @@ -525,20 +525,8 @@ get_tunnel_ol_flags_by_ptype(uint32_t ptype)
>> }
>> }
>>
>> -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)
>> +parse_l4_proto(const struct rte_mbuf *m, uint32_t off, uint32_t ptype, bool parse_inner)
>> {
>> int frag = 0, ret;
>>
>> @@ -557,16 +545,19 @@ parse_l4_proto(const struct rte_mbuf *m, uint32_t off, uint32_t ptype)
>> 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;
>> - }
>> + if (!parse_inner && (ptype & RTE_PTYPE_L3_MASK) != RTE_PTYPE_L3_IPV6_EXT)
>> + return ip6h->proto;
>> +
>> + if (parse_inner && (ptype & RTE_PTYPE_INNER_L3_MASK) != RTE_PTYPE_INNER_L3_IPV6_EXT)
>> + return ip6h->proto;
>>
>> - return ip6h->proto;
>> + off += sizeof(struct rte_ipv6_hdr);
>> + ret = rte_net_skip_ip6_ext(ip6h->proto, m, &off, &frag);
>> + if (ret < 0)
>> + return 0;
>> + return ret;
>> }
>> +
>> return 0;
>> }
>>
>> @@ -705,7 +696,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
>> 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);
>> + info.l4_proto = parse_l4_proto(m, info.l2_len, ptype, false);
>
>
> Setting parse_inner to false would cause l4_proto to be set to the extension
> header type (rather than the real L4 protocol). Was this change intentional?
> Looks like it would cause checksum to be computed incorrectly for simple
> case of IPV6 with extension header and TCP.
>
Setting `parse_inner` to `false` does not result in `l4_proto` being assigned as an extended header type.
The purpose of `parse_inner` is solely to indicate whether the `parse_l4_proto` function is handling the outer packet header or the inner packet header.
Perhaps renaming the variable to `is_inner` would be more appropriate.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-09-16 6:34 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-08-30 1:29 [PATCH] app/testpmd: fix L4 protocol retrieval from L3 header Dengdui Huang
2025-09-15 16:39 ` Stephen Hemminger
2025-09-16 6:34 ` huangdengdui
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).