[v1] net/ixgbe: adjust error for UDP with zero checksum

Message ID 20210202070652.145861-1-haiyue.wang@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Qi Zhang
Headers
Series [v1] net/ixgbe: adjust error for UDP with zero checksum |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK
ci/intel-Testing success Testing PASS
ci/iol-broadcom-Performance success Performance Testing PASS
ci/iol-broadcom-Functional success Functional Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-abi-testing success Testing PASS
ci/iol-testing warning Testing issues

Commit Message

Wang, Haiyue Feb. 2, 2021, 7:06 a.m. UTC
  There is an 82599 errata that UDP frames with a zero checksum are
incorrectly marked as checksum invalid by the hardware.  This was
leading to misleading PKT_RX_L4_CKSUM_BAD flag. This patch adds a
test around this checksum error flag set for this condition.

1. UDP Test
  sendp(Ether()/IP()/UDP(chksum=0)/Raw("a"*100), iface="ens802f0")
  port 0/queue 0: received 1 packets
    ol_flags: PKT_RX_L4_CKSUM_GOOD PKT_RX_IP_CKSUM_GOOD

2. TCP Test
  sendp(Ether()/IP()/TCP(chksum=0)/Raw("a"*100), iface="ens802f0")
  port 0/queue 0: received 1 packets
    ol_flags: PKT_RX_L4_CKSUM_BAD PKT_RX_IP_CKSUM_GOOD

Bugzilla ID: 629
Cc: stable@dpdk.org

Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
---
 doc/guides/nics/ixgbe.rst              |  6 ++++
 drivers/net/ixgbe/ixgbe_rxtx.c         | 27 +++++++++++---
 drivers/net/ixgbe/ixgbe_rxtx.h         |  2 ++
 drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c | 49 ++++++++++++++++++++------
 4 files changed, 70 insertions(+), 14 deletions(-)
  

Comments

David Marchand Feb. 2, 2021, 9:45 a.m. UTC | #1
Hello Haiyue,

Thanks for working on it quickly.
Cc: ARM maintainers.

On Tue, Feb 2, 2021 at 8:23 AM Haiyue Wang <haiyue.wang@intel.com> wrote:
>
> There is an 82599 errata that UDP frames with a zero checksum are
> incorrectly marked as checksum invalid by the hardware.  This was

Maybe add a reference to the 82599 hw errata, is this listed in the datasheet?


> leading to misleading PKT_RX_L4_CKSUM_BAD flag. This patch adds a
> test around this checksum error flag set for this condition.
>
> 1. UDP Test
>   sendp(Ether()/IP()/UDP(chksum=0)/Raw("a"*100), iface="ens802f0")
>   port 0/queue 0: received 1 packets
>     ol_flags: PKT_RX_L4_CKSUM_GOOD PKT_RX_IP_CKSUM_GOOD
>
> 2. TCP Test
>   sendp(Ether()/IP()/TCP(chksum=0)/Raw("a"*100), iface="ens802f0")
>   port 0/queue 0: received 1 packets
>     ol_flags: PKT_RX_L4_CKSUM_BAD PKT_RX_IP_CKSUM_GOOD
>
> Bugzilla ID: 629

The problem has always been present, so I would flag:
Fixes: af75078fece3 ("first public release")

> Cc: stable@dpdk.org
>

Reported-by: Paolo Valerio <pvalerio@redhat.com>
> Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
> ---
>  doc/guides/nics/ixgbe.rst              |  6 ++++
>  drivers/net/ixgbe/ixgbe_rxtx.c         | 27 +++++++++++---
>  drivers/net/ixgbe/ixgbe_rxtx.h         |  2 ++
>  drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c | 49 ++++++++++++++++++++------
>  4 files changed, 70 insertions(+), 14 deletions(-)
>
> diff --git a/doc/guides/nics/ixgbe.rst b/doc/guides/nics/ixgbe.rst
> index 696cbd93b..de210b7b8 100644
> --- a/doc/guides/nics/ixgbe.rst
> +++ b/doc/guides/nics/ixgbe.rst
> @@ -287,6 +287,12 @@ the VFs which are required.::
>  Currently hot-plugging of representor ports is not supported so all required
>  representors must be specified on the creation of the PF.
>
> +Limitations or Known issues
> +---------------------------
> +The 82599 hardware errata: UDP frames with a zero checksum can be marked as
> +checksum errors. To support zero checksum, the UDP checksum is always marked
> +as good.
> +

