Commit 760f2d01 authored by Daniel Lezcano's avatar Daniel Lezcano Committed by David S. Miller

[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: default avatarDaniel Lezcano <dlezcano@fr.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 89918fc2
...@@ -619,8 +619,8 @@ static inline int snmp6_unregister_dev(struct inet6_dev *idev) ...@@ -619,8 +619,8 @@ static inline int snmp6_unregister_dev(struct inet6_dev *idev)
#endif #endif
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
extern ctl_table ipv6_route_table[]; extern ctl_table ipv6_route_table_template[];
extern ctl_table ipv6_icmp_table[]; extern ctl_table ipv6_icmp_table_template[];
extern int ipv6_sysctl_register(void); extern int ipv6_sysctl_register(void);
extern void ipv6_sysctl_unregister(void); extern void ipv6_sysctl_unregister(void);
......
...@@ -5,6 +5,15 @@ ...@@ -5,6 +5,15 @@
#ifndef __NETNS_IPV6_H__ #ifndef __NETNS_IPV6_H__
#define __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_ipv6 {
struct netns_sysctl_ipv6 sysctl;
}; };
#endif #endif
...@@ -907,7 +907,7 @@ int icmpv6_err_convert(int type, int code, int *err) ...@@ -907,7 +907,7 @@ int icmpv6_err_convert(int type, int code, int *err)
EXPORT_SYMBOL(icmpv6_err_convert); EXPORT_SYMBOL(icmpv6_err_convert);
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
ctl_table ipv6_icmp_table[] = { ctl_table ipv6_icmp_table_template[] = {
{ {
.ctl_name = NET_IPV6_ICMP_RATELIMIT, .ctl_name = NET_IPV6_ICMP_RATELIMIT,
.procname = "ratelimit", .procname = "ratelimit",
...@@ -918,5 +918,15 @@ ctl_table ipv6_icmp_table[] = { ...@@ -918,5 +918,15 @@ ctl_table ipv6_icmp_table[] = {
}, },
{ .ctl_name = 0 }, { .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 #endif
...@@ -2409,7 +2409,7 @@ int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp, ...@@ -2409,7 +2409,7 @@ int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp,
return -EINVAL; return -EINVAL;
} }
ctl_table ipv6_route_table[] = { ctl_table ipv6_route_table_template[] = {
{ {
.procname = "flush", .procname = "flush",
.data = &flush_delay, .data = &flush_delay,
...@@ -2499,6 +2499,15 @@ ctl_table ipv6_route_table[] = { ...@@ -2499,6 +2499,15 @@ ctl_table ipv6_route_table[] = {
{ .ctl_name = 0 } { .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 #endif
int __init ip6_route_init(void) int __init ip6_route_init(void)
......
...@@ -14,20 +14,23 @@ ...@@ -14,20 +14,23 @@
#include <net/addrconf.h> #include <net/addrconf.h>
#include <net/inet_frag.h> #include <net/inet_frag.h>
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, .ctl_name = NET_IPV6_ROUTE,
.procname = "route", .procname = "route",
.maxlen = 0, .maxlen = 0,
.mode = 0555, .mode = 0555,
.child = ipv6_route_table .child = ipv6_route_table_template
}, },
{ {
.ctl_name = NET_IPV6_ICMP, .ctl_name = NET_IPV6_ICMP,
.procname = "icmp", .procname = "icmp",
.maxlen = 0, .maxlen = 0,
.mode = 0555, .mode = 0555,
.child = ipv6_icmp_table .child = ipv6_icmp_table_template
}, },
{ {
.ctl_name = NET_IPV6_BINDV6ONLY, .ctl_name = NET_IPV6_BINDV6ONLY,
...@@ -89,22 +92,66 @@ struct ctl_path net_ipv6_ctl_path[] = { ...@@ -89,22 +92,66 @@ struct ctl_path net_ipv6_ctl_path[] = {
}; };
EXPORT_SYMBOL_GPL(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) static int ipv6_sysctl_net_init(struct net *net)
{ {
ipv6_sysctl_header = register_net_sysctl_table(net, net_ipv6_ctl_path, 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); ipv6_table);
if (!ipv6_sysctl_header) if (!net->ipv6.sysctl.table)
return -ENOMEM; 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) 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 = { static struct pernet_operations ipv6_sysctl_net_ops = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment