diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2007-09-27 09:04:26 +0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-11 03:52:46 +0400 |
commit | 9dd776b6d7b0b85966b6ddd03e2b2aae59012ab1 (patch) | |
tree | ed92aee1f242bb31a0965a4156063eac916ae15e /net/core | |
parent | 8b41d1887db718be9a2cd9e18c58ce25a4c7fd93 (diff) | |
download | linux-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/core')
-rw-r--r-- | net/core/net_namespace.c | 43 |
1 files changed, 41 insertions, 2 deletions
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; |