]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - net/core/net_namespace.c
genetlink: make netns aware
[mirror_ubuntu-artful-kernel.git] / net / core / net_namespace.c
CommitLineData
5f256bec
EB
1#include <linux/workqueue.h>
2#include <linux/rtnetlink.h>
3#include <linux/cache.h>
4#include <linux/slab.h>
5#include <linux/list.h>
6#include <linux/delay.h>
9dd776b6 7#include <linux/sched.h>
c93cf61f 8#include <linux/idr.h>
11a28d37 9#include <linux/rculist.h>
5f256bec 10#include <net/net_namespace.h>
dec827d1 11#include <net/netns/generic.h>
5f256bec
EB
12
13/*
14 * Our network namespace constructor/destructor lists
15 */
16
17static LIST_HEAD(pernet_list);
18static struct list_head *first_device = &pernet_list;
19static DEFINE_MUTEX(net_mutex);
20
5f256bec 21LIST_HEAD(net_namespace_list);
b76a461f 22EXPORT_SYMBOL_GPL(net_namespace_list);
5f256bec 23
5f256bec 24struct net init_net;
ff4b9502 25EXPORT_SYMBOL(init_net);
5f256bec 26
dec827d1
PE
27#define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */
28
5f256bec
EB
29/*
30 * setup_net runs the initializers for the network namespace object.
31 */
1a2ee93d 32static __net_init int setup_net(struct net *net)
5f256bec
EB
33{
34 /* Must be called with net_mutex held */
35 struct pernet_operations *ops;
486a87f1 36 int error = 0;
5f256bec 37
5f256bec 38 atomic_set(&net->count, 1);
486a87f1 39
5d1e4468 40#ifdef NETNS_REFCNT_DEBUG
5f256bec 41 atomic_set(&net->use_count, 0);
5d1e4468 42#endif
5f256bec 43
768f3591 44 list_for_each_entry(ops, &pernet_list, list) {
5f256bec
EB
45 if (ops->init) {
46 error = ops->init(net);
47 if (error < 0)
48 goto out_undo;
49 }
50 }
51out:
52 return error;
768f3591 53
5f256bec
EB
54out_undo:
55 /* Walk through the list backwards calling the exit functions
56 * for the pernet modules whose init functions did not fail.
57 */
768f3591 58 list_for_each_entry_continue_reverse(ops, &pernet_list, list) {
5f256bec
EB
59 if (ops->exit)
60 ops->exit(net);
61 }
310928d9
DL
62
63 rcu_barrier();
5f256bec
EB
64 goto out;
65}
66
486a87f1 67static struct net_generic *net_alloc_generic(void)
6a1a3b9f 68{
486a87f1
DL
69 struct net_generic *ng;
70 size_t generic_size = sizeof(struct net_generic) +
71 INITIAL_NET_GEN_PTRS * sizeof(void *);
72
73 ng = kzalloc(generic_size, GFP_KERNEL);
74 if (ng)
75 ng->len = INITIAL_NET_GEN_PTRS;
76
77 return ng;
6a1a3b9f
PE
78}
79
ebe47d47
CN
80#ifdef CONFIG_NET_NS
81static struct kmem_cache *net_cachep;
82static struct workqueue_struct *netns_wq;
83
486a87f1 84static struct net *net_alloc(void)
45a19b0a 85{
486a87f1
DL
86 struct net *net = NULL;
87 struct net_generic *ng;
88
89 ng = net_alloc_generic();
90 if (!ng)
91 goto out;
92
93 net = kmem_cache_zalloc(net_cachep, GFP_KERNEL);
45a19b0a 94 if (!net)
486a87f1 95 goto out_free;
45a19b0a 96
486a87f1
DL
97 rcu_assign_pointer(net->gen, ng);
98out:
99 return net;
100
101out_free:
102 kfree(ng);
103 goto out;
104}
105
106static void net_free(struct net *net)
107{
5d1e4468 108#ifdef NETNS_REFCNT_DEBUG
45a19b0a
JFS
109 if (unlikely(atomic_read(&net->use_count) != 0)) {
110 printk(KERN_EMERG "network namespace not free! Usage: %d\n",
111 atomic_read(&net->use_count));
112 return;
113 }
5d1e4468 114#endif
4ef079cc 115 kfree(net->gen);
45a19b0a
JFS
116 kmem_cache_free(net_cachep, net);
117}
118
088eb2d9 119static struct net *net_create(void)
9dd776b6 120{
088eb2d9
AD
121 struct net *net;
122 int rv;
9dd776b6 123
088eb2d9
AD
124 net = net_alloc();
125 if (!net)
126 return ERR_PTR(-ENOMEM);
9dd776b6 127 mutex_lock(&net_mutex);
088eb2d9
AD
128 rv = setup_net(net);
129 if (rv == 0) {
486a87f1 130 rtnl_lock();
11a28d37 131 list_add_tail_rcu(&net->list, &net_namespace_list);
486a87f1
DL
132 rtnl_unlock();
133 }
9dd776b6 134 mutex_unlock(&net_mutex);
088eb2d9
AD
135 if (rv < 0) {
136 net_free(net);
137 return ERR_PTR(rv);
138 }
139 return net;
140}
486a87f1 141
088eb2d9
AD
142struct net *copy_net_ns(unsigned long flags, struct net *old_net)
143{
144 if (!(flags & CLONE_NEWNET))
145 return get_net(old_net);
146 return net_create();
9dd776b6
EB
147}
148
6a1a3b9f
PE
149static void cleanup_net(struct work_struct *work)
150{
151 struct pernet_operations *ops;
152 struct net *net;
153
154 net = container_of(work, struct net, work);
155
156 mutex_lock(&net_mutex);
157
158 /* Don't let anyone else find us. */
159 rtnl_lock();
11a28d37 160 list_del_rcu(&net->list);
6a1a3b9f
PE
161 rtnl_unlock();
162
11a28d37
JB
163 /*
164 * Another CPU might be rcu-iterating the list, wait for it.
165 * This needs to be before calling the exit() notifiers, so
166 * the rcu_barrier() below isn't sufficient alone.
167 */
168 synchronize_rcu();
169
6a1a3b9f
PE
170 /* Run all of the network namespace exit methods */
171 list_for_each_entry_reverse(ops, &pernet_list, list) {
172 if (ops->exit)
173 ops->exit(net);
174 }
175
176 mutex_unlock(&net_mutex);
177
178 /* Ensure there are no outstanding rcu callbacks using this
179 * network namespace.
180 */
181 rcu_barrier();
182
183 /* Finally it is safe to free my network namespace structure */
184 net_free(net);
185}
186
187void __put_net(struct net *net)
188{
189 /* Cleanup the network namespace in process context */
190 INIT_WORK(&net->work, cleanup_net);
3ef1355d 191 queue_work(netns_wq, &net->work);
6a1a3b9f
PE
192}
193EXPORT_SYMBOL_GPL(__put_net);
194
195#else
196struct net *copy_net_ns(unsigned long flags, struct net *old_net)
197{
198 if (flags & CLONE_NEWNET)
199 return ERR_PTR(-EINVAL);
200 return old_net;
201}
202#endif
203
5f256bec
EB
204static int __init net_ns_init(void)
205{
486a87f1 206 struct net_generic *ng;
5f256bec 207
d57a9212 208#ifdef CONFIG_NET_NS
5f256bec
EB
209 net_cachep = kmem_cache_create("net_namespace", sizeof(struct net),
210 SMP_CACHE_BYTES,
211 SLAB_PANIC, NULL);
3ef1355d
BT
212
213 /* Create workqueue for cleanup */
214 netns_wq = create_singlethread_workqueue("netns");
215 if (!netns_wq)
216 panic("Could not create netns workq");
d57a9212 217#endif
3ef1355d 218
486a87f1
DL
219 ng = net_alloc_generic();
220 if (!ng)
221 panic("Could not allocate generic netns");
222
223 rcu_assign_pointer(init_net.gen, ng);
224
5f256bec 225 mutex_lock(&net_mutex);
ca0f3112
SH
226 if (setup_net(&init_net))
227 panic("Could not setup the initial network namespace");
5f256bec 228
f4618d39 229 rtnl_lock();
11a28d37 230 list_add_tail_rcu(&init_net.list, &net_namespace_list);
f4618d39 231 rtnl_unlock();
5f256bec
EB
232
233 mutex_unlock(&net_mutex);
5f256bec
EB
234
235 return 0;
236}
237
238pure_initcall(net_ns_init);
239
ed160e83 240#ifdef CONFIG_NET_NS
5f256bec
EB
241static int register_pernet_operations(struct list_head *list,
242 struct pernet_operations *ops)
243{
244 struct net *net, *undo_net;
245 int error;
246
5f256bec 247 list_add_tail(&ops->list, list);
1dba323b
PE
248 if (ops->init) {
249 for_each_net(net) {
5f256bec
EB
250 error = ops->init(net);
251 if (error)
252 goto out_undo;
253 }
254 }
1dba323b 255 return 0;
5f256bec
EB
256
257out_undo:
258 /* If I have an error cleanup all namespaces I initialized */
259 list_del(&ops->list);
1dba323b
PE
260 if (ops->exit) {
261 for_each_net(undo_net) {
262 if (undo_net == net)
263 goto undone;
5f256bec 264 ops->exit(undo_net);
1dba323b 265 }
5f256bec
EB
266 }
267undone:
1dba323b 268 return error;
5f256bec
EB
269}
270
271static void unregister_pernet_operations(struct pernet_operations *ops)
272{
273 struct net *net;
274
275 list_del(&ops->list);
1dba323b
PE
276 if (ops->exit)
277 for_each_net(net)
5f256bec
EB
278 ops->exit(net);
279}
280
ed160e83
DL
281#else
282
283static int register_pernet_operations(struct list_head *list,
284 struct pernet_operations *ops)
285{
286 if (ops->init == NULL)
287 return 0;
288 return ops->init(&init_net);
289}
290
291static void unregister_pernet_operations(struct pernet_operations *ops)
292{
293 if (ops->exit)
294 ops->exit(&init_net);
295}
296#endif
297
c93cf61f
PE
298static DEFINE_IDA(net_generic_ids);
299
5f256bec
EB
300/**
301 * register_pernet_subsys - register a network namespace subsystem
302 * @ops: pernet operations structure for the subsystem
303 *
304 * Register a subsystem which has init and exit functions
305 * that are called when network namespaces are created and
306 * destroyed respectively.
307 *
308 * When registered all network namespace init functions are
309 * called for every existing network namespace. Allowing kernel
310 * modules to have a race free view of the set of network namespaces.
311 *
312 * When a new network namespace is created all of the init
313 * methods are called in the order in which they were registered.
314 *
315 * When a network namespace is destroyed all of the exit methods
316 * are called in the reverse of the order with which they were
317 * registered.
318 */
319int register_pernet_subsys(struct pernet_operations *ops)
320{
321 int error;
322 mutex_lock(&net_mutex);
323 error = register_pernet_operations(first_device, ops);
324 mutex_unlock(&net_mutex);
325 return error;
326}
327EXPORT_SYMBOL_GPL(register_pernet_subsys);
328
329/**
330 * unregister_pernet_subsys - unregister a network namespace subsystem
331 * @ops: pernet operations structure to manipulate
332 *
333 * Remove the pernet operations structure from the list to be
53379e57 334 * used when network namespaces are created or destroyed. In
5f256bec
EB
335 * addition run the exit method for all existing network
336 * namespaces.
337 */
338void unregister_pernet_subsys(struct pernet_operations *module)
339{
340 mutex_lock(&net_mutex);
341 unregister_pernet_operations(module);
342 mutex_unlock(&net_mutex);
343}
344EXPORT_SYMBOL_GPL(unregister_pernet_subsys);
345
485ac57b
AD
346int register_pernet_gen_subsys(int *id, struct pernet_operations *ops)
347{
348 int rv;
349
350 mutex_lock(&net_mutex);
351again:
352 rv = ida_get_new_above(&net_generic_ids, 1, id);
353 if (rv < 0) {
354 if (rv == -EAGAIN) {
355 ida_pre_get(&net_generic_ids, GFP_KERNEL);
356 goto again;
357 }
358 goto out;
359 }
360 rv = register_pernet_operations(first_device, ops);
361 if (rv < 0)
362 ida_remove(&net_generic_ids, *id);
485ac57b 363out:
357f5b0b 364 mutex_unlock(&net_mutex);
485ac57b
AD
365 return rv;
366}
367EXPORT_SYMBOL_GPL(register_pernet_gen_subsys);
368
369void unregister_pernet_gen_subsys(int id, struct pernet_operations *ops)
370{
371 mutex_lock(&net_mutex);
372 unregister_pernet_operations(ops);
373 ida_remove(&net_generic_ids, id);
374 mutex_unlock(&net_mutex);
375}
376EXPORT_SYMBOL_GPL(unregister_pernet_gen_subsys);
377
5f256bec
EB
378/**
379 * register_pernet_device - register a network namespace device
380 * @ops: pernet operations structure for the subsystem
381 *
382 * Register a device which has init and exit functions
383 * that are called when network namespaces are created and
384 * destroyed respectively.
385 *
386 * When registered all network namespace init functions are
387 * called for every existing network namespace. Allowing kernel
388 * modules to have a race free view of the set of network namespaces.
389 *
390 * When a new network namespace is created all of the init
391 * methods are called in the order in which they were registered.
392 *
393 * When a network namespace is destroyed all of the exit methods
394 * are called in the reverse of the order with which they were
395 * registered.
396 */
397int register_pernet_device(struct pernet_operations *ops)
398{
399 int error;
400 mutex_lock(&net_mutex);
401 error = register_pernet_operations(&pernet_list, ops);
402 if (!error && (first_device == &pernet_list))
403 first_device = &ops->list;
404 mutex_unlock(&net_mutex);
405 return error;
406}
407EXPORT_SYMBOL_GPL(register_pernet_device);
408
c93cf61f
PE
409int register_pernet_gen_device(int *id, struct pernet_operations *ops)
410{
411 int error;
412 mutex_lock(&net_mutex);
413again:
414 error = ida_get_new_above(&net_generic_ids, 1, id);
415 if (error) {
416 if (error == -EAGAIN) {
417 ida_pre_get(&net_generic_ids, GFP_KERNEL);
418 goto again;
419 }
420 goto out;
421 }
422 error = register_pernet_operations(&pernet_list, ops);
423 if (error)
424 ida_remove(&net_generic_ids, *id);
425 else if (first_device == &pernet_list)
426 first_device = &ops->list;
427out:
428 mutex_unlock(&net_mutex);
429 return error;
430}
431EXPORT_SYMBOL_GPL(register_pernet_gen_device);
432
5f256bec
EB
433/**
434 * unregister_pernet_device - unregister a network namespace netdevice
435 * @ops: pernet operations structure to manipulate
436 *
437 * Remove the pernet operations structure from the list to be
53379e57 438 * used when network namespaces are created or destroyed. In
5f256bec
EB
439 * addition run the exit method for all existing network
440 * namespaces.
441 */
442void unregister_pernet_device(struct pernet_operations *ops)
443{
444 mutex_lock(&net_mutex);
445 if (&ops->list == first_device)
446 first_device = first_device->next;
447 unregister_pernet_operations(ops);
448 mutex_unlock(&net_mutex);
449}
450EXPORT_SYMBOL_GPL(unregister_pernet_device);
c93cf61f
PE
451
452void unregister_pernet_gen_device(int id, struct pernet_operations *ops)
453{
454 mutex_lock(&net_mutex);
455 if (&ops->list == first_device)
456 first_device = first_device->next;
457 unregister_pernet_operations(ops);
458 ida_remove(&net_generic_ids, id);
459 mutex_unlock(&net_mutex);
460}
461EXPORT_SYMBOL_GPL(unregister_pernet_gen_device);
dec827d1
PE
462
463static void net_generic_release(struct rcu_head *rcu)
464{
465 struct net_generic *ng;
466
467 ng = container_of(rcu, struct net_generic, rcu);
468 kfree(ng);
469}
470
471int net_assign_generic(struct net *net, int id, void *data)
472{
473 struct net_generic *ng, *old_ng;
474
475 BUG_ON(!mutex_is_locked(&net_mutex));
476 BUG_ON(id == 0);
477
478 ng = old_ng = net->gen;
479 if (old_ng->len >= id)
480 goto assign;
481
482 ng = kzalloc(sizeof(struct net_generic) +
483 id * sizeof(void *), GFP_KERNEL);
484 if (ng == NULL)
485 return -ENOMEM;
486
487 /*
488 * Some synchronisation notes:
489 *
490 * The net_generic explores the net->gen array inside rcu
491 * read section. Besides once set the net->gen->ptr[x]
492 * pointer never changes (see rules in netns/generic.h).
493 *
494 * That said, we simply duplicate this array and schedule
495 * the old copy for kfree after a grace period.
496 */
497
498 ng->len = id;
dec827d1
PE
499 memcpy(&ng->ptr, &old_ng->ptr, old_ng->len);
500
501 rcu_assign_pointer(net->gen, ng);
502 call_rcu(&old_ng->rcu, net_generic_release);
503assign:
504 ng->ptr[id - 1] = data;
505 return 0;
506}
507EXPORT_SYMBOL_GPL(net_assign_generic);