iph = ip_hdr(skb);
        if (is_erspan_type1(gre_hdr_len)) {
                ver = 0;
 -              tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex,
 -                                        tpi->flags | TUNNEL_NO_KEY,
 +              __set_bit(IP_TUNNEL_NO_KEY_BIT, flags);
 +              tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, flags,
                                          iph->saddr, iph->daddr, 0);
        } else {
+               if (unlikely(!pskb_may_pull(skb,
+                                           gre_hdr_len + sizeof(*ershdr))))
+                       return PACKET_REJECT;
+ 
                ershdr = (struct erspan_base_hdr *)(skb->data + gre_hdr_len);
                ver = ershdr->ver;
 -              tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex,
 -                                        tpi->flags | TUNNEL_KEY,
+               iph = ip_hdr(skb);
 +              __set_bit(IP_TUNNEL_KEY_BIT, flags);
 +              tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, flags,
                                          iph->saddr, iph->daddr, tpi->key);
        }
  
 
        if (!w) {
                /* New dump:
                 *
-                * 1. hook callback destructor.
-                */
-               cb->args[3] = (long)cb->done;
-               cb->done = fib6_dump_done;
- 
-               /*
-                * 2. allocate and initialize walker.
+                * 1. allocate and initialize walker.
                 */
                w = kzalloc(sizeof(*w), GFP_ATOMIC);
 -              if (!w)
 -                      return -ENOMEM;
 +              if (!w) {
 +                      err = -ENOMEM;
 +                      goto unlock;
 +              }
                w->func = fib6_dump_node;
                cb->args[2] = (long)w;
+ 
+               /* 2. hook callback destructor.
+                */
+               cb->args[3] = (long)cb->done;
+               cb->done = fib6_dump_done;
+ 
        }
  
        arg.skb = skb;