diff options
-rw-r--r-- | include/linux/sysctl.h | 1 | ||||
-rw-r--r-- | include/net/ip.h | 3 | ||||
-rw-r--r-- | kernel/sysctl_binary.c | 2 | ||||
-rw-r--r-- | net/ipv4/ip_input.c | 22 | ||||
-rw-r--r-- | net/ipv4/sysctl_net_ipv4.c | 7 |
5 files changed, 26 insertions, 9 deletions
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index c34b4c82b0dc..20825e5f433f 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h | |||
@@ -425,6 +425,7 @@ enum | |||
425 | NET_TCP_ALLOWED_CONG_CONTROL=123, | 425 | NET_TCP_ALLOWED_CONG_CONTROL=123, |
426 | NET_TCP_MAX_SSTHRESH=124, | 426 | NET_TCP_MAX_SSTHRESH=124, |
427 | NET_TCP_FRTO_RESPONSE=125, | 427 | NET_TCP_FRTO_RESPONSE=125, |
428 | NET_IPV4_EARLY_DEMUX=126, | ||
428 | }; | 429 | }; |
429 | 430 | ||
430 | enum { | 431 | enum { |
diff --git a/include/net/ip.h b/include/net/ip.h index 83e0619f59d0..50841bd6f10e 100644 --- a/include/net/ip.h +++ b/include/net/ip.h | |||
@@ -210,6 +210,9 @@ extern int inet_peer_threshold; | |||
210 | extern int inet_peer_minttl; | 210 | extern int inet_peer_minttl; |
211 | extern int inet_peer_maxttl; | 211 | extern int inet_peer_maxttl; |
212 | 212 | ||
213 | /* From ip_input.c */ | ||
214 | extern int sysctl_ip_early_demux; | ||
215 | |||
213 | /* From ip_output.c */ | 216 | /* From ip_output.c */ |
214 | extern int sysctl_ip_dynaddr; | 217 | extern int sysctl_ip_dynaddr; |
215 | 218 | ||
diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c index a650694883a1..6a3cf8253aae 100644 --- a/kernel/sysctl_binary.c +++ b/kernel/sysctl_binary.c | |||
@@ -415,6 +415,8 @@ static const struct bin_table bin_net_ipv4_table[] = { | |||
415 | { CTL_INT, NET_IPV4_IPFRAG_SECRET_INTERVAL, "ipfrag_secret_interval" }, | 415 | { CTL_INT, NET_IPV4_IPFRAG_SECRET_INTERVAL, "ipfrag_secret_interval" }, |
416 | /* NET_IPV4_IPFRAG_MAX_DIST "ipfrag_max_dist" no longer used */ | 416 | /* NET_IPV4_IPFRAG_MAX_DIST "ipfrag_max_dist" no longer used */ |
417 | 417 | ||
418 | { CTL_INT, NET_IPV4_EARLY_DEMUX, "ip_early_demux" }, | ||
419 | |||
418 | { CTL_INT, 2088 /* NET_IPQ_QMAX */, "ip_queue_maxlen" }, | 420 | { CTL_INT, 2088 /* NET_IPQ_QMAX */, "ip_queue_maxlen" }, |
419 | 421 | ||
420 | /* NET_TCP_DEFAULT_WIN_SCALE unused */ | 422 | /* NET_TCP_DEFAULT_WIN_SCALE unused */ |
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, |
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index ef32956ed655..12aa0c5867c4 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
@@ -301,6 +301,13 @@ static struct ctl_table ipv4_table[] = { | |||
301 | .proc_handler = proc_dointvec | 301 | .proc_handler = proc_dointvec |
302 | }, | 302 | }, |
303 | { | 303 | { |
304 | .procname = "ip_early_demux", | ||
305 | .data = &sysctl_ip_early_demux, | ||
306 | .maxlen = sizeof(int), | ||
307 | .mode = 0644, | ||
308 | .proc_handler = proc_dointvec | ||
309 | }, | ||
310 | { | ||
304 | .procname = "ip_dynaddr", | 311 | .procname = "ip_dynaddr", |
305 | .data = &sysctl_ip_dynaddr, | 312 | .data = &sysctl_ip_dynaddr, |
306 | .maxlen = sizeof(int), | 313 | .maxlen = sizeof(int), |