Skip to content

Commit

Permalink
cfg80211: always notify userspace when wireless netdev is removed
Browse files Browse the repository at this point in the history
This change alters the semantics of NL80211_CMD_DEL_INTERFACE events
by always sending this event whenever a net_device object associated
with a wdev is destroyed.  Prior to this change, this event was only
emitted as a result of NL80211_CMD_DEL_INTERFACE command sent from
userspace.  This allows userspace to reliably detect when wireless
interfaces have been removed, e.g. due to USB removal events, etc.

For wireless device objects without an associated net_device (e.g.
NL80211_IFTYPE_P2P_DEVICE), the NL80211_CMD_DEL_INTERFACE event is
now generated inside cfg80211_unregister_wdev.

Signed-off-by: Denis Kenzior <denkenz@gmail.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  • Loading branch information
Denis Kenzior authored and Johannes Berg committed Aug 11, 2016
1 parent 896ff06 commit 7f8ed01
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 17 deletions.
4 changes: 4 additions & 0 deletions net/wireless/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,8 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev)
if (WARN_ON(wdev->netdev))
return;

nl80211_notify_iface(rdev, wdev, NL80211_CMD_DEL_INTERFACE);

list_del_rcu(&wdev->list);
rdev->devlist_generation++;

Expand Down Expand Up @@ -1159,6 +1161,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
* remove and clean it up.
*/
if (!list_empty(&wdev->list)) {
nl80211_notify_iface(rdev, wdev,
NL80211_CMD_DEL_INTERFACE);
sysfs_remove_link(&dev->dev.kobj, "phy80211");
list_del_rcu(&wdev->list);
rdev->devlist_generation++;
Expand Down
18 changes: 1 addition & 17 deletions net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -2871,18 +2871,10 @@ static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct wireless_dev *wdev = info->user_ptr[1];
struct sk_buff *msg;
int status;

if (!rdev->ops->del_virtual_intf)
return -EOPNOTSUPP;

msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (msg && nl80211_send_iface(msg, 0, 0, 0, rdev, wdev, true) < 0) {
nlmsg_free(msg);
msg = NULL;
}

/*
* If we remove a wireless device without a netdev then clear
* user_ptr[1] so that nl80211_post_doit won't dereference it
Expand All @@ -2893,15 +2885,7 @@ static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
if (!wdev->netdev)
info->user_ptr[1] = NULL;

status = rdev_del_virtual_intf(rdev, wdev);
if (status >= 0 && msg)
genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
msg, 0, NL80211_MCGRP_CONFIG,
GFP_KERNEL);
else
nlmsg_free(msg);

return status;
return rdev_del_virtual_intf(rdev, wdev);
}

static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info)
Expand Down

0 comments on commit 7f8ed01

Please sign in to comment.