net: gro: skb_gro_header helper function
authorRichard Gobert <richardbgobert@gmail.com>
Tue, 23 Aug 2022 07:10:49 +0000 (09:10 +0200)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 25 Aug 2022 08:33:21 +0000 (10:33 +0200)
Introduce a simple helper function to replace a common pattern.
When accessing the GRO header, we fetch the pointer from frag0,
then test its validity and fetch it from the skb when necessary.

This leads to the pattern
skb_gro_header_fast -> skb_gro_header_hard -> skb_gro_header_slow
recurring many times throughout GRO code.

This patch replaces these patterns with a single inlined function
call, improving code readability.

Signed-off-by: Richard Gobert <richardbgobert@gmail.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/r/20220823071034.GA56142@debian
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/geneve.c
drivers/net/vxlan/vxlan_core.c
include/net/gro.h
net/8021q/vlan_core.c
net/ethernet/eth.c
net/ipv4/af_inet.c
net/ipv4/fou.c
net/ipv4/gre_offload.c
net/ipv4/tcp_offload.c
net/ipv6/ip6_offload.c

index 7962c37..01aa947 100644 (file)
@@ -503,12 +503,9 @@ static struct sk_buff *geneve_gro_receive(struct sock *sk,
 
        off_gnv = skb_gro_offset(skb);
        hlen = off_gnv + sizeof(*gh);
-       gh = skb_gro_header_fast(skb, off_gnv);
-       if (skb_gro_header_hard(skb, hlen)) {
-               gh = skb_gro_header_slow(skb, hlen, off_gnv);
-               if (unlikely(!gh))
-                       goto out;
-       }
+       gh = skb_gro_header(skb, hlen, off_gnv);
+       if (unlikely(!gh))
+               goto out;
 
        if (gh->ver != GENEVE_VER || gh->oam)
                goto out;
index c328524..1a47d04 100644 (file)
@@ -713,12 +713,9 @@ static struct sk_buff *vxlan_gro_receive(struct sock *sk,
 
        off_vx = skb_gro_offset(skb);
        hlen = off_vx + sizeof(*vh);
-       vh   = skb_gro_header_fast(skb, off_vx);
-       if (skb_gro_header_hard(skb, hlen)) {
-               vh = skb_gro_header_slow(skb, hlen, off_vx);
-               if (unlikely(!vh))
-                       goto out;
-       }
+       vh = skb_gro_header(skb, hlen, off_vx);
+       if (unlikely(!vh))
+               goto out;
 
        skb_gro_postpull_rcsum(skb, vh, sizeof(struct vxlanhdr));
 
index 867656b..5bf15c2 100644 (file)
@@ -160,6 +160,17 @@ static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int hlen,
        return skb->data + offset;
 }
 
+static inline void *skb_gro_header(struct sk_buff *skb,
+                                       unsigned int hlen, unsigned int offset)
+{
+       void *ptr;
+
+       ptr = skb_gro_header_fast(skb, offset);
+       if (skb_gro_header_hard(skb, hlen))
+               ptr = skb_gro_header_slow(skb, hlen, offset);
+       return ptr;
+}
+
 static inline void *skb_gro_network_header(struct sk_buff *skb)
 {
        return (NAPI_GRO_CB(skb)->frag0 ?: skb->data) +
@@ -301,12 +312,9 @@ static inline void *skb_gro_remcsum_process(struct sk_buff *skb, void *ptr,
                return ptr;
        }
 
-       ptr = skb_gro_header_fast(skb, off);
-       if (skb_gro_header_hard(skb, off + plen)) {
-               ptr = skb_gro_header_slow(skb, off + plen, off);
-               if (!ptr)
-                       return NULL;
-       }
+       ptr = skb_gro_header(skb, off + plen, off);
+       if (!ptr)
+               return NULL;
 
        delta = remcsum_adjust(ptr + hdrlen, NAPI_GRO_CB(skb)->csum,
                               start, offset);
@@ -329,12 +337,9 @@ static inline void skb_gro_remcsum_cleanup(struct sk_buff *skb,
        if (!grc->delta)
                return;
 
-       ptr = skb_gro_header_fast(skb, grc->offset);
-       if (skb_gro_header_hard(skb, grc->offset + sizeof(u16))) {
-               ptr = skb_gro_header_slow(skb, plen, grc->offset);
-               if (!ptr)
-                       return;
-       }
+       ptr = skb_gro_header(skb, plen, grc->offset);
+       if (!ptr)
+               return;
 
        remcsum_unadjust((__sum16 *)ptr, grc->delta);
 }
@@ -405,9 +410,7 @@ static inline struct udphdr *udp_gro_udphdr(struct sk_buff *skb)
 
        off  = skb_gro_offset(skb);
        hlen = off + sizeof(*uh);
-       uh   = skb_gro_header_fast(skb, off);
-       if (skb_gro_header_hard(skb, hlen))
-               uh = skb_gro_header_slow(skb, hlen, off);
+       uh   = skb_gro_header(skb, hlen, off);
 
        return uh;
 }
index 5aa8144..0beb44f 100644 (file)
@@ -467,12 +467,9 @@ static struct sk_buff *vlan_gro_receive(struct list_head *head,
 
        off_vlan = skb_gro_offset(skb);
        hlen = off_vlan + sizeof(*vhdr);
-       vhdr = skb_gro_header_fast(skb, off_vlan);
-       if (skb_gro_header_hard(skb, hlen)) {
-               vhdr = skb_gro_header_slow(skb, hlen, off_vlan);
-               if (unlikely(!vhdr))
-                       goto out;
-       }
+       vhdr = skb_gro_header(skb, hlen, off_vlan);
+       if (unlikely(!vhdr))
+               goto out;
 
        type = vhdr->h_vlan_encapsulated_proto;
 
index 62b89d6..e02daa7 100644 (file)
@@ -414,12 +414,9 @@ struct sk_buff *eth_gro_receive(struct list_head *head, struct sk_buff *skb)
 
        off_eth = skb_gro_offset(skb);
        hlen = off_eth + sizeof(*eh);
-       eh = skb_gro_header_fast(skb, off_eth);
-       if (skb_gro_header_hard(skb, hlen)) {
-               eh = skb_gro_header_slow(skb, hlen, off_eth);
-               if (unlikely(!eh))
-                       goto out;
-       }
+       eh = skb_gro_header(skb, hlen, off_eth);
+       if (unlikely(!eh))
+               goto out;
 
        flush = 0;
 
index 2e6a3cb..d3ab1ae 100644 (file)
@@ -1464,12 +1464,9 @@ struct sk_buff *inet_gro_receive(struct list_head *head, struct sk_buff *skb)
 
        off = skb_gro_offset(skb);
        hlen = off + sizeof(*iph);
-       iph = skb_gro_header_fast(skb, off);
-       if (skb_gro_header_hard(skb, hlen)) {
-               iph = skb_gro_header_slow(skb, hlen, off);
-               if (unlikely(!iph))
-                       goto out;
-       }
+       iph = skb_gro_header(skb, hlen, off);
+       if (unlikely(!iph))
+               goto out;
 
        proto = iph->protocol;
 
index 025a33c..cb5bfb7 100644 (file)
@@ -323,12 +323,9 @@ static struct sk_buff *gue_gro_receive(struct sock *sk,
        off = skb_gro_offset(skb);
        len = off + sizeof(*guehdr);
 
-       guehdr = skb_gro_header_fast(skb, off);
-       if (skb_gro_header_hard(skb, len)) {
-               guehdr = skb_gro_header_slow(skb, len, off);
-               if (unlikely(!guehdr))
-                       goto out;
-       }
+       guehdr = skb_gro_header(skb, len, off);
+       if (unlikely(!guehdr))
+               goto out;
 
        switch (guehdr->version) {
        case 0:
index 07073fa..2b9cb53 100644 (file)
@@ -137,12 +137,9 @@ static struct sk_buff *gre_gro_receive(struct list_head *head,
 
        off = skb_gro_offset(skb);
        hlen = off + sizeof(*greh);
-       greh = skb_gro_header_fast(skb, off);
-       if (skb_gro_header_hard(skb, hlen)) {
-               greh = skb_gro_header_slow(skb, hlen, off);
-               if (unlikely(!greh))
-                       goto out;
-       }
+       greh = skb_gro_header(skb, hlen, off);
+       if (unlikely(!greh))
+               goto out;
 
        /* Only support version 0 and K (key), C (csum) flags. Note that
         * although the support for the S (seq#) flag can be added easily
index 30abde8..a844a0d 100644 (file)
@@ -195,12 +195,9 @@ struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb)
 
        off = skb_gro_offset(skb);
        hlen = off + sizeof(*th);
-       th = skb_gro_header_fast(skb, off);
-       if (skb_gro_header_hard(skb, hlen)) {
-               th = skb_gro_header_slow(skb, hlen, off);
-               if (unlikely(!th))
-                       goto out;
-       }
+       th = skb_gro_header(skb, hlen, off);
+       if (unlikely(!th))
+               goto out;
 
        thlen = th->doff * 4;
        if (thlen < sizeof(*th))
index d12dba2..d37a8c9 100644 (file)
@@ -219,12 +219,9 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *ipv6_gro_receive(struct list_head *head,
 
        off = skb_gro_offset(skb);
        hlen = off + sizeof(*iph);
-       iph = skb_gro_header_fast(skb, off);
-       if (skb_gro_header_hard(skb, hlen)) {
-               iph = skb_gro_header_slow(skb, hlen, off);
-               if (unlikely(!iph))
-                       goto out;
-       }
+       iph = skb_gro_header_slow(skb, hlen, off);
+       if (unlikely(!iph))
+               goto out;
 
        skb_set_network_header(skb, off);
        skb_gro_pull(skb, sizeof(*iph));