If the driver/hw can't report a valid checksum hint, it should
announce it does not know if the checksum is valid (neither bad, nor
good).

So the workaround for udp packets (on this hw model) would be to
report PKT_RX_L4_CKSUM_UNKNOWN.
The sw application will then have to recompute the checksum itself if needed.
  
Wang, Haiyue Feb. 2, 2021, 12:42 p.m. UTC | #2
Hi David,

> -----Original Message-----
> From: David Marchand <david.marchand@redhat.com>
> Sent: Tuesday, February 2, 2021 17:45
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: dev <dev@dpdk.org>; pvalerio@redhat.com; Aaron Conole <aconole@redhat.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>; Rong, Leyi <leyi.rong@intel.com>; Tu, Lijuan <lijuan.tu@intel.com>; dpdk
> stable <stable@dpdk.org>; Guo, Jia <jia.guo@intel.com>; Richardson, Bruce <bruce.richardson@intel.com>;
> Ananyev, Konstantin <konstantin.ananyev@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>;
> Ruifeng Wang (Arm Technology China) <ruifeng.wang@arm.com>
> Subject: Re: [PATCH v1] net/ixgbe: adjust error for UDP with zero checksum
> 
> Hello Haiyue,
> 
> Thanks for working on it quickly.
> Cc: ARM maintainers.
> 
> On Tue, Feb 2, 2021 at 8:23 AM Haiyue Wang <haiyue.wang@intel.com> wrote:
> >
> > There is an 82599 errata that UDP frames with a zero checksum are
> > incorrectly marked as checksum invalid by the hardware.  This was
> 
> Maybe add a reference to the 82599 hw errata, is this listed in the datasheet?
> 

I didn't find open and official doc, but on:

https://www.mouser.es/pdfdocs/82599specupdate.pdf

44 Integrity Error Reported for IPv4/UDP Packets
With Zero Checksum
Problem: According to the UDP specification “an all zero transmitted checksum value
means that the transmitter generated no checksum (for debugging or for higher
level protocols that don’t care)”, these packets should be received without a
checksum error notation. The 82599 reports an L4 integrity error if such packets
are received.
Implication: UDP packets without a checksum will have an L4 integrity error indication in the
Rx descriptor.
Workaround: If bits L4E and L4I are set in the Rx descriptor, the software driver should
check if the checksum is zero and then ignore this error.
Status: B0=Yes; No Fix

> 
> > leading to misleading PKT_RX_L4_CKSUM_BAD flag. This patch adds a
> > test around this checksum error flag set for this condition.
> >
> > 1. UDP Test
> >   sendp(Ether()/IP()/UDP(chksum=0)/Raw("a"*100), iface="ens802f0")
> >   port 0/queue 0: received 1 packets
> >     ol_flags: PKT_RX_L4_CKSUM_GOOD PKT_RX_IP_CKSUM_GOOD
> >
> > 2. TCP Test
> >   sendp(Ether()/IP()/TCP(chksum=0)/Raw("a"*100), iface="ens802f0")
> >   port 0/queue 0: received 1 packets
> >     ol_flags: PKT_RX_L4_CKSUM_BAD PKT_RX_IP_CKSUM_GOOD
> >
> > Bugzilla ID: 629
> 
> The problem has always been present, so I would flag:
> Fixes: af75078fece3 ("first public release")
> 
> > Cc: stable@dpdk.org
> >
> 
> Reported-by: Paolo Valerio <pvalerio@redhat.com>
> > Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
> > ---
> >  doc/guides/nics/ixgbe.rst              |  6 ++++
> >  drivers/net/ixgbe/ixgbe_rxtx.c         | 27 +++++++++++---
> >  drivers/net/ixgbe/ixgbe_rxtx.h         |  2 ++
> >  drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c | 49 ++++++++++++++++++++------
> >  4 files changed, 70 insertions(+), 14 deletions(-)
> >
> > diff --git a/doc/guides/nics/ixgbe.rst b/doc/guides/nics/ixgbe.rst
> > index 696cbd93b..de210b7b8 100644
> > --- a/doc/guides/nics/ixgbe.rst
> > +++ b/doc/guides/nics/ixgbe.rst
> > @@ -287,6 +287,12 @@ the VFs which are required.::
> >  Currently hot-plugging of representor ports is not supported so all required
> >  representors must be specified on the creation of the PF.
> >
> > +Limitations or Known issues
> > +---------------------------
> > +The 82599 hardware errata: UDP frames with a zero checksum can be marked as
> > +checksum errors. To support zero checksum, the UDP checksum is always marked
> > +as good.
> > +
> 
> If the driver/hw can't report a valid checksum hint, it should
> announce it does not know if the checksum is valid (neither bad, nor
> good).
> 
> So the workaround for udp packets (on this hw model) would be to
> report PKT_RX_L4_CKSUM_UNKNOWN.
> The sw application will then have to recompute the checksum itself if needed.
> 

