Commit 95bdfccb2bf4ea21c0065772c6a2c75cbaf6ad0d
Committed by
David S. Miller
1 parent
e51b6ba077
Exists in
master
and in
7 other branches
[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 */ |
net/sysctl_net.c
... | ... | @@ -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); |