aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ip_input.c')
-rw-r--r--net/ipv4/ip_input.c22
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
316int sysctl_ip_early_demux __read_mostly = 1;
317
316static int ip_rcv_finish(struct sk_buff *skb) 318static 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,