diff options
Diffstat (limited to 'net/ipv4/gre.c')
| -rw-r--r-- | net/ipv4/gre.c | 22 | 
1 files changed, 6 insertions, 16 deletions
diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c index c6933f2ea310..dbfc21de3479 100644 --- a/net/ipv4/gre.c +++ b/net/ipv4/gre.c @@ -15,8 +15,8 @@  #include <linux/kmod.h>  #include <linux/skbuff.h>  #include <linux/in.h> +#include <linux/ip.h>  #include <linux/netdevice.h> -#include <linux/version.h>  #include <linux/spinlock.h>  #include <net/protocol.h>  #include <net/gre.h> @@ -97,27 +97,17 @@ drop:  static void gre_err(struct sk_buff *skb, u32 info)  {  	const struct gre_protocol *proto; -	u8 ver; - -	if (!pskb_may_pull(skb, 12)) -		goto drop; +	const struct iphdr *iph = (const struct iphdr *)skb->data; +	u8 ver = skb->data[(iph->ihl<<2) + 1]&0x7f; -	ver = skb->data[1]&0x7f;  	if (ver >= GREPROTO_MAX) -		goto drop; +		return;  	rcu_read_lock();  	proto = rcu_dereference(gre_proto[ver]); -	if (!proto || !proto->err_handler) -		goto drop_unlock; -	proto->err_handler(skb, info); -	rcu_read_unlock(); -	return; - -drop_unlock: +	if (proto && proto->err_handler) +		proto->err_handler(skb, info);  	rcu_read_unlock(); -drop: -	kfree_skb(skb);  }  static const struct net_protocol net_gre_protocol = {  |