Make sense, but not sure the vector path can handle this more easily. Will try.

> 
> --
> David Marchand
  
David Marchand Feb. 2, 2021, 12:53 p.m. UTC | #3
On Tue, Feb 2, 2021 at 1:42 PM Wang, Haiyue <haiyue.wang@intel.com> wrote:
> > If the driver/hw can't report a valid checksum hint, it should
> > announce it does not know if the checksum is valid (neither bad, nor
> > good).
> >
> > So the workaround for udp packets (on this hw model) would be to
> > report PKT_RX_L4_CKSUM_UNKNOWN.
> > The sw application will then have to recompute the checksum itself if needed.
> >
>
> Make sense, but not sure the vector path can handle this more easily. Will try.

Refining this a bit.
It looks like hw correctly reports "good" checksums, so maybe instead
report PKT_RX_L4_CKSUM_UNKNOWN only for reports of "bad" checksums
from the hw?
  
Wang, Haiyue Feb. 2, 2021, 12:54 p.m. UTC | #4
> -----Original Message-----
> From: David Marchand <david.marchand@redhat.com>
> Sent: Tuesday, February 2, 2021 17:45
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: dev <dev@dpdk.org>; pvalerio@redhat.com; Aaron Conole <aconole@redhat.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>; Rong, Leyi <leyi.rong@intel.com>; Tu, Lijuan <lijuan.tu@intel.com>; dpdk
> stable <stable@dpdk.org>; Guo, Jia <jia.guo@intel.com>; Richardson, Bruce <bruce.richardson@intel.com>;
> Ananyev, Konstantin <konstantin.ananyev@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>;
> Ruifeng Wang (Arm Technology China) <ruifeng.wang@arm.com>
> Subject: Re: [PATCH v1] net/ixgbe: adjust error for UDP with zero checksum
> 


> 
> If the driver/hw can't report a valid checksum hint, it should
> announce it does not know if the checksum is valid (neither bad, nor
> good).
> 
> So the workaround for udp packets (on this hw model) would be to
> report PKT_RX_L4_CKSUM_UNKNOWN.
> The sw application will then have to recompute the checksum itself if needed.
> 

Looks like this workaround will make OVS performance drop a lot, since
every UDP packet needs to do checksum by SW:

            bool  hwol_good_l4_csum = dp_packet_l4_checksum_valid(pkt)
                                      || dp_packet_hwol_tx_l4_checksum(pkt);
            /* Validate the checksum only when hwol is not supported. */
            if (extract_l4(&ctx->key, l4, dp_packet_l4_size(pkt),
                           &ctx->icmp_related, l3, !hwol_good_l4_csum,
                           NULL)) {
                ctx->hash = conn_key_hash(&ctx->key, ct->hash_basis);
                return true;
            }

The lesser of the two rights, marking as good seems a little better.

> 
> --
> David Marchand
  
