diff options
Diffstat (limited to 'net/ipv4/ip_input.c')
-rw-r--r-- | net/ipv4/ip_input.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 93b092c9a394..bca25179cdb9 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -313,6 +313,8 @@ drop: | |||
313 | return true; | 313 | return true; |
314 | } | 314 | } |
315 | 315 | ||
316 | int sysctl_ip_early_demux __read_mostly = 1; | ||
317 | |||
316 | static int ip_rcv_finish(struct sk_buff *skb) | 318 | static int ip_rcv_finish(struct sk_buff *skb) |
317 | { | 319 | { |
318 | const struct iphdr *iph = ip_hdr(skb); | 320 | const struct iphdr *iph = ip_hdr(skb); |
@@ -323,16 +325,18 @@ static int ip_rcv_finish(struct sk_buff *skb) | |||
323 | * how the packet travels inside Linux networking. | 325 | * how the packet travels inside Linux networking. |
324 | */ | 326 | */ |
325 | if (skb_dst(skb) == NULL) { | 327 | if (skb_dst(skb) == NULL) { |
326 | const struct net_protocol *ipprot; | 328 | int err = -ENOENT; |
327 | int protocol = iph->protocol; | ||
328 | int err; | ||
329 | 329 | ||
330 | rcu_read_lock(); | 330 | if (sysctl_ip_early_demux) { |
331 | ipprot = rcu_dereference(inet_protos[protocol]); | 331 | const struct net_protocol *ipprot; |
332 | err = -ENOENT; | 332 | int protocol = iph->protocol; |
333 | if (ipprot && ipprot->early_demux) | 333 | |
334 | err = ipprot->early_demux(skb); | 334 | rcu_read_lock(); |
335 | rcu_read_unlock(); | 335 | ipprot = rcu_dereference(inet_protos[protocol]); |
336 | if (ipprot && ipprot->early_demux) | ||
337 | err = ipprot->early_demux(skb); | ||
338 | rcu_read_unlock(); | ||
339 | } | ||
336 | 340 | ||
337 | if (err) { | 341 | if (err) { |
338 | err = ip_route_input_noref(skb, iph->daddr, iph->saddr, | 342 | err = ip_route_input_noref(skb, iph->daddr, iph->saddr, |