Commit 95bdfccb2bf4ea21c0065772c6a2c75cbaf6ad0d

Authored by Eric W. Biederman
Committed by David S. Miller
1 parent e51b6ba077

[NET]: Implement the per network namespace sysctl infrastructure

The user interface is: register_net_sysctl_table and
unregister_net_sysctl_table.  Very much like the current
interface except there is a network namespace parameter.

With this any sysctl registered with register_net_sysctl_table
will only show up to tasks in the same network namespace.

All other sysctls continue to be globally visible.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Cc: Serge Hallyn <serue@us.ibm.com>
Cc: Daniel Lezcano <dlezcano@fr.ibm.com>
Cc: Cedric Le Goater <clg@fr.ibm.com>
Cc: Pavel Emelyanov <xemul@openvz.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 2 changed files with 66 additions and 0 deletions Side-by-side Diff

include/net/net_namespace.h
... ... @@ -25,6 +25,8 @@
25 25 struct proc_dir_entry *proc_net_stat;
26 26 struct proc_dir_entry *proc_net_root;
27 27  
  28 + struct list_head sysctl_table_headers;
  29 +
28 30 struct net_device *loopback_dev; /* The loopback */
29 31  
30 32 struct list_head dev_base_head;
... ... @@ -143,6 +145,13 @@
143 145 extern void unregister_pernet_subsys(struct pernet_operations *);
144 146 extern int register_pernet_device(struct pernet_operations *);
145 147 extern void unregister_pernet_device(struct pernet_operations *);
  148 +
  149 +struct ctl_path;
  150 +struct ctl_table;
  151 +struct ctl_table_header;
  152 +extern struct ctl_table_header *register_net_sysctl_table(struct net *net,
  153 + const struct ctl_path *path, struct ctl_table *table);
  154 +extern void unregister_net_sysctl_table(struct ctl_table_header *header);
146 155  
147 156 #endif /* __NET_NET_NAMESPACE_H */
... ... @@ -14,6 +14,7 @@
14 14  
15 15 #include <linux/mm.h>
16 16 #include <linux/sysctl.h>
  17 +#include <linux/nsproxy.h>
17 18  
18 19 #include <net/sock.h>
19 20  
... ... @@ -54,4 +55,60 @@
54 55 #endif
55 56 { 0 },
56 57 };
  58 +
  59 +static struct list_head *
  60 +net_ctl_header_lookup(struct ctl_table_root *root, struct nsproxy *namespaces)
  61 +{
  62 + return &namespaces->net_ns->sysctl_table_headers;
  63 +}
  64 +
  65 +static struct ctl_table_root net_sysctl_root = {
  66 + .lookup = net_ctl_header_lookup,
  67 +};
  68 +
  69 +static int sysctl_net_init(struct net *net)
  70 +{
  71 + INIT_LIST_HEAD(&net->sysctl_table_headers);
  72 + return 0;
  73 +}
  74 +
  75 +static void sysctl_net_exit(struct net *net)
  76 +{
  77 + WARN_ON(!list_empty(&net->sysctl_table_headers));
  78 + return;
  79 +}
  80 +
  81 +static struct pernet_operations sysctl_pernet_ops = {
  82 + .init = sysctl_net_init,
  83 + .exit = sysctl_net_exit,
  84 +};
  85 +
  86 +static __init int sysctl_init(void)
  87 +{
  88 + int ret;
  89 + ret = register_pernet_subsys(&sysctl_pernet_ops);
  90 + if (ret)
  91 + goto out;
  92 + register_sysctl_root(&net_sysctl_root);
  93 +out:
  94 + return ret;
  95 +}
  96 +subsys_initcall(sysctl_init);
  97 +
  98 +struct ctl_table_header *register_net_sysctl_table(struct net *net,
  99 + const struct ctl_path *path, struct ctl_table *table)
  100 +{
  101 + struct nsproxy namespaces;
  102 + namespaces = *current->nsproxy;
  103 + namespaces.net_ns = net;
  104 + return __register_sysctl_paths(&net_sysctl_root,
  105 + &namespaces, path, table);
  106 +}
  107 +EXPORT_SYMBOL_GPL(register_net_sysctl_table);
  108 +
  109 +void unregister_net_sysctl_table(struct ctl_table_header *header)
  110 +{
  111 + return unregister_sysctl_table(header);
  112 +}
  113 +EXPORT_SYMBOL_GPL(unregister_net_sysctl_table);