2016-02-26 14:06:28

by Jouni Malinen

[permalink] [raw]
Subject: [PATCH 1/3] cfg80211: Allow a scan request for a specific BSSID

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 <[email protected]>
---
include/net/cfg80211.h | 2 ++
include/uapi/linux/nl80211.h | 4 +++-
net/wireless/nl80211.c | 6 ++++++
3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 9e1b24c..14c0c43 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -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;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 5a30a75..23bf066 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -322,7 +322,9 @@
* @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,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 98c9242..1b43f78 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -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;
--
1.9.1



2016-02-26 14:06:43

by Jouni Malinen

[permalink] [raw]
Subject: [PATCH 3/3] mac80211_hwsim: Support a hw scan request for a specific BSSID

If the hw scan request specifies a single BSSID, use that value instead
of the wildcard BSSID in the Probe Request frames.

Signed-off-by: Jouni Malinen <[email protected]>
---
drivers/net/wireless/mac80211_hwsim.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index a723a85..281c6b7 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1909,6 +1909,7 @@ static void hw_scan_work(struct work_struct *work)
/* send probes */
for (i = 0; i < req->n_ssids; i++) {
struct sk_buff *probe;
+ struct ieee80211_mgmt *mgmt;

probe = ieee80211_probereq_get(hwsim->hw,
hwsim->scan_addr,
@@ -1918,6 +1919,10 @@ static void hw_scan_work(struct work_struct *work)
if (!probe)
continue;

+ mgmt = (struct ieee80211_mgmt *) probe->data;
+ memcpy(mgmt->da, req->bssid, ETH_ALEN);
+ memcpy(mgmt->bssid, req->bssid, ETH_ALEN);
+
if (req->ie_len)
memcpy(skb_put(probe, req->ie_len), req->ie,
req->ie_len);
--
1.9.1


2016-02-26 18:27:10

by Jouni Malinen

[permalink] [raw]
Subject: Re: [PATCH 1/3] cfg80211: Allow a scan request for a specific BSSID

On Fri, Feb 26, 2016 at 04:06:04PM +0200, Jouni Malinen wrote:
> 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.

> include/net/cfg80211.h | 2 ++
> include/uapi/linux/nl80211.h | 4 +++-
> net/wireless/nl80211.c | 6 ++++++

> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> @@ -1471,6 +1472,7 @@ struct cfg80211_scan_request {
> + u8 bssid[ETH_ALEN] __aligned(2);


You should know better to run all hwsim test cases before sending
patches out.. nl80211 one is not enough when we have WEXT. :)

Johannes, please drop this. I'll need to talk to myself to get a fixed
version with the two other rdev_scan() callers updated to fill in the
bssid field.

--
Jouni Malinen PGP id EFC895FA

2016-02-26 14:06:39

by Jouni Malinen

[permalink] [raw]
Subject: [PATCH 2/3] mac80211: Support a scan request for a specific BSSID

If the cfg80211 scan trigger operation specifies a single BSSID, use
that value instead of the wildcard BSSID in the Probe Request frames.

Signed-off-by: Jouni Malinen <[email protected]>
---
net/mac80211/scan.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index ae980ce..b025a82 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -497,7 +497,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,

for (i = 0; i < scan_req->n_ssids; i++)
ieee80211_send_probe_req(
- sdata, local->scan_addr, NULL,
+ sdata, local->scan_addr, scan_req->bssid,
scan_req->ssids[i].ssid, scan_req->ssids[i].ssid_len,
scan_req->ie, scan_req->ie_len,
scan_req->rates[band], false,
--
1.9.1