linux/net/ipv6/sysctl_net_ipv6.c
<<
>>
Prefs
   1/*
   2 * sysctl_net_ipv6.c: sysctl interface to net IPV6 subsystem.
   3 *
   4 * Changes:
   5 * YOSHIFUJI Hideaki @USAGI:    added icmp sysctl table.
   6 */
   7
   8#include <linux/mm.h>
   9#include <linux/sysctl.h>
  10#include <linux/in6.h>
  11#include <linux/ipv6.h>
  12#include <linux/slab.h>
  13#include <linux/export.h>
  14#include <net/ndisc.h>
  15#include <net/ipv6.h>
  16#include <net/addrconf.h>
  17#include <net/inet_frag.h>
  18
  19static ctl_table ipv6_table_template[] = {
  20        {
  21                .procname       = "bindv6only",
  22                .data           = &init_net.ipv6.sysctl.bindv6only,
  23                .maxlen         = sizeof(int),
  24                .mode           = 0644,
  25                .proc_handler   = proc_dointvec
  26        },
  27        { }
  28};
  29
  30static ctl_table ipv6_rotable[] = {
  31        {
  32                .procname       = "mld_max_msf",
  33                .data           = &sysctl_mld_max_msf,
  34                .maxlen         = sizeof(int),
  35                .mode           = 0644,
  36                .proc_handler   = proc_dointvec
  37        },
  38        { }
  39};
  40
  41static int __net_init ipv6_sysctl_net_init(struct net *net)
  42{
  43        struct ctl_table *ipv6_table;
  44        struct ctl_table *ipv6_route_table;
  45        struct ctl_table *ipv6_icmp_table;
  46        int err;
  47
  48        err = -ENOMEM;
  49        ipv6_table = kmemdup(ipv6_table_template, sizeof(ipv6_table_template),
  50                             GFP_KERNEL);
  51        if (!ipv6_table)
  52                goto out;
  53        ipv6_table[0].data = &net->ipv6.sysctl.bindv6only;
  54
  55        ipv6_route_table = ipv6_route_sysctl_init(net);
  56        if (!ipv6_route_table)
  57                goto out_ipv6_table;
  58
  59        ipv6_icmp_table = ipv6_icmp_sysctl_init(net);
  60        if (!ipv6_icmp_table)
  61                goto out_ipv6_route_table;
  62
  63        net->ipv6.sysctl.hdr = register_net_sysctl(net, "net/ipv6", ipv6_table);
  64        if (!net->ipv6.sysctl.hdr)
  65                goto out_ipv6_icmp_table;
  66
  67        net->ipv6.sysctl.route_hdr =
  68                register_net_sysctl(net, "net/ipv6/route", ipv6_route_table);
  69        if (!net->ipv6.sysctl.route_hdr)
  70                goto out_unregister_ipv6_table;
  71
  72        net->ipv6.sysctl.icmp_hdr =
  73                register_net_sysctl(net, "net/ipv6/icmp", ipv6_icmp_table);
  74        if (!net->ipv6.sysctl.icmp_hdr)
  75                goto out_unregister_route_table;
  76
  77        err = 0;
  78out:
  79        return err;
  80out_unregister_route_table:
  81        unregister_net_sysctl_table(net->ipv6.sysctl.route_hdr);
  82out_unregister_ipv6_table:
  83        unregister_net_sysctl_table(net->ipv6.sysctl.hdr);
  84out_ipv6_icmp_table:
  85        kfree(ipv6_icmp_table);
  86out_ipv6_route_table:
  87        kfree(ipv6_route_table);
  88out_ipv6_table:
  89        kfree(ipv6_table);
  90        goto out;
  91}
  92
  93static void __net_exit ipv6_sysctl_net_exit(struct net *net)
  94{
  95        struct ctl_table *ipv6_table;
  96        struct ctl_table *ipv6_route_table;
  97        struct ctl_table *ipv6_icmp_table;
  98
  99        ipv6_table = net->ipv6.sysctl.hdr->ctl_table_arg;
 100        ipv6_route_table = net->ipv6.sysctl.route_hdr->ctl_table_arg;
 101        ipv6_icmp_table = net->ipv6.sysctl.icmp_hdr->ctl_table_arg;
 102
 103        unregister_net_sysctl_table(net->ipv6.sysctl.icmp_hdr);
 104        unregister_net_sysctl_table(net->ipv6.sysctl.route_hdr);
 105        unregister_net_sysctl_table(net->ipv6.sysctl.hdr);
 106
 107        kfree(ipv6_table);
 108        kfree(ipv6_route_table);
 109        kfree(ipv6_icmp_table);
 110}
 111
 112static struct pernet_operations ipv6_sysctl_net_ops = {
 113        .init = ipv6_sysctl_net_init,
 114        .exit = ipv6_sysctl_net_exit,
 115};
 116
 117static struct ctl_table_header *ip6_header;
 118
 119int ipv6_sysctl_register(void)
 120{
 121        int err = -ENOMEM;
 122
 123        ip6_header = register_net_sysctl(&init_net, "net/ipv6", ipv6_rotable);
 124        if (ip6_header == NULL)
 125                goto out;
 126
 127        err = register_pernet_subsys(&ipv6_sysctl_net_ops);
 128        if (err)
 129                goto err_pernet;
 130out:
 131        return err;
 132
 133err_pernet:
 134        unregister_net_sysctl_table(ip6_header);
 135        goto out;
 136}
 137
 138void ipv6_sysctl_unregister(void)
 139{
 140        unregister_net_sysctl_table(ip6_header);
 141        unregister_pernet_subsys(&ipv6_sysctl_net_ops);
 142}
 143
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.