All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Alexander Y. Fomichev" <git.user@gmail.com>
To: Veaceslav Falico <vfalico@redhat.com>
Cc: netdev@vger.kernel.org
Subject: Re: Is it normal to have cross namespace symlinks?
Date: Thu, 21 Aug 2014 19:13:16 +0400	[thread overview]
Message-ID: <20140821191316.27807ef7@mad-cat.int.e5.ru> (raw)
In-Reply-To: <20140821121205.GR9476@redhat.com>

[-- 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);

  reply	other threads:[~2014-08-21 15:13 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140821191316.27807ef7@mad-cat.int.e5.ru \
    --to=git.user@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=vfalico@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.