net: Move GSO csum into SKB_GSO_CB
authorAlexander Duyck <aduyck@mirantis.com>
Fri, 5 Feb 2016 23:27:37 +0000 (15:27 -0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 11 Feb 2016 13:55:33 +0000 (08:55 -0500)
This patch moves the checksum maintained by GSO out of skb->csum and into
the GSO context block in order to allow for us to work on outer checksums
while maintaining the inner checksum offsets in the case of the inner
checksum being offloaded, while the outer checksums will be computed.

While updating the code I also did a minor cleanu-up on gso_make_checksum.
The change is mostly to make it so that we store the values and compute the
checksum instead of computing the checksum and then storing the values we
needed to update.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
Acked-by: Tom Herbert <tom@herbertland.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/skbuff.h
net/core/skbuff.c

index 11f935c1a090419d6cda938aa925bfa79de3616b..acece7ce376f90c2c25b5066f546564ea0ac4345 100644 (file)
@@ -3549,6 +3549,7 @@ static inline struct sec_path *skb_sec_path(struct sk_buff *skb)
 struct skb_gso_cb {
        int     mac_offset;
        int     encap_level;
+       __wsum  csum;
        __u16   csum_start;
 };
 #define SKB_SGO_CB_OFFSET      32
@@ -3585,15 +3586,14 @@ static inline int gso_pskb_expand_head(struct sk_buff *skb, int extra)
  */
 static inline __sum16 gso_make_checksum(struct sk_buff *skb, __wsum res)
 {
-       int plen = SKB_GSO_CB(skb)->csum_start - skb_headroom(skb) -
-                  skb_transport_offset(skb);
-       __wsum partial;
+       unsigned char *csum_start = skb_transport_header(skb);
+       int plen = (skb->head + SKB_GSO_CB(skb)->csum_start) - csum_start;
+       __wsum partial = SKB_GSO_CB(skb)->csum;
 
-       partial = csum_partial(skb_transport_header(skb), plen, skb->csum);
-       skb->csum = res;
-       SKB_GSO_CB(skb)->csum_start -= plen;
+       SKB_GSO_CB(skb)->csum = res;
+       SKB_GSO_CB(skb)->csum_start = csum_start - skb->head;
 
-       return csum_fold(partial);
+       return csum_fold(csum_partial(csum_start, plen, partial));
 }
 
 static inline bool skb_is_gso(const struct sk_buff *skb)
index b2df375ec9c2173a8132b8efa1c3062f0510284b..02c638a643ea347c5e1977eeb4992ab89b203933 100644 (file)
@@ -3100,11 +3100,12 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
 
                if (!sg && !nskb->remcsum_offload) {
                        nskb->ip_summed = CHECKSUM_NONE;
-                       nskb->csum = skb_copy_and_csum_bits(head_skb, offset,
-                                                           skb_put(nskb, len),
-                                                           len, 0);
+                       SKB_GSO_CB(nskb)->csum =
+                               skb_copy_and_csum_bits(head_skb, offset,
+                                                      skb_put(nskb, len),
+                                                      len, 0);
                        SKB_GSO_CB(nskb)->csum_start =
-                           skb_headroom(nskb) + doffset;
+                               skb_headroom(nskb) + doffset;
                        continue;
                }
 
@@ -3171,11 +3172,12 @@ skip_fraglist:
 
 perform_csum_check:
                if (!csum && !nskb->remcsum_offload) {
-                       nskb->csum = skb_checksum(nskb, doffset,
-                                                 nskb->len - doffset, 0);
                        nskb->ip_summed = CHECKSUM_NONE;
+                       SKB_GSO_CB(nskb)->csum =
+                               skb_checksum(nskb, doffset,
+                                            nskb->len - doffset, 0);
                        SKB_GSO_CB(nskb)->csum_start =
-                           skb_headroom(nskb) + doffset;
+                               skb_headroom(nskb) + doffset;
                }
        } while ((offset += len) < head_skb->len);