aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/gre.c21
1 files changed, 6 insertions, 15 deletions
diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c
index 9dbe10875fbd..dbfc21de3479 100644
--- a/net/ipv4/gre.c
+++ b/net/ipv4/gre.c
@@ -15,6 +15,7 @@
15#include <linux/kmod.h> 15#include <linux/kmod.h>
16#include <linux/skbuff.h> 16#include <linux/skbuff.h>
17#include <linux/in.h> 17#include <linux/in.h>
18#include <linux/ip.h>
18#include <linux/netdevice.h> 19#include <linux/netdevice.h>
19#include <linux/spinlock.h> 20#include <linux/spinlock.h>
20#include <net/protocol.h> 21#include <net/protocol.h>
@@ -96,27 +97,17 @@ drop:
96static void gre_err(struct sk_buff *skb, u32 info) 97static void gre_err(struct sk_buff *skb, u32 info)
97{ 98{
98 const struct gre_protocol *proto; 99 const struct gre_protocol *proto;
99 u8 ver; 100 const struct iphdr *iph = (const struct iphdr *)skb->data;
100 101 u8 ver = skb->data[(iph->ihl<<2) + 1]&0x7f;
101 if (!pskb_may_pull(skb, 12))
102 goto drop;
103 102
104 ver = skb->data[1]&0x7f;
105 if (ver >= GREPROTO_MAX) 103 if (ver >= GREPROTO_MAX)
106 goto drop; 104 return;
107 105
108 rcu_read_lock(); 106 rcu_read_lock();
109 proto = rcu_dereference(gre_proto[ver]); 107 proto = rcu_dereference(gre_proto[ver]);
110 if (!proto || !proto->err_handler) 108 if (proto && proto->err_handler)
111 goto drop_unlock; 109 proto->err_handler(skb, info);
112 proto->err_handler(skb, info);
113 rcu_read_unlock();
114 return;
115
116drop_unlock:
117 rcu_read_unlock(); 110 rcu_read_unlock();
118drop:
119 kfree_skb(skb);
120} 111}
121 112
122static const struct net_protocol net_gre_protocol = { 113static const struct net_protocol net_gre_protocol = {