Home » Mailing lists » Devel » [PATCH 00/16] core network namespace support
[PATCH 03/16] net: Basic network namespace infrastructure. [message #19969 is a reply to message #19968] |
Sat, 08 September 2007 21:15 |
ebiederm
Messages: 1354 Registered: February 2006
|
Senior Member |
|
|
This is the basic infrastructure needed to support network
namespaces. This infrastructure is:
- Registration functions to support initializing per network
namespace data when a network namespaces is created or destroyed.
- struct net. The network namespace data structure.
This structure will grow as variables are made per network
namespace but this is the minimal starting point.
- Functions to grab a reference to the network namespace.
I provide both get/put functions that keep a network namespace
from being freed. And hold/release functions serve as weak references
and will warn if their count is not zero when the data structure
is freed. Useful for dealing with more complicated data structures
like the ipv4 route cache.
- A list of all of the network namespaces so we can iterate over them.
- A slab for the network namespace data structure allowing leaks
to be spotted.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
include/net/net_namespace.h | 68 ++++++++++
net/core/Makefile | 2 +-
net/core/net_namespace.c | 292 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 361 insertions(+), 1 deletions(-)
create mode 100644 include/net/net_namespace.h
create mode 100644 net/core/net_namespace.c
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
new file mode 100644
index 0000000..6344b77
--- /dev/null
+++ b/include/net/net_namespace.h
@@ -0,0 +1,68 @@
+/*
+ * Operations on the network namespace
+ */
+#ifndef __NET_NET_NAMESPACE_H
+#define __NET_NET_NAMESPACE_H
+
+#include <asm/atomic.h>
+#include <linux/workqueue.h>
+#include <linux/list.h>
+
+struct net {
+ atomic_t count; /* To decided when the network
+ * namespace should be freed.
+ */
+ atomic_t use_count; /* To track references we
+ * destroy on demand
+ */
+ struct list_head list; /* list of network namespaces */
+ struct work_struct work; /* work struct for freeing */
+};
+
+extern struct net init_net;
+extern struct list_head net_namespace_list;
+
+extern void __put_net(struct net *net);
+
+static inline struct net *get_net(struct net *net)
+{
+ atomic_inc(&net->count);
+ return net;
+}
+
+static inline void put_net(struct net *net)
+{
+ if (atomic_dec_and_test(&net->count))
+ __put_net(net);
+}
+
+static inline struct net *hold_net(struct net *net)
+{
+ atomic_inc(&net->use_count);
+ return net;
+}
+
+static inline void release_net(struct net *net)
+{
+ atomic_dec(&net->use_count);
+}
+
+extern void net_lock(void);
+extern void net_unlock(void);
+
+#define for_each_net(VAR) \
+ list_for_each_entry(VAR, &net_namespace_list, list)
+
+
+struct pernet_operations {
+ struct list_head list;
+ int (*init)(struct net *net);
+ void (*exit)(struct net *net);
+};
+
+extern int register_pernet_subsys(struct pernet_operations *);
+extern void unregister_pernet_subsys(struct pernet_operations *);
+extern int register_pernet_device(struct pernet_operations *);
+extern void unregister_pernet_device(struct pernet_operations *);
+
+#endif /* __NET_NET_NAMESPACE_H */
diff --git a/net/core/Makefile b/net/core/Makefile
index 4751613..ea9b3f3 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -3,7 +3,7 @@
#
obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \
- gen_stats.o gen_estimator.o
+ gen_stats.o gen_estimator.o net_namespace.o
obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
new file mode 100644
index 0000000..f259a9b
--- /dev/null
+++ b/net/core/net_namespace.c
@@ -0,0 +1,292 @@
+#include <linux/workqueue.h>
+#include <linux/rtnetlink.h>
+#include <linux/cache.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <net/net_namespace.h>
+
+/*
+ * Our network namespace constructor/destructor lists
+ */
+
+static LIST_HEAD(pernet_list);
+static struct list_head *first_device = &pernet_list;
+static DEFINE_MUTEX(net_mutex);
+
+static DEFINE_MUTEX(net_list_mutex);
+LIST_HEAD(net_namespace_list);
+
+static struct kmem_cache *net_cachep;
+
+struct net init_net;
+EXPORT_SYMBOL_GPL(init_net);
+
+void net_lock(void)
+{
+ mutex_lock(&net_list_mutex);
+}
+
+void net_unlock(void)
+{
+ mutex_unlock(&net_list_mutex);
+}
+
+static struct net *net_alloc(void)
+{
+ return kmem_cache_alloc(net_cachep, GFP_KERNEL);
+}
+
+static void net_free(struct net *net)
+{
+ if (!net)
+ return;
+
+ if (unlikely(atomic_read(&net->use_count) != 0)) {
+ printk(KERN_EMERG "network namespace not free! Usage: %d\n",
+ atomic_read(&net->use_count));
+ return;
+ }
+
+ kmem_cache_free(net_cachep, net);
+}
+
+static void cleanup_net(struct work_struct *work)
+{
+ struct pernet_operations *ops;
+ struct list_head *ptr;
+ struct net *net;
+
+ net = container_of(work, struct net, work);
+
+ mutex_lock(&net_mutex);
+
+ /* Don't let anyone else find us. */
+ net_lock();
+ list_del(&net->list);
+ net_unlock();
+
+ /* Run all of the network namespace exit methods */
+ list_for_each_prev(ptr, &pernet_list) {
+ ops = list_entry(ptr, struct pernet_operations, list);
+ if (ops->exit)
+ ops->exit(net);
+ }
+
+ mutex_unlock(&net_mutex);
+
+ /* Ensure there are no outstanding rcu callbacks using this
+ * network namespace.
+ */
+ rcu_barrier();
+
+ /* Finally it is safe to free my network namespace structure */
+ net_free(net);
+}
+
+
+void __put_net(struct net *net)
+{
+ /* Cleanup the network namespace in process context */
+ INIT_WORK(&net->work, cleanup_net);
+ schedule_work(&net->work);
+}
+EXPORT_SYMBOL_GPL(__put_net);
+
+/*
+ * setup_net runs the initializers for the network namespace object.
+ */
+static int setup_net(struct net *net)
+{
+ /* Must be called with net_mutex held */
+ struct pernet_operations *ops;
+ struct list_head *ptr;
+ int error;
+
+ memset(net, 0, sizeof(struct net));
+ atomic_set(&net->count, 1);
+ atomic_set(&net->use_count, 0);
+
+ error = 0;
+ list_for_each(ptr, &pernet_list) {
+ ops = list_entry(ptr, struct pernet_operations, list);
+ if (ops->init) {
+ error = ops->init(net);
+ if (error < 0)
+ goto out_undo;
+ }
+ }
+out:
+ return error;
+out_undo:
+ /* Walk through the list backwards calling the exit functions
+ * for the pernet modules whose init functions did not fail.
+ */
+ for (ptr = ptr->prev; ptr != &pernet_list; ptr = ptr->prev) {
+ ops = list_entry(ptr, struct pernet_operations, list);
+ if (ops->exit)
+ ops->exit(net);
+ }
+ goto out;
+}
+
+static int __init net_ns_init(void)
+{
+ int err;
+
+ printk(KERN_INFO "net_namespace: %zd bytes\n", sizeof(struct net));
+ net_cachep = kmem_cache_create("net_namespace", sizeof(struct net),
+ SMP_CACHE_BYTES,
+ SLAB_PANIC, NULL);
+ mutex_lock(&net_mutex);
+ err = setup_net(&init_net);
+
+ net_lock();
+ list_add_tail(&init_net.list, &net_namespace_list);
+ net_unlock();
+
+ mutex_unlock(&net_mutex);
+ if (err)
+ panic("Could not setup the initial network namespace");
+
+ return 0;
+}
+
+pure_initcall(net_ns_init);
+
+static int register_pernet_operations(struct list_head *list,
+ struct pernet_operations *ops)
+{
+ struct net *net, *undo_net;
+ int error;
+
+ error = 0;
+ list_add_tail(&ops->list, list);
+ for_each_net(net) {
+ if (ops->init) {
+ error = ops->init(net);
+ if (error)
+ goto out_undo;
+ }
+ }
+out:
+ return error;
+
+out_undo:
+ /* If I have an error cleanup all namespaces I initialized */
+ list_del(&ops->list);
+ for_each_net(undo_net) {
+ if (undo_net == net)
+ goto undone;
+ if (ops->exit)
+ ops->exit(undo_net);
+ }
+undone:
+ goto out;
+}
+
+static void unregister_pernet_operations(struct pernet_operations *ops)
+{
+ struct net *net;
+
+ list_del(&ops->list);
+ for_each_net(net)
+ if (ops->exit)
+ ops->exit(net);
+}
+
+/**
+ * register_pernet_subsys - register a network namespace subsystem
+ * @ops: pernet operations structure for the subsystem
+ *
+ * Register a subsystem which has init and exit functions
+ * that are called when network namespaces are created and
+ * destroyed respectively.
+ *
+ * When registered all network namespace init functions are
+ * called for every existing network namespace. Allowing kernel
+ * modules to have a race free view of the set of network namespaces.
+ *
+ * When a new network namespace is created all of the init
+ * methods are called in the order in which they were registered.
+ *
+ * When a network namespace is destroyed all of the exit methods
+ * are called in the reverse of the order with which they were
+ * registered.
+ */
+int register_pernet_subsys(struct pernet_operations *ops)
+{
+ int error;
+ mutex_lock(&net_mutex);
+ error = register_pernet_operations(first_device, ops);
+ mutex_unlock(&net_mutex);
+ return error;
+}
+EXPORT_SYMBOL_GPL(register_pernet_subsys);
+
+/**
+ * unregister_pernet_subsys - unregister a network namespace subsystem
+ * @ops: pernet operations structure to manipulate
+ *
+ * Remove the pernet operations structure from the list to be
+ * used when network namespaces are created or destoryed. In
+ * addition run the exit method for all existing network
+ * namespaces.
+ */
+void unregister_pernet_subsys(struct pernet_operations *module)
+{
+ mutex_lock(&net_mutex);
+ unregister_pernet_operations(module);
+ mutex_unlock(&net_mutex);
+}
+EXPORT_SYMBOL_GPL(unregister_pernet_subsys);
+
+/**
+ * register_pernet_device - register a network namespace device
+ * @ops: pernet operations structure for the subsystem
+ *
+ * Register a device which has init and exit functions
+ * that are called when network namespaces are created and
+ * destroyed respectively.
+ *
+ * When registered all network namespa
...
|
|
|
|
|
[PATCH 00/16] core network namespace support
By: ebiederm on Sat, 08 September 2007 21:07
|
|
|
[PATCH 01/16] appletalk: In notifier handlers convert the void pointer to a netdevice
By: ebiederm on Sat, 08 September 2007 21:09
|
|
|
[PATCH 02/16] net: Don't implement dev_ifname32 inline
By: ebiederm on Sat, 08 September 2007 21:13
|
|
|
[PATCH 03/16] net: Basic network namespace infrastructure.
By: ebiederm on Sat, 08 September 2007 21:15
|
|
|
[PATCH 04/16] net: Add a network namespace parameter to tasks
By: ebiederm on Sat, 08 September 2007 21:17
|
|
|
[PATCH 05/16] net: Add a network namespace tag to struct net_device
By: ebiederm on Sat, 08 September 2007 21:18
|
|
|
[PATCH 07/16] net: Make /proc/net per network namespace
By: ebiederm on Sat, 08 September 2007 21:20
|
|
|
[PATCH 08/16] net: Make socket creation namespace safe.
By: ebiederm on Sat, 08 September 2007 21:23
|
|
|
[PATCH 09/16] net: Initialize the network namespace of network devices.
By: ebiederm on Sat, 08 September 2007 21:24
|
|
|
[PATCH 10/16] net: Make packet reception network namespace safe
By: ebiederm on Sat, 08 September 2007 21:25
|
|
|
[PATCH 11/16] net: Make device event notification network namespace safe
By: ebiederm on Sat, 08 September 2007 21:27
|
|
|
[PATCH 12/16] net: Support multiple network namespaces with netlink
By: ebiederm on Sat, 08 September 2007 21:28
|
|
|
[PATCH 13/16] net: Make the device list and device lookups per namespace.
By: ebiederm on Sat, 08 September 2007 21:35
|
|
|
[PATCH 14/16] net: Factor out __dev_alloc_name from dev_alloc_name
By: ebiederm on Sat, 08 September 2007 21:36
|
|
|
[PATCH 15/16] net: Implement network device movement between namespaces
By: ebiederm on Sat, 08 September 2007 21:38
|
|
|
[PATCH 16/16] net: netlink support for moving devices between network namespaces.
By: ebiederm on Sat, 08 September 2007 21:43
|
|
|
[PATCH 17/16] net: Disable netfilter sockopts when not in the initial network namespace
By: ebiederm on Sat, 08 September 2007 21:47
|
|
|
Re: [PATCH 17/16] net: Disable netfilter sockopts when not in the initial network namespace
By: ebiederm on Mon, 10 September 2007 15:27
|
|
|
Re: [PATCH 17/16] net: Disable netfilter sockopts when not in the initial network namespace
|
|
|
Re: [PATCH 17/16] net: Disable netfilter sockopts when not in the initial network namespace
By: davem on Wed, 12 September 2007 11:59
|
|
|
Re: [PATCH 17/16] net: Disable netfilter sockopts when not in the initial network namespace
By: davem on Wed, 12 September 2007 12:03
|
|
|
Re: [PATCH 17/16] net: Disable netfilter sockopts when not in the initial network namespace
By: ebiederm on Wed, 12 September 2007 12:16
|
|
|
Re: [PATCH 16/16] net: netlink support for moving devices between network namespaces.
By: ebiederm on Mon, 10 September 2007 19:30
|
|
|
Re: [PATCH 16/16] net: netlink support for moving devices between network namespaces.
By: serue on Tue, 11 September 2007 00:54
|
|
|
Re: [PATCH 16/16] net: netlink support for moving devices between network namespaces.
By: serue on Mon, 10 September 2007 19:07
|
|
|
Re: [PATCH 16/16] net: netlink support for moving devices between network namespaces.
By: davem on Wed, 12 September 2007 11:57
|
|
|
Re: [PATCH 15/16] net: Implement network device movement between namespaces
By: davem on Wed, 12 September 2007 11:54
|
|
|
Re: [PATCH 14/16] net: Factor out __dev_alloc_name from dev_alloc_name
By: davem on Wed, 12 September 2007 11:49
|
|
|
Re: [PATCH 13/16] net: Make the device list and device lookups per namespace.
By: davem on Wed, 12 September 2007 11:39
|
|
|
Re: [PATCH 12/16] net: Support multiple network namespaces with netlink
By: ebiederm on Mon, 10 September 2007 15:24
|
|
|
Re: [PATCH 12/16] net: Support multiple network namespaces with netlink
|
|
|
Re: [PATCH 12/16] net: Support multiple network namespaces with netlink
By: davem on Wed, 12 September 2007 11:06
|
|
|
Re: [PATCH 11/16] net: Make device event notification network namespace safe
By: davem on Wed, 12 September 2007 11:02
|
|
|
Re: [PATCH 10/16] net: Make packet reception network namespace safe
By: davem on Wed, 12 September 2007 11:00
|
|
|
Re: [PATCH 09/16] net: Initialize the network namespace of network devices.
By: davem on Wed, 12 September 2007 10:58
|
|
|
Re: [PATCH 08/16] net: Make socket creation namespace safe.
By: davem on Wed, 12 September 2007 10:04
|
|
|
Re: [PATCH 07/16] net: Make /proc/net per network namespace
By: davem on Wed, 12 September 2007 10:02
|
|
|
Re: [PATCH 07/16] net: Make /proc/net per network namespace
|
|
|
Re: [PATCH 07/16] net: Make /proc/net per network namespace
By: davem on Wed, 12 September 2007 12:19
|
|
|
[PATCH 06/16] net: Add a network namespace parameter to struct sock
By: ebiederm on Sat, 08 September 2007 21:21
|
|
|
Re: [PATCH 06/16] net: Add a network namespace parameter to struct sock
By: davem on Wed, 12 September 2007 09:58
|
|
|
Re: [PATCH 06/16] net: Add a network namespace parameter to struct sock
By: den on Thu, 20 September 2007 12:55
|
|
|
Re: [PATCH 06/16] net: Add a network namespace parameter to struct sock
|
|
|
Re: [PATCH 06/16] net: Add a network namespace parameter to struct sock
By: den on Fri, 21 September 2007 05:04
|
|
|
Re: [PATCH 06/16] net: Add a network namespace parameter to struct sock
By: ebiederm on Fri, 21 September 2007 05:58
|
|
|
Re: [PATCH 06/16] net: Add a network namespace parameter to struct sock
|
|
|
Re: [PATCH 05/16] net: Add a network namespace tag to struct net_device
By: davem on Wed, 12 September 2007 09:57
|
|
|
Re: [PATCH 04/16] net: Add a network namespace parameter to tasks
By: davem on Wed, 12 September 2007 09:55
|
|
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
By: paulmck on Sun, 09 September 2007 00:33
|
|
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
By: ebiederm on Sun, 09 September 2007 10:04
|
|
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
By: paulmck on Sun, 09 September 2007 16:45
|
|
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
By: ebiederm on Mon, 10 September 2007 06:32
|
|
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
By: ebiederm on Sun, 09 September 2007 10:18
|
|
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
|
|
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
By: ebiederm on Mon, 10 September 2007 06:40
|
|
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
By: ebiederm on Mon, 10 September 2007 15:53
|
|
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
|
|
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
|
|
|
Re: [PATCH 03/16] net: Basic network namespace infrastructure.
By: davem on Wed, 12 September 2007 09:52
|
|
|
Re: [PATCH 02/16] net: Don't implement dev_ifname32 inline
By: davem on Wed, 12 September 2007 09:39
|
|
|
Re: [PATCH 01/16] appletalk: In notifier handlers convert the void pointer to a netdevice
By: davem on Wed, 12 September 2007 09:27
|
Goto Forum:
Current Time: Thu Sep 12 12:19:53 GMT 2024
Total time taken to generate the page: 0.05337 seconds
|