Wang, Haiyue Feb. 2, 2021, 12:56 p.m. UTC | #5
> -----Original Message-----
> From: David Marchand <david.marchand@redhat.com>
> Sent: Tuesday, February 2, 2021 20:54
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: dev <dev@dpdk.org>; pvalerio@redhat.com; Aaron Conole <aconole@redhat.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>; Rong, Leyi <leyi.rong@intel.com>; Tu, Lijuan <lijuan.tu@intel.com>; dpdk
> stable <stable@dpdk.org>; Guo, Jia <jia.guo@intel.com>; Richardson, Bruce <bruce.richardson@intel.com>;
> Ananyev, Konstantin <konstantin.ananyev@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>;
> Ruifeng Wang (Arm Technology China) <ruifeng.wang@arm.com>
> Subject: Re: [PATCH v1] net/ixgbe: adjust error for UDP with zero checksum
> 
> On Tue, Feb 2, 2021 at 1:42 PM Wang, Haiyue <haiyue.wang@intel.com> wrote:
> > > If the driver/hw can't report a valid checksum hint, it should
> > > announce it does not know if the checksum is valid (neither bad, nor
> > > good).
> > >
> > > So the workaround for udp packets (on this hw model) would be to
> > > report PKT_RX_L4_CKSUM_UNKNOWN.
> > > The sw application will then have to recompute the checksum itself if needed.
> > >
> >
> > Make sense, but not sure the vector path can handle this more easily. Will try.
> 
> Refining this a bit.
> It looks like hw correctly reports "good" checksums, so maybe instead
> report PKT_RX_L4_CKSUM_UNKNOWN only for reports of "bad" checksums
> from the hw?

I guess Paolo will complain about the performance drop for zero checksum
UDP. ;-)

> 
> --
> David Marchand
  
Wang, Haiyue Feb. 2, 2021, 2:28 p.m. UTC | #6
> -----Original Message-----
> From: Wang, Haiyue
> Sent: Tuesday, February 2, 2021 20:57
> To: David Marchand <david.marchand@redhat.com>
> Cc: dev <dev@dpdk.org>; pvalerio@redhat.com; Aaron Conole <aconole@redhat.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>; Rong, Leyi <leyi.rong@intel.com>; Tu, Lijuan <Lijuan.Tu@intel.com>; dpdk
> stable <stable@dpdk.org>; Guo, Jia <jia.guo@intel.com>; Richardson, Bruce <bruce.richardson@intel.com>;
> Ananyev, Konstantin <konstantin.ananyev@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>;
> Ruifeng Wang (Arm Technology China) <ruifeng.wang@arm.com>
> Subject: RE: [PATCH v1] net/ixgbe: adjust error for UDP with zero checksum
> 
> > -----Original Message-----
> > From: David Marchand <david.marchand@redhat.com>
> > Sent: Tuesday, February 2, 2021 20:54
> > To: Wang, Haiyue <haiyue.wang@intel.com>
> > Cc: dev <dev@dpdk.org>; pvalerio@redhat.com; Aaron Conole <aconole@redhat.com>; Zhang, Qi Z
> > <qi.z.zhang@intel.com>; Rong, Leyi <leyi.rong@intel.com>; Tu, Lijuan <lijuan.tu@intel.com>; dpdk
> > stable <stable@dpdk.org>; Guo, Jia <jia.guo@intel.com>; Richardson, Bruce
> <bruce.richardson@intel.com>;
> > Ananyev, Konstantin <konstantin.ananyev@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>;
> > Ruifeng Wang (Arm Technology China) <ruifeng.wang@arm.com>
> > Subject: Re: [PATCH v1] net/ixgbe: adjust error for UDP with zero checksum
> >
> > On Tue, Feb 2, 2021 at 1:42 PM Wang, Haiyue <haiyue.wang@intel.com> wrote:
> > > > If the driver/hw can't report a valid checksum hint, it should
> > > > announce it does not know if the checksum is valid (neither bad, nor
> > > > good).
> > > >
> > > > So the workaround for udp packets (on this hw model) would be to
> > > > report PKT_RX_L4_CKSUM_UNKNOWN.
> > > > The sw application will then have to recompute the checksum itself if needed.
> > > >
> > >
> > > Make sense, but not sure the vector path can handle this more easily. Will try.
> >
> > Refining this a bit.
> > It looks like hw correctly reports "good" checksums, so maybe instead
> > report PKT_RX_L4_CKSUM_UNKNOWN only for reports of "bad" checksums
> > from the hw?
> 
> I guess Paolo will complain about the performance drop for zero checksum
> UDP. ;-)
> 

