All of lore.kernel.org
 help / color / mirror / Atom feed
* Is it normal to have cross namespace symlinks?
@ 2014-08-21 10:38 Alexander Y. Fomichev
  2014-08-21 12:12 ` Veaceslav Falico
  0 siblings, 1 reply; 13+ messages in thread
From: Alexander Y. Fomichev @ 2014-08-21 10:38 UTC (permalink / raw)
  To: netdev

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?

-- 

Best regards.
        Alexander Y. Fomichev <Aleksandr.Fomichev@x5.ru>
	        +7-495-662-88-88 ext. 11346

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Is it normal to have cross namespace symlinks?
  2014-08-21 10:38 Is it normal to have cross namespace symlinks? Alexander Y. Fomichev
@ 2014-08-21 12:12 ` Veaceslav Falico
  2014-08-21 15:13   ` Alexander Y. Fomichev
  0 siblings, 1 reply; 13+ messages in thread
From: Veaceslav Falico @ 2014-08-21 12:12 UTC (permalink / raw)
  To: Alexander Y. Fomichev; +Cc: netdev

On Thu, Aug 21, 2014 at 02:38:16PM +0400, Alexander Y. Fomichev wrote:
>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.
>v
>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.

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?

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Is it normal to have cross namespace symlinks?
  2014-08-21 12:12 ` Veaceslav Falico
@ 2014-08-21 15:13   ` Alexander Y. Fomichev
  2014-08-21 15:29     ` Veaceslav Falico
  0 siblings, 1 reply; 13+ messages in thread
From: Alexander Y. Fomichev @ 2014-08-21 15:13 UTC (permalink / raw)
  To: Veaceslav Falico; +Cc: netdev

[-- Attachment #1: Type: text/plain, Size: 2611 bytes --]

On Thu, 21 Aug 2014 14:12:05 +0200
Veaceslav Falico <vfalico@redhat.com> wrote:

> On Thu, Aug 21, 2014 at 02:38:16PM +0400, Alexander Y. Fomichev wrote:
> >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.
> >v
> >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.
> 
> 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.

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.

> 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.

-- 

Best regards.
        Alexander Y. Fomichev <Aleksandr.Fomichev@x5.ru>
	        +7-495-662-88-88 ext. 11346

[-- Attachment #2: fix_netdev_adjacent_sysfs_links.patch --]
[-- Type: text/x-patch, Size: 3431 bytes --]

diff --git a/net/core/dev.c b/net/core/dev.c
index b65a505..683cedf 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -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 char
 	dev_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);

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: Is it normal to have cross namespace symlinks?
  2014-08-21 15:13   ` Alexander Y. Fomichev
@ 2014-08-21 15:29     ` Veaceslav Falico
  2014-08-22  8:53       ` [PATCH] netdev_adjacent_sysfs_*: fix cross-namespace symlinks Alexander Y. Fomichev
  2014-08-22 10:34       ` Alexander Y. Fomichev
  0 siblings, 2 replies; 13+ messages in thread
From: Veaceslav Falico @ 2014-08-21 15:29 UTC (permalink / raw)
  To: Alexander Y. Fomichev; +Cc: netdev

On Thu, Aug 21, 2014 at 07:13:16PM +0400, Alexander Y. Fomichev wrote:
>On Thu, 21 Aug 2014 14:12:05 +0200
>Veaceslav Falico <vfalico@redhat.com> wrote:
>
>> On Thu, Aug 21, 2014 at 02:38:16PM +0400, Alexander Y. Fomichev wrote:
>> >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.
>> >v
>> >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.
>>
>> 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.
>
>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.

>
>> 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.

Yep, agreed.

Thank you!

>
>-- 
>
>Best regards.
>        Alexander Y. Fomichev <Aleksandr.Fomichev@x5.ru>
>	        +7-495-662-88-88 ext. 11346

>diff --git a/net/core/dev.c b/net/core/dev.c
>index b65a505..683cedf 100644
>--- a/net/core/dev.c
>+++ b/net/core/dev.c
>@@ -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 char
> 	dev_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);

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH] netdev_adjacent_sysfs_*: fix cross-namespace symlinks
  2014-08-21 15:29     ` Veaceslav Falico
@ 2014-08-22  8:53       ` Alexander Y. Fomichev
  2014-08-22 10:34       ` Alexander Y. Fomichev
  1 sibling, 0 replies; 13+ messages in thread
From: Alexander Y. Fomichev @ 2014-08-22  8:53 UTC (permalink / raw)
  To: netdev

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(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index b65a505..683cedf 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -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 char
 	dev_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);
-- 
2.0.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH] netdev_adjacent_sysfs_*: fix cross-namespace symlinks
  2014-08-21 15:29     ` Veaceslav Falico
  2014-08-22  8:53       ` [PATCH] netdev_adjacent_sysfs_*: fix cross-namespace symlinks Alexander Y. Fomichev
@ 2014-08-22 10:34       ` Alexander Y. Fomichev
  2014-08-22 18:30         ` David Miller
  1 sibling, 1 reply; 13+ messages in thread
From: Alexander Y. Fomichev @ 2014-08-22 10:34 UTC (permalink / raw)
  To: netdev; +Cc: Alexander Y. Fomichev, vfalico

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(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index b65a505..683cedf 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -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 char
 	dev_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);
-- 
2.0.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH] netdev_adjacent_sysfs_*: fix cross-namespace symlinks
  2014-08-22 10:34       ` Alexander Y. Fomichev
@ 2014-08-22 18:30         ` David Miller
  2014-08-22 23:15           ` [PATCH] net: prevent of emerging " Alexander Y. Fomichev
  0 siblings, 1 reply; 13+ messages in thread
