summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2007-09-27 09:04:26 +0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-11 03:52:46 +0400
commit9dd776b6d7b0b85966b6ddd03e2b2aae59012ab1 (patch)
treeed92aee1f242bb31a0965a4156063eac916ae15e /net
parent8b41d1887db718be9a2cd9e18c58ce25a4c7fd93 (diff)
downloadlinux-9dd776b6d7b0b85966b6ddd03e2b2aae59012ab1.tar.xz
[NET]: Add network namespace clone & unshare support.
This patch allows you to create a new network namespace using sys_clone, or sys_unshare. As the network namespace is still experimental and under development clone and unshare support is only made available when CONFIG_NET_NS is selected at compile time. As this patch introduces network namespace support into code paths that exist when the CONFIG_NET is not selected there are a few additions made to net_namespace.h to allow a few more functions to be used when the networking stack is not compiled in. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/Kconfig8
-rw-r--r--net/core/net_namespace.c43
2 files changed, 49 insertions, 2 deletions
diff --git a/net/Kconfig b/net/Kconfig
index cdba08ca2efe..ab4e6da5012f 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -27,6 +27,14 @@ if NET
menu "Networking options"
+config NET_NS
+ bool "Network namespace support"
+ default n
+ depends on EXPERIMENTAL && !SYSFS
+ help
+ Allow user space to create what appear to be multiple instances
+ of the network stack.
+
source "net/packet/Kconfig"
source "net/unix/Kconfig"
source "net/xfrm/Kconfig"
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 0e6cb02d7b77..e478e353ea6b 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -4,6 +4,7 @@
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/delay.h>
+#include <linux/sched.h>
#include <net/net_namespace.h>
/*
@@ -32,12 +33,10 @@ void net_unlock(void)
mutex_unlock(&net_list_mutex);
}
-#if 0
static struct net *net_alloc(void)
{
return kmem_cache_alloc(net_cachep, GFP_KERNEL);
}
-#endif
static void net_free(struct net *net)
{
@@ -128,6 +127,46 @@ out_undo:
goto out;
}
+struct net *copy_net_ns(unsigned long flags, struct net *old_net)
+{
+ struct net *new_net = NULL;
+ int err;
+
+ get_net(old_net);
+
+ if (!(flags & CLONE_NEWNET))
+ return old_net;
+
+#ifndef CONFIG_NET_NS
+ return ERR_PTR(-EINVAL);
+#endif
+
+ err = -ENOMEM;
+ new_net = net_alloc();
+ if (!new_net)
+ goto out;
+
+ mutex_lock(&net_mutex);
+ err = setup_net(new_net);
+ if (err)
+ goto out_unlock;
+
+ net_lock();
+ list_add_tail(&new_net->list, &net_namespace_list);
+ net_unlock();
+
+
+out_unlock:
+ mutex_unlock(&net_mutex);
+out:
+ put_net(old_net);
+ if (err) {
+ net_free(new_net);
+ new_net = ERR_PTR(err);
+ }
+ return new_net;
+}
+
static int __init net_ns_init(void)
{
int err;