00001 #include <linux/workqueue.h>
00002 #include <linux/rtnetlink.h>
00003 #include <linux/cache.h>
00004 #include <linux/slab.h>
00005 #include <linux/list.h>
00006 #include <linux/delay.h>
00007 #include <linux/sched.h>
00008 #include <linux/idr.h>
00009 #include <net/net_namespace.h>
00010 #include <net/netns/generic.h>
00011
00012
00013
00014
00015
00016 static LIST_HEAD(pernet_list);
00017 static struct list_head *first_device = &pernet_list;
00018 static DEFINE_MUTEX(net_mutex);
00019
00020 LIST_HEAD(net_namespace_list);
00021 EXPORT_SYMBOL_GPL(net_namespace_list);
00022
00023 struct net init_net;
00024 EXPORT_SYMBOL(init_net);
00025
00026 #define INITIAL_NET_GEN_PTRS 13
00027
00028
00029
00030
00031 static __net_init int setup_net(struct net *net)
00032 {
00033
00034 struct pernet_operations *ops;
00035 int error = 0;
00036
00037 atomic_set(&net->count, 1);
00038
00039 #ifdef NETNS_REFCNT_DEBUG
00040 atomic_set(&net->use_count, 0);
00041 #endif
00042
00043 list_for_each_entry(ops, &pernet_list, list) {
00044 if (ops->init) {
00045 error = ops->init(net);
00046 if (error < 0)
00047 goto out_undo;
00048 }
00049 }
00050 out:
00051 return error;
00052
00053 out_undo:
00054
00055
00056
00057 list_for_each_entry_continue_reverse(ops, &pernet_list, list) {
00058 if (ops->exit)
00059 ops->exit(net);
00060 }
00061
00062 #ifndef DDE_LINUX
00063 rcu_barrier();
00064 #endif
00065 goto out;
00066 }
00067
00068 static struct net_generic *net_alloc_generic(void)
00069 {
00070 struct net_generic *ng;
00071 size_t generic_size = sizeof(struct net_generic) +
00072 INITIAL_NET_GEN_PTRS * sizeof(void *);
00073
00074 ng = kzalloc(generic_size, GFP_KERNEL);
00075 if (ng)
00076 ng->len = INITIAL_NET_GEN_PTRS;
00077
00078 return ng;
00079 }
00080
00081 #ifdef CONFIG_NET_NS
00082 static struct kmem_cache *net_cachep;
00083 static struct workqueue_struct *netns_wq;
00084
00085 static struct net *net_alloc(void)
00086 {
00087 struct net *net = NULL;
00088 struct net_generic *ng;
00089
00090 ng = net_alloc_generic();
00091 if (!ng)
00092 goto out;
00093
00094 net = kmem_cache_zalloc(net_cachep, GFP_KERNEL);
00095 if (!net)
00096 goto out_free;
00097
00098 rcu_assign_pointer(net->gen, ng);
00099 out:
00100 return net;
00101
00102 out_free:
00103 kfree(ng);
00104 goto out;
00105 }
00106
00107 static void net_free(struct net *net)
00108 {
00109 #ifdef NETNS_REFCNT_DEBUG
00110 if (unlikely(atomic_read(&net->use_count) != 0)) {
00111 printk(KERN_EMERG "network namespace not free! Usage: %d\n",
00112 atomic_read(&net->use_count));
00113 return;
00114 }
00115 #endif
00116 kfree(net->gen);
00117 kmem_cache_free(net_cachep, net);
00118 }
00119
00120 struct net *copy_net_ns(unsigned long flags, struct net *old_net)
00121 {
00122 struct net *new_net = NULL;
00123 int err;
00124
00125 get_net(old_net);
00126
00127 if (!(flags & CLONE_NEWNET))
00128 return old_net;
00129
00130 err = -ENOMEM;
00131 new_net = net_alloc();
00132 if (!new_net)
00133 goto out_err;
00134
00135 mutex_lock(&net_mutex);
00136 err = setup_net(new_net);
00137 if (!err) {
00138 rtnl_lock();
00139 list_add_tail(&new_net->list, &net_namespace_list);
00140 rtnl_unlock();
00141 }
00142 mutex_unlock(&net_mutex);
00143
00144 if (err)
00145 goto out_free;
00146 out:
00147 put_net(old_net);
00148 return new_net;
00149
00150 out_free:
00151 net_free(new_net);
00152 out_err:
00153 new_net = ERR_PTR(err);
00154 goto out;
00155 }
00156
00157 static void cleanup_net(struct work_struct *work)
00158 {
00159 struct pernet_operations *ops;
00160 struct net *net;
00161
00162 net = container_of(work, struct net, work);
00163
00164 mutex_lock(&net_mutex);
00165
00166
00167 rtnl_lock();
00168 list_del(&net->list);
00169 rtnl_unlock();
00170
00171
00172 list_for_each_entry_reverse(ops, &pernet_list, list) {
00173 if (ops->exit)
00174 ops->exit(net);
00175 }
00176
00177 mutex_unlock(&net_mutex);
00178
00179
00180
00181
00182 rcu_barrier();
00183
00184
00185 net_free(net);
00186 }
00187
00188 void __put_net(struct net *net)
00189 {
00190
00191 INIT_WORK(&net->work, cleanup_net);
00192 queue_work(netns_wq, &net->work);
00193 }
00194 EXPORT_SYMBOL_GPL(__put_net);
00195
00196 #else
00197 struct net *copy_net_ns(unsigned long flags, struct net *old_net)
00198 {
00199 if (flags & CLONE_NEWNET)
00200 return ERR_PTR(-EINVAL);
00201 return old_net;
00202 }
00203 #endif
00204
00205 static int __init net_ns_init(void)
00206 {
00207 struct net_generic *ng;
00208 int err;
00209
00210 printk(KERN_INFO "net_namespace: %zd bytes\n", sizeof(struct net));
00211 #ifdef CONFIG_NET_NS
00212 net_cachep = kmem_cache_create("net_namespace", sizeof(struct net),
00213 SMP_CACHE_BYTES,
00214 SLAB_PANIC, NULL);
00215
00216
00217 netns_wq = create_singlethread_workqueue("netns");
00218 if (!netns_wq)
00219 panic("Could not create netns workq");
00220 #endif
00221
00222 ng = net_alloc_generic();
00223 if (!ng)
00224 panic("Could not allocate generic netns");
00225
00226 rcu_assign_pointer(init_net.gen, ng);
00227
00228 mutex_lock(&net_mutex);
00229 err = setup_net(&init_net);
00230
00231 rtnl_lock();
00232 list_add_tail(&init_net.list, &net_namespace_list);
00233 rtnl_unlock();
00234
00235 mutex_unlock(&net_mutex);
00236 if (err)
00237 panic("Could not setup the initial network namespace");
00238
00239 return 0;
00240 }
00241
00242 pure_initcall(net_ns_init);
00243
00244 #ifdef CONFIG_NET_NS
00245 static int register_pernet_operations(struct list_head *list,
00246 struct pernet_operations *ops)
00247 {
00248 struct net *net, *undo_net;
00249 int error;
00250
00251 list_add_tail(&ops->list, list);
00252 if (ops->init) {
00253 for_each_net(net) {
00254 error = ops->init(net);
00255 if (error)
00256 goto out_undo;
00257 }
00258 }
00259 return 0;
00260
00261 out_undo:
00262
00263 list_del(&ops->list);
00264 if (ops->exit) {
00265 for_each_net(undo_net) {
00266 if (undo_net == net)
00267 goto undone;
00268 ops->exit(undo_net);
00269 }
00270 }
00271 undone:
00272 return error;
00273 }
00274
00275 static void unregister_pernet_operations(struct pernet_operations *ops)
00276 {
00277 struct net *net;
00278
00279 list_del(&ops->list);
00280 if (ops->exit)
00281 for_each_net(net)
00282 ops->exit(net);
00283 }
00284
00285 #else
00286
00287 static int register_pernet_operations(struct list_head *list,
00288 struct pernet_operations *ops)
00289 {
00290 if (ops->init == NULL)
00291 return 0;
00292 return ops->init(&init_net);
00293 }
00294
00295 static void unregister_pernet_operations(struct pernet_operations *ops)
00296 {
00297 if (ops->exit)
00298 ops->exit(&init_net);
00299 }
00300 #endif
00301
00302 static DEFINE_IDA(net_generic_ids);
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 int register_pernet_subsys(struct pernet_operations *ops)
00324 {
00325 int error;
00326 mutex_lock(&net_mutex);
00327 error = register_pernet_operations(first_device, ops);
00328 mutex_unlock(&net_mutex);
00329 return error;
00330 }
00331 EXPORT_SYMBOL_GPL(register_pernet_subsys);
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 void unregister_pernet_subsys(struct pernet_operations *module)
00343 {
00344 mutex_lock(&net_mutex);
00345 unregister_pernet_operations(module);
00346 mutex_unlock(&net_mutex);
00347 }
00348 EXPORT_SYMBOL_GPL(unregister_pernet_subsys);
00349
00350 int register_pernet_gen_subsys(int *id, struct pernet_operations *ops)
00351 {
00352 int rv;
00353
00354 mutex_lock(&net_mutex);
00355 again:
00356 rv = ida_get_new_above(&net_generic_ids, 1, id);
00357 if (rv < 0) {
00358 if (rv == -EAGAIN) {
00359 ida_pre_get(&net_generic_ids, GFP_KERNEL);
00360 goto again;
00361 }
00362 goto out;
00363 }
00364 rv = register_pernet_operations(first_device, ops);
00365 if (rv < 0)
00366 ida_remove(&net_generic_ids, *id);
00367 out:
00368 mutex_unlock(&net_mutex);
00369 return rv;
00370 }
00371 EXPORT_SYMBOL_GPL(register_pernet_gen_subsys);
00372
00373 void unregister_pernet_gen_subsys(int id, struct pernet_operations *ops)
00374 {
00375 mutex_lock(&net_mutex);
00376 unregister_pernet_operations(ops);
00377 ida_remove(&net_generic_ids, id);
00378 mutex_unlock(&net_mutex);
00379 }
00380 EXPORT_SYMBOL_GPL(unregister_pernet_gen_subsys);
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 int register_pernet_device(struct pernet_operations *ops)
00402 {
00403 int error;
00404 mutex_lock(&net_mutex);
00405 error = register_pernet_operations(&pernet_list, ops);
00406 if (!error && (first_device == &pernet_list))
00407 first_device = &ops->list;
00408 mutex_unlock(&net_mutex);
00409 return error;
00410 }
00411 EXPORT_SYMBOL_GPL(register_pernet_device);
00412
00413 int register_pernet_gen_device(int *id, struct pernet_operations *ops)
00414 {
00415 int error;
00416 mutex_lock(&net_mutex);
00417 again:
00418 error = ida_get_new_above(&net_generic_ids, 1, id);
00419 if (error) {
00420 if (error == -EAGAIN) {
00421 ida_pre_get(&net_generic_ids, GFP_KERNEL);
00422 goto again;
00423 }
00424 goto out;
00425 }
00426 error = register_pernet_operations(&pernet_list, ops);
00427 if (error)
00428 ida_remove(&net_generic_ids, *id);
00429 else if (first_device == &pernet_list)
00430 first_device = &ops->list;
00431 out:
00432 mutex_unlock(&net_mutex);
00433 return error;
00434 }
00435 EXPORT_SYMBOL_GPL(register_pernet_gen_device);
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446 void unregister_pernet_device(struct pernet_operations *ops)
00447 {
00448 mutex_lock(&net_mutex);
00449 if (&ops->list == first_device)
00450 first_device = first_device->next;
00451 unregister_pernet_operations(ops);
00452 mutex_unlock(&net_mutex);
00453 }
00454 EXPORT_SYMBOL_GPL(unregister_pernet_device);
00455
00456 void unregister_pernet_gen_device(int id, struct pernet_operations *ops)
00457 {
00458 mutex_lock(&net_mutex);
00459 if (&ops->list == first_device)
00460 first_device = first_device->next;
00461 unregister_pernet_operations(ops);
00462 ida_remove(&net_generic_ids, id);
00463 mutex_unlock(&net_mutex);
00464 }
00465 EXPORT_SYMBOL_GPL(unregister_pernet_gen_device);
00466
00467 static void net_generic_release(struct rcu_head *rcu)
00468 {
00469 struct net_generic *ng;
00470
00471 ng = container_of(rcu, struct net_generic, rcu);
00472 kfree(ng);
00473 }
00474
00475 int net_assign_generic(struct net *net, int id, void *data)
00476 {
00477 struct net_generic *ng, *old_ng;
00478
00479 BUG_ON(!mutex_is_locked(&net_mutex));
00480 BUG_ON(id == 0);
00481
00482 ng = old_ng = net->gen;
00483 if (old_ng->len >= id)
00484 goto assign;
00485
00486 ng = kzalloc(sizeof(struct net_generic) +
00487 id * sizeof(void *), GFP_KERNEL);
00488 if (ng == NULL)
00489 return -ENOMEM;
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502 ng->len = id;
00503 memcpy(&ng->ptr, &old_ng->ptr, old_ng->len);
00504
00505 rcu_assign_pointer(net->gen, ng);
00506 call_rcu(&old_ng->rcu, net_generic_release);
00507 assign:
00508 ng->ptr[id - 1] = data;
00509 return 0;
00510 }
00511 EXPORT_SYMBOL_GPL(net_assign_generic);