mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
[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 <dlezcano@fr.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
89918fc270
commit
760f2d0186
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -14,20 +14,23 @@
|
||||
#include <net/addrconf.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,
|
||||
.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 = {
|
||||
|
Loading…
Reference in New Issue
Block a user