Hi Gregory,

> -----Original Message-----
> From: dev <dev-boun...@dpdk.org> On Behalf Of Gregory Etelson
> Sent: Monday, July 19, 2021 11:33 AM
> 
> TX checksum of a tunnelled packet can be calculated for outer headers only
> or for both outer and inner parts. The calculation method is determined by
> application.
> If TX checksum calculation can be offloaded, hardware ignores existing
> checksum value and replaces it with an updated result.
> If TX checksum is calculated by a software, existing value must be zeroed
> first.
> The testpmd checksum forwarding engine always zeroed inner checksums.
> If inner checksum calculation was offloaded, that header was left with 0
> checksum value.
> Following outer software checksum calculation produced wrong value.
> The patch zeroes inner IPv4 checksum only before software calculation.
> 
> Fixes: 51f694dd40f5 ("app/testpmd: rework checksum forward engine")
> 
> Cc: sta...@dpdk.org
> 
> Signed-off-by: Gregory Etelson <getel...@nvidia.com>
> Reviewed-by: Dmitry Kozlyuk <dmitry.kozl...@gmail.com>
> ---
>  app/test-pmd/csumonly.c | 23 ++++++++++++-----------
>  1 file changed, 12 insertions(+), 11 deletions(-)
> 
> diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c index
> 089936587b..a658cd5389 100644
> --- a/app/test-pmd/csumonly.c
> +++ b/app/test-pmd/csumonly.c
> @@ -480,17 +480,18 @@ process_inner_cksums(void *l3_hdr, const struct
> testpmd_offload_info *info,
> 
>       if (info->ethertype == _htons(RTE_ETHER_TYPE_IPV4)) {
>               ipv4_hdr = l3_hdr;
> -             ipv4_hdr->hdr_checksum = 0;
> 
>               ol_flags |= PKT_TX_IPV4;
>               if (info->l4_proto == IPPROTO_TCP && tso_segsz) {
>                       ol_flags |= PKT_TX_IP_CKSUM;
>               } else {
> -                     if (tx_offloads & DEV_TX_OFFLOAD_IPV4_CKSUM)
> +                     if (tx_offloads & DEV_TX_OFFLOAD_IPV4_CKSUM) {
>                               ol_flags |= PKT_TX_IP_CKSUM;
> -                     else
> +                     } else if (ipv4_hdr->hdr_checksum) {
> +                             ipv4_hdr->hdr_checksum = 0;
>                               ipv4_hdr->hdr_checksum =
>                                       rte_ipv4_cksum(ipv4_hdr);
> +                     }
>               }
>       } else if (info->ethertype == _htons(RTE_ETHER_TYPE_IPV6))
>               ol_flags |= PKT_TX_IPV6;
> @@ -501,10 +502,10 @@ process_inner_cksums(void *l3_hdr, const struct
> testpmd_offload_info *info,
>               udp_hdr = (struct rte_udp_hdr *)((char *)l3_hdr + info-
> >l3_len);
>               /* do not recalculate udp cksum if it was 0 */
>               if (udp_hdr->dgram_cksum != 0) {
> -                     udp_hdr->dgram_cksum = 0;
> -                     if (tx_offloads & DEV_TX_OFFLOAD_UDP_CKSUM)
> +                     if (tx_offloads & DEV_TX_OFFLOAD_UDP_CKSUM) {
>                               ol_flags |= PKT_TX_UDP_CKSUM;
> -                     else {
> +                     } else if (udp_hdr->dgram_cksum) {
> +                             udp_hdr->dgram_cksum = 0;
>                               udp_hdr->dgram_cksum =
>                                       get_udptcp_checksum(l3_hdr,
> udp_hdr,
>                                               info->ethertype);
> @@ -514,12 +515,12 @@ process_inner_cksums(void *l3_hdr, const struct
> testpmd_offload_info *info,
>                       ol_flags |= PKT_TX_UDP_SEG;
>       } else if (info->l4_proto == IPPROTO_TCP) {
>               tcp_hdr = (struct rte_tcp_hdr *)((char *)l3_hdr + info-
> >l3_len);
> -             tcp_hdr->cksum = 0;
>               if (tso_segsz)
>                       ol_flags |= PKT_TX_TCP_SEG;
> -             else if (tx_offloads & DEV_TX_OFFLOAD_TCP_CKSUM)
> +             else if (tx_offloads & DEV_TX_OFFLOAD_TCP_CKSUM) {
>                       ol_flags |= PKT_TX_TCP_CKSUM;
> -             else {
> +             } else if (tcp_hdr->cksum) {
> +                     tcp_hdr->cksum = 0;
>                       tcp_hdr->cksum =
>                               get_udptcp_checksum(l3_hdr, tcp_hdr,
>                                       info->ethertype);
> @@ -529,13 +530,13 @@ process_inner_cksums(void *l3_hdr, const struct
> testpmd_offload_info *info,
>       } else if (info->l4_proto == IPPROTO_SCTP) {
>               sctp_hdr = (struct rte_sctp_hdr *)
>                       ((char *)l3_hdr + info->l3_len);
> -             sctp_hdr->cksum = 0;
>               /* sctp payload must be a multiple of 4 to be
>                * offloaded */
>               if ((tx_offloads & DEV_TX_OFFLOAD_SCTP_CKSUM) &&
>                       ((ipv4_hdr->total_length & 0x3) == 0)) {
>                       ol_flags |= PKT_TX_SCTP_CKSUM;
> -             } else {
> +             } else if (sctp_hdr->cksum) {
> +                     sctp_hdr->cksum = 0;
>                       /* XXX implement CRC32c, example available in
>                        * RFC3309 */
>               }
> --
> 2.31.1

Acked-by: Ori Kam <or...@nvidia.com>
Thanks,
Ori

Reply via email to