Merge tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / net / ipv4 / ip_gre.c
index d1d09f3e5f9ec9493d7749447307784a771f501e..20a64fe6254b0c134edfcc2faebd3eac00934e0a 100644 (file)
@@ -268,20 +268,11 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
        int len;
 
        itn = net_generic(net, erspan_net_id);
-       len = gre_hdr_len + sizeof(*ershdr);
-
-       /* Check based hdr len */
-       if (unlikely(!pskb_may_pull(skb, len)))
-               return PACKET_REJECT;
 
        iph = ip_hdr(skb);
        ershdr = (struct erspan_base_hdr *)(skb->data + gre_hdr_len);
        ver = ershdr->ver;
 
-       /* The original GRE header does not have key field,
-        * Use ERSPAN 10-bit session ID as key.
-        */
-       tpi->key = cpu_to_be32(get_session_id(ershdr));
        tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex,
                                  tpi->flags | TUNNEL_KEY,
                                  iph->saddr, iph->daddr, tpi->key);
@@ -569,8 +560,7 @@ err_free_skb:
        dev->stats.tx_dropped++;
 }
 
-static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev,
-                          __be16 proto)
+static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct ip_tunnel *tunnel = netdev_priv(dev);
        struct ip_tunnel_info *tun_info;
@@ -578,10 +568,10 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev,
        struct erspan_metadata *md;
        struct rtable *rt = NULL;
        bool truncate = false;
+       __be16 df, proto;
        struct flowi4 fl;
        int tunnel_hlen;
        int version;
-       __be16 df;
        int nhoff;
        int thoff;
 
@@ -626,18 +616,20 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev,
        if (version == 1) {
                erspan_build_header(skb, ntohl(tunnel_id_to_key32(key->tun_id)),
                                    ntohl(md->u.index), truncate, true);
+               proto = htons(ETH_P_ERSPAN);
        } else if (version == 2) {
                erspan_build_header_v2(skb,
                                       ntohl(tunnel_id_to_key32(key->tun_id)),
                                       md->u.md2.dir,
                                       get_hwid(&md->u.md2),
                                       truncate, true);
+               proto = htons(ETH_P_ERSPAN2);
        } else {
                goto err_free_rt;
        }
 
        gre_build_header(skb, 8, TUNNEL_SEQ,
-                        htons(ETH_P_ERSPAN), 0, htonl(tunnel->o_seqno++));
+                        proto, 0, htonl(tunnel->o_seqno++));
 
        df = key->tun_flags & TUNNEL_DONT_FRAGMENT ?  htons(IP_DF) : 0;
 
@@ -721,12 +713,13 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb,
 {
        struct ip_tunnel *tunnel = netdev_priv(dev);
        bool truncate = false;
+       __be16 proto;
 
        if (!pskb_inet_may_pull(skb))
                goto free_skb;
 
        if (tunnel->collect_md) {
-               erspan_fb_xmit(skb, dev, skb->protocol);
+               erspan_fb_xmit(skb, dev);
                return NETDEV_TX_OK;
        }
 
@@ -742,19 +735,22 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb,
        }
 
        /* Push ERSPAN header */
-       if (tunnel->erspan_ver == 1)
+       if (tunnel->erspan_ver == 1) {
                erspan_build_header(skb, ntohl(tunnel->parms.o_key),
                                    tunnel->index,
                                    truncate, true);
-       else if (tunnel->erspan_ver == 2)
+               proto = htons(ETH_P_ERSPAN);
+       } else if (tunnel->erspan_ver == 2) {
                erspan_build_header_v2(skb, ntohl(tunnel->parms.o_key),
                                       tunnel->dir, tunnel->hwid,
                                       truncate, true);
-       else
+               proto = htons(ETH_P_ERSPAN2);
+       } else {
                goto free_skb;
+       }
 
        tunnel->parms.o_flags &= ~TUNNEL_KEY;
-       __gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_ERSPAN));
+       __gre_xmit(skb, dev, &tunnel->parms.iph, proto);
        return NETDEV_TX_OK;
 
 free_skb: