UPSTREAM: wifi: cfg80211: clean up links appropriately

This was missing earlier, we need to remove links when
interfaces are being destroyed, and we also need to
stop (AP) operations when a link is being destroyed.
Address these issues to remove many warnings that will
otherwise appear in mac80211.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>

Bug: 253289327
Change-Id: I5645aa4887d1a44a93c2ccf805c4e27977e007a3
(cherry picked from commit cdf0a0a80c841cfede6926d417a8756ea4c52d26)
Signed-off-by: Kiran Kumar Lokere <quic_klokere@quicinc.com>
This commit is contained in:
Johannes Berg
2022-07-06 09:57:42 +02:00
committed by Todd Kjos
parent 6b5b4300ba
commit 3ce62ab9f9
4 changed files with 52 additions and 10 deletions

View File

@@ -342,7 +342,7 @@ void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev)
wiphy_lock(&rdev->wiphy);
cfg80211_leave(rdev, wdev);
rdev_del_virtual_intf(rdev, wdev);
cfg80211_remove_virtual_intf(rdev, wdev);
wiphy_unlock(&rdev->wiphy);
}
}
@@ -1436,6 +1436,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
case NETDEV_GOING_DOWN:
wiphy_lock(&rdev->wiphy);
cfg80211_leave(rdev, wdev);
cfg80211_remove_links(wdev);
wiphy_unlock(&rdev->wiphy);
break;
case NETDEV_DOWN:

View File

@@ -562,4 +562,9 @@ void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid);
void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev);
void cfg80211_pmsr_free_wk(struct work_struct *work);
void cfg80211_remove_link(struct wireless_dev *wdev, unsigned int link_id);
void cfg80211_remove_links(struct wireless_dev *wdev);
int cfg80211_remove_virtual_intf(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev);
#endif /* __NET_WIRELESS_CORE_H */

View File

@@ -4276,7 +4276,7 @@ static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
mutex_lock(&rdev->wiphy.mtx);
return rdev_del_virtual_intf(rdev, wdev);
return cfg80211_remove_virtual_intf(rdev, wdev);
}
static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info)
@@ -15771,7 +15771,6 @@ static int nl80211_add_link(struct sk_buff *skb, struct genl_info *info)
static int nl80211_remove_link(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
unsigned int link_id = nl80211_link_id(info->attrs);
struct net_device *dev = info->user_ptr[1];
struct wireless_dev *wdev = dev->ieee80211_ptr;
@@ -15787,14 +15786,8 @@ static int nl80211_remove_link(struct sk_buff *skb, struct genl_info *info)
return -EINVAL;
}
/* FIXME: stop the link operations first */
wdev_lock(wdev);
wdev->valid_links &= ~BIT(link_id);
rdev_del_intf_link(rdev, wdev, link_id);
eth_zero_addr(wdev->links[link_id].addr);
cfg80211_remove_link(wdev, link_id);
wdev_unlock(wdev);
return 0;

View File

@@ -2445,3 +2445,46 @@ bool cfg80211_iftype_allowed(struct wiphy *wiphy, enum nl80211_iftype iftype,
return false;
}
EXPORT_SYMBOL(cfg80211_iftype_allowed);
void cfg80211_remove_link(struct wireless_dev *wdev, unsigned int link_id)
{
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
ASSERT_WDEV_LOCK(wdev);
switch (wdev->iftype) {
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_P2P_GO:
__cfg80211_stop_ap(rdev, wdev->netdev, link_id, true);
break;
default:
/* per-link not relevant */
break;
}
wdev->valid_links &= ~BIT(link_id);
rdev_del_intf_link(rdev, wdev, link_id);
eth_zero_addr(wdev->links[link_id].addr);
}
void cfg80211_remove_links(struct wireless_dev *wdev)
{
unsigned int link_id;
wdev_lock(wdev);
if (wdev->valid_links) {
for_each_valid_link(wdev, link_id)
cfg80211_remove_link(wdev, link_id);
}
wdev_unlock(wdev);
}
int cfg80211_remove_virtual_intf(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev)
{
cfg80211_remove_links(wdev);
return rdev_del_virtual_intf(rdev, wdev);
}