From 4a61b586cd7eaab6242eca58e8e6e3c8ebd88bd2 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Wed, 5 Dec 2007 01:43:25 -0800 Subject: [IPV6]: Make the ipv6/sysctl_net_ipv6.c compilation cleaner Since this file is entirely enclosed with the #ifdef CONFIG_SYSCTL/#endif pair, it's OK to move this CONFIG_ into a Makefile. Signed-off-by: Pavel Emelyanov Signed-off-by: David S. Miller --- net/ipv6/sysctl_net_ipv6.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'net/ipv6/sysctl_net_ipv6.c') diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 68bb2548e469..227efa726acd 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -14,8 +14,6 @@ #include #include -#ifdef CONFIG_SYSCTL - static ctl_table ipv6_table[] = { { .ctl_name = NET_IPV6_ROUTE, @@ -115,8 +113,3 @@ void ipv6_sysctl_unregister(void) { unregister_sysctl_table(ipv6_sysctl_header); } - -#endif /* CONFIG_SYSCTL */ - - - -- cgit v1.2.3-59-g8ed1b From 4d43b78ac27ca50fe42718192ac7c80474417389 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Wed, 5 Dec 2007 01:44:02 -0800 Subject: [IPV6]: Use sysctl paths to register ipv6 sysctl tables I have already done this for core, ipv4 and tr tables, so repeat this for the ipv6 ones. This makes the ipv6.ko smaller and creates the ground needed for net namespaces support in ipv6.ko ssctls. Signed-off-by: Pavel Emelyanov Signed-off-by: David S. Miller --- net/ipv6/sysctl_net_ipv6.c | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) (limited to 'net/ipv6/sysctl_net_ipv6.c') diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 227efa726acd..0b5bec3cb797 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -82,31 +82,17 @@ static ctl_table ipv6_table[] = { { .ctl_name = 0 } }; -static struct ctl_table_header *ipv6_sysctl_header; - -static ctl_table ipv6_net_table[] = { - { - .ctl_name = NET_IPV6, - .procname = "ipv6", - .mode = 0555, - .child = ipv6_table - }, - { .ctl_name = 0 } +static struct ctl_path ipv6_ctl_path[] = { + { .procname = "net", .ctl_name = CTL_NET, }, + { .procname = "ipv6", .ctl_name = NET_IPV6, }, + { }, }; -static ctl_table ipv6_root_table[] = { - { - .ctl_name = CTL_NET, - .procname = "net", - .mode = 0555, - .child = ipv6_net_table - }, - { .ctl_name = 0 } -}; +static struct ctl_table_header *ipv6_sysctl_header; void ipv6_sysctl_register(void) { - ipv6_sysctl_header = register_sysctl_table(ipv6_root_table); + ipv6_sysctl_header = register_sysctl_paths(ipv6_ctl_path, ipv6_table); } void ipv6_sysctl_unregister(void) -- cgit v1.2.3-59-g8ed1b From 3d7cc2ba628dcc6b55a2bafc7eaf35019fdcc201 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Wed, 9 Jan 2008 00:33:11 -0800 Subject: [NETFILTER]: Switch to using ctl_paths in nf_queue and conntrack modules This includes the most simple cases for netfilter. The first part is tne queue modules for ipv4 and ipv6, on which the net/ipv4/ and net/ipv6/ paths are reused from the appropriate ipv4 and ipv6 code. The conntrack module is also patched, but this hunk is very small and simple. Signed-off-by: Pavel Emelyanov Acked-by: Patrick McHardy Signed-off-by: David S. Miller --- include/net/ip.h | 2 ++ include/net/ipv6.h | 2 ++ net/ipv4/netfilter/ip_queue.c | 23 ++--------------------- net/ipv4/sysctl_net_ipv4.c | 5 +++-- net/ipv6/netfilter/ip6_queue.c | 22 +--------------------- net/ipv6/sysctl_net_ipv6.c | 6 ++++-- net/netfilter/nf_conntrack_standalone.c | 15 ++++++--------- 7 files changed, 20 insertions(+), 55 deletions(-) (limited to 'net/ipv6/sysctl_net_ipv6.c') diff --git a/include/net/ip.h b/include/net/ip.h index cbeb97d38860..6850a80a6886 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -177,6 +177,8 @@ extern void inet_get_local_port_range(int *low, int *high); extern int sysctl_ip_default_ttl; extern int sysctl_ip_nonlocal_bind; +extern struct ctl_path net_ipv4_ctl_path[]; + /* From ip_fragment.c */ struct inet_frags_ctl; extern struct inet_frags_ctl ip4_frags_ctl; diff --git a/include/net/ipv6.h b/include/net/ipv6.h index f2adedff927f..e371f322017d 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -112,6 +112,8 @@ struct frag_hdr { extern int sysctl_ipv6_bindv6only; extern int sysctl_mld_max_msf; +extern struct ctl_path net_ipv6_ctl_path[]; + #define _DEVINC(statname, modifier, idev, field) \ ({ \ struct inet6_dev *_idev = (idev); \ diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 68b12ce8ba55..7361315f20c6 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c @@ -29,6 +29,7 @@ #include #include #include +#include #define IPQ_QMAX_DEFAULT 1024 #define IPQ_PROC_FS_NAME "ip_queue" @@ -525,26 +526,6 @@ static ctl_table ipq_table[] = { { .ctl_name = 0 } }; -static ctl_table ipq_dir_table[] = { - { - .ctl_name = NET_IPV4, - .procname = "ipv4", - .mode = 0555, - .child = ipq_table - }, - { .ctl_name = 0 } -}; - -static ctl_table ipq_root_table[] = { - { - .ctl_name = CTL_NET, - .procname = "net", - .mode = 0555, - .child = ipq_dir_table - }, - { .ctl_name = 0 } -}; - static int ip_queue_show(struct seq_file *m, void *v) { read_lock_bh(&queue_lock); @@ -610,7 +591,7 @@ static int __init ip_queue_init(void) } register_netdevice_notifier(&ipq_dev_notifier); - ipq_sysctl_header = register_sysctl_table(ipq_root_table); + ipq_sysctl_header = register_sysctl_paths(net_ipv4_ctl_path, ipq_table); status = nf_register_queue_handler(PF_INET, &nfqh); if (status < 0) { diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index a5a9f8e3bb25..45536a91266a 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -846,17 +846,18 @@ static struct ctl_table ipv4_table[] = { { .ctl_name = 0 } }; -static __initdata struct ctl_path net_ipv4_path[] = { +struct ctl_path net_ipv4_ctl_path[] = { { .procname = "net", .ctl_name = CTL_NET, }, { .procname = "ipv4", .ctl_name = NET_IPV4, }, { }, }; +EXPORT_SYMBOL_GPL(net_ipv4_ctl_path); static __init int sysctl_ipv4_init(void) { struct ctl_table_header *hdr; - hdr = register_sysctl_paths(net_ipv4_path, ipv4_table); + hdr = register_sysctl_paths(net_ipv4_ctl_path, ipv4_table); return hdr == NULL ? -ENOMEM : 0; } diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index e5b0059582f5..a20db0bb5a1f 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c @@ -529,26 +529,6 @@ static ctl_table ipq_table[] = { { .ctl_name = 0 } }; -static ctl_table ipq_dir_table[] = { - { - .ctl_name = NET_IPV6, - .procname = "ipv6", - .mode = 0555, - .child = ipq_table - }, - { .ctl_name = 0 } -}; - -static ctl_table ipq_root_table[] = { - { - .ctl_name = CTL_NET, - .procname = "net", - .mode = 0555, - .child = ipq_dir_table - }, - { .ctl_name = 0 } -}; - static int ip6_queue_show(struct seq_file *m, void *v) { read_lock_bh(&queue_lock); @@ -614,7 +594,7 @@ static int __init ip6_queue_init(void) } register_netdevice_notifier(&ipq_dev_notifier); - ipq_sysctl_header = register_sysctl_table(ipq_root_table); + ipq_sysctl_header = register_sysctl_paths(net_ipv6_ctl_path, ipq_table); status = nf_register_queue_handler(PF_INET6, &nfqh); if (status < 0) { diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 0b5bec3cb797..4ad8d9d3cb7a 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -82,17 +82,19 @@ static ctl_table ipv6_table[] = { { .ctl_name = 0 } }; -static struct ctl_path ipv6_ctl_path[] = { +struct ctl_path net_ipv6_ctl_path[] = { { .procname = "net", .ctl_name = CTL_NET, }, { .procname = "ipv6", .ctl_name = NET_IPV6, }, { }, }; +EXPORT_SYMBOL_GPL(net_ipv6_ctl_path); static struct ctl_table_header *ipv6_sysctl_header; void ipv6_sysctl_register(void) { - ipv6_sysctl_header = register_sysctl_paths(ipv6_ctl_path, ipv6_table); + ipv6_sysctl_header = register_sysctl_paths(net_ipv6_ctl_path, + ipv6_table); } void ipv6_sysctl_unregister(void) diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 9efdd37fc195..2ad49331302b 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -383,15 +383,11 @@ static ctl_table nf_ct_netfilter_table[] = { { .ctl_name = 0 } }; -static ctl_table nf_ct_net_table[] = { - { - .ctl_name = CTL_NET, - .procname = "net", - .mode = 0555, - .child = nf_ct_netfilter_table, - }, - { .ctl_name = 0 } +struct ctl_path nf_ct_path[] = { + { .procname = "net", .ctl_name = CTL_NET, }, + { } }; + EXPORT_SYMBOL_GPL(nf_ct_log_invalid); #endif /* CONFIG_SYSCTL */ @@ -418,7 +414,8 @@ static int __init nf_conntrack_standalone_init(void) proc_stat->owner = THIS_MODULE; #endif #ifdef CONFIG_SYSCTL - nf_ct_sysctl_header = register_sysctl_table(nf_ct_net_table); + nf_ct_sysctl_header = register_sysctl_paths(nf_ct_path, + nf_ct_netfilter_table); if (nf_ct_sysctl_header == NULL) { printk("nf_conntrack: can't register to sysctl.\n"); ret = -ENOMEM; -- cgit v1.2.3-59-g8ed1b From 291480c09a9452a3d8852a9bfeb5ba2cbcfe662c Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Thu, 10 Jan 2008 02:47:55 -0800 Subject: [NETNS][IPV6]: Make ipv6_sysctl_register to return a value. This patch makes the function ipv6_sysctl_register to return a value. The af_inet6 init function is now able to handle an error and catch it from the initialization of the sysctl. Signed-off-by: Daniel Lezcano Signed-off-by: David S. Miller --- include/net/ipv6.h | 2 +- net/ipv6/af_inet6.c | 5 ++++- net/ipv6/sysctl_net_ipv6.c | 9 +++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) (limited to 'net/ipv6/sysctl_net_ipv6.c') diff --git a/include/net/ipv6.h b/include/net/ipv6.h index e371f322017d..3e086f8bb449 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -622,7 +622,7 @@ static inline int snmp6_unregister_dev(struct inet6_dev *idev) extern ctl_table ipv6_route_table[]; extern ctl_table ipv6_icmp_table[]; -extern void ipv6_sysctl_register(void); +extern int ipv6_sysctl_register(void); extern void ipv6_sysctl_unregister(void); #endif diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 34c20533ba5d..a2842400a09e 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -783,7 +783,9 @@ static int __init inet6_init(void) */ #ifdef CONFIG_SYSCTL - ipv6_sysctl_register(); + err = ipv6_sysctl_register(); + if (err) + goto sysctl_fail; #endif err = icmpv6_init(&inet6_family_ops); if (err) @@ -897,6 +899,7 @@ ndisc_fail: icmp_fail: #ifdef CONFIG_SYSCTL ipv6_sysctl_unregister(); +sysctl_fail: #endif cleanup_ipv6_mibs(); out_unregister_sock: diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 4ad8d9d3cb7a..f713fbf34c23 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -91,10 +91,15 @@ EXPORT_SYMBOL_GPL(net_ipv6_ctl_path); static struct ctl_table_header *ipv6_sysctl_header; -void ipv6_sysctl_register(void) +int ipv6_sysctl_register(void) { ipv6_sysctl_header = register_sysctl_paths(net_ipv6_ctl_path, - ipv6_table); + ipv6_table); + if (!ipv6_sysctl_header) + return -ENOMEM; + + return 0; + } void ipv6_sysctl_unregister(void) -- cgit v1.2.3-59-g8ed1b From 89918fc270bb77cb1a0703f0ea566a692b32e324 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Thu, 10 Jan 2008 02:49:34 -0800 Subject: [NETNS][IPV6]: Make the ipv6 sysctl to be a netns subsystem. The initialization of the sysctl for the ipv6 protocol is changed to a network namespace subsystem. That means when a new network namespace is created the initialization function for the sysctl will be called. That do not change the behavior of the sysctl in case of the kernel with the network namespace disabled. Signed-off-by: Daniel Lezcano Signed-off-by: David S. Miller --- net/ipv6/sysctl_net_ipv6.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'net/ipv6/sysctl_net_ipv6.c') diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index f713fbf34c23..7329decf1f9d 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -91,10 +91,10 @@ EXPORT_SYMBOL_GPL(net_ipv6_ctl_path); static struct ctl_table_header *ipv6_sysctl_header; -int ipv6_sysctl_register(void) +static int ipv6_sysctl_net_init(struct net *net) { - ipv6_sysctl_header = register_sysctl_paths(net_ipv6_ctl_path, - ipv6_table); + ipv6_sysctl_header = register_net_sysctl_table(net, net_ipv6_ctl_path, + ipv6_table); if (!ipv6_sysctl_header) return -ENOMEM; @@ -102,7 +102,22 @@ int ipv6_sysctl_register(void) } +static void ipv6_sysctl_net_exit(struct net *net) +{ + unregister_net_sysctl_table(ipv6_sysctl_header); +} + +static struct pernet_operations ipv6_sysctl_net_ops = { + .init = ipv6_sysctl_net_init, + .exit = ipv6_sysctl_net_exit, +}; + +int ipv6_sysctl_register(void) +{ + return register_pernet_subsys(&ipv6_sysctl_net_ops); +} + void ipv6_sysctl_unregister(void) { - unregister_sysctl_table(ipv6_sysctl_header); + unregister_pernet_subsys(&ipv6_sysctl_net_ops); } -- cgit v1.2.3-59-g8ed1b From 760f2d0186225f06d46e07232d65219c5055cad3 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Thu, 10 Jan 2008 02:53:43 -0800 Subject: [NETNS][IPV6]: Make multiple instance of sysctl tables. Each network namespace wants its own set of sysctl value, eg. we should not be able from a namespace to set a sysctl value for another namespace , especially for the initial network namespace. This patch duplicates the sysctl table when we register a new network namespace for ipv6. The duplicated table are postfixed with the "template" word to notify the developper the table is cloned. Signed-off-by: Daniel Lezcano Signed-off-by: David S. Miller --- include/net/ipv6.h | 4 +-- include/net/netns/ipv6.h | 9 +++++++ net/ipv6/icmp.c | 12 ++++++++- net/ipv6/route.c | 11 +++++++- net/ipv6/sysctl_net_ipv6.c | 67 +++++++++++++++++++++++++++++++++++++++------- 5 files changed, 89 insertions(+), 14 deletions(-) (limited to 'net/ipv6/sysctl_net_ipv6.c') diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 3e086f8bb449..5519035491e7 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -619,8 +619,8 @@ static inline int snmp6_unregister_dev(struct inet6_dev *idev) #endif #ifdef CONFIG_SYSCTL -extern ctl_table ipv6_route_table[]; -extern ctl_table ipv6_icmp_table[]; +extern ctl_table ipv6_route_table_template[]; +extern ctl_table ipv6_icmp_table_template[]; extern int ipv6_sysctl_register(void); extern void ipv6_sysctl_unregister(void); diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index 6f82046e3013..58fbf30d9fdb 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -5,6 +5,15 @@ #ifndef __NETNS_IPV6_H__ #define __NETNS_IPV6_H__ +struct ctl_table_header; + +struct netns_sysctl_ipv6 { +#ifdef CONFIG_SYSCTL + struct ctl_table_header *table; +#endif +}; + struct netns_ipv6 { + struct netns_sysctl_ipv6 sysctl; }; #endif diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index c3bbd8687307..dfe3b37c43e9 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -907,7 +907,7 @@ int icmpv6_err_convert(int type, int code, int *err) EXPORT_SYMBOL(icmpv6_err_convert); #ifdef CONFIG_SYSCTL -ctl_table ipv6_icmp_table[] = { +ctl_table ipv6_icmp_table_template[] = { { .ctl_name = NET_IPV6_ICMP_RATELIMIT, .procname = "ratelimit", @@ -918,5 +918,15 @@ ctl_table ipv6_icmp_table[] = { }, { .ctl_name = 0 }, }; + +struct ctl_table *ipv6_icmp_sysctl_init(struct net *net) +{ + struct ctl_table *table; + + table = kmemdup(ipv6_icmp_table_template, + sizeof(ipv6_icmp_table_template), + GFP_KERNEL); + return table; +} #endif diff --git a/net/ipv6/route.c b/net/ipv6/route.c index b80ef5784207..0c7382f4fb85 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2409,7 +2409,7 @@ int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp, return -EINVAL; } -ctl_table ipv6_route_table[] = { +ctl_table ipv6_route_table_template[] = { { .procname = "flush", .data = &flush_delay, @@ -2499,6 +2499,15 @@ ctl_table ipv6_route_table[] = { { .ctl_name = 0 } }; +struct ctl_table *ipv6_route_sysctl_init(struct net *net) +{ + struct ctl_table *table; + + table = kmemdup(ipv6_route_table_template, + sizeof(ipv6_route_table_template), + GFP_KERNEL); + return table; +} #endif int __init ip6_route_init(void) diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 7329decf1f9d..7970f3366f87 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -14,20 +14,23 @@ #include #include -static ctl_table ipv6_table[] = { +extern struct ctl_table *ipv6_route_sysctl_init(struct net *net); +extern struct ctl_table *ipv6_icmp_sysctl_init(struct net *net); + +static ctl_table ipv6_table_template[] = { { .ctl_name = NET_IPV6_ROUTE, .procname = "route", .maxlen = 0, .mode = 0555, - .child = ipv6_route_table + .child = ipv6_route_table_template }, { .ctl_name = NET_IPV6_ICMP, .procname = "icmp", .maxlen = 0, .mode = 0555, - .child = ipv6_icmp_table + .child = ipv6_icmp_table_template }, { .ctl_name = NET_IPV6_BINDV6ONLY, @@ -89,22 +92,66 @@ struct ctl_path net_ipv6_ctl_path[] = { }; EXPORT_SYMBOL_GPL(net_ipv6_ctl_path); -static struct ctl_table_header *ipv6_sysctl_header; - static int ipv6_sysctl_net_init(struct net *net) { - ipv6_sysctl_header = register_net_sysctl_table(net, net_ipv6_ctl_path, - ipv6_table); - if (!ipv6_sysctl_header) + struct ctl_table *ipv6_table; + struct ctl_table *ipv6_route_table; + struct ctl_table *ipv6_icmp_table; + int err; + + err = -ENOMEM; + ipv6_table = kmemdup(ipv6_table_template, sizeof(ipv6_table_template), + GFP_KERNEL); + if (!ipv6_table) + goto out; + + ipv6_route_table = ipv6_route_sysctl_init(net); + if (!ipv6_route_table) + goto out_ipv6_table; + + ipv6_icmp_table = ipv6_icmp_sysctl_init(net); + if (!ipv6_icmp_table) + goto out_ipv6_route_table; + + ipv6_table[0].child = ipv6_route_table; + ipv6_table[1].child = ipv6_icmp_table; + + net->ipv6.sysctl.table = register_net_sysctl_table(net, net_ipv6_ctl_path, + ipv6_table); + if (!net->ipv6.sysctl.table) return -ENOMEM; - return 0; + if (!net->ipv6.sysctl.table) + goto out_ipv6_icmp_table; + + err = 0; +out: + return err; +out_ipv6_icmp_table: + kfree(ipv6_icmp_table); +out_ipv6_route_table: + kfree(ipv6_route_table); +out_ipv6_table: + kfree(ipv6_table); + goto out; } static void ipv6_sysctl_net_exit(struct net *net) { - unregister_net_sysctl_table(ipv6_sysctl_header); + struct ctl_table *ipv6_table; + struct ctl_table *ipv6_route_table; + struct ctl_table *ipv6_icmp_table; + + ipv6_table = net->ipv6.sysctl.table->ctl_table_arg; + ipv6_route_table = ipv6_table[0].child; + ipv6_icmp_table = ipv6_table[1].child; + + unregister_net_sysctl_table(net->ipv6.sysctl.table); + + kfree(ipv6_table); + kfree(ipv6_route_table); + kfree(ipv6_icmp_table); } static struct pernet_operations ipv6_sysctl_net_ops = { -- cgit v1.2.3-59-g8ed1b From 99bc9c4e45e7e783cf0b0a25cc03a103c038f254 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Thu, 10 Jan 2008 02:54:53 -0800 Subject: [NETNS][IPV6]: Make bindv6only sysctl per namespace. This patch moves the bindv6only sysctl to the network namespace structure. Until the ipv6 protocol is not per namespace, the sysctl variable is always from the initial network namespace. Signed-off-by: Daniel Lezcano Signed-off-by: David S. Miller --- include/net/ipv6.h | 1 - include/net/netns/ipv6.h | 1 + net/ipv6/af_inet6.c | 5 ++--- net/ipv6/sysctl_net_ipv6.c | 4 +++- 4 files changed, 6 insertions(+), 5 deletions(-) (limited to 'net/ipv6/sysctl_net_ipv6.c') diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 5519035491e7..d03a4076e227 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -109,7 +109,6 @@ struct frag_hdr { #include /* sysctls */ -extern int sysctl_ipv6_bindv6only; extern int sysctl_mld_max_msf; extern struct ctl_path net_ipv6_ctl_path[]; diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index 58fbf30d9fdb..42b9b412fb87 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -11,6 +11,7 @@ struct netns_sysctl_ipv6 { #ifdef CONFIG_SYSCTL struct ctl_table_header *table; #endif + int bindv6only; }; struct netns_ipv6 { diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 72b898fe2dde..70662bf8ab98 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -66,8 +66,6 @@ MODULE_AUTHOR("Cast of dozens"); MODULE_DESCRIPTION("IPv6 protocol stack for Linux"); MODULE_LICENSE("GPL"); -int sysctl_ipv6_bindv6only __read_mostly; - /* The inetsw6 table contains everything that inet6_create needs to * build a new socket. */ @@ -193,7 +191,7 @@ lookup_protocol: np->mcast_hops = -1; np->mc_loop = 1; np->pmtudisc = IPV6_PMTUDISC_WANT; - np->ipv6only = sysctl_ipv6_bindv6only; + np->ipv6only = init_net.ipv6.sysctl.bindv6only; /* Init the ipv4 part of the socket since we can have sockets * using v6 API for ipv4. @@ -721,6 +719,7 @@ static void cleanup_ipv6_mibs(void) static int inet6_net_init(struct net *net) { + net->ipv6.sysctl.bindv6only = 0; return 0; } diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 7970f3366f87..13be97a928cb 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -35,7 +35,7 @@ static ctl_table ipv6_table_template[] = { { .ctl_name = NET_IPV6_BINDV6ONLY, .procname = "bindv6only", - .data = &sysctl_ipv6_bindv6only, + .data = &init_net.ipv6.sysctl.bindv6only, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec @@ -116,6 +116,8 @@ static int ipv6_sysctl_net_init(struct net *net) ipv6_table[0].child = ipv6_route_table; ipv6_table[1].child = ipv6_icmp_table; + ipv6_table[2].data = &net->ipv6.sysctl.bindv6only; + net->ipv6.sysctl.table = register_net_sysctl_table(net, net_ipv6_ctl_path, ipv6_table); if (!net->ipv6.sysctl.table) -- cgit v1.2.3-59-g8ed1b From e71e0349eb32bc438fa80d8990c6f3592967d111 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Thu, 10 Jan 2008 02:56:03 -0800 Subject: [NETNS][IPV6]: Make ip6_frags per namespace. The ip6_frags is moved to the network namespace structure. Because there can be multiple instances of the network namespaces, and the ip6_frags is no longer a global static variable, a helper function has been added to facilitate the initialization of the variables. Until the ipv6 protocol is not per namespace, the variables are accessed relatively from the initial network namespace. Signed-off-by: Daniel Lezcano Signed-off-by: David S. Miller --- include/net/ipv6.h | 3 --- include/net/netns/ipv6.h | 3 +++ net/ipv6/af_inet6.c | 8 ++++++++ net/ipv6/reassembly.c | 16 +++++++--------- net/ipv6/sysctl_net_ipv6.c | 12 ++++++++---- 5 files changed, 26 insertions(+), 16 deletions(-) (limited to 'net/ipv6/sysctl_net_ipv6.c') diff --git a/include/net/ipv6.h b/include/net/ipv6.h index d03a4076e227..c8e8cb241090 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -572,9 +572,6 @@ extern int inet6_hash_connect(struct inet_timewait_death_row *death_row, /* * reassembly.c */ -struct inet_frags_ctl; -extern struct inet_frags_ctl ip6_frags_ctl; - extern const struct proto_ops inet6_stream_ops; extern const struct proto_ops inet6_dgram_ops; diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index 42b9b412fb87..ea4a71ac23d4 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -2,6 +2,8 @@ * ipv6 in net namespaces */ +#include + #ifndef __NETNS_IPV6_H__ #define __NETNS_IPV6_H__ @@ -11,6 +13,7 @@ struct netns_sysctl_ipv6 { #ifdef CONFIG_SYSCTL struct ctl_table_header *table; #endif + struct inet_frags_ctl frags; int bindv6only; }; diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 70662bf8ab98..c4a1882fa80f 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -72,6 +72,8 @@ MODULE_LICENSE("GPL"); static struct list_head inetsw6[SOCK_MAX]; static DEFINE_SPINLOCK(inetsw6_lock); +void ipv6_frag_sysctl_init(struct net *net); + static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk) { const int offset = sk->sk_prot->obj_size - sizeof(struct ipv6_pinfo); @@ -720,6 +722,12 @@ static void cleanup_ipv6_mibs(void) static int inet6_net_init(struct net *net) { net->ipv6.sysctl.bindv6only = 0; + net->ipv6.sysctl.frags.high_thresh = 256 * 1024; + net->ipv6.sysctl.frags.low_thresh = 192 * 1024; + net->ipv6.sysctl.frags.timeout = IPV6_FRAG_TIMEOUT; + net->ipv6.sysctl.frags.secret_interval = 10 * 60 * HZ; + ipv6_frag_sysctl_init(net); + return 0; } diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index bf4173daecbb..5cd0bc693a5f 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -82,13 +82,6 @@ struct frag_queue __u16 nhoffset; }; -struct inet_frags_ctl ip6_frags_ctl __read_mostly = { - .high_thresh = 256 * 1024, - .low_thresh = 192 * 1024, - .timeout = IPV6_FRAG_TIMEOUT, - .secret_interval = 10 * 60 * HZ, -}; - static struct inet_frags ip6_frags; int ip6_frag_nqueues(void) @@ -605,7 +598,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb) return 1; } - if (atomic_read(&ip6_frags.mem) > ip6_frags_ctl.high_thresh) + if (atomic_read(&ip6_frags.mem) > init_net.ipv6.sysctl.frags.high_thresh) ip6_evictor(ip6_dst_idev(skb->dst)); if ((fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr, @@ -632,6 +625,11 @@ static struct inet6_protocol frag_protocol = .flags = INET6_PROTO_NOPOLICY, }; +void ipv6_frag_sysctl_init(struct net *net) +{ + ip6_frags.ctl = &net->ipv6.sysctl.frags; +} + int __init ipv6_frag_init(void) { int ret; @@ -639,7 +637,7 @@ int __init ipv6_frag_init(void) ret = inet6_add_protocol(&frag_protocol, IPPROTO_FRAGMENT); if (ret) goto out; - ip6_frags.ctl = &ip6_frags_ctl; + ip6_frags.hashfn = ip6_hashfn; ip6_frags.constructor = ip6_frag_init; ip6_frags.destructor = NULL; diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 13be97a928cb..ae3cfd1b8e0e 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -43,7 +43,7 @@ static ctl_table ipv6_table_template[] = { { .ctl_name = NET_IPV6_IP6FRAG_HIGH_THRESH, .procname = "ip6frag_high_thresh", - .data = &ip6_frags_ctl.high_thresh, + .data = &init_net.ipv6.sysctl.frags.high_thresh, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec @@ -51,7 +51,7 @@ static ctl_table ipv6_table_template[] = { { .ctl_name = NET_IPV6_IP6FRAG_LOW_THRESH, .procname = "ip6frag_low_thresh", - .data = &ip6_frags_ctl.low_thresh, + .data = &init_net.ipv6.sysctl.frags.low_thresh, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec @@ -59,7 +59,7 @@ static ctl_table ipv6_table_template[] = { { .ctl_name = NET_IPV6_IP6FRAG_TIME, .procname = "ip6frag_time", - .data = &ip6_frags_ctl.timeout, + .data = &init_net.ipv6.sysctl.frags.timeout, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, @@ -68,7 +68,7 @@ static ctl_table ipv6_table_template[] = { { .ctl_name = NET_IPV6_IP6FRAG_SECRET_INTERVAL, .procname = "ip6frag_secret_interval", - .data = &ip6_frags_ctl.secret_interval, + .data = &init_net.ipv6.sysctl.frags.secret_interval, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, @@ -117,6 +117,10 @@ static int ipv6_sysctl_net_init(struct net *net) ipv6_table[1].child = ipv6_icmp_table; ipv6_table[2].data = &net->ipv6.sysctl.bindv6only; + ipv6_table[3].data = &net->ipv6.sysctl.frags.high_thresh; + ipv6_table[4].data = &net->ipv6.sysctl.frags.low_thresh; + ipv6_table[5].data = &net->ipv6.sysctl.frags.timeout; + ipv6_table[6].data = &net->ipv6.sysctl.frags.secret_interval; net->ipv6.sysctl.table = register_net_sysctl_table(net, net_ipv6_ctl_path, ipv6_table); -- cgit v1.2.3-59-g8ed1b From 7c76509d0da99f29289b9b7ab134791e45d49b15 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Thu, 10 Jan 2008 02:57:43 -0800 Subject: [NETNS][IPV6]: Make mld_max_msf readonly in other namespaces. The mld_max_msf protects the system with a maximum allowed multicast source filters. Making this variable per namespace can be potentially an problem if someone inside a namespace set it to a big value, that will impact the whole system including other namespaces. I don't see any benefits to have it per namespace for now, so in order to keep a directory entry in a newly created namespace, I make it read-only when we are not in the initial network namespace. Signed-off-by: Daniel Lezcano Signed-off-by: David S. Miller --- net/ipv6/sysctl_net_ipv6.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'net/ipv6/sysctl_net_ipv6.c') diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index ae3cfd1b8e0e..d223159638d3 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -122,6 +122,12 @@ static int ipv6_sysctl_net_init(struct net *net) ipv6_table[5].data = &net->ipv6.sysctl.frags.timeout; ipv6_table[6].data = &net->ipv6.sysctl.frags.secret_interval; + /* We don't want this value to be per namespace, it should be global + to all namespaces, so make it read-only when we are not in the + init network namespace */ + if (net != &init_net) + ipv6_table[7].mode = 0444; + net->ipv6.sysctl.table = register_net_sysctl_table(net, net_ipv6_ctl_path, ipv6_table); if (!net->ipv6.sysctl.table) -- cgit v1.2.3-59-g8ed1b From 4990509f19e8f1e000a83a88fc46328f73b8a88a Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Thu, 10 Jan 2008 03:01:01 -0800 Subject: [NETNS][IPV6]: Make sysctls route per namespace. All the sysctl concerning the routes are moved to the network namespace structure. A helper function is called to initialize the variables. Because the ipv6 protocol is not yet per namespace, the variables are accessed relatively from the network namespace. Signed-off-by: Daniel Lezcano Signed-off-by: David S. Miller --- include/net/ip6_route.h | 2 -- include/net/netns/ipv6.h | 8 ++++++++ net/ipv6/af_inet6.c | 8 ++++++++ net/ipv6/ip6_fib.c | 14 ++++++++----- net/ipv6/route.c | 49 +++++++++++++++++++--------------------------- net/ipv6/sysctl_net_ipv6.c | 11 +++++++++++ 6 files changed, 56 insertions(+), 36 deletions(-) (limited to 'net/ipv6/sysctl_net_ipv6.c') diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 1a0698b1e86c..faac0eee1ef3 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -43,8 +43,6 @@ extern struct rt6_info ip6_prohibit_entry; extern struct rt6_info ip6_blk_hole_entry; #endif -extern int ip6_rt_gc_interval; - extern void ip6_route_input(struct sk_buff *skb); extern struct dst_entry * ip6_route_output(struct sock *sk, diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index ea4a71ac23d4..050d08809ef2 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -15,6 +15,14 @@ struct netns_sysctl_ipv6 { #endif struct inet_frags_ctl frags; int bindv6only; + int flush_delay; + int ip6_rt_max_size; + int ip6_rt_gc_min_interval; + int ip6_rt_gc_timeout; + int ip6_rt_gc_interval; + int ip6_rt_gc_elasticity; + int ip6_rt_mtu_expires; + int ip6_rt_min_advmss; }; struct netns_ipv6 { diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index c4a1882fa80f..3aea84a1822a 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -726,6 +726,14 @@ static int inet6_net_init(struct net *net) net->ipv6.sysctl.frags.low_thresh = 192 * 1024; net->ipv6.sysctl.frags.timeout = IPV6_FRAG_TIMEOUT; net->ipv6.sysctl.frags.secret_interval = 10 * 60 * HZ; + net->ipv6.sysctl.flush_delay = 0; + net->ipv6.sysctl.ip6_rt_max_size = 4096; + net->ipv6.sysctl.ip6_rt_gc_min_interval = HZ / 2; + net->ipv6.sysctl.ip6_rt_gc_timeout = 60*HZ; + net->ipv6.sysctl.ip6_rt_gc_interval = 30*HZ; + net->ipv6.sysctl.ip6_rt_gc_elasticity = 9; + net->ipv6.sysctl.ip6_rt_mtu_expires = 10*60*HZ; + net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40; ipv6_frag_sysctl_init(net); return 0; diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 7165a5e90f45..0e83164aa3e6 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -681,13 +681,15 @@ static __inline__ void fib6_start_gc(struct rt6_info *rt) { if (ip6_fib_timer.expires == 0 && (rt->rt6i_flags & (RTF_EXPIRES|RTF_CACHE))) - mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval); + mod_timer(&ip6_fib_timer, jiffies + + init_net.ipv6.sysctl.ip6_rt_gc_interval); } void fib6_force_start_gc(void) { if (ip6_fib_timer.expires == 0) - mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval); + mod_timer(&ip6_fib_timer, jiffies + + init_net.ipv6.sysctl.ip6_rt_gc_interval); } /* @@ -1447,7 +1449,8 @@ void fib6_run_gc(unsigned long dummy) { if (dummy != ~0UL) { spin_lock_bh(&fib6_gc_lock); - gc_args.timeout = dummy ? (int)dummy : ip6_rt_gc_interval; + gc_args.timeout = dummy ? (int)dummy : + init_net.ipv6.sysctl.ip6_rt_gc_interval; } else { local_bh_disable(); if (!spin_trylock(&fib6_gc_lock)) { @@ -1455,7 +1458,7 @@ void fib6_run_gc(unsigned long dummy) local_bh_enable(); return; } - gc_args.timeout = ip6_rt_gc_interval; + gc_args.timeout = init_net.ipv6.sysctl.ip6_rt_gc_interval; } gc_args.more = 0; @@ -1463,7 +1466,8 @@ void fib6_run_gc(unsigned long dummy) fib6_clean_all(fib6_age, 0, NULL); if (gc_args.more) - mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval); + mod_timer(&ip6_fib_timer, jiffies + + init_net.ipv6.sysctl.ip6_rt_gc_interval); else { del_timer(&ip6_fib_timer); ip6_fib_timer.expires = 0; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 0c7382f4fb85..d2b3cf695aff 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -73,14 +73,6 @@ #define CLONE_OFFLINK_ROUTE 0 -static int ip6_rt_max_size = 4096; -static int ip6_rt_gc_min_interval = HZ / 2; -static int ip6_rt_gc_timeout = 60*HZ; -int ip6_rt_gc_interval = 30*HZ; -static int ip6_rt_gc_elasticity = 9; -static int ip6_rt_mtu_expires = 10*60*HZ; -static int ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40; - static struct rt6_info * ip6_rt_copy(struct rt6_info *ort); static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); static struct dst_entry *ip6_negative_advice(struct dst_entry *); @@ -894,8 +886,8 @@ static inline unsigned int ipv6_advmss(unsigned int mtu) { mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); - if (mtu < ip6_rt_min_advmss) - mtu = ip6_rt_min_advmss; + if (mtu < init_net.ipv6.sysctl.ip6_rt_min_advmss) + mtu = init_net.ipv6.sysctl.ip6_rt_min_advmss; /* * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and @@ -995,19 +987,19 @@ static int ip6_dst_gc(void) static unsigned long last_gc; unsigned long now = jiffies; - if (time_after(last_gc + ip6_rt_gc_min_interval, now) && - atomic_read(&ip6_dst_ops.entries) <= ip6_rt_max_size) + if (time_after(last_gc + init_net.ipv6.sysctl.ip6_rt_gc_min_interval, now) && + atomic_read(&ip6_dst_ops.entries) <= init_net.ipv6.sysctl.ip6_rt_max_size) goto out; expire++; fib6_run_gc(expire); last_gc = now; if (atomic_read(&ip6_dst_ops.entries) < ip6_dst_ops.gc_thresh) - expire = ip6_rt_gc_timeout>>1; + expire = init_net.ipv6.sysctl.ip6_rt_gc_timeout>>1; out: - expire -= expire>>ip6_rt_gc_elasticity; - return (atomic_read(&ip6_dst_ops.entries) > ip6_rt_max_size); + expire -= expire>>init_net.ipv6.sysctl.ip6_rt_gc_elasticity; + return (atomic_read(&ip6_dst_ops.entries) > init_net.ipv6.sysctl.ip6_rt_max_size); } /* Clean host part of a prefix. Not necessary in radix tree, @@ -1513,7 +1505,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, rt->u.dst.metrics[RTAX_MTU-1] = pmtu; if (allfrag) rt->u.dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; - dst_set_expires(&rt->u.dst, ip6_rt_mtu_expires); + dst_set_expires(&rt->u.dst, init_net.ipv6.sysctl.ip6_rt_mtu_expires); rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES; goto out; } @@ -1539,7 +1531,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, * which is 10 mins. After 10 mins the decreased pmtu is expired * and detecting PMTU increase will be automatically happened. */ - dst_set_expires(&nrt->u.dst, ip6_rt_mtu_expires); + dst_set_expires(&nrt->u.dst, init_net.ipv6.sysctl.ip6_rt_mtu_expires); nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES; ip6_ins_rt(nrt); @@ -2395,15 +2387,14 @@ static inline void ipv6_route_proc_fini(struct net *net) #ifdef CONFIG_SYSCTL -static int flush_delay; - static int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp, void __user *buffer, size_t *lenp, loff_t *ppos) { + int delay = init_net.ipv6.sysctl.flush_delay; if (write) { proc_dointvec(ctl, write, filp, buffer, lenp, ppos); - fib6_run_gc(flush_delay <= 0 ? ~0UL : (unsigned long)flush_delay); + fib6_run_gc(delay <= 0 ? ~0UL : (unsigned long)delay); return 0; } else return -EINVAL; @@ -2412,7 +2403,7 @@ int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp, ctl_table ipv6_route_table_template[] = { { .procname = "flush", - .data = &flush_delay, + .data = &init_net.ipv6.sysctl.flush_delay, .maxlen = sizeof(int), .mode = 0200, .proc_handler = &ipv6_sysctl_rtcache_flush @@ -2428,7 +2419,7 @@ ctl_table ipv6_route_table_template[] = { { .ctl_name = NET_IPV6_ROUTE_MAX_SIZE, .procname = "max_size", - .data = &ip6_rt_max_size, + .data = &init_net.ipv6.sysctl.ip6_rt_max_size, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec, @@ -2436,7 +2427,7 @@ ctl_table ipv6_route_table_template[] = { { .ctl_name = NET_IPV6_ROUTE_GC_MIN_INTERVAL, .procname = "gc_min_interval", - .data = &ip6_rt_gc_min_interval, + .data = &init_net.ipv6.sysctl.ip6_rt_gc_min_interval, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, @@ -2445,7 +2436,7 @@ ctl_table ipv6_route_table_template[] = { { .ctl_name = NET_IPV6_ROUTE_GC_TIMEOUT, .procname = "gc_timeout", - .data = &ip6_rt_gc_timeout, + .data = &init_net.ipv6.sysctl.ip6_rt_gc_timeout, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, @@ -2454,7 +2445,7 @@ ctl_table ipv6_route_table_template[] = { { .ctl_name = NET_IPV6_ROUTE_GC_INTERVAL, .procname = "gc_interval", - .data = &ip6_rt_gc_interval, + .data = &init_net.ipv6.sysctl.ip6_rt_gc_interval, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, @@ -2463,7 +2454,7 @@ ctl_table ipv6_route_table_template[] = { { .ctl_name = NET_IPV6_ROUTE_GC_ELASTICITY, .procname = "gc_elasticity", - .data = &ip6_rt_gc_elasticity, + .data = &init_net.ipv6.sysctl.ip6_rt_gc_elasticity, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, @@ -2472,7 +2463,7 @@ ctl_table ipv6_route_table_template[] = { { .ctl_name = NET_IPV6_ROUTE_MTU_EXPIRES, .procname = "mtu_expires", - .data = &ip6_rt_mtu_expires, + .data = &init_net.ipv6.sysctl.ip6_rt_mtu_expires, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, @@ -2481,7 +2472,7 @@ ctl_table ipv6_route_table_template[] = { { .ctl_name = NET_IPV6_ROUTE_MIN_ADVMSS, .procname = "min_adv_mss", - .data = &ip6_rt_min_advmss, + .data = &init_net.ipv6.sysctl.ip6_rt_min_advmss, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, @@ -2490,7 +2481,7 @@ ctl_table ipv6_route_table_template[] = { { .ctl_name = NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS, .procname = "gc_min_interval_ms", - .data = &ip6_rt_gc_min_interval, + .data = &init_net.ipv6.sysctl.ip6_rt_gc_min_interval, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_ms_jiffies, diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index d223159638d3..b4ba422f2714 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -113,7 +113,18 @@ static int ipv6_sysctl_net_init(struct net *net) if (!ipv6_icmp_table) goto out_ipv6_route_table; + ipv6_route_table[0].data = &net->ipv6.sysctl.flush_delay; + /* ipv6_route_table[1].data will be handled when we have + routes per namespace */ + ipv6_route_table[2].data = &net->ipv6.sysctl.ip6_rt_max_size; + ipv6_route_table[3].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval; + ipv6_route_table[4].data = &net->ipv6.sysctl.ip6_rt_gc_timeout; + ipv6_route_table[5].data = &net->ipv6.sysctl.ip6_rt_gc_interval; + ipv6_route_table[6].data = &net->ipv6.sysctl.ip6_rt_gc_elasticity; + ipv6_route_table[7].data = &net->ipv6.sysctl.ip6_rt_mtu_expires; + ipv6_route_table[8].data = &net->ipv6.sysctl.ip6_rt_min_advmss; ipv6_table[0].child = ipv6_route_table; + ipv6_table[1].child = ipv6_icmp_table; ipv6_table[2].data = &net->ipv6.sysctl.bindv6only; -- cgit v1.2.3-59-g8ed1b From 41a76906b3225997036efd88cbaae69d60b1e947 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Thu, 10 Jan 2008 03:02:40 -0800 Subject: [NETNS][IPV6]: Make icmpv6_time sysctl per namespace. This patch moves the icmpv6_time sysctl to the network namespace structure. Because the ipv6 protocol is not yet per namespace, the variable is accessed relatively to the initial network namespace. Signed-off-by: Daniel Lezcano Signed-off-by: David S. Miller --- include/net/netns/ipv6.h | 1 + net/ipv6/af_inet6.c | 1 + net/ipv6/icmp.c | 6 ++---- net/ipv6/sysctl_net_ipv6.c | 1 + 4 files changed, 5 insertions(+), 4 deletions(-) (limited to 'net/ipv6/sysctl_net_ipv6.c') diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index 050d08809ef2..10733a6f1bd4 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -23,6 +23,7 @@ struct netns_sysctl_ipv6 { int ip6_rt_gc_elasticity; int ip6_rt_mtu_expires; int ip6_rt_min_advmss; + int icmpv6_time; }; struct netns_ipv6 { diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 3aea84a1822a..218b8b3050a1 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -734,6 +734,7 @@ static int inet6_net_init(struct net *net) net->ipv6.sysctl.ip6_rt_gc_elasticity = 9; net->ipv6.sysctl.ip6_rt_mtu_expires = 10*60*HZ; net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40; + net->ipv6.sysctl.icmpv6_time = 1*HZ; ipv6_frag_sysctl_init(net); return 0; diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index dfe3b37c43e9..5395afe55ca5 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -154,8 +154,6 @@ static int is_ineligible(struct sk_buff *skb) return 0; } -static int sysctl_icmpv6_time __read_mostly = 1*HZ; - /* * Check the ICMP output rate limit */ @@ -186,7 +184,7 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type, res = 1; } else { struct rt6_info *rt = (struct rt6_info *)dst; - int tmo = sysctl_icmpv6_time; + int tmo = init_net.ipv6.sysctl.icmpv6_time; /* Give more bandwidth to wider prefixes. */ if (rt->rt6i_dst.plen < 128) @@ -911,7 +909,7 @@ ctl_table ipv6_icmp_table_template[] = { { .ctl_name = NET_IPV6_ICMP_RATELIMIT, .procname = "ratelimit", - .data = &sysctl_icmpv6_time, + .data = &init_net.ipv6.sysctl.icmpv6_time, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index b4ba422f2714..5e0af4d46324 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -125,6 +125,7 @@ static int ipv6_sysctl_net_init(struct net *net) ipv6_route_table[8].data = &net->ipv6.sysctl.ip6_rt_min_advmss; ipv6_table[0].child = ipv6_route_table; + ipv6_icmp_table[0].data = &net->ipv6.sysctl.icmpv6_time; ipv6_table[1].child = ipv6_icmp_table; ipv6_table[2].data = &net->ipv6.sysctl.bindv6only; -- cgit v1.2.3-59-g8ed1b From 2334ecbdb27bd1745c0fc6d05cce09ed9585e4c1 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Tue, 22 Jan 2008 17:18:38 +0900 Subject: [IPV6]: Sparse: Declare non-static ipv6_{route,icmp,frag}_sysctl_init() in header. Fix the following sparse warnings: | net/ipv6/route.c:2491:18: warning: symbol 'ipv6_route_sysctl_init' was not declared. Should it be static? | net/ipv6/icmp.c:922:18: warning: symbol 'ipv6_icmp_sysctl_init' was not declared. Should it be static? | net/ipv6/reassembly.c:628:6: warning: symbol 'ipv6_frag_sysctl_init' was not declared. Should it be static? Signed-off-by: YOSHIFUJI Hideaki --- include/net/ipv6.h | 4 ++++ net/ipv6/af_inet6.c | 2 -- net/ipv6/sysctl_net_ipv6.c | 3 --- 3 files changed, 4 insertions(+), 5 deletions(-) (limited to 'net/ipv6/sysctl_net_ipv6.c') diff --git a/include/net/ipv6.h b/include/net/ipv6.h index c8e8cb241090..3712caeae74e 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -586,6 +586,10 @@ extern int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf, int __user *optlen); #ifdef CONFIG_PROC_FS +extern struct ctl_table *ipv6_icmp_sysctl_init(struct net *net); +extern void ipv6_frag_sysctl_init(struct net *net); +extern struct ctl_table *ipv6_route_sysctl_init(struct net *net); + extern int ac6_proc_init(void); extern void ac6_proc_exit(void); extern int raw6_proc_init(void); diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 3150c4be3c0c..6738a7b0e67f 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -72,8 +72,6 @@ MODULE_LICENSE("GPL"); static struct list_head inetsw6[SOCK_MAX]; static DEFINE_SPINLOCK(inetsw6_lock); -void ipv6_frag_sysctl_init(struct net *net); - static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk) { const int offset = sk->sk_prot->obj_size - sizeof(struct ipv6_pinfo); diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 5e0af4d46324..7197eb74a755 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -14,9 +14,6 @@ #include #include -extern struct ctl_table *ipv6_route_sysctl_init(struct net *net); -extern struct ctl_table *ipv6_icmp_sysctl_init(struct net *net); - static ctl_table ipv6_table_template[] = { { .ctl_name = NET_IPV6_ROUTE, -- cgit v1.2.3-59-g8ed1b From 8d8354d2fb9277f165715a6e1cb92bcc89259975 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Tue, 22 Jan 2008 05:58:31 -0800 Subject: [NETNS][FRAGS]: Move ctl tables around. This is a preparation for sysctl netns-ization. Move the ctl tables to the files, where the tuning variables reside. Plus make the helpers to register the tables. This will simplify the later patches and will keep similar things closer to each other. ipv4, ipv6 and conntrack_reasm are patched differently, but the result is all the tables are in appropriate files. Signed-off-by: Pavel Emelyanov Signed-off-by: David S. Miller --- include/net/ip.h | 5 -- include/net/ipv6.h | 1 - include/net/netfilter/ipv6/nf_conntrack_ipv6.h | 4 +- net/ipv4/ip_fragment.c | 74 +++++++++++++++++++++++++- net/ipv4/sysctl_net_ipv4.c | 42 --------------- net/ipv6/af_inet6.c | 5 -- net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 29 ---------- net/ipv6/netfilter/nf_conntrack_reasm.c | 31 ++++++++++- net/ipv6/reassembly.c | 66 +++++++++++++++++++++-- net/ipv6/sysctl_net_ipv6.c | 40 +------------- 10 files changed, 169 insertions(+), 128 deletions(-) (limited to 'net/ipv6/sysctl_net_ipv6.c') diff --git a/include/net/ip.h b/include/net/ip.h index 6850a80a6886..9d43ac222d15 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -179,11 +179,6 @@ extern int sysctl_ip_nonlocal_bind; extern struct ctl_path net_ipv4_ctl_path[]; -/* From ip_fragment.c */ -struct inet_frags_ctl; -extern struct inet_frags_ctl ip4_frags_ctl; -extern int sysctl_ipfrag_max_dist; - /* From inetpeer.c */ extern int inet_peer_threshold; extern int inet_peer_minttl; diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 3712caeae74e..87ca1bf17d71 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -587,7 +587,6 @@ extern int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf, #ifdef CONFIG_PROC_FS extern struct ctl_table *ipv6_icmp_sysctl_init(struct net *net); -extern void ipv6_frag_sysctl_init(struct net *net); extern struct ctl_table *ipv6_route_sysctl_init(struct net *net); extern int ac6_proc_init(void); diff --git a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h index f703533fb4db..abc55ad75c2b 100644 --- a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h +++ b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h @@ -16,6 +16,8 @@ extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, int (*okfn)(struct sk_buff *)); struct inet_frags_ctl; -extern struct inet_frags_ctl nf_frags_ctl; + +#include +extern struct ctl_table nf_ct_ipv6_sysctl_table[]; #endif /* _NF_CONNTRACK_IPV6_H*/ diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 2143bf30597a..a53463e594b9 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -50,7 +50,7 @@ * as well. Or notify me, at least. --ANK */ -int sysctl_ipfrag_max_dist __read_mostly = 64; +static int sysctl_ipfrag_max_dist __read_mostly = 64; struct ipfrag_skb_cb { @@ -74,7 +74,7 @@ struct ipq { struct inet_peer *peer; }; -struct inet_frags_ctl ip4_frags_ctl __read_mostly = { +static struct inet_frags_ctl ip4_frags_ctl __read_mostly = { /* * Fragment cache limits. We will commit 256K at one time. Should we * cross that limit we will prune down to 192K. This should cope with @@ -607,8 +607,78 @@ int ip_defrag(struct sk_buff *skb, u32 user) return -ENOMEM; } +#ifdef CONFIG_SYSCTL +static int zero; + +static struct ctl_table ip4_frags_ctl_table[] = { + { + .ctl_name = NET_IPV4_IPFRAG_HIGH_THRESH, + .procname = "ipfrag_high_thresh", + .data = &ip4_frags_ctl.high_thresh, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_IPFRAG_LOW_THRESH, + .procname = "ipfrag_low_thresh", + .data = &ip4_frags_ctl.low_thresh, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV4_IPFRAG_TIME, + .procname = "ipfrag_time", + .data = &ip4_frags_ctl.timeout, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies + }, + { + .ctl_name = NET_IPV4_IPFRAG_SECRET_INTERVAL, + .procname = "ipfrag_secret_interval", + .data = &ip4_frags_ctl.secret_interval, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies + }, + { + .procname = "ipfrag_max_dist", + .data = &sysctl_ipfrag_max_dist, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .extra1 = &zero + }, + { } +}; + +static int ip4_frags_ctl_register(struct net *net) +{ + struct ctl_table_header *hdr; + + hdr = register_net_sysctl_table(net, net_ipv4_ctl_path, + ip4_frags_ctl_table); + return hdr == NULL ? -ENOMEM : 0; +} +#else +static inline int ip4_frags_ctl_register(struct net *net) +{ + return 0; +} +#endif + +static int ipv4_frags_init_net(struct net *net) +{ + return ip4_frags_ctl_register(net); +} + void __init ipfrag_init(void) { + ipv4_frags_init_net(&init_net); ip4_frags.ctl = &ip4_frags_ctl; ip4_frags.hashfn = ip4_hashfn; ip4_frags.constructor = ip4_frag_init; diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 45536a91266a..82cdf23837e3 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -283,22 +283,6 @@ static struct ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = &proc_dointvec }, - { - .ctl_name = NET_IPV4_IPFRAG_HIGH_THRESH, - .procname = "ipfrag_high_thresh", - .data = &ip4_frags_ctl.high_thresh, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = NET_IPV4_IPFRAG_LOW_THRESH, - .procname = "ipfrag_low_thresh", - .data = &ip4_frags_ctl.low_thresh, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, { .ctl_name = NET_IPV4_DYNADDR, .procname = "ip_dynaddr", @@ -307,15 +291,6 @@ static struct ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = &proc_dointvec }, - { - .ctl_name = NET_IPV4_IPFRAG_TIME, - .procname = "ipfrag_time", - .data = &ip4_frags_ctl.timeout, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec_jiffies, - .strategy = &sysctl_jiffies - }, { .ctl_name = NET_IPV4_TCP_KEEPALIVE_TIME, .procname = "tcp_keepalive_time", @@ -658,23 +633,6 @@ static struct ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = &proc_dointvec }, - { - .ctl_name = NET_IPV4_IPFRAG_SECRET_INTERVAL, - .procname = "ipfrag_secret_interval", - .data = &ip4_frags_ctl.secret_interval, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec_jiffies, - .strategy = &sysctl_jiffies - }, - { - .procname = "ipfrag_max_dist", - .data = &sysctl_ipfrag_max_dist, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec_minmax, - .extra1 = &zero - }, { .ctl_name = NET_TCP_NO_METRICS_SAVE, .procname = "tcp_no_metrics_save", diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 6738a7b0e67f..bddac0e8780f 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -721,10 +721,6 @@ static void cleanup_ipv6_mibs(void) static int inet6_net_init(struct net *net) { net->ipv6.sysctl.bindv6only = 0; - net->ipv6.sysctl.frags.high_thresh = 256 * 1024; - net->ipv6.sysctl.frags.low_thresh = 192 * 1024; - net->ipv6.sysctl.frags.timeout = IPV6_FRAG_TIMEOUT; - net->ipv6.sysctl.frags.secret_interval = 10 * 60 * HZ; net->ipv6.sysctl.flush_delay = 0; net->ipv6.sysctl.ip6_rt_max_size = 4096; net->ipv6.sysctl.ip6_rt_gc_min_interval = HZ / 2; @@ -734,7 +730,6 @@ static int inet6_net_init(struct net *net) net->ipv6.sysctl.ip6_rt_mtu_expires = 10*60*HZ; net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40; net->ipv6.sysctl.icmpv6_time = 1*HZ; - ipv6_frag_sysctl_init(net); return 0; } diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index cf42f5cfc338..2d7b0246475d 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -297,35 +297,6 @@ static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { }, }; -#ifdef CONFIG_SYSCTL -static ctl_table nf_ct_ipv6_sysctl_table[] = { - { - .procname = "nf_conntrack_frag6_timeout", - .data = &nf_frags_ctl.timeout, - .maxlen = sizeof(unsigned int), - .mode = 0644, - .proc_handler = &proc_dointvec_jiffies, - }, - { - .ctl_name = NET_NF_CONNTRACK_FRAG6_LOW_THRESH, - .procname = "nf_conntrack_frag6_low_thresh", - .data = &nf_frags_ctl.low_thresh, - .maxlen = sizeof(unsigned int), - .mode = 0644, - .proc_handler = &proc_dointvec, - }, - { - .ctl_name = NET_NF_CONNTRACK_FRAG6_HIGH_THRESH, - .procname = "nf_conntrack_frag6_high_thresh", - .data = &nf_frags_ctl.high_thresh, - .maxlen = sizeof(unsigned int), - .mode = 0644, - .proc_handler = &proc_dointvec, - }, - { .ctl_name = 0 } -}; -#endif - #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) #include diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index e170c67c47a5..d631631189b6 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -70,7 +70,7 @@ struct nf_ct_frag6_queue __u16 nhoffset; }; -struct inet_frags_ctl nf_frags_ctl __read_mostly = { +static struct inet_frags_ctl nf_frags_ctl __read_mostly = { .high_thresh = 256 * 1024, .low_thresh = 192 * 1024, .timeout = IPV6_FRAG_TIMEOUT, @@ -79,6 +79,35 @@ struct inet_frags_ctl nf_frags_ctl __read_mostly = { static struct inet_frags nf_frags; +#ifdef CONFIG_SYSCTL +struct ctl_table nf_ct_ipv6_sysctl_table[] = { + { + .procname = "nf_conntrack_frag6_timeout", + .data = &nf_frags_ctl.timeout, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + }, + { + .ctl_name = NET_NF_CONNTRACK_FRAG6_LOW_THRESH, + .procname = "nf_conntrack_frag6_low_thresh", + .data = &nf_frags_ctl.low_thresh, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = NET_NF_CONNTRACK_FRAG6_HIGH_THRESH, + .procname = "nf_conntrack_frag6_high_thresh", + .data = &nf_frags_ctl.high_thresh, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { .ctl_name = 0 } +}; +#endif + static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr, struct in6_addr *daddr) { diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 4dfcddc871ce..1815ff0cf628 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -625,12 +625,70 @@ static struct inet6_protocol frag_protocol = .flags = INET6_PROTO_NOPOLICY, }; -void ipv6_frag_sysctl_init(struct net *net) +#ifdef CONFIG_SYSCTL +static struct ctl_table ip6_frags_ctl_table[] = { + { + .ctl_name = NET_IPV6_IP6FRAG_HIGH_THRESH, + .procname = "ip6frag_high_thresh", + .data = &init_net.ipv6.sysctl.frags.high_thresh, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV6_IP6FRAG_LOW_THRESH, + .procname = "ip6frag_low_thresh", + .data = &init_net.ipv6.sysctl.frags.low_thresh, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = NET_IPV6_IP6FRAG_TIME, + .procname = "ip6frag_time", + .data = &init_net.ipv6.sysctl.frags.timeout, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies, + }, + { + .ctl_name = NET_IPV6_IP6FRAG_SECRET_INTERVAL, + .procname = "ip6frag_secret_interval", + .data = &init_net.ipv6.sysctl.frags.secret_interval, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies + }, + { } +}; + +static int ip6_frags_sysctl_register(struct net *net) +{ + struct ctl_table_header *hdr; + + hdr = register_net_sysctl_table(net, net_ipv6_ctl_path, + ip6_frags_ctl_table); + return hdr == NULL ? -ENOMEM : 0; +} +#else +static inline int ip6_frags_sysctl_register(struct net *net) { - if (net != &init_net) - return; + return 0; +} +#endif +static int ipv6_frags_init_net(struct net *net) +{ ip6_frags.ctl = &net->ipv6.sysctl.frags; + + net->ipv6.sysctl.frags.high_thresh = 256 * 1024; + net->ipv6.sysctl.frags.low_thresh = 192 * 1024; + net->ipv6.sysctl.frags.timeout = IPV6_FRAG_TIMEOUT; + net->ipv6.sysctl.frags.secret_interval = 10 * 60 * HZ; + + return ip6_frags_sysctl_register(net); } int __init ipv6_frag_init(void) @@ -641,6 +699,8 @@ int __init ipv6_frag_init(void) if (ret) goto out; + ipv6_frags_init_net(&init_net); + ip6_frags.hashfn = ip6_hashfn; ip6_frags.constructor = ip6_frag_init; ip6_frags.destructor = NULL; diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 7197eb74a755..408691b777c2 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -37,40 +37,6 @@ static ctl_table ipv6_table_template[] = { .mode = 0644, .proc_handler = &proc_dointvec }, - { - .ctl_name = NET_IPV6_IP6FRAG_HIGH_THRESH, - .procname = "ip6frag_high_thresh", - .data = &init_net.ipv6.sysctl.frags.high_thresh, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = NET_IPV6_IP6FRAG_LOW_THRESH, - .procname = "ip6frag_low_thresh", - .data = &init_net.ipv6.sysctl.frags.low_thresh, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = NET_IPV6_IP6FRAG_TIME, - .procname = "ip6frag_time", - .data = &init_net.ipv6.sysctl.frags.timeout, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec_jiffies, - .strategy = &sysctl_jiffies, - }, - { - .ctl_name = NET_IPV6_IP6FRAG_SECRET_INTERVAL, - .procname = "ip6frag_secret_interval", - .data = &init_net.ipv6.sysctl.frags.secret_interval, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec_jiffies, - .strategy = &sysctl_jiffies - }, { .ctl_name = NET_IPV6_MLD_MAX_MSF, .procname = "mld_max_msf", @@ -126,16 +92,12 @@ static int ipv6_sysctl_net_init(struct net *net) ipv6_table[1].child = ipv6_icmp_table; ipv6_table[2].data = &net->ipv6.sysctl.bindv6only; - ipv6_table[3].data = &net->ipv6.sysctl.frags.high_thresh; - ipv6_table[4].data = &net->ipv6.sysctl.frags.low_thresh; - ipv6_table[5].data = &net->ipv6.sysctl.frags.timeout; - ipv6_table[6].data = &net->ipv6.sysctl.frags.secret_interval; /* We don't want this value to be per namespace, it should be global to all namespaces, so make it read-only when we are not in the init network namespace */ if (net != &init_net) - ipv6_table[7].mode = 0444; + ipv6_table[3].mode = 0444; net->ipv6.sysctl.table = register_net_sysctl_table(net, net_ipv6_ctl_path, ipv6_table); -- cgit v1.2.3-59-g8ed1b