linux/net/sysctl_net.c
<<
>>
Prefs
   1/* -*- linux-c -*-
   2 * sysctl_net.c: sysctl interface to net subsystem.
   3 *
   4 * Begun April 1, 1996, Mike Shaver.
   5 * Added /proc/sys/net directories for each protocol family. [MS]
   6 *
   7 * Revision 1.2  1996/05/08  20:24:40  shaver
   8 * Added bits for NET_BRIDGE and the NET_IPV4_ARP stuff and
   9 * NET_IPV4_IP_FORWARD.
  10 *
  11 *
  12 */
  13
  14#include <linux/mm.h>
  15#include <linux/export.h>
  16#include <linux/sysctl.h>
  17#include <linux/nsproxy.h>
  18
  19#include <net/sock.h>
  20
  21#ifdef CONFIG_INET
  22#include <net/ip.h>
  23#endif
  24
  25#ifdef CONFIG_NET
  26#include <linux/if_ether.h>
  27#endif
  28
  29#ifdef CONFIG_TR
  30#include <linux/if_tr.h>
  31#endif
  32
  33static struct ctl_table_set *
  34net_ctl_header_lookup(struct ctl_table_root *root, struct nsproxy *namespaces)
  35{
  36        return &namespaces->net_ns->sysctls;
  37}
  38
  39static int is_seen(struct ctl_table_set *set)
  40{
  41        return &current->nsproxy->net_ns->sysctls == set;
  42}
  43
  44/* Return standard mode bits for table entry. */
  45static int net_ctl_permissions(struct ctl_table_root *root,
  46                               struct nsproxy *nsproxy,
  47                               struct ctl_table *table)
  48{
  49        /* Allow network administrator to have same access as root. */
  50        if (capable(CAP_NET_ADMIN)) {
  51                int mode = (table->mode >> 6) & 7;
  52                return (mode << 6) | (mode << 3) | mode;
  53        }
  54        return table->mode;
  55}
  56
  57static struct ctl_table_root net_sysctl_root = {
  58        .lookup = net_ctl_header_lookup,
  59        .permissions = net_ctl_permissions,
  60};
  61
  62static int net_ctl_ro_header_perms(struct ctl_table_root *root,
  63                struct nsproxy *namespaces, struct ctl_table *table)
  64{
  65        if (net_eq(namespaces->net_ns, &init_net))
  66                return table->mode;
  67        else
  68                return table->mode & ~0222;
  69}
  70
  71static struct ctl_table_root net_sysctl_ro_root = {
  72        .permissions = net_ctl_ro_header_perms,
  73};
  74
  75static int __net_init sysctl_net_init(struct net *net)
  76{
  77        setup_sysctl_set(&net->sysctls,
  78                         &net_sysctl_ro_root.default_set,
  79                         is_seen);
  80        return 0;
  81}
  82
  83static void __net_exit sysctl_net_exit(struct net *net)
  84{
  85        WARN_ON(!list_empty(&net->sysctls.list));
  86}
  87
  88static struct pernet_operations sysctl_pernet_ops = {
  89        .init = sysctl_net_init,
  90        .exit = sysctl_net_exit,
  91};
  92
  93static __init int sysctl_init(void)
  94{
  95        int ret;
  96        ret = register_pernet_subsys(&sysctl_pernet_ops);
  97        if (ret)
  98                goto out;
  99        register_sysctl_root(&net_sysctl_root);
 100        setup_sysctl_set(&net_sysctl_ro_root.default_set, NULL, NULL);
 101        register_sysctl_root(&net_sysctl_ro_root);
 102out:
 103        return ret;
 104}
 105subsys_initcall(sysctl_init);
 106
 107struct ctl_table_header *register_net_sysctl_table(struct net *net,
 108        const struct ctl_path *path, struct ctl_table *table)
 109{
 110        struct nsproxy namespaces;
 111        namespaces = *current->nsproxy;
 112        namespaces.net_ns = net;
 113        return __register_sysctl_paths(&net_sysctl_root,
 114                                        &namespaces, path, table);
 115}
 116EXPORT_SYMBOL_GPL(register_net_sysctl_table);
 117
 118struct ctl_table_header *register_net_sysctl_rotable(const
 119                struct ctl_path *path, struct ctl_table *table)
 120{
 121        return __register_sysctl_paths(&net_sysctl_ro_root,
 122                        &init_nsproxy, path, table);
 123}
 124EXPORT_SYMBOL_GPL(register_net_sysctl_rotable);
 125
 126void unregister_net_sysctl_table(struct ctl_table_header *header)
 127{
 128        unregister_sysctl_table(header);
 129}
 130EXPORT_SYMBOL_GPL(unregister_net_sysctl_table);
 131