net: move altnames together with the netdevice
authorJakub Kicinski <kuba@kernel.org>
Wed, 18 Oct 2023 01:38:16 +0000 (18:38 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 25 Oct 2023 10:03:16 +0000 (12:03 +0200)
commit 8e15aee621618a3ee3abecaf1fd8c1428098b7ef upstream.

The altname nodes are currently not moved to the new netns
when netdevice itself moves:

  [ ~]# ip netns add test
  [ ~]# ip -netns test link add name eth0 type dummy
  [ ~]# ip -netns test link property add dev eth0 altname some-name
  [ ~]# ip -netns test link show dev some-name
  2: eth0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
      link/ether 1e:67:ed:19:3d:24 brd ff:ff:ff:ff:ff:ff
      altname some-name
  [ ~]# ip -netns test link set dev eth0 netns 1
  [ ~]# ip link
  ...
  3: eth0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
      link/ether 02:40:88:62:ec:b8 brd ff:ff:ff:ff:ff:ff
      altname some-name
  [ ~]# ip li show dev some-name
  Device "some-name" does not exist.

Remove them from the hash table when device is unlisted
and add back when listed again.

Fixes: 36fbf1e52bd3 ("net: rtnetlink: add linkprop commands to add and delete alternative ifnames")
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/core/dev.c

index 9cacd17feeaaec08b47ef19e515ea208525324e0..0d5aa820fd8300ec9f332d74358cd2eeeba2d6cc 100644 (file)
@@ -381,6 +381,7 @@ static void netdev_name_node_alt_flush(struct net_device *dev)
 /* Device list insertion */
 static void list_netdevice(struct net_device *dev)
 {
+       struct netdev_name_node *name_node;
        struct net *net = dev_net(dev);
 
        ASSERT_RTNL();
@@ -392,6 +393,9 @@ static void list_netdevice(struct net_device *dev)
                           dev_index_hash(net, dev->ifindex));
        write_unlock(&dev_base_lock);
 
+       netdev_for_each_altname(dev, name_node)
+               netdev_name_node_add(net, name_node);
+
        dev_base_seq_inc(net);
 }
 
@@ -400,8 +404,13 @@ static void list_netdevice(struct net_device *dev)
  */
 static void unlist_netdevice(struct net_device *dev, bool lock)
 {
+       struct netdev_name_node *name_node;
+
        ASSERT_RTNL();
 
+       netdev_for_each_altname(dev, name_node)
+               netdev_name_node_del(name_node);
+
        /* Unlink dev from the device chain */
        if (lock)
                write_lock(&dev_base_lock);
@@ -10851,7 +10860,6 @@ void unregister_netdevice_many(struct list_head *head)
        synchronize_net();
 
        list_for_each_entry(dev, head, unreg_list) {
-               struct netdev_name_node *name_node;
                struct sk_buff *skb = NULL;
 
                /* Shutdown queueing discipline. */
@@ -10877,9 +10885,6 @@ void unregister_netdevice_many(struct list_head *head)
                dev_uc_flush(dev);
                dev_mc_flush(dev);
 
-               netdev_for_each_altname(dev, name_node)
-                       netdev_name_node_del(name_node);
-               synchronize_rcu();
                netdev_name_node_alt_flush(dev);
                netdev_name_node_free(dev->name_node);