From: David Miller @ 2014-08-22 18:30 UTC (permalink / raw)
  To: git.user; +Cc: netdev, vfalico

From: "Alexander Y. Fomichev" <git.user@gmail.com>
Date: Fri, 22 Aug 2014 14:34:53 +0400

> 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.

Please resubmit this with a proper Signed-off-by tag.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH] net: prevent of emerging cross-namespace symlinks
  2014-08-22 18:30         ` David Miller
@ 2014-08-22 23:15           ` Alexander Y. Fomichev
  2014-08-25  1:28             ` David Miller
  0 siblings, 1 reply; 13+ messages in thread
From: Alexander Y. Fomichev @ 2014-08-22 23:15 UTC (permalink / raw)
  To: netdev; +Cc: Alexander Y. Fomichev, vfalico, David Miller

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.

Signed-off-by: Alexander Y. Fomichev <git.user@gmail.com>
---
 net/core/dev.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 61 insertions(+), 1 deletion(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index b65a5051361f..683cedfdad8e 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -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 char
 	dev_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);
-- 
2.0.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH] net: prevent of emerging cross-namespace symlinks
  2014-08-22 23:15           ` [PATCH] net: prevent of emerging " Alexander Y. Fomichev
@ 2014-08-25  1:28             ` David Miller
  2014-08-25 12:06               ` Alexander Y. Fomichev
  2014-08-25 12:26               ` Alexander Y. Fomichev
  0 siblings, 2 replies; 13+ messages in thread
From: David Miller @ 2014-08-25  1:28 UTC (permalink / raw)
  To: git.user; +Cc: netdev, vfalico

From: "Alexander Y. Fomichev" <git.user@gmail.com>
Date: Sat, 23 Aug 2014 03:15:10 +0400

> 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.
> 
> Signed-off-by: Alexander Y. Fomichev <git.user@gmail.com>
 ...
> -	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.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH] net: prevent of emerging cross-namespace symlinks
  2014-08-25  1:28             ` David Miller
@ 2014-08-25 12:06               ` Alexander Y. Fomichev
  2014-08-25 12:39                 ` Alexander Y. Fomichev
  2014-08-25 12:26               ` Alexander Y. Fomichev
  1 sibling, 1 reply; 13+ messages in thread
From: Alexander Y. Fomichev @ 2014-08-25 12:06 UTC (permalink / raw)
  To: netdev; +Cc: Alexander Y. Fomichev, vfalico, David Miller

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(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index b65a5051361f..66738e9d66e4 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH] net: prevent of emerging cross-namespace symlinks
  2014-08-25  1:28             ` David Miller
  2014-08-25 12:06               ` Alexander Y. Fomichev
@ 2014-08-25 12:26               ` Alexander Y. Fomichev
  2014-08-25 22:18                 ` David Miller
  1 sibling, 1 reply; 13+ messages in thread
From: Alexander Y. Fomichev @ 2014-08-25 12:26 UTC (permalink / raw)
  To: netdev; +Cc: Alexander Y. Fomichev, vfalico, David Miller

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.

Signed-off-by: Alexander Y. Fomichev <git.user@gmail.com>
---
 net/core/dev.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 60 insertions(+), 1 deletion(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index b65a5051361f..66738e9d66e4 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH] net: prevent of emerging cross-namespace symlinks
  2014-08-25 12:06               ` Alexander Y. Fomichev
@ 2014-08-25 12:39                 ` Alexander Y. Fomichev
  0 siblings, 0 replies; 13+ messages in thread
From: Alexander Y. Fomichev @ 2014-08-25 12:39 UTC (permalink / raw)
  To: netdev; +Cc: Alexander Y. Fomichev, vfalico, David Miller

oops! not signed again, sorry. ignore pls.

On Mon, Aug 25, 2014 at 4:06 PM, Alexander Y. Fomichev
<git.user@gmail.com> wrote:
> 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(-)
>
> diff --git a/net/core/dev.c b/net/core/dev.c
> index b65a5051361f..66738e9d66e4 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -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
>



-- 
Best regards.
       Alexander Y. Fomichev <git.user@gmail.com>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] net: prevent of emerging cross-namespace symlinks
  2014-08-25 12:26               ` Alexander Y. Fomichev
@ 2014-08-25 22:18                 ` David Miller
  0 siblings, 0 replies; 13+ messages in thread
From: David Miller @ 2014-08-25 22:18 UTC (permalink / raw)
  To: git.user; +Cc: netdev, vfalico

From: "Alexander Y. Fomichev" <git.user@gmail.com>
Date: Mon, 25 Aug 2014 16:26:45 +0400

> 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.
> 
> Signed-off-by: Alexander Y. Fomichev <git.user@gmail.com>

Applied, thanks.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2014-08-25 22:18 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-21 10:38 Is it normal to have cross namespace symlinks? Alexander Y. Fomichev
2014-08-21 12:12 ` Veaceslav Falico
2014-08-21 15:13   ` Alexander Y. Fomichev
2014-08-21 15:29     ` Veaceslav Falico
2014-08-22  8:53       ` [PATCH] netdev_adjacent_sysfs_*: fix cross-namespace symlinks Alexander Y. Fomichev
2014-08-22 10:34       ` Alexander Y. Fomichev
2014-08-22 18:30         ` David Miller
2014-08-22 23:15           ` [PATCH] net: prevent of emerging " Alexander Y. Fomichev
2014-08-25  1:28             ` David Miller
2014-08-25 12:06               ` Alexander Y. Fomichev
2014-08-25 12:39                 ` Alexander Y. Fomichev
2014-08-25 12:26               ` Alexander Y. Fomichev
2014-08-25 22:18                 ` David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.