aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2016-08-03 17:58:33 -0400
committerJohannes Berg <johannes.berg@intel.com>2016-08-11 10:51:41 -0400
commit896ff0635a312022c91e2bef30c80abc27af62e8 (patch)
treeaa28f1eb1bbb97da2ef565117e79f8d51087cc56 /net/wireless
parenteae4430ee7c5ea1152400cfc070f3746d41fa134 (diff)
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>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.c2
-rw-r--r--net/wireless/nl80211.c46
-rw-r--r--net/wireless/nl80211.h3
3 files changed, 37 insertions, 14 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 7645e97362c0..7758c0fe781a 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -1079,6 +1079,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
1079 wdev->iftype == NL80211_IFTYPE_P2P_CLIENT || 1079 wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
1080 wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr) 1080 wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
1081 dev->priv_flags |= IFF_DONT_BRIDGE; 1081 dev->priv_flags |= IFF_DONT_BRIDGE;
1082
1083 nl80211_notify_iface(rdev, wdev, NL80211_CMD_NEW_INTERFACE);
1082 break; 1084 break;
1083 case NETDEV_GOING_DOWN: 1085 case NETDEV_GOING_DOWN:
1084 cfg80211_leave(rdev, wdev); 1086 cfg80211_leave(rdev, wdev);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index f02653a08993..a8c062dbd51d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2751,7 +2751,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
2751 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 2751 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2752 struct vif_params params; 2752 struct vif_params params;
2753 struct wireless_dev *wdev; 2753 struct wireless_dev *wdev;
2754 struct sk_buff *msg, *event; 2754 struct sk_buff *msg;
2755 int err; 2755 int err;
2756 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; 2756 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
2757 u32 flags; 2757 u32 flags;
@@ -2855,20 +2855,15 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
2855 return -ENOBUFS; 2855 return -ENOBUFS;
2856 } 2856 }
2857 2857
2858 event = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 2858 /*
2859 if (event) { 2859 * For wdevs which have no associated netdev object (e.g. of type
2860 if (nl80211_send_iface(event, 0, 0, 0, 2860 * NL80211_IFTYPE_P2P_DEVICE), emit the NEW_INTERFACE event here.
2861 rdev, wdev, false) < 0) { 2861 * For all other types, the event will be generated from the
2862 nlmsg_free(event); 2862 * netdev notifier
2863 goto out; 2863 */
2864 } 2864 if (!wdev->netdev)
2865 2865 nl80211_notify_iface(rdev, wdev, NL80211_CMD_NEW_INTERFACE);
2866 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
2867 event, 0, NL80211_MCGRP_CONFIG,
2868 GFP_KERNEL);
2869 }
2870 2866
2871out:
2872 return genlmsg_reply(msg, info); 2867 return genlmsg_reply(msg, info);
2873} 2868}
2874 2869
@@ -11847,6 +11842,29 @@ void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
11847 NL80211_MCGRP_CONFIG, GFP_KERNEL); 11842 NL80211_MCGRP_CONFIG, GFP_KERNEL);
11848} 11843}
11849 11844
11845void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
11846 struct wireless_dev *wdev,
11847 enum nl80211_commands cmd)
11848{
11849 struct sk_buff *msg;
11850
11851 WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
11852 cmd != NL80211_CMD_DEL_INTERFACE);
11853
11854 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11855 if (!msg)
11856 return;
11857
11858 if (nl80211_send_iface(msg, 0, 0, 0, rdev, wdev,
11859 cmd == NL80211_CMD_DEL_INTERFACE) < 0) {
11860 nlmsg_free(msg);
11861 return;
11862 }
11863
11864 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
11865 NL80211_MCGRP_CONFIG, GFP_KERNEL);
11866}
11867
11850static int nl80211_add_scan_req(struct sk_buff *msg, 11868static int nl80211_add_scan_req(struct sk_buff *msg,
11851 struct cfg80211_registered_device *rdev) 11869 struct cfg80211_registered_device *rdev)
11852{ 11870{
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index a63f402b10b7..7e3821d7fcc5 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -7,6 +7,9 @@ int nl80211_init(void);
7void nl80211_exit(void); 7void nl80211_exit(void);
8void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev, 8void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
9 enum nl80211_commands cmd); 9 enum nl80211_commands cmd);
10void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
11 struct wireless_dev *wdev,
12 enum nl80211_commands cmd);
10void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, 13void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
11 struct wireless_dev *wdev); 14 struct wireless_dev *wdev);
12struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev, 15struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,