summaryrefslogtreecommitdiff
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorArend Van Spriel <arend.vanspriel@broadcom.com>2017-04-21 15:05:01 +0300
committerJohannes Berg <johannes.berg@intel.com>2017-04-27 00:17:39 +0300
commit3007e3529ce1efd9c370a7b81633e45f730ae35b (patch)
tree38aaa1f36f1de530f3fb7fcedd5365a3b5eb9d32 /net/wireless/nl80211.c
parentca986ad9bcd3893c8b0b4cc2cafcc8cf1554409c (diff)
downloadlinux-3007e3529ce1efd9c370a7b81633e45f730ae35b.tar.xz
nl80211: add support for BSSIDs in scheduled scan matchsets
This patch allows for the scheduled scan request to specify matchsets for specific BSSIDs. Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> Reviewed-by: Franky Lin <franky.lin@broadcom.com> Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> [docs, netlink policy fix] Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index ac7e2314f9ec..dce69a87d4d0 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -497,6 +497,7 @@ static const struct nla_policy
nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
.len = IEEE80211_MAX_SSID_LEN },
+ [NL80211_SCHED_SCAN_MATCH_ATTR_BSSID] = { .len = ETH_ALEN },
[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
};
@@ -7036,8 +7037,15 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
NULL);
if (err)
return ERR_PTR(err);
+
+ /* SSID and BSSID are mutually exclusive */
+ if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] &&
+ tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID])
+ return ERR_PTR(-EINVAL);
+
/* add other standalone attributes here */
- if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]) {
+ if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] ||
+ tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID]) {
n_match_sets++;
continue;
}
@@ -7208,7 +7216,7 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
nla_for_each_nested(attr,
attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
tmp) {
- struct nlattr *ssid, *rssi;
+ struct nlattr *ssid, *bssid, *rssi;
err = nla_parse_nested(tb,
NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
@@ -7217,7 +7225,8 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
if (err)
goto out_free;
ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
- if (ssid) {
+ bssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID];
+ if (ssid || bssid) {
if (WARN_ON(i >= n_match_sets)) {
/* this indicates a programming error,
* the loop above should have verified
@@ -7227,14 +7236,25 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
goto out_free;
}
- if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
- err = -EINVAL;
- goto out_free;
+ if (ssid) {
+ if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
+ err = -EINVAL;
+ goto out_free;
+ }
+ memcpy(request->match_sets[i].ssid.ssid,
+ nla_data(ssid), nla_len(ssid));
+ request->match_sets[i].ssid.ssid_len =
+ nla_len(ssid);
+ }
+ if (bssid) {
+ if (nla_len(bssid) != ETH_ALEN) {
+ err = -EINVAL;
+ goto out_free;
+ }
+ memcpy(request->match_sets[i].bssid,
+ nla_data(bssid), ETH_ALEN);
}
- memcpy(request->match_sets[i].ssid.ssid,
- nla_data(ssid), nla_len(ssid));
- request->match_sets[i].ssid.ssid_len =
- nla_len(ssid);
+
/* special attribute - old implementation w/a */
request->match_sets[i].rssi_thold =
default_match_rssi;