Commit 3891845e authored by Eric W. Biederman's avatar Eric W. Biederman Committed by David S. Miller

netns: Coexist with the sysfs limitations v2

To make testing of the network namespace simpler allow
the network namespace code and the sysfs code to be
compiled and run at the same time.  To do this only
virtual devices are allowed in the additional network
namespaces and those virtual devices are not placed
in the kobject tree.

Since virtual devices don't actually do anything interesting
hardware wise that needs device management there should
be no loss in keeping them out of the kobject tree and
by implication sysfs.  The gain in ease of testing
and code coverage should be significant.

Changelog:

v2: As pointed out by Benjamin Thery it only makes sense to call
    device_rename in the initial network namespace for now.
Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
Acked-by: default avatarBenjamin Thery <benjamin.thery@bull.net>
Tested-by: default avatarSerge Hallyn <serue@us.ibm.com>
Acked-by: default avatarSerge Hallyn <serue@us.ibm.com>
Acked-by: default avatarDaniel Lezcano <dlezcano@fr.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7c510e4b
...@@ -27,7 +27,7 @@ menu "Networking options" ...@@ -27,7 +27,7 @@ menu "Networking options"
config NET_NS config NET_NS
bool "Network namespace support" bool "Network namespace support"
default n default n
depends on EXPERIMENTAL && !SYSFS && NAMESPACES depends on EXPERIMENTAL && NAMESPACES
help help
Allow user space to create what appear to be multiple instances Allow user space to create what appear to be multiple instances
of the network stack. of the network stack.
......
...@@ -924,11 +924,16 @@ int dev_change_name(struct net_device *dev, const char *newname) ...@@ -924,11 +924,16 @@ int dev_change_name(struct net_device *dev, const char *newname)
strlcpy(dev->name, newname, IFNAMSIZ); strlcpy(dev->name, newname, IFNAMSIZ);
rollback: rollback:
/* For now only devices in the initial network namespace
* are in sysfs.
*/
if (net == &init_net) {
ret = device_rename(&dev->dev, dev->name); ret = device_rename(&dev->dev, dev->name);
if (ret) { if (ret) {
memcpy(dev->name, oldname, IFNAMSIZ); memcpy(dev->name, oldname, IFNAMSIZ);
return ret; return ret;
} }
}
write_lock_bh(&dev_base_lock); write_lock_bh(&dev_base_lock);
hlist_del(&dev->name_hlist); hlist_del(&dev->name_hlist);
...@@ -4460,6 +4465,15 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char ...@@ -4460,6 +4465,15 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
if (dev->features & NETIF_F_NETNS_LOCAL) if (dev->features & NETIF_F_NETNS_LOCAL)
goto out; goto out;
#ifdef CONFIG_SYSFS
/* Don't allow real devices to be moved when sysfs
* is enabled.
*/
err = -EINVAL;
if (dev->dev.parent)
goto out;
#endif
/* Ensure the device has been registrered */ /* Ensure the device has been registrered */
err = -EINVAL; err = -EINVAL;
if (dev->reg_state != NETREG_REGISTERED) if (dev->reg_state != NETREG_REGISTERED)
...@@ -4517,6 +4531,8 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char ...@@ -4517,6 +4531,8 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
*/ */
dev_addr_discard(dev); dev_addr_discard(dev);
netdev_unregister_kobject(dev);
/* Actually switch the network namespace */ /* Actually switch the network namespace */
dev_net_set(dev, net); dev_net_set(dev, net);
...@@ -4533,7 +4549,6 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char ...@@ -4533,7 +4549,6 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
} }
/* Fixup kobjects */ /* Fixup kobjects */
netdev_unregister_kobject(dev);
err = netdev_register_kobject(dev); err = netdev_register_kobject(dev);
WARN_ON(err); WARN_ON(err);
......
...@@ -476,6 +476,10 @@ void netdev_unregister_kobject(struct net_device * net) ...@@ -476,6 +476,10 @@ void netdev_unregister_kobject(struct net_device * net)
struct device *dev = &(net->dev); struct device *dev = &(net->dev);
kobject_get(&dev->kobj); kobject_get(&dev->kobj);
if (dev_net(net) != &init_net)
return;
device_del(dev); device_del(dev);
} }
...@@ -501,6 +505,9 @@ int netdev_register_kobject(struct net_device *net) ...@@ -501,6 +505,9 @@ int netdev_register_kobject(struct net_device *net)
#endif #endif
#endif /* CONFIG_SYSFS */ #endif /* CONFIG_SYSFS */
if (dev_net(net) != &init_net)
return 0;
return device_add(dev); return device_add(dev);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment