cfg80211: Allow a scan request for a specific BSSID
authorJouni Malinen <jouni@qca.qualcomm.com>
Fri, 26 Feb 2016 20:12:47 +0000 (22:12 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 5 Apr 2016 08:56:28 +0000 (10:56 +0200)
This allows scans for a specific BSSID to be optimized by the user space
application by requesting the driver to set the Probe Request frame
BSSID field (Address 3) to the specified BSSID instead of the wildcard
BSSID. This prevents other APs from replying which reduces airtime need
and latency in getting the response from the target AP through.

This is an optimization and as such, it is acceptable for some of the
drivers not to support the mechanism. If not supported, the wildcard
BSSID will be used and more responses may be received.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/wireless/nl80211.c
net/wireless/scan.c
net/wireless/sme.c

index 9e1b24c29f0c65ce997d71a566e63125f7a6e248..14c0c437d973f1047218335ce77d8cc1337568e3 100644 (file)
@@ -1455,6 +1455,7 @@ struct cfg80211_ssid {
  * @mac_addr_mask: MAC address mask used with randomisation, bits that
  *     are 0 in the mask should be randomised, bits that are 1 should
  *     be taken from the @mac_addr
+ * @bssid: BSSID to scan for (most commonly, the wildcard BSSID)
  */
 struct cfg80211_scan_request {
        struct cfg80211_ssid *ssids;
@@ -1471,6 +1472,7 @@ struct cfg80211_scan_request {
 
        u8 mac_addr[ETH_ALEN] __aligned(2);
        u8 mac_addr_mask[ETH_ALEN] __aligned(2);
+       u8 bssid[ETH_ALEN] __aligned(2);
 
        /* internal */
        struct wiphy *wiphy;
index 5a30a75636338364f0400eeb82954f059da17b22..23bf0667540c25e43ff7d70bc66109786957c4ad 100644 (file)
  * @NL80211_CMD_GET_SCAN: get scan results
  * @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters
  *     %NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the
- *     probe requests at CCK rate or not.
+ *     probe requests at CCK rate or not. %NL80211_ATTR_MAC can be used to
+ *     specify a BSSID to scan for; if not included, the wildcard BSSID will
+ *     be used.
  * @NL80211_CMD_NEW_SCAN_RESULTS: scan notification (as a reply to
  *     NL80211_CMD_GET_SCAN and on the "scan" multicast group)
  * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons,
index 98c924260b3d312055c598255cff8478bccba1e9..1b43f7839eebfdf3e6b288733561ed49e9b1d3ca 100644 (file)
@@ -5996,6 +5996,12 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
        request->no_cck =
                nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
 
+       if (info->attrs[NL80211_ATTR_MAC])
+               memcpy(request->bssid, nla_data(info->attrs[NL80211_ATTR_MAC]),
+                      ETH_ALEN);
+       else
+               eth_broadcast_addr(request->bssid);
+
        request->wdev = wdev;
        request->wiphy = &rdev->wiphy;
        request->scan_start = jiffies;
index 14d5369eb778714fe0a97dc14e585cf3790b775c..50ea8e3fcbeb022dd4062d04d7f562c0cf750b52 100644 (file)
@@ -1293,6 +1293,8 @@ int cfg80211_wext_siwscan(struct net_device *dev,
                if (wiphy->bands[i])
                        creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
 
+       eth_broadcast_addr(creq->bssid);
+
        rdev->scan_req = creq;
        err = rdev_scan(rdev, creq);
        if (err) {
index 5445581717874e1409d994f24c9ca7263e62ab38..65882d2777c0e9985122041d4674e5dd3dc1d067 100644 (file)
@@ -119,6 +119,8 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
                wdev->conn->params.ssid_len);
        request->ssids[0].ssid_len = wdev->conn->params.ssid_len;
 
+       eth_broadcast_addr(request->bssid);
+
        request->wdev = wdev;
        request->wiphy = &rdev->wiphy;
        request->scan_start = jiffies;