Deep into OVS for detail, 'PKT_RX_L4_CKSUM_UNKNOWN' is a graceful way. ;-)
Will work for this target.

    /* Validation must be skipped if checksum is 0 on IPv4 packets */
    return (udp->udp_csum == 0 && key->dl_type == htons(ETH_TYPE_IP))
           || (validate_checksum ? checksum_valid(key, data, size, l3) : true);

> >
> > --
> > David Marchand
  
Paolo Valerio Feb. 2, 2021, 5:42 p.m. UTC | #7
"Wang, Haiyue" <haiyue.wang@intel.com> writes:

>> -----Original Message-----
>> From: Wang, Haiyue
>> Sent: Tuesday, February 2, 2021 20:57
>> To: David Marchand <david.marchand@redhat.com>
>> Cc: dev <dev@dpdk.org>; pvalerio@redhat.com; Aaron Conole <aconole@redhat.com>; Zhang, Qi Z
>> <qi.z.zhang@intel.com>; Rong, Leyi <leyi.rong@intel.com>; Tu, Lijuan <Lijuan.Tu@intel.com>; dpdk
>> stable <stable@dpdk.org>; Guo, Jia <jia.guo@intel.com>; Richardson, Bruce <bruce.richardson@intel.com>;
>> Ananyev, Konstantin <konstantin.ananyev@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>;
>> Ruifeng Wang (Arm Technology China) <ruifeng.wang@arm.com>
>> Subject: RE: [PATCH v1] net/ixgbe: adjust error for UDP with zero checksum
>> 
>> > -----Original Message-----
>> > From: David Marchand <david.marchand@redhat.com>
>> > Sent: Tuesday, February 2, 2021 20:54
>> > To: Wang, Haiyue <haiyue.wang@intel.com>
>> > Cc: dev <dev@dpdk.org>; pvalerio@redhat.com; Aaron Conole <aconole@redhat.com>; Zhang, Qi Z
>> > <qi.z.zhang@intel.com>; Rong, Leyi <leyi.rong@intel.com>; Tu, Lijuan <lijuan.tu@intel.com>; dpdk
>> > stable <stable@dpdk.org>; Guo, Jia <jia.guo@intel.com>; Richardson, Bruce
>> <bruce.richardson@intel.com>;
>> > Ananyev, Konstantin <konstantin.ananyev@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>;
>> > Ruifeng Wang (Arm Technology China) <ruifeng.wang@arm.com>
>> > Subject: Re: [PATCH v1] net/ixgbe: adjust error for UDP with zero checksum
>> >
>> > On Tue, Feb 2, 2021 at 1:42 PM Wang, Haiyue <haiyue.wang@intel.com> wrote:
>> > > > If the driver/hw can't report a valid checksum hint, it should
>> > > > announce it does not know if the checksum is valid (neither bad, nor
>> > > > good).
>> > > >
>> > > > So the workaround for udp packets (on this hw model) would be to
>> > > > report PKT_RX_L4_CKSUM_UNKNOWN.
>> > > > The sw application will then have to recompute the checksum itself if needed.
>> > > >
>> > >
>> > > Make sense, but not sure the vector path can handle this more easily. Will try.
>> >
>> > Refining this a bit.
>> > It looks like hw correctly reports "good" checksums, so maybe instead
>> > report PKT_RX_L4_CKSUM_UNKNOWN only for reports of "bad" checksums
>> > from the hw?
>> 
>> I guess Paolo will complain about the performance drop for zero checksum
>> UDP. ;-)
>>

:)

>
> Deep into OVS for detail, 'PKT_RX_L4_CKSUM_UNKNOWN' is a graceful way. ;-)
> Will work for this target.

yes, validation gets skipped in such case.
I'll be happy to test it once posted.

