cfg80211: always notify userspace of new wireless netdevs
This change alters the semantics of NL80211_CMD_NEW_INTERFACE events by always sending this event whenever a new net_device object associated with a wdev is registered. Prior to this change, this event was only sent as a result of NL80211_CMD_NEW_INTERFACE command sent from userspace. This allows userspace to reliably detect new wireless interfaces (e.g. due to hardware hot-plug events, etc). For wdevs created without an associated net_device object (e.g. NL80211_IFTYPE_P2P_DEVICE), the NL80211_CMD_NEW_INTERFACE event is still generated inside the relevant nl80211 command handler. Signed-off-by: Denis Kenzior <denkenz@gmail.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
eae4430ee7
commit
896ff0635a
@ -1079,6 +1079,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
|
||||
wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
|
||||
wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
|
||||
dev->priv_flags |= IFF_DONT_BRIDGE;
|
||||
|
||||
nl80211_notify_iface(rdev, wdev, NL80211_CMD_NEW_INTERFACE);
|
||||
break;
|
||||
case NETDEV_GOING_DOWN:
|
||||
cfg80211_leave(rdev, wdev);
|
||||
|
@ -2751,7 +2751,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
struct vif_params params;
|
||||
struct wireless_dev *wdev;
|
||||
struct sk_buff *msg, *event;
|
||||
struct sk_buff *msg;
|
||||
int err;
|
||||
enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
|
||||
u32 flags;
|
||||
@ -2855,20 +2855,15 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
event = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (event) {
|
||||
if (nl80211_send_iface(event, 0, 0, 0,
|
||||
rdev, wdev, false) < 0) {
|
||||
nlmsg_free(event);
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* For wdevs which have no associated netdev object (e.g. of type
|
||||
* NL80211_IFTYPE_P2P_DEVICE), emit the NEW_INTERFACE event here.
|
||||
* For all other types, the event will be generated from the
|
||||
* netdev notifier
|
||||
*/
|
||||
if (!wdev->netdev)
|
||||
nl80211_notify_iface(rdev, wdev, NL80211_CMD_NEW_INTERFACE);
|
||||
|
||||
genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
|
||||
event, 0, NL80211_MCGRP_CONFIG,
|
||||
GFP_KERNEL);
|
||||
}
|
||||
|
||||
out:
|
||||
return genlmsg_reply(msg, info);
|
||||
}
|
||||
|
||||
@ -11847,6 +11842,29 @@ void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
|
||||
NL80211_MCGRP_CONFIG, GFP_KERNEL);
|
||||
}
|
||||
|
||||
void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev,
|
||||
enum nl80211_commands cmd)
|
||||
{
|
||||
struct sk_buff *msg;
|
||||
|
||||
WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
|
||||
cmd != NL80211_CMD_DEL_INTERFACE);
|
||||
|
||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
if (nl80211_send_iface(msg, 0, 0, 0, rdev, wdev,
|
||||
cmd == NL80211_CMD_DEL_INTERFACE) < 0) {
|
||||
nlmsg_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
|
||||
NL80211_MCGRP_CONFIG, GFP_KERNEL);
|
||||
}
|
||||
|
||||
static int nl80211_add_scan_req(struct sk_buff *msg,
|
||||
struct cfg80211_registered_device *rdev)
|
||||
{
|
||||
|
@ -7,6 +7,9 @@ int nl80211_init(void);
|
||||
void nl80211_exit(void);
|
||||
void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
|
||||
enum nl80211_commands cmd);
|
||||
void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev,
|
||||
enum nl80211_commands cmd);
|
||||
void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev);
|
||||
struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
|
||||
|
Loading…
Reference in New Issue
Block a user