From b793f848f5e048cf023961ae179af189770d19c4 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 21 Jun 2012 13:58:31 +0000 Subject: [PATCH] --- yaml --- r: 314561 b: refs/heads/master c: 6648bd7e0e62c0c8c03b15e00c9e7015e232feff h: refs/heads/master i: 314559: 61a757401c2a91c6b4792cc0e9e05cf8c5ddbff4 v: v3 --- [refs] | 2 +- trunk/include/linux/sysctl.h | 1 + trunk/include/net/ip.h | 3 +++ trunk/kernel/sysctl_binary.c | 2 ++ trunk/net/ipv4/ip_input.c | 22 +++++++++++++--------- trunk/net/ipv4/sysctl_net_ipv4.c | 7 +++++++ 6 files changed, 27 insertions(+), 10 deletions(-) diff --git a/[refs] b/[refs] index 853a5b1cab00..3897230de133 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8e27628ecf883b9e5825103e40e6f86bf8225f1a +refs/heads/master: 6648bd7e0e62c0c8c03b15e00c9e7015e232feff diff --git a/trunk/include/linux/sysctl.h b/trunk/include/linux/sysctl.h index c34b4c82b0dc..20825e5f433f 100644 --- a/trunk/include/linux/sysctl.h +++ b/trunk/include/linux/sysctl.h @@ -425,6 +425,7 @@ enum NET_TCP_ALLOWED_CONG_CONTROL=123, NET_TCP_MAX_SSTHRESH=124, NET_TCP_FRTO_RESPONSE=125, + NET_IPV4_EARLY_DEMUX=126, }; enum { diff --git a/trunk/include/net/ip.h b/trunk/include/net/ip.h index 83e0619f59d0..50841bd6f10e 100644 --- a/trunk/include/net/ip.h +++ b/trunk/include/net/ip.h @@ -210,6 +210,9 @@ extern int inet_peer_threshold; extern int inet_peer_minttl; extern int inet_peer_maxttl; +/* From ip_input.c */ +extern int sysctl_ip_early_demux; + /* From ip_output.c */ extern int sysctl_ip_dynaddr; diff --git a/trunk/kernel/sysctl_binary.c b/trunk/kernel/sysctl_binary.c index a650694883a1..6a3cf8253aae 100644 --- a/trunk/kernel/sysctl_binary.c +++ b/trunk/kernel/sysctl_binary.c @@ -415,6 +415,8 @@ static const struct bin_table bin_net_ipv4_table[] = { { CTL_INT, NET_IPV4_IPFRAG_SECRET_INTERVAL, "ipfrag_secret_interval" }, /* NET_IPV4_IPFRAG_MAX_DIST "ipfrag_max_dist" no longer used */ + { CTL_INT, NET_IPV4_EARLY_DEMUX, "ip_early_demux" }, + { CTL_INT, 2088 /* NET_IPQ_QMAX */, "ip_queue_maxlen" }, /* NET_TCP_DEFAULT_WIN_SCALE unused */ diff --git a/trunk/net/ipv4/ip_input.c b/trunk/net/ipv4/ip_input.c index 93b092c9a394..bca25179cdb9 100644 --- a/trunk/net/ipv4/ip_input.c +++ b/trunk/net/ipv4/ip_input.c @@ -313,6 +313,8 @@ static inline bool ip_rcv_options(struct sk_buff *skb) return true; } +int sysctl_ip_early_demux __read_mostly = 1; + static int ip_rcv_finish(struct sk_buff *skb) { const struct iphdr *iph = ip_hdr(skb); @@ -323,16 +325,18 @@ static int ip_rcv_finish(struct sk_buff *skb) * how the packet travels inside Linux networking. */ if (skb_dst(skb) == NULL) { - const struct net_protocol *ipprot; - int protocol = iph->protocol; - int err; + int err = -ENOENT; - rcu_read_lock(); - ipprot = rcu_dereference(inet_protos[protocol]); - err = -ENOENT; - if (ipprot && ipprot->early_demux) - err = ipprot->early_demux(skb); - rcu_read_unlock(); + if (sysctl_ip_early_demux) { + const struct net_protocol *ipprot; + int protocol = iph->protocol; + + rcu_read_lock(); + ipprot = rcu_dereference(inet_protos[protocol]); + if (ipprot && ipprot->early_demux) + err = ipprot->early_demux(skb); + rcu_read_unlock(); + } if (err) { err = ip_route_input_noref(skb, iph->daddr, iph->saddr, diff --git a/trunk/net/ipv4/sysctl_net_ipv4.c b/trunk/net/ipv4/sysctl_net_ipv4.c index ef32956ed655..12aa0c5867c4 100644 --- a/trunk/net/ipv4/sysctl_net_ipv4.c +++ b/trunk/net/ipv4/sysctl_net_ipv4.c @@ -300,6 +300,13 @@ static struct ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = proc_dointvec }, + { + .procname = "ip_early_demux", + .data = &sysctl_ip_early_demux, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec + }, { .procname = "ip_dynaddr", .data = &sysctl_ip_dynaddr,