>
>     /* Validation must be skipped if checksum is 0 on IPv4 packets */
>     return (udp->udp_csum == 0 && key->dl_type == htons(ETH_TYPE_IP))
>            || (validate_checksum ? checksum_valid(key, data, size, l3) : true);
>
>> >
>> > --
>> > David Marchand
  

Patch

diff --git a/doc/guides/nics/ixgbe.rst b/doc/guides/nics/ixgbe.rst
index 696cbd93b..de210b7b8 100644
--- a/doc/guides/nics/ixgbe.rst
+++ b/doc/guides/nics/ixgbe.rst
@@ -287,6 +287,12 @@  the VFs which are required.::
 Currently hot-plugging of representor ports is not supported so all required
 representors must be specified on the creation of the PF.
 
+Limitations or Known issues
+---------------------------
+The 82599 hardware errata: UDP frames with a zero checksum can be marked as
+checksum errors. To support zero checksum, the UDP checksum is always marked
+as good.
+
 Supported Chipsets and NICs
 ---------------------------
 
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index c1f0c446a..550e3f390 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -1466,7 +1466,8 @@  rx_desc_status_to_pkt_flags(uint32_t rx_status, uint64_t vlan_flags)
 }
 
 static inline uint64_t
-rx_desc_error_to_pkt_flags(uint32_t rx_status)
+rx_desc_error_to_pkt_flags(uint32_t rx_status, uint16_t pkt_info,
+			   uint8_t rx_udp_csum_zero_err)
 {
 	uint64_t pkt_flags;
 
@@ -1480,6 +1481,12 @@  rx_desc_error_to_pkt_flags(uint32_t rx_status)
 		PKT_RX_IP_CKSUM_BAD | PKT_RX_L4_CKSUM_GOOD,
 		PKT_RX_IP_CKSUM_BAD | PKT_RX_L4_CKSUM_BAD
 	};
+
+	if ((rx_status & IXGBE_RXDADV_ERR_TCPE) &&
+	    (pkt_info & IXGBE_RXDADV_PKTTYPE_UDP) &&
+	    rx_udp_csum_zero_err)
+		rx_status &= ~IXGBE_RXDADV_ERR_TCPE;
+
 	pkt_flags = error_to_pkt_flags_map[(rx_status >>
 		IXGBE_RXDADV_ERR_CKSUM_BIT) & IXGBE_RXDADV_ERR_CKSUM_MSK];
 
@@ -1569,7 +1576,9 @@  ixgbe_rx_scan_hw_ring(struct ixgbe_rx_queue *rxq)
 			/* convert descriptor fields to rte mbuf flags */
 			pkt_flags = rx_desc_status_to_pkt_flags(s[j],
 				vlan_flags);
-			pkt_flags |= rx_desc_error_to_pkt_flags(s[j]);
+			pkt_flags |= rx_desc_error_to_pkt_flags(s[j],
+					(uint16_t)pkt_info[j],
+					rxq->rx_udp_csum_zero_err);
 			pkt_flags |= ixgbe_rxd_pkt_info_to_pkt_flags
 					((uint16_t)pkt_info[j]);
 			mb->ol_flags = pkt_flags;
@@ -1902,7 +1911,9 @@  ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		rxm->vlan_tci = rte_le_to_cpu_16(rxd.wb.upper.vlan);
 
 		pkt_flags = rx_desc_status_to_pkt_flags(staterr, vlan_flags);
-		pkt_flags = pkt_flags | rx_desc_error_to_pkt_flags(staterr);
+		pkt_flags = pkt_flags |
+			rx_desc_error_to_pkt_flags(staterr, (uint16_t)pkt_info,
+						   rxq->rx_udp_csum_zero_err);
 		pkt_flags = pkt_flags |
 			ixgbe_rxd_pkt_info_to_pkt_flags((uint16_t)pkt_info);
 		rxm->ol_flags = pkt_flags;
