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 7962c37b3f14bc244db5725a0578132601d892aa..01aa94776ce30833a0641cc63d50f8738df2c60a 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 c3285242f74fbdb9efe03712fe680f24faefecb3..1a47d04f5d1a27b122ab8271fddeac6eff60ed0b 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 867656b0739c0985cae50d1aaf2e1d70bb1c80ed..5bf15c212434141885e1f00c2b9779614ba90535 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 5aa8144101dc6c82b6251ac9e2b25cc6eeda8fb4..0beb44f2fe1f0df45b8125cf4b7b9610fa7503e9 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 62b89d6f54fd2c6ed1b75064ba8f1db4c1200a23..e02daa74e8334508d17611b323699d5c9fc2ae59 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 2e6a3cb06815101c6b034dc76489c28a6c9143b2..d3ab1ae32ef58dab3edfb804c32d7c2e421b8219 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 025a33c1b04d6b761dd7eade5ba9130f3a2c8d5b..cb5bfb77944cabea2fb88237436f29f3596e1391 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 07073fa35205ef80882c854c6a7b3eebe746f365..2b9cb5398335bc1a0c7b48b638360016141e1ba5 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 30abde86db45e560680669ddfb533bcf12deacb0..a844a0d38482d916251f3aca4555c75c9770820c 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 d12dba2dd5354dbb79bb80df4038dec2544cddeb..d37a8c97e6deae68fddea958e7ef360e0a14ebb0 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));