]> git.itanic.dy.fi Git - linux-stable/commitdiff
net-gre-gro: Fix a bug that breaks the forwarding path
authorJerry Chu <hkchu@google.com>
Mon, 14 Jul 2014 22:54:46 +0000 (15:54 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 28 Jul 2014 15:06:01 +0000 (08:06 -0700)
[ Upstream commit c3caf1192f904de2f1381211f564537235d50de3 ]

Fixed a bug that was introduced by my GRE-GRO patch
(bf5a755f5e9186406bbf50f4087100af5bd68e40 net-gre-gro: Add GRE
support to the GRO stack) that breaks the forwarding path
because various GSO related fields were not set. The bug will
cause on the egress path either the GSO code to fail, or a
GRE-TSO capable (NETIF_F_GSO_GRE) NICs to choke. The following
fix has been tested for both cases.

Signed-off-by: H.K. Jerry Chu <hkchu@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/core/dev.c
net/ipv4/af_inet.c
net/ipv4/gre_offload.c
net/ipv4/tcp_offload.c
net/ipv6/tcpv6_offload.c

index 051f17d6ff757cf3987b3988fdb8ff025e3235be..37bddf729e773fc9ee1fa101eb9bfc4d4b3efb9d 100644 (file)
@@ -4058,6 +4058,8 @@ static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)
        skb->vlan_tci = 0;
        skb->dev = napi->dev;
        skb->skb_iif = 0;
+       skb->encapsulation = 0;
+       skb_shinfo(skb)->gso_type = 0;
        skb->truesize = SKB_TRUESIZE(skb_end_offset(skb));
 
        napi->skb = skb;
index 19ab78aca547fc7fb45e56607e7adafd0036d947..07bd8edef417c9a6831b397bdf1cd40a4f5b672a 100644 (file)
@@ -1434,6 +1434,9 @@ static int inet_gro_complete(struct sk_buff *skb, int nhoff)
        int proto = iph->protocol;
        int err = -ENOSYS;
 
+       if (skb->encapsulation)
+               skb_set_inner_network_header(skb, nhoff);
+
        csum_replace2(&iph->check, iph->tot_len, newlen);
        iph->tot_len = newlen;
 
index f1d32280cb54d596691ac7173e4f3151dc4b11b1..2d24f293f977063fd3c929f1f1ae099cffb6d222 100644 (file)
@@ -255,6 +255,9 @@ static int gre_gro_complete(struct sk_buff *skb, int nhoff)
        int err = -ENOENT;
        __be16 type;
 
+       skb->encapsulation = 1;
+       skb_shinfo(skb)->gso_type = SKB_GSO_GRE;
+
        type = greh->protocol;
        if (greh->flags & GRE_KEY)
                grehlen += GRE_HEADER_SECTION;
index b92b81718ca42bc9e47b415c321eb143d7266852..c25953a386d0edbc84a6ae20340e305130d419a0 100644 (file)
@@ -310,7 +310,7 @@ static int tcp4_gro_complete(struct sk_buff *skb, int thoff)
 
        th->check = ~tcp_v4_check(skb->len - thoff, iph->saddr,
                                  iph->daddr, 0);
-       skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
+       skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4;
 
        return tcp_gro_complete(skb);
 }
index 8517d3cd1aed460bbfb1bfb0f515924f008b790d..01b0ff9a0c2c00d6734537254e2150edcbcb64d7 100644 (file)
@@ -73,7 +73,7 @@ static int tcp6_gro_complete(struct sk_buff *skb, int thoff)
 
        th->check = ~tcp_v6_check(skb->len - thoff, &iph->saddr,
                                  &iph->daddr, 0);
-       skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
+       skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV6;
 
        return tcp_gro_complete(skb);
 }