gre: Call gso_make_checksum
authorTom Herbert <therbert@google.com>
Thu, 5 Jun 2014 00:20:23 +0000 (17:20 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 5 Jun 2014 05:46:38 +0000 (22:46 -0700)
Call gso_make_checksum. This should have the benefit of using a
checksum that may have been previously computed for the packet.

This also adds NETIF_F_GSO_GRE_CSUM to differentiate devices that
offload GRE GSO with and without the GRE checksum offloaed.

Signed-off-by: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/netdev_features.h
include/linux/skbuff.h
include/net/gre.h
net/ipv4/af_inet.c
net/ipv4/gre_demux.c
net/ipv4/gre_offload.c
net/ipv4/tcp_offload.c
net/ipv4/udp_offload.c
net/ipv6/ip6_offload.c
net/ipv6/udp_offload.c
net/mpls/mpls_gso.c

index f1338e0f98669d8833d31886413107d6094465ef..e5a589435e2b7df943a935b4cf6dfd6c46dd74ed 100644 (file)
@@ -42,6 +42,7 @@ enum {
        NETIF_F_TSO6_BIT,               /* ... TCPv6 segmentation */
        NETIF_F_FSO_BIT,                /* ... FCoE segmentation */
        NETIF_F_GSO_GRE_BIT,            /* ... GRE with TSO */
+       NETIF_F_GSO_GRE_CSUM_BIT,       /* ... GRE with csum with TSO */
        NETIF_F_GSO_IPIP_BIT,           /* ... IPIP tunnel with TSO */
        NETIF_F_GSO_SIT_BIT,            /* ... SIT tunnel with TSO */
        NETIF_F_GSO_UDP_TUNNEL_BIT,     /* ... UDP TUNNEL with TSO */
@@ -112,6 +113,7 @@ enum {
 #define NETIF_F_RXFCS          __NETIF_F(RXFCS)
 #define NETIF_F_RXALL          __NETIF_F(RXALL)
 #define NETIF_F_GSO_GRE                __NETIF_F(GSO_GRE)
+#define NETIF_F_GSO_GRE_CSUM   __NETIF_F(GSO_GRE_CSUM)
 #define NETIF_F_GSO_IPIP       __NETIF_F(GSO_IPIP)
 #define NETIF_F_GSO_SIT                __NETIF_F(GSO_SIT)
 #define NETIF_F_GSO_UDP_TUNNEL __NETIF_F(GSO_UDP_TUNNEL)
index 5a6d10a538f5820b003887100f837fdb4a767e6e..c705808bef9ce8b7c92e7436a3fc1b8dfa13ccc0 100644 (file)
@@ -347,6 +347,8 @@ enum {
        SKB_GSO_MPLS = 1 << 10,
 
        SKB_GSO_UDP_TUNNEL_CSUM = 1 << 11,
+
+       SKB_GSO_GRE_CSUM = 1 << 12,
 };
 
 #if BITS_PER_LONG > 32
index 70046a0b0b89c13d0f71f6180ed64e7dacf869e6..b53182018743f4383e525c43f30fc25bd5b4f5a8 100644 (file)
@@ -37,9 +37,10 @@ void gre_build_header(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
                      int hdr_len);
 
 static inline struct sk_buff *gre_handle_offloads(struct sk_buff *skb,
-                                                 bool gre_csum)
+                                                 bool csum)
 {
-       return iptunnel_handle_offloads(skb, gre_csum, SKB_GSO_GRE);
+       return iptunnel_handle_offloads(skb, csum,
+                                       csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE);
 }
 
 
index 0070ab87109b6ee83d29a331744b209cd2fd2354..d5e6836cf772d677271c46681ffa442baa9d0c99 100644 (file)
@@ -1254,6 +1254,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
                       SKB_GSO_DODGY |
                       SKB_GSO_TCP_ECN |
                       SKB_GSO_GRE |
+                      SKB_GSO_GRE_CSUM |
                       SKB_GSO_IPIP |
                       SKB_GSO_SIT |
                       SKB_GSO_TCPV6 |
index fbfd829f4049a36d1d3d590ec5d913785740fb24..4e9619bca732b869a70ac0db32c8b1285c9446fa 100644 (file)
@@ -84,7 +84,8 @@ void gre_build_header(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
                        ptr--;
                }
                if (tpi->flags&TUNNEL_CSUM &&
-                   !(skb_shinfo(skb)->gso_type & SKB_GSO_GRE)) {
+                   !(skb_shinfo(skb)->gso_type &
+                     (SKB_GSO_GRE|SKB_GSO_GRE_CSUM))) {
                        *ptr = 0;
                        *(__sum16 *)ptr = csum_fold(skb_checksum(skb, 0,
                                                                 skb->len, 0));
index f1d32280cb54d596691ac7173e4f3151dc4b11b1..24deb3928b9e005f70eb62e4324274eb9ccf9ca3 100644 (file)
@@ -42,6 +42,7 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
                                  SKB_GSO_DODGY |
                                  SKB_GSO_TCP_ECN |
                                  SKB_GSO_GRE |
+                                 SKB_GSO_GRE_CSUM |
                                  SKB_GSO_IPIP)))
                goto out;
 
