[PATCH] gro: fix packet type comparisons

Morten Brørup mb at smartsharesystems.com
Mon Nov 2 15:11:17 CET 2026


> From: Thomas Monjalon [mailto:thomas at monjalon.net]
> Sent: Monday, 2 November 2026 12.27
> 
> 17/10/2026 19:02, Morten Brørup:
> > Identifying packet types requires masking with the mask, not the
> value,
> > before comparing to the value.
> [...]
> >  #define IS_IPV4_UDP_PKT(ptype) (RTE_ETH_IS_IPV4_HDR(ptype) && \
> > -		((ptype & RTE_PTYPE_L4_UDP) == RTE_PTYPE_L4_UDP) && \
> > +		((ptype & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_UDP) && \
> >  		(RTE_ETH_IS_TUNNEL_PKT(ptype) == 0))
> [...]
> >  #define IS_IPV4_VXLAN_UDP4_PKT(ptype) (RTE_ETH_IS_IPV4_HDR(ptype) &&
> \
> > -		((ptype & RTE_PTYPE_L4_UDP) == RTE_PTYPE_L4_UDP) && \
> > -		((ptype & RTE_PTYPE_TUNNEL_VXLAN) == \
> > +		((ptype & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_UDP) && \
> > +		((ptype & RTE_PTYPE_TUNNEL_MASK) == \
> >  		 RTE_PTYPE_TUNNEL_VXLAN) && \
> > -		((ptype & RTE_PTYPE_INNER_L4_UDP) == \
> > +		((ptype & RTE_PTYPE_INNER_L4_MASK) == \
> >  		 RTE_PTYPE_INNER_L4_UDP) && \
> 
> 
> My AI is not happy:
> "
> The UDP checks introduce a regression.
> gro_udp4_reassemble() only processes IPv4 fragments,

Great review feedback!

I'm not using GRO, so I didn't know the expected behavior.
I spotted this by random luck, and it looked completely wrong, so I sent a quick patch.

> but the new comparison:
> 
> (ptype & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_UDP
> 
> rejects packets marked RTE_PTYPE_L4_FRAG.
> 
> The previous check accepted them because RTE_PTYPE_L4_FRAG is 0x300 and
> RTE_PTYPE_L4_UDP is 0x200.

Now that I have learned that gro_udp4_reassemble() doesn't want UDP packets, it wants fragments, then the correct comparison is:

 #define IS_IPV4_UDP_PKT(ptype) (RTE_ETH_IS_IPV4_HDR(ptype) && \
-		((ptype & RTE_PTYPE_L4_UDP) == RTE_PTYPE_L4_UDP) && \
+		((ptype & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_FRAG) && \
 		(RTE_ETH_IS_TUNNEL_PKT(ptype) == 0))

But then the macro name seems misleading.
Renaming it to IS_IPV4_FRAG_PKT() might be confusing when used in the code below, so adding a comment to the macro definition is probably better.

Under all circumstances, the formula "((ptype & RTE_PTYPE_L4_UDP) == RTE_PTYPE_L4_UDP)" is wrong:
It not only matches UDP packets (0x200) and IP fragments (0x300), it matches anything with the 0x200 bit set, including RTE_PTYPE_L4_NONFRAG (0x600) and RTE_PTYPE_L4_IGMP (0x700).

> 
> The same applies to IS_IPV4_VXLAN_UDP4_PKT():
> requiring an exact match against RTE_PTYPE_INNER_L4_UDP excludes inner
> fragments,
> which are precisely what gro_vxlan_udp4_reassemble() processes.
> 
> Could you preserve fragment handling in both UDP checks and add
> regression tests?
> "

I will look into it later, when I have time for it.
Marking the patch Changes Requested for now.

Anyone feel free to take over and fix it.



More information about the stable mailing list