]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ipv6/sysctl_net_ipv6.c
[NETFILTER]: Update modules' descriptions
[linux-2.6-omap-h63xx.git] / net / ipv6 / sysctl_net_ipv6.c
index 3fb44277207be3c8b318f93a1aa8d59e42227b1a..5e0af4d463249c7de484856cda94e23af8b88a28 100644 (file)
 #include <net/ndisc.h>
 #include <net/ipv6.h>
 #include <net/addrconf.h>
+#include <net/inet_frag.h>
 
-#ifdef CONFIG_SYSCTL
+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[] = {
+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,
                .procname       = "bindv6only",
-               .data           = &sysctl_ipv6_bindv6only,
+               .data           = &init_net.ipv6.sysctl.bindv6only,
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
@@ -41,7 +43,7 @@ static ctl_table ipv6_table[] = {
        {
                .ctl_name       = NET_IPV6_IP6FRAG_HIGH_THRESH,
                .procname       = "ip6frag_high_thresh",
-               .data           = &sysctl_ip6frag_high_thresh,
+               .data           = &init_net.ipv6.sysctl.frags.high_thresh,
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
@@ -49,7 +51,7 @@ static ctl_table ipv6_table[] = {
        {
                .ctl_name       = NET_IPV6_IP6FRAG_LOW_THRESH,
                .procname       = "ip6frag_low_thresh",
-               .data           = &sysctl_ip6frag_low_thresh,
+               .data           = &init_net.ipv6.sysctl.frags.low_thresh,
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
@@ -57,7 +59,7 @@ static ctl_table ipv6_table[] = {
        {
                .ctl_name       = NET_IPV6_IP6FRAG_TIME,
                .procname       = "ip6frag_time",
-               .data           = &sysctl_ip6frag_time,
+               .data           = &init_net.ipv6.sysctl.frags.timeout,
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
@@ -66,7 +68,7 @@ static ctl_table ipv6_table[] = {
        {
                .ctl_name       = NET_IPV6_IP6FRAG_SECRET_INTERVAL,
                .procname       = "ip6frag_secret_interval",
-               .data           = &sysctl_ip6frag_secret_interval,
+               .data           = &init_net.ipv6.sysctl.frags.secret_interval,
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
@@ -83,39 +85,110 @@ 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 }
+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 ctl_table ipv6_root_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = ipv6_net_table
-       },
-       { .ctl_name = 0 }
-};
-
-void ipv6_sysctl_register(void)
+static int ipv6_sysctl_net_init(struct net *net)
 {
-       ipv6_sysctl_header = register_sysctl_table(ipv6_root_table);
+       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_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_icmp_table[0].data = &net->ipv6.sysctl.icmpv6_time;
+       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;
+
+       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;
 }
 
-void ipv6_sysctl_unregister(void)
+static void ipv6_sysctl_net_exit(struct net *net)
 {
-       unregister_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;
 
-#endif /* CONFIG_SYSCTL */
+       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);
+}