diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2008-01-22 06:08:36 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 15:10:37 -0800 |
commit | e4a2d5c2bccd5bd29de5ae4f14ff4448fac9cfc8 (patch) | |
tree | e6ae6835ec20401b1a59de0c8c0f8519fba3a4b4 /net | |
parent | 6ddc082223ef0f73717b4133fa7e648842bbfd02 (diff) | |
download | linux-e4a2d5c2bccd5bd29de5ae4f14ff4448fac9cfc8.tar.bz2 |
[NETNS][FRAGS]: Duplicate sysctl tables for new namespaces.
Each namespace has to have own tables to tune their
different parameters, so duplicate the tables and
register them.
All the tables in sub-namespaces are temporarily made
read-only.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/ip_fragment.c | 42 | ||||
-rw-r--r-- | net/ipv6/reassembly.c | 41 |
2 files changed, 77 insertions, 6 deletions
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 4f013343cef7..c51e1a11dc6b 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -661,17 +661,53 @@ static struct ctl_table ip4_frags_ctl_table[] = { static int ip4_frags_ctl_register(struct net *net) { + struct ctl_table *table; struct ctl_table_header *hdr; - hdr = register_net_sysctl_table(net, net_ipv4_ctl_path, - ip4_frags_ctl_table); - return hdr == NULL ? -ENOMEM : 0; + table = ip4_frags_ctl_table; + if (net != &init_net) { + table = kmemdup(table, sizeof(ip4_frags_ctl_table), GFP_KERNEL); + if (table == NULL) + goto err_alloc; + + table[0].mode &= ~0222; + table[1].mode &= ~0222; + table[2].mode &= ~0222; + table[3].mode &= ~0222; + table[4].mode &= ~0222; + } + + hdr = register_net_sysctl_table(net, net_ipv4_ctl_path, table); + if (hdr == NULL) + goto err_reg; + + net->ipv4.frags_hdr = hdr; + return 0; + +err_reg: + if (net != &init_net) + kfree(table); +err_alloc: + return -ENOMEM; +} + +static void ip4_frags_ctl_unregister(struct net *net) +{ + struct ctl_table *table; + + table = net->ipv4.frags_hdr->ctl_table_arg; + unregister_net_sysctl_table(net->ipv4.frags_hdr); + kfree(table); } #else static inline int ip4_frags_ctl_register(struct net *net) { return 0; } + +static inline void ip4_frags_ctl_unregister(struct net *net) +{ +} #endif static int ipv4_frags_init_net(struct net *net) diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 241b2cc49bf5..0300dcbf1a75 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -670,17 +670,52 @@ static struct ctl_table ip6_frags_ctl_table[] = { static int ip6_frags_sysctl_register(struct net *net) { + struct ctl_table *table; struct ctl_table_header *hdr; - hdr = register_net_sysctl_table(net, net_ipv6_ctl_path, - ip6_frags_ctl_table); - return hdr == NULL ? -ENOMEM : 0; + table = ip6_frags_ctl_table; + if (net != &init_net) { + table = kmemdup(table, sizeof(ip6_frags_ctl_table), GFP_KERNEL); + if (table == NULL) + goto err_alloc; + + table[0].mode &= ~0222; + table[1].mode &= ~0222; + table[2].mode &= ~0222; + table[3].mode &= ~0222; + } + + hdr = register_net_sysctl_table(net, net_ipv6_ctl_path, table); + if (hdr == NULL) + goto err_reg; + + net->ipv6.sysctl.frags_hdr = hdr; + return 0; + +err_reg: + if (net != &init_net) + kfree(table); +err_alloc: + return -ENOMEM; +} + +static void ip6_frags_sysctl_unregister(struct net *net) +{ + struct ctl_table *table; + + table = net->ipv6.sysctl.frags_hdr->ctl_table_arg; + unregister_net_sysctl_table(net->ipv6.sysctl.frags_hdr); + kfree(table); } #else static inline int ip6_frags_sysctl_register(struct net *net) { return 0; } + +static inline void ip6_frags_sysctl_unregister(struct net *net) +{ +} #endif static int ipv6_frags_init_net(struct net *net) |