|
@@ -14,7 +14,9 @@
|
|
#include <linux/netdevice.h>
|
|
#include <linux/netdevice.h>
|
|
#include <linux/if_arp.h>
|
|
#include <linux/if_arp.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/slab.h>
|
|
|
|
+#include <linux/nsproxy.h>
|
|
#include <net/sock.h>
|
|
#include <net/sock.h>
|
|
|
|
+#include <net/net_namespace.h>
|
|
#include <linux/rtnetlink.h>
|
|
#include <linux/rtnetlink.h>
|
|
#include <linux/wireless.h>
|
|
#include <linux/wireless.h>
|
|
#include <linux/vmalloc.h>
|
|
#include <linux/vmalloc.h>
|
|
@@ -766,6 +768,38 @@ static void rx_queue_remove_kobjects(struct net_device *net)
|
|
kset_unregister(net->queues_kset);
|
|
kset_unregister(net->queues_kset);
|
|
}
|
|
}
|
|
#endif /* CONFIG_RPS */
|
|
#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 */
|
|
#endif /* CONFIG_SYSFS */
|
|
|
|
|
|
#ifdef CONFIG_HOTPLUG
|
|
#ifdef CONFIG_HOTPLUG
|
|
@@ -806,6 +840,13 @@ static void netdev_release(struct device *d)
|
|
kfree((char *)dev - dev->padded);
|
|
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 = {
|
|
static struct class net_class = {
|
|
.name = "net",
|
|
.name = "net",
|
|
.dev_release = netdev_release,
|
|
.dev_release = netdev_release,
|
|
@@ -815,6 +856,8 @@ static struct class net_class = {
|
|
#ifdef CONFIG_HOTPLUG
|
|
#ifdef CONFIG_HOTPLUG
|
|
.dev_uevent = netdev_uevent,
|
|
.dev_uevent = netdev_uevent,
|
|
#endif
|
|
#endif
|
|
|
|
+ .ns_type = &net_ns_type_operations,
|
|
|
|
+ .namespace = net_namespace,
|
|
};
|
|
};
|
|
|
|
|
|
/* Delete sysfs entries but hold kobject reference until after all
|
|
/* 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)
|
|
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);
|
|
return class_register(&net_class);
|
|
}
|
|
}
|