@@ -55,6 +56,8 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
                goto out;
 
        csum = !!(greh->flags & GRE_CSUM);
+       if (csum)
+               skb->encap_hdr_csum = 1;
 
        if (unlikely(!pskb_may_pull(skb, ghl)))
                goto out;
@@ -94,10 +97,13 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
                                }
                        }
 
-                       greh = (struct gre_base_hdr *)(skb->data);
+                       skb_reset_transport_header(skb);
+
+                       greh = (struct gre_base_hdr *)
+                           skb_transport_header(skb);
                        pcsum = (__be32 *)(greh + 1);
                        *pcsum = 0;
-                       *(__sum16 *)pcsum = csum_fold(skb_checksum(skb, 0, skb->len, 0));
+                       *(__sum16 *)pcsum = gso_make_checksum(skb, 0);
                }
                __skb_push(skb, tnl_hlen - ghl);
 
index c02f2d2e7babf831f1f85c28b9f291264969558a..4e86c59ec7f7f07fe06c6db20d17851da6f1563f 100644 (file)
@@ -57,6 +57,7 @@ struct sk_buff *tcp_gso_segment(struct sk_buff *skb,
                               SKB_GSO_TCP_ECN |
                               SKB_GSO_TCPV6 |
                               SKB_GSO_GRE |
+                              SKB_GSO_GRE_CSUM |
                               SKB_GSO_IPIP |
                               SKB_GSO_SIT |
                               SKB_GSO_MPLS |
index 5c23f4765af9214ee285052a7b38d9d064bb9b27..7b1840110173964c81f3891b868f19162dffe784 100644 (file)
@@ -74,7 +74,8 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb,
                                      SKB_GSO_UDP_TUNNEL |
                                      SKB_GSO_UDP_TUNNEL_CSUM |
                                      SKB_GSO_IPIP |
-                                     SKB_GSO_GRE | SKB_GSO_MPLS) ||
+                                     SKB_GSO_GRE | SKB_GSO_GRE_CSUM |
+                                     SKB_GSO_MPLS) ||
                             !(type & (SKB_GSO_UDP))))
                        goto out;
 
index d54c5744e3db5f742f22f70b9b4c9b8a72a9d77c..65eda2a8af48280e0c068f24d8ef7adc8c7d8c9e 100644 (file)
@@ -97,6 +97,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
                       SKB_GSO_DODGY |
                       SKB_GSO_TCP_ECN |
                       SKB_GSO_GRE |
+                      SKB_GSO_GRE_CSUM |
                       SKB_GSO_IPIP |
                       SKB_GSO_SIT |
                       SKB_GSO_UDP_TUNNEL |
index 79da8b305cedbac881e5c2f275ee500de03995c6..0ae3d98f83e00533c14e6f8c23ab78a5a6a72625 100644 (file)
@@ -65,6 +65,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
                                      SKB_GSO_UDP_TUNNEL |
                                      SKB_GSO_UDP_TUNNEL_CSUM |
                                      SKB_GSO_GRE |
+                                     SKB_GSO_GRE_CSUM |
                                      SKB_GSO_IPIP |
                                      SKB_GSO_SIT |
                                      SKB_GSO_MPLS) ||
index 851cd880b0c048c4dcd45e1b6652888338490cf9..6b38d083e1c973c55e18914748d49fe4968a7188 100644 (file)
@@ -33,6 +33,7 @@ static struct sk_buff *mpls_gso_segment(struct sk_buff *skb,
                                  SKB_GSO_DODGY |
                                  SKB_GSO_TCP_ECN |
                                  SKB_GSO_GRE |
+                                 SKB_GSO_GRE_CSUM |
                                  SKB_GSO_IPIP |
                                  SKB_GSO_MPLS)))
                goto out;