[Devel] [PATCH 12/12] L2 network namespace (v3): L3 network namespace intro
Dmitry Mishin
dim at openvz.org
Wed Jan 17 08:18:25 PST 2007
Inroduce two kind of network namespaces - level 2 and level 3. First one is
namespace with full set of networking objects, while second one -
socket-level with restricted set.
Signed-off-by: Dmitry Mishin <dim at openvz.org>
---
include/linux/net_namespace.h | 3 +++
net/core/net_namespace.c | 40 ++++++++++++++++++++++++++++------------
2 files changed, 31 insertions(+), 12 deletions(-)
--- linux-2.6.20-rc4-mm1.net_ns.orig/include/linux/net_namespace.h
+++ linux-2.6.20-rc4-mm1.net_ns/include/linux/net_namespace.h
@@ -24,6 +24,9 @@ struct net_namespace {
int fib4_trie_last_dflt;
#endif
unsigned int hash;
+#define NET_NS_LEVEL2 1
+#define NET_NS_LEVEL3 2
+ unsigned int level;
};
extern struct net_namespace init_net_ns;
--- linux-2.6.20-rc4-mm1.net_ns.orig/net/core/net_namespace.c
+++ linux-2.6.20-rc4-mm1.net_ns/net/core/net_namespace.c
@@ -30,13 +30,19 @@ EXPORT_PER_CPU_SYMBOL_GPL(exec_net_ns);
/*
* Clone a new ns copying an original net ns, setting refcount to 1
+ * @level: level of namespace to create
* @old_ns: namespace to clone
- * Return NULL on error (failure to kmalloc), new ns otherwise
+ * Return ERR_PTR on error, new ns otherwise
*/
-static struct net_namespace *clone_net_ns(struct net_namespace *old_ns)
+static struct net_namespace *clone_net_ns(unsigned int level,
+ struct net_namespace *old_ns)
{
struct net_namespace *ns;
+ /* level 3 namespaces are incomplete in order to have childs */
+ if (current_net_ns->level == NET_NS_LEVEL3)
+ return ERR_PTR(-EPERM);
+
ns = kzalloc(sizeof(struct net_namespace), GFP_KERNEL);
if (!ns)
return NULL;
@@ -48,20 +54,25 @@ static struct net_namespace *clone_net_n
if ((push_net_ns(ns)) != old_ns)
BUG();
+ if (level == NET_NS_LEVEL2) {
#ifdef CONFIG_IP_MULTIPLE_TABLES
- INIT_LIST_HEAD(&ns->fib_rules_ops_list);
+ INIT_LIST_HEAD(&ns->fib_rules_ops_list);
#endif
- if (ip_fib_struct_init())
- goto out_fib4;
+ if (ip_fib_struct_init())
+ goto out_fib4;
+ }
+ ns->level = level;
if (loopback_init())
goto out_loopback;
pop_net_ns(old_ns);
- printk(KERN_DEBUG "NET_NS: created new netcontext %p for %s "
- "(pid=%d)\n", ns, current->comm, current->tgid);
+ printk(KERN_DEBUG "NET_NS: created new netcontext %p, level %u, "
+ "for %s (pid=%d)\n", ns, (ns->level == NET_NS_LEVEL2) ?
+ 2 : 3, current->comm, current->tgid);
return ns;
out_loopback:
- ip_fib_struct_cleanup(ns);
+ if (level == NET_NS_LEVEL2)
+ ip_fib_struct_cleanup(ns);
out_fib4:
pop_net_ns(old_ns);
BUG_ON(atomic_read(&ns->kref.refcount) != 1);
@@ -75,13 +86,17 @@ out_fib4:
int unshare_net_ns(unsigned long unshare_flags,
struct net_namespace **new_net)
{
+ unsigned int level;
+
if (unshare_flags & (CLONE_NEWNET2|CLONE_NEWNET3)) {
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- *new_net = clone_net_ns(current->nsproxy->net_ns);
- if (!*new_net)
- return -ENOMEM;
+ level = (unshare_flags & CLONE_NEWNET2) ? NET_NS_LEVEL2 :
+ NET_NS_LEVEL3;
+ *new_net = clone_net_ns(level, current->nsproxy->net_ns);
+ if (IS_ERR(*new_net))
+ return PTR_ERR(*new_net);
}
return 0;
@@ -110,7 +125,8 @@ void free_net_ns(struct kref *kref)
ns, atomic_read(&ns->kref.refcount));
return;
}
- ip_fib_struct_cleanup(ns);
+ if (ns->level == NET_NS_LEVEL2)
+ ip_fib_struct_cleanup(ns);
printk(KERN_DEBUG "NET_NS: net namespace %p destroyed\n", ns);
kfree(ns);
}
_______________________________________________
Containers mailing list
Containers at lists.osdl.org
https://lists.osdl.org/mailman/listinfo/containers
More information about the Devel
mailing list