diff options
author | Nicolas Dichtel <nicolas.dichtel@6wind.com> | 2018-01-25 15:01:39 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-01-29 12:23:52 -0500 |
commit | 38e01b30563a5b5ade7b54e5d739d16a2b02fe82 (patch) | |
tree | 4c8fa3f46034244bb2e5eaa7cc1258b0ae427c68 /net/core/dev.c | |
parent | c36ac8e2307334c83e8bf81ed361f0e4959d995f (diff) | |
download | lwn-38e01b30563a5b5ade7b54e5d739d16a2b02fe82.tar.gz lwn-38e01b30563a5b5ade7b54e5d739d16a2b02fe82.zip |
dev: advertise the new ifindex when the netns iface changes
The goal is to let the user follow an interface that moves to another
netns.
CC: Jiri Benc <jbenc@redhat.com>
CC: Christian Brauner <christian.brauner@ubuntu.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Reviewed-by: Jiri Benc <jbenc@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 59987eb6511a..858501b12869 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -7360,7 +7360,7 @@ static void rollback_registered_many(struct list_head *head) if (!dev->rtnl_link_ops || dev->rtnl_link_state == RTNL_LINK_INITIALIZED) skb = rtmsg_ifinfo_build_skb(RTM_DELLINK, dev, ~0U, 0, - GFP_KERNEL, NULL); + GFP_KERNEL, NULL, 0); /* * Flush the unicast and multicast chains @@ -8473,7 +8473,7 @@ EXPORT_SYMBOL(unregister_netdev); int dev_change_net_namespace(struct net_device *dev, struct net *net, const char *pat) { - int err, new_nsid; + int err, new_nsid, new_ifindex; ASSERT_RTNL(); @@ -8529,8 +8529,16 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char call_netdevice_notifiers(NETDEV_UNREGISTER, dev); rcu_barrier(); call_netdevice_notifiers(NETDEV_UNREGISTER_FINAL, dev); + new_nsid = peernet2id_alloc(dev_net(dev), net); - rtmsg_ifinfo_newnet(RTM_DELLINK, dev, ~0U, GFP_KERNEL, &new_nsid); + /* If there is an ifindex conflict assign a new one */ + if (__dev_get_by_index(net, dev->ifindex)) + new_ifindex = dev_new_index(net); + else + new_ifindex = dev->ifindex; + + rtmsg_ifinfo_newnet(RTM_DELLINK, dev, ~0U, GFP_KERNEL, &new_nsid, + new_ifindex); /* * Flush the unicast and multicast chains @@ -8544,10 +8552,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char /* Actually switch the network namespace */ dev_net_set(dev, net); - - /* If there is an ifindex conflict assign a new one */ - if (__dev_get_by_index(net, dev->ifindex)) - dev->ifindex = dev_new_index(net); + dev->ifindex = new_ifindex; /* Send a netdev-add uevent to the new namespace */ kobject_uevent(&dev->dev.kobj, KOBJ_ADD); |