]> Git Repo - linux.git/commitdiff
udp: do not transition UDP GRO fraglist partial checksums to unnecessary
authorAntoine Tenart <[email protected]>
Tue, 26 Mar 2024 11:34:00 +0000 (12:34 +0100)
committerDavid S. Miller <[email protected]>
Fri, 29 Mar 2024 11:30:44 +0000 (11:30 +0000)
UDP GRO validates checksums and in udp4/6_gro_complete fraglist packets
are converted to CHECKSUM_UNNECESSARY to avoid later checks. However
this is an issue for CHECKSUM_PARTIAL packets as they can be looped in
an egress path and then their partial checksums are not fixed.

Different issues can be observed, from invalid checksum on packets to
traces like:

  gen01: hw csum failure
  skb len=3008 headroom=160 headlen=1376 tailroom=0
  mac=(106,14) net=(120,40) trans=160
  shinfo(txflags=0 nr_frags=0 gso(size=0 type=0 segs=0))
  csum(0xffff232e ip_summed=2 complete_sw=0 valid=0 level=0)
  hash(0x77e3d716 sw=1 l4=1) proto=0x86dd pkttype=0 iif=12
  ...

Fix this by only converting CHECKSUM_NONE packets to
CHECKSUM_UNNECESSARY by reusing __skb_incr_checksum_unnecessary. All
other checksum types are kept as-is, including CHECKSUM_COMPLETE as
fraglist packets being segmented back would have their skb->csum valid.

Fixes: 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.")
Signed-off-by: Antoine Tenart <[email protected]>
Reviewed-by: Willem de Bruijn <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
net/ipv4/udp_offload.c
net/ipv6/udp_offload.c

index 3bb69464930bf93dbeded1cc07d97e9208fd8682..548476d782371e1a48639fcd34c7b0bdfbc78179 100644 (file)
@@ -722,13 +722,7 @@ INDIRECT_CALLABLE_SCOPE int udp4_gro_complete(struct sk_buff *skb, int nhoff)
                skb_shinfo(skb)->gso_type |= (SKB_GSO_FRAGLIST|SKB_GSO_UDP_L4);
                skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count;
 
-               if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
-                       if (skb->csum_level < SKB_MAX_CSUM_LEVEL)
-                               skb->csum_level++;
-               } else {
-                       skb->ip_summed = CHECKSUM_UNNECESSARY;
-                       skb->csum_level = 0;
-               }
+               __skb_incr_checksum_unnecessary(skb);
 
                return 0;
        }
index 312bcaeea96fb78ac488124cf7795aa834392c64..bbd347de00b450bb3ecbbfa41c4dab9d36bb79d9 100644 (file)
@@ -174,13 +174,7 @@ INDIRECT_CALLABLE_SCOPE int udp6_gro_complete(struct sk_buff *skb, int nhoff)
                skb_shinfo(skb)->gso_type |= (SKB_GSO_FRAGLIST|SKB_GSO_UDP_L4);
                skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count;
 
-               if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
-                       if (skb->csum_level < SKB_MAX_CSUM_LEVEL)
-                               skb->csum_level++;
-               } else {
-                       skb->ip_summed = CHECKSUM_UNNECESSARY;
-                       skb->csum_level = 0;
-               }
+               __skb_incr_checksum_unnecessary(skb);
 
                return 0;
        }
This page took 0.047123 seconds and 4 git commands to generate.