linux/net/core/net_namespace.c
<<
>>
Prefs
   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>
   7#include <linux/sched.h>
   8#include <net/net_namespace.h>
   9
  10/*
  11 *      Our network namespace constructor/destructor lists
  12 */
  13
  14static LIST_HEAD(pernet_list);
  15static struct list_head *first_device = &pernet_list;
  16static DEFINE_MUTEX(net_mutex);
  17
  18LIST_HEAD(net_namespace_list);
  19
  20struct net init_net;
  21EXPORT_SYMBOL(init_net);
  22
  23/*
  24 * setup_net runs the initializers for the network namespace object.
  25 */
  26static __net_init int setup_net(struct net *net)
  27{
  28        /* Must be called with net_mutex held */
  29        struct pernet_operations *ops;
  30        int error;
  31
  32        atomic_set(&net->count, 1);
  33        atomic_set(&net->use_count, 0);
  34
  35        error = 0;
  36        list_for_each_entry(ops, &pernet_list, list) {
  37                if (ops->init) {
  38                        error = ops->init(net);
  39                        if (error < 0)
  40                                goto out_undo;
  41                }
  42        }
  43out:
  44        return error;
  45
  46out_undo:
  47        /* Walk through the list backwards calling the exit functions
  48         * for the pernet modules whose init functions did not fail.
  49         */
  50        list_for_each_entry_continue_reverse(ops, &pernet_list, list) {
  51                if (ops->exit)
  52                        ops->exit(net);
  53        }
  54
  55        rcu_barrier();
  56        goto out;
  57}
  58
  59#ifdef CONFIG_NET_NS
  60static struct kmem_cache *net_cachep;
  61
  62static struct net *net_alloc(void)
  63{
  64        return kmem_cache_zalloc(net_cachep, GFP_KERNEL);
  65}
  66
  67static void net_free(struct net *net)
  68{
  69        if (!net)
  70                return;
  71
  72        if (unlikely(atomic_read(&net->use_count) != 0)) {
  73                printk(KERN_EMERG "network namespace not free! Usage: %d\n",
  74                        atomic_read(&net->use_count));
  75                return;
  76        }
  77
  78        kmem_cache_free(net_cachep, net);
  79}
  80
  81struct net *copy_net_ns(unsigned long flags, struct net *old_net)
  82{
  83        struct net *new_net = NULL;
  84        int err;
  85
  86        get_net(old_net);
  87
  88        if (!(flags & CLONE_NEWNET))
  89                return old_net;
  90
  91        err = -ENOMEM;
  92        new_net = net_alloc();
  93        if (!new_net)
  94                goto out;
  95
  96        mutex_lock(&net_mutex);
  97        err = setup_net(new_net);
  98        if (err)
  99                goto out_unlock;
 100
 101        rtnl_lock();
 102        list_add_tail(&new_net->list, &net_namespace_list);
 103        rtnl_unlock();
 104
 105
 106out_unlock:
 107        mutex_unlock(&net_mutex);
 108out:
 109        put_net(old_net);
 110        if (err) {
 111                net_free(new_net);
 112                new_net = ERR_PTR(err);
 113        }
 114        return new_net;
 115}
 116
 117static void cleanup_net(struct work_struct *work)
 118{
 119        struct pernet_operations *ops;
 120        struct net *net;
 121
 122        net = container_of(work, struct net, work);
 123
 124        mutex_lock(&net_mutex);
 125
 126        /* Don't let anyone else find us. */
 127        rtnl_lock();
 128        list_del(&net->list);
 129        rtnl_unlock();
 130
 131        /* Run all of the network namespace exit methods */
 132        list_for_each_entry_reverse(ops, &pernet_list, list) {
 133                if (ops->exit)
 134                        ops->exit(net);
 135        }
 136
 137        mutex_unlock(&net_mutex);
 138
 139        /* Ensure there are no outstanding rcu callbacks using this
 140         * network namespace.
 141         */
 142        rcu_barrier();
 143
 144        /* Finally it is safe to free my network namespace structure */
 145        net_free(net);
 146}
 147
 148void __put_net(struct net *net)
 149{
 150        /* Cleanup the network namespace in process context */
 151        INIT_WORK(&net->work, cleanup_net);
 152        schedule_work(&net->work);
 153}
 154EXPORT_SYMBOL_GPL(__put_net);
 155
 156#else
 157struct net *copy_net_ns(unsigned long flags, struct net *old_net)
 158{
 159        if (flags & CLONE_NEWNET)
 160                return ERR_PTR(-EINVAL);
 161        return old_net;
 162}
 163#endif
 164
 165static int __init net_ns_init(void)
 166{
 167        int err;
 168
 169        printk(KERN_INFO "net_namespace: %zd bytes\n", sizeof(struct net));
 170#ifdef CONFIG_NET_NS
 171        net_cachep = kmem_cache_create("net_namespace", sizeof(struct net),
 172                                        SMP_CACHE_BYTES,
 173                                        SLAB_PANIC, NULL);
 174#endif
 175        mutex_lock(&net_mutex);
 176        err = setup_net(&init_net);
 177
 178        rtnl_lock();
 179        list_add_tail(&init_net.list, &net_namespace_list);
 180        rtnl_unlock();
 181
 182        mutex_unlock(&net_mutex);
 183        if (err)
 184                panic("Could not setup the initial network namespace");
 185
 186        return 0;
 187}
 188
 189pure_initcall(net_ns_init);
 190
 191#ifdef CONFIG_NET_NS
 192static int register_pernet_operations(struct list_head *list,
 193                                      struct pernet_operations *ops)
 194{
 195        struct net *net, *undo_net;
 196        int error;
 197
 198        list_add_tail(&ops->list, list);
 199        if (ops->init) {
 200                for_each_net(net) {
 201                        error = ops->init(net);
 202                        if (error)
 203                                goto out_undo;
 204                }
 205        }
 206        return 0;
 207
 208out_undo:
 209        /* If I have an error cleanup all namespaces I initialized */
 210        list_del(&ops->list);
 211        if (ops->exit) {
 212                for_each_net(undo_net) {
 213                        if (undo_net == net)
 214                                goto undone;
 215                        ops->exit(undo_net);
 216                }
 217        }
 218undone:
 219        return error;
 220}
 221
 222static void unregister_pernet_operations(struct pernet_operations *ops)
 223{
 224        struct net *net;
 225
 226        list_del(&ops->list);
 227        if (ops->exit)
 228                for_each_net(net)
 229                        ops->exit(net);
 230}
 231
 232#else
 233
 234static int register_pernet_operations(struct list_head *list,
 235                                      struct pernet_operations *ops)
 236{
 237        if (ops->init == NULL)
 238                return 0;
 239        return ops->init(&init_net);
 240}
 241
 242static void unregister_pernet_operations(struct pernet_operations *ops)
 243{
 244        if (ops->exit)
 245                ops->exit(&init_net);
 246}
 247#endif
 248
 249/**
 250 *      register_pernet_subsys - register a network namespace subsystem
 251 *      @ops:  pernet operations structure for the subsystem
 252 *
 253 *      Register a subsystem which has init and exit functions
 254 *      that are called when network namespaces are created and
 255 *      destroyed respectively.
 256 *
 257 *      When registered all network namespace init functions are
 258 *      called for every existing network namespace.  Allowing kernel
 259 *      modules to have a race free view of the set of network namespaces.
 260 *
 261 *      When a new network namespace is created all of the init
 262 *      methods are called in the order in which they were registered.
 263 *
 264 *      When a network namespace is destroyed all of the exit methods
 265 *      are called in the reverse of the order with which they were
 266 *      registered.
 267 */
 268int register_pernet_subsys(struct pernet_operations *ops)
 269{
 270        int error;
 271        mutex_lock(&net_mutex);
 272        error =  register_pernet_operations(first_device, ops);
 273        mutex_unlock(&net_mutex);
 274        return error;
 275}
 276EXPORT_SYMBOL_GPL(register_pernet_subsys);
 277
 278/**
 279 *      unregister_pernet_subsys - unregister a network namespace subsystem
 280 *      @ops: pernet operations structure to manipulate
 281 *
 282 *      Remove the pernet operations structure from the list to be
 283 *      used when network namespaces are created or destoryed.  In
 284 *      addition run the exit method for all existing network
 285 *      namespaces.
 286 */
 287void unregister_pernet_subsys(struct pernet_operations *module)
 288{
 289        mutex_lock(&net_mutex);
 290        unregister_pernet_operations(module);
 291        mutex_unlock(&net_mutex);
 292}
 293EXPORT_SYMBOL_GPL(unregister_pernet_subsys);
 294
 295/**
 296 *      register_pernet_device - register a network namespace device
 297 *      @ops:  pernet operations structure for the subsystem
 298 *
 299 *      Register a device which has init and exit functions
 300 *      that are called when network namespaces are created and
 301 *      destroyed respectively.
 302 *
 303 *      When registered all network namespace init functions are
 304 *      called for every existing network namespace.  Allowing kernel
 305 *      modules to have a race free view of the set of network namespaces.
 306 *
 307 *      When a new network namespace is created all of the init
 308 *      methods are called in the order in which they were registered.
 309 *
 310 *      When a network namespace is destroyed all of the exit methods
 311 *      are called in the reverse of the order with which they were
 312 *      registered.
 313 */
 314int register_pernet_device(struct pernet_operations *ops)
 315{
 316        int error;
 317        mutex_lock(&net_mutex);
 318        error = register_pernet_operations(&pernet_list, ops);
 319        if (!error && (first_device == &pernet_list))
 320                first_device = &ops->list;
 321        mutex_unlock(&net_mutex);
 322        return error;
 323}
 324EXPORT_SYMBOL_GPL(register_pernet_device);
 325
 326/**
 327 *      unregister_pernet_device - unregister a network namespace netdevice
 328 *      @ops: pernet operations structure to manipulate
 329 *
 330 *      Remove the pernet operations structure from the list to be
 331 *      used when network namespaces are created or destoryed.  In
 332 *      addition run the exit method for all existing network
 333 *      namespaces.
 334 */
 335void unregister_pernet_device(struct pernet_operations *ops)
 336{
 337        mutex_lock(&net_mutex);
 338        if (&ops->list == first_device)
 339                first_device = first_device->next;
 340        unregister_pernet_operations(ops);
 341        mutex_unlock(&net_mutex);
 342}
 343EXPORT_SYMBOL_GPL(unregister_pernet_device);
 344