Is it normal to have cross namespace symlinks?
Subsystems (2)
Hello guys!
Recently i switched to 3.14.x stable branch and i've got a bunch of warnings:
[ 44.717746] ------------[ cut here ]------------ [ 44.717750] WARNING: CPU: 1 PID: 7007 at fs/sysfs/dir.c:52
sysfs_warn_dup+0x86/0xa0() [ 44.717751] sysfs: cannot create
duplicate filename '/devices/pci0000:00/0000:00:1c.4/0000:05:00.0/net/eth1/upper_eth1'
[ 37.759856] ------------[ cut here ]------------ [ 37.759863] WARNING: CPU: 1 PID: 3822 at fs/sysfs/dir.c:52
sysfs_warn_dup+0x86/0xa0() [ 37.759864] sysfs: cannot create
duplicate filename '/devices/virtual/net/bond0/upper_eth0'
....
It was triggered by renaming of macvlan interfaces in a freshly created network namespaces. Just start two lxc containers one by one with macvlans on the same lowerdev and rename devices inside containers (with the same name) and voila.
I investigated problem a bit and i see that code in net/core/dev.c which working with sysfs symlinks upper_dev / lower_dev is absolutely unaware of namespaces. I mean code which uses functions netdev_adjacent_sysfs_del,netdev_adjacent_sysfs_add netdev_adjacent_rename_links,dev_change_name
just not takes into account that dev and adj_dev could be in a different namespaces. If userland asks to rename interface in a new namespace this code renames an upper_dev link
in a parent namespace accordingly. I hadn't tried but i'll bet it works vice-versa as well. It leads to warnings i've wrote above and also creation inside namespaces a pretty meaningless links:/sys/devices/virtual/net/eth1/lower_eth1
-> ../../../pci0000:00/0000:00:1c.4/0000:05:00.0/net/eth1 or probably deletion of symlinks of a perfectly valid devices.
At the same time this issue is not affecting most of current functionality and seems like nobody cares about that. I suspect that there's (almost) no real users of sysfs uppder_dev/lower_dev simlinks, am i right?
Signature · 3 lines
Best regards.
Alexander Y. Fomichev <[email protected]>
+7-495-662-88-88 ext. 11346Quoted 17 lines · Alexander Y. Fomichev
Hello guys!
Recently i switched to 3.14.x stable branch and i've got a bunch of warnings:
[ 44.717746] ------------[ cut here ]------------ [ 44.717750] WARNING: CPU: 1 PID: 7007 at fs/sysfs/dir.c:52sysfs_warn_dup+0x86/0xa0() [ 44.717751] sysfs: cannot create
duplicate filename '/devices/pci0000:00/0000:00:1c.4/0000:05:00.0/net/eth1/upper_eth1'[ 37.759856] ------------[ cut here ]------------ [ 37.759863] WARNING: CPU: 1 PID: 3822 at fs/sysfs/dir.c:52sysfs_warn_dup+0x86/0xa0() [ 37.759864] sysfs: cannot create
duplicate filename '/devices/virtual/net/bond0/upper_eth0'
....
Quoted 12 lines
It was triggered by renaming of macvlan interfaces in a freshly created network namespaces. Just start two lxc containers one by one with macvlans on the same lowerdev and rename devices inside containers (with the same name) and voila.
v
I investigated problem a bit and i see that code innet/core/dev.cwhich working with sysfs symlinksupper_dev/lower_devis absolutely unaware of namespaces. I mean code which uses functions netdev_adjacent_sysfs_del,netdev_adjacent_sysfs_add netdev_adjacent_rename_links,dev_change_name
just not takes into account that dev andadj_devcould be in a different namespaces.
That's indeed so. When I've implemented it, I indeed didn't take into account net_ns, my bad.
Before the code, though, I'm not sure on how exactly to fix this. The only idea which comes to mind is to prohibit inter-net_ns symlinks (which can be done without much hassle) - i.e. to remove/add them on net_ns change, and to prohibit creating them on adding an inter-ns upper links.
However, as I definitely lack experience using net_ns, maybe there are other, better way, to fix this?
Quoted 31 lines · On Thu, 21 Aug 2014 14:12:05 +0200 Veaceslav Falico <[email protected]> wrote:
Quoted 17 lines · Alexander Y. Fomichev
Hello guys!
Recently i switched to 3.14.x stable branch and i've got a bunch of warnings:
[ 44.717746] ------------[ cut here ]------------ [ 44.717750] WARNING: CPU: 1 PID: 7007 at fs/sysfs/dir.c:52sysfs_warn_dup+0x86/0xa0() [ 44.717751] sysfs: cannot create
duplicate filename '/devices/pci0000:00/0000:00:1c.4/0000:05:00.0/net/eth1/upper_eth1'[ 37.759856] ------------[ cut here ]------------ [ 37.759863] WARNING: CPU: 1 PID: 3822 at fs/sysfs/dir.c:52sysfs_warn_dup+0x86/0xa0() [ 37.759864] sysfs: cannot create
duplicate filename '/devices/virtual/net/bond0/upper_eth0'
....Quoted 12 lines
It was triggered by renaming of macvlan interfaces in a freshly created network namespaces. Just start two lxc containers one by one with macvlans on the same lowerdev and rename devices inside containers (with the same name) and voila.
v
I investigated problem a bit and i see that code innet/core/dev.cwhich working with sysfs symlinksupper_dev/lower_devis absolutely unaware of namespaces. I mean code which uses functions netdev_adjacent_sysfs_del,netdev_adjacent_sysfs_add netdev_adjacent_rename_links,dev_change_name
just not takes into account that dev andadj_devcould be in a different namespaces.
Quoted 8 lines
That's indeed so. When I've implemented it, I indeed didn't take into account
net_ns, my bad.Before the code, though, I'm not sure on how exactly to fix this. The only idea which comes to mind is to prohibit inter-net_ns symlinks (which can be done without much hassle) - i.e. to remove/add them on
net_nschange, and to prohibit creating them on adding an inter-ns upper links.
uh.. seems like this is a first and only what come to mind. At least i have something similar in my local tree. Though it looks pretty ugly and required two ad-hoc functions traversing both adj_list(s). Though again it works as expected in both directions so i attached it just in case.
Quoted 2 lines
However, as I definitely lack experience using
net_ns, maybe there are other, better way, to fix this?
I can not say with confidence.. Someone of namespace guys better be here. as far as i can see the most notable thing in this context, netdev belongs to only one net_ns at any one time and a little sense to have a symlink on non-existent device.
Signature · 3 lines
Best regards.
Alexander Y. Fomichev <[email protected]>
+7-495-662-88-88 ext. 11346net/core/dev.c +61 -1
@@ -4889,7 +4889,8 @@ static void __netdev_adjacent_dev_remove(struct net_device *dev,if (adj->master)sysfs_remove_link (&(dev->dev.kobj),"master" ); -if (netdev_adjacent_is_neigh_list (dev, dev_list)) +if (netdev_adjacent_is_neigh_list (dev, dev_list) && +net_eq (dev_net (dev),dev_net (adj_dev)))netdev_adjacent_sysfs_del (dev, adj_dev->name, dev_list);list_del_rcu (&adj->list);
@@ -5159,11 +5160,65 @@ void netdev_upper_dev_unlink(struct net_device *dev, }EXPORT_SYMBOL (netdev_upper_dev_unlink); +void netdev_adjacent_add_links (struct net_device *dev) +{ +struct netdev_adjacent *iter; + +struct net *net =dev_net (dev); + +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_add (iter->dev, dev, + &iter->dev->adj_list.lower); +netdev_adjacent_sysfs_add (dev, iter->dev, + &dev->adj_list.upper); + } + +list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_add (iter->dev, dev, + &iter->dev->adj_list.upper); +netdev_adjacent_sysfs_add (dev, iter->dev, + &dev->adj_list.lower); + } +} + +void netdev_adjacent_del_links (struct net_device *dev) +{ +struct netdev_adjacent *iter; + +struct net *net =dev_net (dev); + +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_del (iter->dev, dev->name, + &iter->dev->adj_list.lower); +netdev_adjacent_sysfs_del (dev, iter->dev->name, + &dev->adj_list.upper); + } + +list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_del (iter->dev, dev->name, + &iter->dev->adj_list.upper); +netdev_adjacent_sysfs_del (dev, iter->dev->name, + &dev->adj_list.lower); + } +} +void netdev_adjacent_rename_links (struct net_device *dev,char *oldname) {struct netdev_adjacent *iter; +struct net *net =dev_net (dev); +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ;netdev_adjacent_sysfs_del (iter->dev, oldname, &iter->dev->adj_list.lower); netdev_adjacent_sysfs_add(iter->dev, dev,
@@ -5171,6 +5226,8 @@ void netdev_adjacent_rename_links(struct net_device *dev, char *oldname) }list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ;netdev_adjacent_sysfs_del (iter->dev, oldname, &iter->dev->adj_list.upper); netdev_adjacent_sysfs_add(iter->dev, dev,
@@ -6771,8 +6828,10 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const chardev_uc_flush (dev);dev_mc_flush (dev); +/* Send a netdev-removed uevent to the old namespace */ kobject_uevent (&dev->dev.kobj,KOBJ_REMOVE ); +netdev_adjacent_del_links (dev);/* Actually switch the network namespace */ dev_net_set (dev, net);
@@ -6787,6 +6846,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char/* Send a netdev-add uevent to the new namespace */ kobject_uevent (&dev->dev.kobj,KOBJ_ADD ); +netdev_adjacent_add_links (dev);/* Fixup kobjects */ err =device_rename (&dev->dev, dev->name);
Quoted 43 lines · Alexander Y. Fomichev
Quoted 31 lines · On Thu, 21 Aug 2014 14:12:05 +0200 Veaceslav Falico <[email protected]> wrote:
Quoted 17 lines · Alexander Y. Fomichev
Hello guys!
Recently i switched to 3.14.x stable branch and i've got a bunch of warnings:
[ 44.717746] ------------[ cut here ]------------ [ 44.717750] WARNING: CPU: 1 PID: 7007 at fs/sysfs/dir.c:52sysfs_warn_dup+0x86/0xa0() [ 44.717751] sysfs: cannot create
duplicate filename '/devices/pci0000:00/0000:00:1c.4/0000:05:00.0/net/eth1/upper_eth1'[ 37.759856] ------------[ cut here ]------------ [ 37.759863] WARNING: CPU: 1 PID: 3822 at fs/sysfs/dir.c:52sysfs_warn_dup+0x86/0xa0() [ 37.759864] sysfs: cannot create
duplicate filename '/devices/virtual/net/bond0/upper_eth0'
....Quoted 12 lines
It was triggered by renaming of macvlan interfaces in a freshly created network namespaces. Just start two lxc containers one by one with macvlans on the same lowerdev and rename devices inside containers (with the same name) and voila.
v
I investigated problem a bit and i see that code innet/core/dev.cwhich working with sysfs symlinksupper_dev/lower_devis absolutely unaware of namespaces. I mean code which uses functions netdev_adjacent_sysfs_del,netdev_adjacent_sysfs_add netdev_adjacent_rename_links,dev_change_name
just not takes into account that dev andadj_devcould be in a different namespaces.Quoted 8 lines
That's indeed so. When I've implemented it, I indeed didn't take into account
net_ns, my bad.Before the code, though, I'm not sure on how exactly to fix this. The only idea which comes to mind is to prohibit inter-net_ns symlinks (which can be done without much hassle) - i.e. to remove/add them on
net_nschange, and to prohibit creating them on adding an inter-ns upper links.
Quoted 5 lines
uh.. seems like this is a first and only what come to mind. At least i have something similar in my local tree. Though it looks pretty ugly and required two ad-hoc functions traversing both
adj_list(s). Though again it works as expected in both directions so i attached it just in case.
It doesn't really matter in this case, as adj_lists are small, and the renaming happens once per reboot.
Anyway, feel free to post it. Even if it doesn't get accepted, it'll be a good starting point.
Quoted 8 lines
Quoted 3 lines
However, as I definitely lack experience using
net_ns, maybe there are other, better way, to fix this?I can not say with confidence.. Someone of namespace guys better be here. as far as i can see the most notable thing in this context, netdev belongs to only one
net_nsat any one time and a little sense to have a symlink on non-existent device.
Yep, agreed.
Thank you!
Quoted 115 lines
Signature · 5 lines
-- Best regards. Alexander Y. Fomichev <[email protected]> +7-495-662-88-88 ext. 11346net/core/dev.c +61
-1@@ -4889,7 +4889,8 @@ static void __netdev_adjacent_dev_remove(struct net_device *dev,if (adj->master)sysfs_remove_link (&(dev->dev.kobj),"master" ); -if (netdev_adjacent_is_neigh_list (dev, dev_list)) +if (netdev_adjacent_is_neigh_list (dev, dev_list) && +net_eq (dev_net (dev),dev_net (adj_dev)))netdev_adjacent_sysfs_del (dev, adj_dev->name, dev_list);list_del_rcu (&adj->list);@@ -5159,11 +5160,65 @@ void netdev_upper_dev_unlink(struct net_device *dev, }EXPORT_SYMBOL (netdev_upper_dev_unlink); +void netdev_adjacent_add_links (struct net_device *dev) +{ +struct netdev_adjacent *iter; + +struct net *net =dev_net (dev); + +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_add (iter->dev, dev, + &iter->dev->adj_list.lower); +netdev_adjacent_sysfs_add (dev, iter->dev, + &dev->adj_list.upper); + } + +list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_add (iter->dev, dev, + &iter->dev->adj_list.upper); +netdev_adjacent_sysfs_add (dev, iter->dev, + &dev->adj_list.lower); + } +} + +void netdev_adjacent_del_links (struct net_device *dev) +{ +struct netdev_adjacent *iter; + +struct net *net =dev_net (dev); + +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_del (iter->dev, dev->name, + &iter->dev->adj_list.lower); +netdev_adjacent_sysfs_del (dev, iter->dev->name, + &dev->adj_list.upper); + } + +list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_del (iter->dev, dev->name, + &iter->dev->adj_list.upper); +netdev_adjacent_sysfs_del (dev, iter->dev->name, + &dev->adj_list.lower); + } +} +void netdev_adjacent_rename_links (struct net_device *dev,char *oldname) {struct netdev_adjacent *iter; +struct net *net =dev_net (dev); +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ;netdev_adjacent_sysfs_del (iter->dev, oldname, &iter->dev->adj_list.lower); netdev_adjacent_sysfs_add(iter->dev, dev,@@ -5171,6 +5226,8 @@ void netdev_adjacent_rename_links(struct net_device *dev, char *oldname) }list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ;netdev_adjacent_sysfs_del (iter->dev, oldname, &iter->dev->adj_list.upper); netdev_adjacent_sysfs_add(iter->dev, dev,@@ -6771,8 +6828,10 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const chardev_uc_flush (dev);dev_mc_flush (dev); +/* Send a netdev-removed uevent to the old namespace */ kobject_uevent (&dev->dev.kobj,KOBJ_REMOVE ); +netdev_adjacent_del_links (dev);/* Actually switch the network namespace */ dev_net_set (dev, net);@@ -6787,6 +6846,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char/* Send a netdev-add uevent to the new namespace */ kobject_uevent (&dev->dev.kobj,KOBJ_ADD ); +netdev_adjacent_add_links (dev);/* Fixup kobjects */ err =device_rename (&dev->dev, dev->name);
PATCH 1/1 netdev_adjacent_sysfs_*: fix cross-namespace symlinks
fix code manipulating symlinks of adjacent net devices.
- prevent creation of sysfs symlink to / from adjacent device on another net_ns.
- Drop all existing symlinks from / to all adj_dev(s) on the current namespace before switching net_ns and recreate them just after.
--- net/core/dev.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-)
net/core/dev.c +61 -1
@@ -4889,7 +4889,8 @@ static void __netdev_adjacent_dev_remove(struct net_device *dev,if (adj->master)sysfs_remove_link (&(dev->dev.kobj),"master" ); -if (netdev_adjacent_is_neigh_list (dev, dev_list)) +if (netdev_adjacent_is_neigh_list (dev, dev_list) && +net_eq (dev_net (dev),dev_net (adj_dev)))netdev_adjacent_sysfs_del (dev, adj_dev->name, dev_list);list_del_rcu (&adj->list);
@@ -5159,11 +5160,65 @@ void netdev_upper_dev_unlink(struct net_device *dev, }EXPORT_SYMBOL (netdev_upper_dev_unlink); +void netdev_adjacent_add_links (struct net_device *dev) +{ +struct netdev_adjacent *iter; + +struct net *net =dev_net (dev); + +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_add (iter->dev, dev, + &iter->dev->adj_list.lower); +netdev_adjacent_sysfs_add (dev, iter->dev, + &dev->adj_list.upper); + } + +list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_add (iter->dev, dev, + &iter->dev->adj_list.upper); +netdev_adjacent_sysfs_add (dev, iter->dev, + &dev->adj_list.lower); + } +} + +void netdev_adjacent_del_links (struct net_device *dev) +{ +struct netdev_adjacent *iter; + +struct net *net =dev_net (dev); + +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_del (iter->dev, dev->name, + &iter->dev->adj_list.lower); +netdev_adjacent_sysfs_del (dev, iter->dev->name, + &dev->adj_list.upper); + } + +list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_del (iter->dev, dev->name, + &iter->dev->adj_list.upper); +netdev_adjacent_sysfs_del (dev, iter->dev->name, + &dev->adj_list.lower); + } +} +void netdev_adjacent_rename_links (struct net_device *dev,char *oldname) {struct netdev_adjacent *iter; +struct net *net =dev_net (dev); +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ;netdev_adjacent_sysfs_del (iter->dev, oldname, &iter->dev->adj_list.lower); netdev_adjacent_sysfs_add(iter->dev, dev,
@@ -5171,6 +5226,8 @@ void netdev_adjacent_rename_links(struct net_device *dev, char *oldname) }list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ;netdev_adjacent_sysfs_del (iter->dev, oldname, &iter->dev->adj_list.upper); netdev_adjacent_sysfs_add(iter->dev, dev,
@@ -6771,8 +6828,10 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const chardev_uc_flush (dev);dev_mc_flush (dev); +/* Send a netdev-removed uevent to the old namespace */ kobject_uevent (&dev->dev.kobj,KOBJ_REMOVE ); +netdev_adjacent_del_links (dev);/* Actually switch the network namespace */ dev_net_set (dev, net);
@@ -6787,6 +6846,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char/* Send a netdev-add uevent to the new namespace */ kobject_uevent (&dev->dev.kobj,KOBJ_ADD ); +netdev_adjacent_add_links (dev);/* Fixup kobjects */ err =device_rename (&dev->dev, dev->name);
Signature · 1 line
2.0.4
PATCH 1/1 netdev_adjacent_sysfs_*: fix cross-namespace symlinks
In reply to Veaceslav Falicofix code manipulating symlinks of adjacent net devices.
- prevent creation of sysfs symlink to / from adjacent device on another net_ns.
- Drop all existing symlinks from / to all adj_dev(s) on the current namespace before switching net_ns and recreate them just after.
--- net/core/dev.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-)
net/core/dev.c +61 -1
@@ -4889,7 +4889,8 @@ static void __netdev_adjacent_dev_remove(struct net_device *dev,if (adj->master)sysfs_remove_link (&(dev->dev.kobj),"master" ); -if (netdev_adjacent_is_neigh_list (dev, dev_list)) +if (netdev_adjacent_is_neigh_list (dev, dev_list) && +net_eq (dev_net (dev),dev_net (adj_dev)))netdev_adjacent_sysfs_del (dev, adj_dev->name, dev_list);list_del_rcu (&adj->list);
@@ -5159,11 +5160,65 @@ void netdev_upper_dev_unlink(struct net_device *dev, }EXPORT_SYMBOL (netdev_upper_dev_unlink); +void netdev_adjacent_add_links (struct net_device *dev) +{ +struct netdev_adjacent *iter; + +struct net *net =dev_net (dev); + +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_add (iter->dev, dev, + &iter->dev->adj_list.lower); +netdev_adjacent_sysfs_add (dev, iter->dev, + &dev->adj_list.upper); + } + +list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_add (iter->dev, dev, + &iter->dev->adj_list.upper); +netdev_adjacent_sysfs_add (dev, iter->dev, + &dev->adj_list.lower); + } +} + +void netdev_adjacent_del_links (struct net_device *dev) +{ +struct netdev_adjacent *iter; + +struct net *net =dev_net (dev); + +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_del (iter->dev, dev->name, + &iter->dev->adj_list.lower); +netdev_adjacent_sysfs_del (dev, iter->dev->name, + &dev->adj_list.upper); + } + +list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_del (iter->dev, dev->name, + &iter->dev->adj_list.upper); +netdev_adjacent_sysfs_del (dev, iter->dev->name, + &dev->adj_list.lower); + } +} +void netdev_adjacent_rename_links (struct net_device *dev,char *oldname) {struct netdev_adjacent *iter; +struct net *net =dev_net (dev); +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ;netdev_adjacent_sysfs_del (iter->dev, oldname, &iter->dev->adj_list.lower); netdev_adjacent_sysfs_add(iter->dev, dev,
@@ -5171,6 +5226,8 @@ void netdev_adjacent_rename_links(struct net_device *dev, char *oldname) }list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ;netdev_adjacent_sysfs_del (iter->dev, oldname, &iter->dev->adj_list.upper); netdev_adjacent_sysfs_add(iter->dev, dev,
@@ -6771,8 +6828,10 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const chardev_uc_flush (dev);dev_mc_flush (dev); +/* Send a netdev-removed uevent to the old namespace */ kobject_uevent (&dev->dev.kobj,KOBJ_REMOVE ); +netdev_adjacent_del_links (dev);/* Actually switch the network namespace */ dev_net_set (dev, net);
@@ -6787,6 +6846,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char/* Send a netdev-add uevent to the new namespace */ kobject_uevent (&dev->dev.kobj,KOBJ_ADD ); +netdev_adjacent_add_links (dev);/* Fixup kobjects */ err =device_rename (&dev->dev, dev->name);
Signature · 1 line
2.0.4
David Miller
maintainerRe: [PATCH] netdev_adjacent_sysfs_*: fix cross-namespace symlinks
From: "Alexander Y. Fomichev" <[email protected]>
Date: Fri, 22 Aug 2014 14:34:53 +0400
Quoted 5 lines
fix code manipulating symlinks of adjacent net devices.
- prevent creation of sysfs symlink to / from adjacent device on anothernet_ns.
- Drop all existing symlinks from / to alladj_dev(s)on the current namespace before switchingnet_nsand recreate them just after.
Please resubmit this with a proper Signed-off-by tag.
PATCH 1/1 net: prevent of emerging cross-namespace symlinks
Code manipulating sysfs symlinks on adjacent net_devices(s) currently doesn't take into account that devices potentially belong to different namespaces.
This patch trying to fix an issue as follows:
- check for net_ns before creating / deleting symlink. for now only netdev_adjacent_rename_links and __netdev_adjacent_dev_remove are affected, afaics __netdev_adjacent_dev_insert implies both net_devs belong to the same namespace.
- Drop all existing symlinks to / from all adj_devs before switching namespace and recreate them just after.
--- net/core/dev.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-)
net/core/dev.c +61 -1
@@ -4889,7 +4889,8 @@ static void __netdev_adjacent_dev_remove(struct net_device *dev,if (adj->master)sysfs_remove_link (&(dev->dev.kobj),"master" ); -if (netdev_adjacent_is_neigh_list (dev, dev_list)) +if (netdev_adjacent_is_neigh_list (dev, dev_list) && +net_eq (dev_net (dev),dev_net (adj_dev)))netdev_adjacent_sysfs_del (dev, adj_dev->name, dev_list);list_del_rcu (&adj->list);
@@ -5159,11 +5160,65 @@ void netdev_upper_dev_unlink(struct net_device *dev, }EXPORT_SYMBOL (netdev_upper_dev_unlink); +void netdev_adjacent_add_links (struct net_device *dev) +{ +struct netdev_adjacent *iter; + +struct net *net =dev_net (dev); + +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_add (iter->dev, dev, + &iter->dev->adj_list.lower); +netdev_adjacent_sysfs_add (dev, iter->dev, + &dev->adj_list.upper); + } + +list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_add (iter->dev, dev, + &iter->dev->adj_list.upper); +netdev_adjacent_sysfs_add (dev, iter->dev, + &dev->adj_list.lower); + } +} + +void netdev_adjacent_del_links (struct net_device *dev) +{ +struct netdev_adjacent *iter; + +struct net *net =dev_net (dev); + +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_del (iter->dev, dev->name, + &iter->dev->adj_list.lower); +netdev_adjacent_sysfs_del (dev, iter->dev->name, + &dev->adj_list.upper); + } + +list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_del (iter->dev, dev->name, + &iter->dev->adj_list.upper); +netdev_adjacent_sysfs_del (dev, iter->dev->name, + &dev->adj_list.lower); + } +} +void netdev_adjacent_rename_links (struct net_device *dev,char *oldname) {struct netdev_adjacent *iter; +struct net *net =dev_net (dev); +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ;netdev_adjacent_sysfs_del (iter->dev, oldname, &iter->dev->adj_list.lower); netdev_adjacent_sysfs_add(iter->dev, dev,
@@ -5171,6 +5226,8 @@ void netdev_adjacent_rename_links(struct net_device *dev, char *oldname) }list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ;netdev_adjacent_sysfs_del (iter->dev, oldname, &iter->dev->adj_list.upper); netdev_adjacent_sysfs_add(iter->dev, dev,
@@ -6771,8 +6828,10 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const chardev_uc_flush (dev);dev_mc_flush (dev); +/* Send a netdev-removed uevent to the old namespace */ kobject_uevent (&dev->dev.kobj,KOBJ_REMOVE ); +netdev_adjacent_del_links (dev);/* Actually switch the network namespace */ dev_net_set (dev, net);
@@ -6787,6 +6846,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char/* Send a netdev-add uevent to the new namespace */ kobject_uevent (&dev->dev.kobj,KOBJ_ADD ); +netdev_adjacent_add_links (dev);/* Fixup kobjects */ err =device_rename (&dev->dev, dev->name);
Signature · 1 line
2.0.4
David Miller
maintainerRe: [PATCH] net: prevent of emerging cross-namespace symlinks
From: "Alexander Y. Fomichev" <[email protected]>
Date: Sat, 23 Aug 2014 03:15:10 +0400
Quoted 14 lines
Code manipulating sysfs symlinks on adjacent
net_devices(s)currently doesn't take into account that devices potentially belong to different namespaces.This patch trying to fix an issue as follows:
- check fornet_nsbefore creating / deleting symlink. for now onlynetdev_adjacent_rename_linksand__netdev_adjacent_dev_removeare affected, afaics__netdev_adjacent_dev_insertimplies bothnet_devsbelong to the same namespace.
- Drop all existing symlinks to / from alladj_devsbefore switching namespace and recreate them just after.Signed-off-by Alexander Y. Fomichev <[email protected]>
...
net/core/dev.c static void __netdev_adjacent_dev_remove(struct net_device *dev, · line 4893
Quoted 3 lines
net/core/dev.c +2
-1-if (netdev_adjacent_is_neigh_list (dev, dev_list)) +if (netdev_adjacent_is_neigh_list (dev, dev_list) && +net_eq (dev_net (dev),dev_net (adj_dev)))
Please indent this properly.
For a multi-line conditional, the second and subsequent lines should begin exactly at the first column after the openning parenthesis of the first line.
You must use the appropriate number of TAB and SPACE characters necessary to do so.
Thank you.
PATCH 1/1 net: prevent of emerging cross-namespace symlinks
Code manipulating sysfs symlinks on adjacent net_devices(s) currently doesn't take into account that devices potentially belong to different namespaces.
This patch trying to fix an issue as follows:
- check for net_ns before creating / deleting symlink. for now only netdev_adjacent_rename_links and __netdev_adjacent_dev_remove are affected, afaics __netdev_adjacent_dev_insert implies both net_devs belong to the same namespace.
- Drop all existing symlinks to / from all adj_devs before switching namespace and recreate them just after.
--- net/core/dev.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-)
net/core/dev.c +60 -1
@@ -4889,7 +4889,8 @@ static void __netdev_adjacent_dev_remove(struct net_device *dev,if (adj->master)sysfs_remove_link (&(dev->dev.kobj),"master" ); -if (netdev_adjacent_is_neigh_list (dev, dev_list)) +if (netdev_adjacent_is_neigh_list (dev, dev_list) && +net_eq (dev_net (dev),dev_net (adj_dev)))netdev_adjacent_sysfs_del (dev, adj_dev->name, dev_list);list_del_rcu (&adj->list);
@@ -5159,11 +5160,65 @@ void netdev_upper_dev_unlink(struct net_device *dev, }EXPORT_SYMBOL (netdev_upper_dev_unlink); +void netdev_adjacent_add_links (struct net_device *dev) +{ +struct netdev_adjacent *iter; + +struct net *net =dev_net (dev); + +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_add (iter->dev, dev, + &iter->dev->adj_list.lower); +netdev_adjacent_sysfs_add (dev, iter->dev, + &dev->adj_list.upper); + } + +list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_add (iter->dev, dev, + &iter->dev->adj_list.upper); +netdev_adjacent_sysfs_add (dev, iter->dev, + &dev->adj_list.lower); + } +} + +void netdev_adjacent_del_links (struct net_device *dev) +{ +struct netdev_adjacent *iter; + +struct net *net =dev_net (dev); + +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_del (iter->dev, dev->name, + &iter->dev->adj_list.lower); +netdev_adjacent_sysfs_del (dev, iter->dev->name, + &dev->adj_list.upper); + } + +list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_del (iter->dev, dev->name, + &iter->dev->adj_list.upper); +netdev_adjacent_sysfs_del (dev, iter->dev->name, + &dev->adj_list.lower); + } +} +void netdev_adjacent_rename_links (struct net_device *dev,char *oldname) {struct netdev_adjacent *iter; +struct net *net =dev_net (dev); +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ;netdev_adjacent_sysfs_del (iter->dev, oldname, &iter->dev->adj_list.lower); netdev_adjacent_sysfs_add(iter->dev, dev,
@@ -5171,6 +5226,8 @@ void netdev_adjacent_rename_links(struct net_device *dev, char *oldname) }list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ;netdev_adjacent_sysfs_del (iter->dev, oldname, &iter->dev->adj_list.upper); netdev_adjacent_sysfs_add(iter->dev, dev,
@@ -6773,6 +6830,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char/* Send a netdev-removed uevent to the old namespace */ kobject_uevent (&dev->dev.kobj,KOBJ_REMOVE ); +netdev_adjacent_del_links (dev);/* Actually switch the network namespace */ dev_net_set (dev, net);
@@ -6787,6 +6845,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char/* Send a netdev-add uevent to the new namespace */ kobject_uevent (&dev->dev.kobj,KOBJ_ADD ); +netdev_adjacent_add_links (dev);/* Fixup kobjects */ err =device_rename (&dev->dev, dev->name);
Signature · 1 line
2.0.4
Re: [PATCH] net: prevent of emerging cross-namespace symlinks
oops! not signed again, sorry. ignore pls.
Quoted 124 lines · Alexander Y. Fomichev
Code manipulating sysfs symlinks on adjacent
net_devices(s)currently doesn't take into account that devices potentially belong to different namespaces.This patch trying to fix an issue as follows:
- check fornet_nsbefore creating / deleting symlink. for now onlynetdev_adjacent_rename_linksand__netdev_adjacent_dev_removeare affected, afaics__netdev_adjacent_dev_insertimplies bothnet_devsbelong to the same namespace.
- Drop all existing symlinks to / from alladj_devsbefore switching namespace and recreate them just after.--- net/core/dev.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-)net/core/dev.c +60
-2@@ -4889,7 +4889,8 @@ static void __netdev_adjacent_dev_remove(struct net_device *dev,if (adj->master)sysfs_remove_link (&(dev->dev.kobj),"master" ); -if (netdev_adjacent_is_neigh_list (dev, dev_list)) +if (netdev_adjacent_is_neigh_list (dev, dev_list) && +net_eq (dev_net (dev),dev_net (adj_dev)))netdev_adjacent_sysfs_del (dev, adj_dev->name, dev_list);list_del_rcu (&adj->list);@@ -5159,11 +5160,65 @@ void netdev_upper_dev_unlink(struct net_device *dev, }EXPORT_SYMBOL (netdev_upper_dev_unlink); +void netdev_adjacent_add_links (struct net_device *dev) +{ +struct netdev_adjacent *iter; + +struct net *net =dev_net (dev); + +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_add (iter->dev, dev, + &iter->dev->adj_list.lower); +netdev_adjacent_sysfs_add (dev, iter->dev, + &dev->adj_list.upper); + } + +list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_add (iter->dev, dev, + &iter->dev->adj_list.upper); +netdev_adjacent_sysfs_add (dev, iter->dev, + &dev->adj_list.lower); + } +} + +void netdev_adjacent_del_links (struct net_device *dev) +{ +struct netdev_adjacent *iter; + +struct net *net =dev_net (dev); + +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_del (iter->dev, dev->name, + &iter->dev->adj_list.lower); +netdev_adjacent_sysfs_del (dev, iter->dev->name, + &dev->adj_list.upper); + } + +list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_del (iter->dev, dev->name, + &iter->dev->adj_list.upper); +netdev_adjacent_sysfs_del (dev, iter->dev->name, + &dev->adj_list.lower); + } +} +void netdev_adjacent_rename_links (struct net_device *dev,char *oldname) {struct netdev_adjacent *iter; +struct net *net =dev_net (dev); +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ;netdev_adjacent_sysfs_del (iter->dev, oldname, &iter->dev->adj_list.lower); netdev_adjacent_sysfs_add(iter->dev, dev,@@ -5171,6 +5226,8 @@ void netdev_adjacent_rename_links(struct net_device *dev, char *oldname) }list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ;netdev_adjacent_sysfs_del (iter->dev, oldname, &iter->dev->adj_list.upper); netdev_adjacent_sysfs_add(iter->dev, dev,@@ -6773,6 +6830,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char/* Send a netdev-removed uevent to the old namespace */ kobject_uevent (&dev->dev.kobj,KOBJ_REMOVE ); +netdev_adjacent_del_links (dev);/* Actually switch the network namespace */ dev_net_set (dev, net);@@ -6787,6 +6845,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char/* Send a netdev-add uevent to the new namespace */ kobject_uevent (&dev->dev.kobj,KOBJ_ADD ); +netdev_adjacent_add_links (dev);/* Fixup kobjects */ err =device_rename (&dev->dev, dev->name); --2.0.4
Signature · 2 lines
Best regards.
Alexander Y. Fomichev <[email protected]>PATCH 1/1 net: prevent of emerging cross-namespace symlinks
In reply to David MillerCode manipulating sysfs symlinks on adjacent net_devices(s) currently doesn't take into account that devices potentially belong to different namespaces.
This patch trying to fix an issue as follows:
- check for net_ns before creating / deleting symlink. for now only netdev_adjacent_rename_links and __netdev_adjacent_dev_remove are affected, afaics __netdev_adjacent_dev_insert implies both net_devs belong to the same namespace.
- Drop all existing symlinks to / from all adj_devs before switching namespace and recreate them just after.
--- net/core/dev.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-)
net/core/dev.c +60 -1
@@ -4889,7 +4889,8 @@ static void __netdev_adjacent_dev_remove(struct net_device *dev,if (adj->master)sysfs_remove_link (&(dev->dev.kobj),"master" ); -if (netdev_adjacent_is_neigh_list (dev, dev_list)) +if (netdev_adjacent_is_neigh_list (dev, dev_list) && +net_eq (dev_net (dev),dev_net (adj_dev)))netdev_adjacent_sysfs_del (dev, adj_dev->name, dev_list);list_del_rcu (&adj->list);
@@ -5159,11 +5160,65 @@ void netdev_upper_dev_unlink(struct net_device *dev, }EXPORT_SYMBOL (netdev_upper_dev_unlink); +void netdev_adjacent_add_links (struct net_device *dev) +{ +struct netdev_adjacent *iter; + +struct net *net =dev_net (dev); + +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_add (iter->dev, dev, + &iter->dev->adj_list.lower); +netdev_adjacent_sysfs_add (dev, iter->dev, + &dev->adj_list.upper); + } + +list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_add (iter->dev, dev, + &iter->dev->adj_list.upper); +netdev_adjacent_sysfs_add (dev, iter->dev, + &dev->adj_list.lower); + } +} + +void netdev_adjacent_del_links (struct net_device *dev) +{ +struct netdev_adjacent *iter; + +struct net *net =dev_net (dev); + +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_del (iter->dev, dev->name, + &iter->dev->adj_list.lower); +netdev_adjacent_sysfs_del (dev, iter->dev->name, + &dev->adj_list.upper); + } + +list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ; +netdev_adjacent_sysfs_del (iter->dev, dev->name, + &iter->dev->adj_list.upper); +netdev_adjacent_sysfs_del (dev, iter->dev->name, + &dev->adj_list.lower); + } +} +void netdev_adjacent_rename_links (struct net_device *dev,char *oldname) {struct netdev_adjacent *iter; +struct net *net =dev_net (dev); +list_for_each_entry (iter, &dev->adj_list.upper, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ;netdev_adjacent_sysfs_del (iter->dev, oldname, &iter->dev->adj_list.lower); netdev_adjacent_sysfs_add(iter->dev, dev,
@@ -5171,6 +5226,8 @@ void netdev_adjacent_rename_links(struct net_device *dev, char *oldname) }list_for_each_entry (iter, &dev->adj_list.lower, list) { +if (!net_eq (net,dev_net (iter->dev))) +continue ;netdev_adjacent_sysfs_del (iter->dev, oldname, &iter->dev->adj_list.upper); netdev_adjacent_sysfs_add(iter->dev, dev,
@@ -6773,6 +6830,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char/* Send a netdev-removed uevent to the old namespace */ kobject_uevent (&dev->dev.kobj,KOBJ_REMOVE ); +netdev_adjacent_del_links (dev);/* Actually switch the network namespace */ dev_net_set (dev, net);
@@ -6787,6 +6845,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char/* Send a netdev-add uevent to the new namespace */ kobject_uevent (&dev->dev.kobj,KOBJ_ADD ); +netdev_adjacent_add_links (dev);/* Fixup kobjects */ err =device_rename (&dev->dev, dev->name);
Signature · 1 line
2.0.4
Re: [PATCH] net: prevent of emerging cross-namespace symlinks
From: "Alexander Y. Fomichev" <[email protected]>
Date: Mon, 25 Aug 2014 16:26:45 +0400
Quoted 13 lines
Code manipulating sysfs symlinks on adjacent
net_devices(s)currently doesn't take into account that devices potentially belong to different namespaces.This patch trying to fix an issue as follows:
- check fornet_nsbefore creating / deleting symlink. for now onlynetdev_adjacent_rename_linksand__netdev_adjacent_dev_removeare affected, afaics__netdev_adjacent_dev_insertimplies bothnet_devsbelong to the same namespace.
- Drop all existing symlinks to / from alladj_devsbefore switching namespace and recreate them just after.
Quoted 1 line
Signed-off-by Alexander Y. Fomichev <[email protected]>
Applied, thanks.