@@ -1995,7 +2006,8 @@  ixgbe_fill_cluster_head_buf(
 	head->vlan_tci = rte_le_to_cpu_16(desc->wb.upper.vlan);
 	pkt_info = rte_le_to_cpu_32(desc->wb.lower.lo_dword.data);
 	pkt_flags = rx_desc_status_to_pkt_flags(staterr, rxq->vlan_flags);
-	pkt_flags |= rx_desc_error_to_pkt_flags(staterr);
+	pkt_flags |= rx_desc_error_to_pkt_flags(staterr, (uint16_t)pkt_info,
+						rxq->rx_udp_csum_zero_err);
 	pkt_flags |= ixgbe_rxd_pkt_info_to_pkt_flags((uint16_t)pkt_info);
 	head->ol_flags = pkt_flags;
 	head->packet_type =
@@ -3116,6 +3128,13 @@  ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	else
 		rxq->pkt_type_mask = IXGBE_PACKET_TYPE_MASK_82599;
 
+	/*
+	 * 82599 errata, UDP frames with a 0 checksum can be marked as checksum
+	 * errors.
+	 */
+	if (hw->mac.type == ixgbe_mac_82599EB)
+		rxq->rx_udp_csum_zero_err = 1;
+
 	/*
 	 * Allocate RX ring hardware descriptors. A memzone large enough to
 	 * handle the maximum ring size is allocated in order to allow for
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.h b/drivers/net/ixgbe/ixgbe_rxtx.h
index 8a25e98df..476ef62cf 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.h
+++ b/drivers/net/ixgbe/ixgbe_rxtx.h
@@ -129,6 +129,8 @@  struct ixgbe_rx_queue {
 	uint8_t             crc_len;  /**< 0 if CRC stripped, 4 otherwise. */
 	uint8_t             drop_en;  /**< If not 0, set SRRCTL.Drop_En. */
 	uint8_t             rx_deferred_start; /**< not in global dev start. */
+	/** UDP frames with a 0 checksum can be marked as checksum errors. */
+	uint8_t             rx_udp_csum_zero_err;
 	/** flags to set in mbuf when a vlan is detected. */
 	uint64_t            vlan_flags;
 	uint64_t	    offloads; /**< Rx offloads with DEV_RX_OFFLOAD_* */
diff --git a/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c b/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c
index 90c076825..8bffafc71 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c
@@ -132,9 +132,9 @@  desc_to_olflags_v_ipsec(__m128i descs[4], struct rte_mbuf **rx_pkts)
 
 static inline void
 desc_to_olflags_v(__m128i descs[4], __m128i mbuf_init, uint8_t vlan_flags,
-	struct rte_mbuf **rx_pkts)
+		  uint16_t udp_p_flag, struct rte_mbuf **rx_pkts)
 {
-	__m128i ptype0, ptype1, vtag0, vtag1, csum;
+	__m128i ptype0, ptype1, vtag0, vtag1, csum, vlan_csum_msk;
 	__m128i rearm0, rearm1, rearm2, rearm3;
 
 	/* mask everything except rss type */
@@ -154,13 +154,29 @@  desc_to_olflags_v(__m128i descs[4], __m128i mbuf_init, uint8_t vlan_flags,
 			PKT_RX_RSS_HASH, PKT_RX_RSS_HASH, PKT_RX_RSS_HASH, 0);
 
 	/* mask everything except vlan present and l4/ip csum error */
-	const __m128i vlan_csum_msk = _mm_set_epi16(
-		(IXGBE_RXDADV_ERR_TCPE | IXGBE_RXDADV_ERR_IPE) >> 16,
-		(IXGBE_RXDADV_ERR_TCPE | IXGBE_RXDADV_ERR_IPE) >> 16,
-		(IXGBE_RXDADV_ERR_TCPE | IXGBE_RXDADV_ERR_IPE) >> 16,
-		(IXGBE_RXDADV_ERR_TCPE | IXGBE_RXDADV_ERR_IPE) >> 16,
-		IXGBE_RXD_STAT_VP, IXGBE_RXD_STAT_VP,
-		IXGBE_RXD_STAT_VP, IXGBE_RXD_STAT_VP);
+	const __m128i vlan_csum_all_msk = _mm_set_epi16
+		((IXGBE_RXDADV_ERR_TCPE | IXGBE_RXDADV_ERR_IPE) >> 16,
+		 (IXGBE_RXDADV_ERR_TCPE | IXGBE_RXDADV_ERR_IPE) >> 16,
+		 (IXGBE_RXDADV_ERR_TCPE | IXGBE_RXDADV_ERR_IPE) >> 16,
+		 (IXGBE_RXDADV_ERR_TCPE | IXGBE_RXDADV_ERR_IPE) >> 16,
+		 IXGBE_RXD_STAT_VP, IXGBE_RXD_STAT_VP,
+		 IXGBE_RXD_STAT_VP, IXGBE_RXD_STAT_VP);
+
+	/* mask everything except UDP header present */
+	const __m128i udptype_msk = _mm_set_epi16
+		(0, 0, 0, 0,
+		 udp_p_flag, udp_p_flag, udp_p_flag, udp_p_flag);
+
+	/* convert UDP header present 16 bits 0x0200 to 8 bits 0x02, then get
+	 * the TCP/UDP checksum error mask 8 bits ~0x40 from 32 bits value of
+	 * 0x40000000.
+	 */
+	const __m128i udp_csum_err_skip = _mm_set_epi8
+		(0, 0, 0, 0,
+		 0, 0, 0, 0,
+		 0, 0, 0, 0,
+		 0, ~(IXGBE_RXDADV_ERR_TCPE >> 24), 0, 0xFF);
+
 	/* map vlan present (0x8), IPE (0x2), L4E (0x1) to ol_flags */
 	const __m128i vlan_csum_map_lo = _mm_set_epi8(
 		0, 0, 0, 0,
@@ -188,9 +204,17 @@  desc_to_olflags_v(__m128i descs[4], __m128i mbuf_init, uint8_t vlan_flags,
 	vtag1 = _mm_unpackhi_epi16(descs[2], descs[3]);
 
 	ptype0 = _mm_unpacklo_epi32(ptype0, ptype1);
+	/* save the UDP header present information */
+	vlan_csum_msk = _mm_and_si128(ptype0, udptype_msk);
 	ptype0 = _mm_and_si128(ptype0, rsstype_msk);
 	ptype0 = _mm_shuffle_epi8(rss_flags, ptype0);
 
+	/* now the most significant 64 bits containing the UDP present */
+	vlan_csum_msk = _mm_slli_si128(vlan_csum_msk, 8);
+	/* use UDP present 0x02 index to get L4 checksum error mask ~0x40 */
+	vlan_csum_msk = _mm_shuffle_epi8(udp_csum_err_skip, vlan_csum_msk);
+	/* then mask out the L4 checksum error bit as needed */
+	vlan_csum_msk = _mm_and_si128(vlan_csum_all_msk, vlan_csum_msk);
 	vtag1 = _mm_unpacklo_epi32(vtag0, vtag1);
 	vtag1 = _mm_and_si128(vtag1, vlan_csum_msk);
 
@@ -341,6 +365,7 @@  _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
 	__m128i dd_check, eop_check;
 	__m128i mbuf_init;
 	uint8_t vlan_flags;
+	uint16_t udp_p_flag = 0; /* Rx Descriptor UDP header present */
 
 	/* nb_pkts has to be floor-aligned to RTE_IXGBE_DESCS_PER_LOOP */
 	nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, RTE_IXGBE_DESCS_PER_LOOP);
@@ -365,6 +390,9 @@  _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
 				rte_cpu_to_le_32(IXGBE_RXDADV_STAT_DD)))
 		return 0;
 
+	if (rxq->rx_udp_csum_zero_err)
+		udp_p_flag = IXGBE_RXDADV_PKTTYPE_UDP;
+
 	/* 4 packets DD mask */
 	dd_check = _mm_set_epi64x(0x0000000100000001LL, 0x0000000100000001LL);
 
@@ -477,7 +505,8 @@  _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts,
 		sterr_tmp1 = _mm_unpackhi_epi32(descs[1], descs[0]);
 
 		/* set ol_flags with vlan packet type */
-		desc_to_olflags_v(descs, mbuf_init, vlan_flags, &rx_pkts[pos]);
+		desc_to_olflags_v(descs, mbuf_init, vlan_flags, udp_p_flag,
+				  &rx_pkts[pos]);
 
 #ifdef RTE_LIB_SECURITY
 		if (unlikely(use_ipsec))