99bc9c4e45
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 <dlezcano@fr.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
173 lines
3.9 KiB
C
173 lines
3.9 KiB
C
/*
|
|
* sysctl_net_ipv6.c: sysctl interface to net IPV6 subsystem.
|
|
*
|
|
* Changes:
|
|
* YOSHIFUJI Hideaki @USAGI: added icmp sysctl table.
|
|
*/
|
|
|
|
#include <linux/mm.h>
|
|
#include <linux/sysctl.h>
|
|
#include <linux/in6.h>
|
|
#include <linux/ipv6.h>
|
|
#include <net/ndisc.h>
|
|
#include <net/ipv6.h>
|
|
#include <net/addrconf.h>
|
|
#include <net/inet_frag.h>
|
|
|
|
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_template
|
|
},
|
|
{
|
|
.ctl_name = NET_IPV6_ICMP,
|
|
.procname = "icmp",
|
|
.maxlen = 0,
|
|
.mode = 0555,
|
|
.child = ipv6_icmp_table_template
|
|
},
|
|
{
|
|
.ctl_name = NET_IPV6_BINDV6ONLY,
|
|
.procname = "bindv6only",
|
|
.data = &init_net.ipv6.sysctl.bindv6only,
|
|
.maxlen = sizeof(int),
|
|
.mode = 0644,
|
|
.proc_handler = &proc_dointvec
|
|
},
|
|
{
|
|
.ctl_name = NET_IPV6_IP6FRAG_HIGH_THRESH,
|
|
.procname = "ip6frag_high_thresh",
|
|
.data = &ip6_frags_ctl.high_thresh,
|
|
.maxlen = sizeof(int),
|
|
.mode = 0644,
|
|
.proc_handler = &proc_dointvec
|
|
},
|
|
{
|
|
.ctl_name = NET_IPV6_IP6FRAG_LOW_THRESH,
|
|
.procname = "ip6frag_low_thresh",
|
|
.data = &ip6_frags_ctl.low_thresh,
|
|
.maxlen = sizeof(int),
|
|
.mode = 0644,
|
|
.proc_handler = &proc_dointvec
|
|
},
|
|
{
|
|
.ctl_name = NET_IPV6_IP6FRAG_TIME,
|
|
.procname = "ip6frag_time",
|
|
.data = &ip6_frags_ctl.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 = &ip6_frags_ctl.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",
|
|
.data = &sysctl_mld_max_msf,
|
|
.maxlen = sizeof(int),
|
|
.mode = 0644,
|
|
.proc_handler = &proc_dointvec
|
|
},
|
|
{ .ctl_name = 0 }
|
|
};
|
|
|
|
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 int ipv6_sysctl_net_init(struct net *net)
|
|
{
|
|
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;
|
|
|
|
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)
|
|
return -ENOMEM;
|
|
|
|
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)
|
|
{
|
|
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 = {
|
|
.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_pernet_subsys(&ipv6_sysctl_net_ops);
|
|
}
|