IP_GRE: Fix GRE_CSUM case.
authorPravin B Shelar <pshelar@nicira.com>
Sun, 24 Feb 2013 20:05:05 +0000 (20:05 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 25 Feb 2013 20:47:41 +0000 (15:47 -0500)
commit "ip_gre: allow CSUM capable devices to handle packets"
aa0e51cdda005cd37e2, broke GRE_CSUM case.
GRE_CSUM needs checksum computed for inner packet. Therefore
csum-calculation can not be offloaded if tunnel device requires
GRE_CSUM.  Following patch fixes it by computing inner packet checksum
for GRE_CSUM type, for all other type of GRE devices csum is offloaded.

CC: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Acked-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/ip_gre.c

index b8bada00d516e134c3856351d993d22819f2d373..4065129345077b15a30cdf6d989343f550ad30fa 100644 (file)
@@ -735,7 +735,7 @@ drop:
        return 0;
 }
 
-static struct sk_buff *handle_offloads(struct sk_buff *skb)
+static struct sk_buff *handle_offloads(struct ip_tunnel *tunnel, struct sk_buff *skb)
 {
        int err;
 
@@ -745,8 +745,12 @@ static struct sk_buff *handle_offloads(struct sk_buff *skb)
                        goto error;
                skb_shinfo(skb)->gso_type |= SKB_GSO_GRE;
                return skb;
-       }
-       if (skb->ip_summed != CHECKSUM_PARTIAL)
+       } else if (skb->ip_summed == CHECKSUM_PARTIAL &&
+                  tunnel->parms.o_flags&GRE_CSUM) {
+               err = skb_checksum_help(skb);
+               if (unlikely(err))
+                       goto error;
+       } else if (skb->ip_summed != CHECKSUM_PARTIAL)
                skb->ip_summed = CHECKSUM_NONE;
 
        return skb;
@@ -776,7 +780,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
        int    err;
        int    pkt_len;
 
-       skb = handle_offloads(skb);
+       skb = handle_offloads(tunnel, skb);
        if (IS_ERR(skb)) {
                dev->stats.tx_dropped++;
                return NETDEV_TX_OK;