ip_gre: Fix WCCPv2 header parsing.
Pravin B Shelar [Mon, 28 Oct 2013 17:38:55 +0000 (10:38 -0700)]
[ No applicable upstream commit, the upstream implementation is
  now completely different and doesn't have this bug. ]

In case of WCCPv2 GRE header has extra four bytes.  Following
patch pull those extra four bytes so that skb offsets are set
correctly.

CC: Eric Dumazet <eric.dumazet@gmail.com>
Reported-by: Peter Schmitt <peter.schmitt82@yahoo.de>
Tested-by: Peter Schmitt <peter.schmitt82@yahoo.de>
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

include/net/ip_tunnels.h
net/ipv4/ip_gre.c
net/ipv4/ip_tunnel.c
net/ipv4/ipip.c

index a9942e1..7ac7f91 100644 (file)
@@ -113,7 +113,7 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
                                   __be32 key);
 
 int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
-                 const struct tnl_ptk_info *tpi, bool log_ecn_error);
+                 const struct tnl_ptk_info *tpi, int hdr_len, bool log_ecn_error);
 int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[],
                         struct ip_tunnel_parm *p);
 int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
index c52fee0..64e4e98 100644 (file)
@@ -335,7 +335,7 @@ static int ipgre_rcv(struct sk_buff *skb)
                                  iph->saddr, iph->daddr, tpi.key);
 
        if (tunnel) {
-               ip_tunnel_rcv(tunnel, skb, &tpi, log_ecn_error);
+               ip_tunnel_rcv(tunnel, skb, &tpi, hdr_len, log_ecn_error);
                return 0;
        }
        icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
index 92d2f0f..46dcf32 100644 (file)
@@ -402,7 +402,7 @@ static struct ip_tunnel *ip_tunnel_create(struct net *net,
 }
 
 int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
-                 const struct tnl_ptk_info *tpi, bool log_ecn_error)
+                 const struct tnl_ptk_info *tpi, int hdr_len, bool log_ecn_error)
 {
        struct pcpu_tstats *tstats;
        const struct iphdr *iph = ip_hdr(skb);
@@ -413,7 +413,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
        skb->protocol = tpi->proto;
 
        skb->mac_header = skb->network_header;
-       __pskb_pull(skb, tunnel->hlen);
+       __pskb_pull(skb, hdr_len);
        skb_postpull_rcsum(skb, skb_transport_header(skb), tunnel->hlen);
 #ifdef CONFIG_NET_IPGRE_BROADCAST
        if (ipv4_is_multicast(iph->daddr)) {
index 7cfc456..f5cc7b3 100644 (file)
@@ -195,7 +195,7 @@ static int ipip_rcv(struct sk_buff *skb)
        if (tunnel) {
                if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
                        goto drop;
-               return ip_tunnel_rcv(tunnel, skb, &tpi, log_ecn_error);
+               return ip_tunnel_rcv(tunnel, skb, &tpi, 0, log_ecn_error);
        }
 
        return -1;