diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 87cafc932e9e..5b734a04ed7d 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -3441,6 +3441,7 @@ struct net_device *dev_get_by_name(struct net *net, const char *name); struct net_device *dev_get_by_name_rcu(struct net *net, const char *name); struct net_device *__dev_get_by_name(struct net *net, const char *name); bool netdev_name_in_use(struct net *net, const char *name); +void netdev_name_node_alt_flush_exit_net(struct net_device *dev); int dev_alloc_name(struct net_device *dev, const char *name); int netif_open(struct net_device *dev, struct netlink_ext_ack *extack); int dev_open(struct net_device *dev, struct netlink_ext_ack *extack); diff --git a/net/core/dev.c b/net/core/dev.c index 38336858c168..18642f6ce97a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -403,6 +403,15 @@ static void netdev_name_node_alt_flush(struct net_device *dev) } } +void netdev_name_node_alt_flush_exit_net(struct net_device *dev) +{ + struct netdev_name_node *name_node, *tmp; + + netdev_for_each_altname_safe(dev, name_node, tmp) + if (netdev_name_in_use(&init_net, name_node->name)) + __netdev_name_node_alt_destroy(name_node); +} + /* Device list insertion */ static void list_netdevice(struct net_device *dev) { @@ -13210,7 +13219,6 @@ static struct pernet_operations __net_initdata netdev_net_ops = { static void __net_exit default_device_exit_net(struct net *net) { - struct netdev_name_node *name_node, *tmp; struct net_device *dev, *aux; /* * Push all migratable network devices back to the @@ -13234,9 +13242,7 @@ static void __net_exit default_device_exit_net(struct net *net) if (netdev_name_in_use(&init_net, fb_name)) snprintf(fb_name, IFNAMSIZ, "dev%%d"); - netdev_for_each_altname_safe(dev, name_node, tmp) - if (netdev_name_in_use(&init_net, name_node->name)) - __netdev_name_node_alt_destroy(name_node); + netdev_name_node_alt_flush_exit_net(dev); err = dev_change_net_namespace(dev, &init_net, fb_name); if (err) { diff --git a/net/wireless/core.c b/net/wireless/core.c index d13310fef691..5310d95fda77 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -165,6 +165,10 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev, list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { if (!wdev->netdev) continue; + + if (!check_net(dev_net(wdev->netdev))) + netdev_name_node_alt_flush_exit_net(wdev->netdev); + wdev->netdev->netns_immutable = false; err = dev_change_net_namespace(wdev->netdev, net, "wlan%d"); if (err)