netns: Teach network device kobjects which namespace they are in.
authorEric W. Biederman <ebiederm@xmission.com>
Wed, 5 May 2010 00:36:45 +0000 (17:36 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 21 May 2010 16:37:32 +0000 (09:37 -0700)
The problem.  Network devices show up in sysfs and with the network
namespace active multiple devices with the same name can show up in
the same directory, ouch!

To avoid that problem and allow existing applications in network namespaces
to see the same interface that is currently presented in sysfs, this
patch enables the tagging directory support in sysfs.

By using the network namespace pointers as tags to separate out the
the sysfs directory entries we ensure that we don't have conflicts
in the directories and applications only see a limited set of
the network devices.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
include/linux/kobject.h
net/Kconfig
net/core/net-sysfs.c

index b60d2dfe4e699a817a9d9b2b6093ee33c2bf4229..cf343a852534bee2f3ed02ffd9cce21210caac8f 100644 (file)
@@ -142,6 +142,7 @@ extern const struct sysfs_ops kobj_sysfs_ops;
  */
 enum kobj_ns_type {
        KOBJ_NS_TYPE_NONE = 0,
+       KOBJ_NS_TYPE_NET,
        KOBJ_NS_TYPES
 };
 
index 0d68b40fc0e625d79aece260f08952c1ac374987..f49532053a980a44d8d72fd3435ce21dcdea18fc 100644 (file)
@@ -45,6 +45,14 @@ config COMPAT_NETLINK_MESSAGES
 
 menu "Networking options"
 
+config NET_NS
+       bool "Network namespace support"
+       default n
+       depends on EXPERIMENTAL && NAMESPACES
+       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"
index c57c4b228bb5b849599124e058322aabe8d203d8..b388cdab9316accc4fff2b994a2f593de7548b10 100644 (file)
@@ -14,7 +14,9 @@
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/slab.h>
+#include <linux/nsproxy.h>
 #include <net/sock.h>
+#include <net/net_namespace.h>
 #include <linux/rtnetlink.h>
 #include <linux/wireless.h>
 #include <linux/vmalloc.h>
@@ -766,6 +768,38 @@ static void rx_queue_remove_kobjects(struct net_device *net)
        kset_unregister(net->queues_kset);
 }
 #endif /* CONFIG_RPS */
+
+static const void *net_current_ns(void)
+{
+       return current->nsproxy->net_ns;
+}
+
+static const void *net_initial_ns(void)
+{
+       return &init_net;
+}
+
+static const void *net_netlink_ns(struct sock *sk)
+{
+       return sock_net(sk);
+}
+
+static struct kobj_ns_type_operations net_ns_type_operations = {
+       .type = KOBJ_NS_TYPE_NET,
+       .current_ns = net_current_ns,
+       .netlink_ns = net_netlink_ns,
+       .initial_ns = net_initial_ns,
+};
+
+static void net_kobj_ns_exit(struct net *net)
+{
+       kobj_ns_exit(KOBJ_NS_TYPE_NET, net);
+}
+
+static struct pernet_operations sysfs_net_ops = {
+       .exit = net_kobj_ns_exit,
+};
+
 #endif /* CONFIG_SYSFS */
 
 #ifdef CONFIG_HOTPLUG
@@ -806,6 +840,13 @@ static void netdev_release(struct device *d)
        kfree((char *)dev - dev->padded);
 }
 
+static const void *net_namespace(struct device *d)
+{
+       struct net_device *dev;
+       dev = container_of(d, struct net_device, dev);
+       return dev_net(dev);
+}
+
 static struct class net_class = {
        .name = "net",
        .dev_release = netdev_release,
@@ -815,6 +856,8 @@ static struct class net_class = {
 #ifdef CONFIG_HOTPLUG
        .dev_uevent = netdev_uevent,
 #endif
+       .ns_type = &net_ns_type_operations,
+       .namespace = net_namespace,
 };
 
 /* Delete sysfs entries but hold kobject reference until after all
@@ -904,5 +947,9 @@ void netdev_initialize_kobject(struct net_device *net)
 
 int netdev_kobject_init(void)
 {
+       kobj_ns_type_register(&net_ns_type_operations);
+#ifdef CONFIG_SYSFS
+       register_pernet_subsys(&sysfs_net_ops);
+#endif
        return class_register(&net_class);
 }