Skip to content

Commit 3007e35

Browse files
Arend Van Sprieljmberg-intel
authored andcommitted
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 <[email protected]> Reviewed-by: Pieter-Paul Giesberts <[email protected]> Reviewed-by: Franky Lin <[email protected]> Signed-off-by: Arend van Spriel <[email protected]> [docs, netlink policy fix] Signed-off-by: Johannes Berg <[email protected]>
1 parent ca986ad commit 3007e35

File tree

3 files changed

+39
-11
lines changed

3 files changed

+39
-11
lines changed

include/net/cfg80211.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1613,11 +1613,15 @@ static inline void get_random_mask_addr(u8 *buf, const u8 *addr, const u8 *mask)
16131613
/**
16141614
* struct cfg80211_match_set - sets of attributes to match
16151615
*
1616-
* @ssid: SSID to be matched; may be zero-length for no match (RSSI only)
1616+
* @ssid: SSID to be matched; may be zero-length in case of BSSID match
1617+
* or no match (RSSI only)
1618+
* @bssid: BSSID to be matched; may be all-zero BSSID in case of SSID match
1619+
* or no match (RSSI only)
16171620
* @rssi_thold: don't report scan results below this threshold (in s32 dBm)
16181621
*/
16191622
struct cfg80211_match_set {
16201623
struct cfg80211_ssid ssid;
1624+
u8 bssid[ETH_ALEN];
16211625
s32 rssi_thold;
16221626
};
16231627

include/uapi/linux/nl80211.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3194,6 +3194,7 @@ enum nl80211_reg_rule_attr {
31943194
* @__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: attribute number 0 is reserved
31953195
* @NL80211_SCHED_SCAN_MATCH_ATTR_SSID: SSID to be used for matching,
31963196
* only report BSS with matching SSID.
3197+
* (This cannot be used together with BSSID.)
31973198
* @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI: RSSI threshold (in dBm) for reporting a
31983199
* BSS in scan results. Filtering is turned off if not specified. Note that
31993200
* if this attribute is in a match set of its own, then it is treated as
@@ -3209,6 +3210,8 @@ enum nl80211_reg_rule_attr {
32093210
* BSS-es in the specified band is to be adjusted before doing
32103211
* RSSI-based BSS selection. The attribute value is a packed structure
32113212
* value as specified by &struct nl80211_bss_select_rssi_adjust.
3213+
* @NL80211_SCHED_SCAN_MATCH_ATTR_BSSID: BSSID to be used for matching
3214+
* (this cannot be used together with SSID).
32123215
* @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter
32133216
* attribute number currently defined
32143217
* @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use
@@ -3220,6 +3223,7 @@ enum nl80211_sched_scan_match_attr {
32203223
NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
32213224
NL80211_SCHED_SCAN_MATCH_ATTR_RELATIVE_RSSI,
32223225
NL80211_SCHED_SCAN_MATCH_ATTR_RSSI_ADJUST,
3226+
NL80211_SCHED_SCAN_MATCH_ATTR_BSSID,
32233227

32243228
/* keep last */
32253229
__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST,

net/wireless/nl80211.c

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,7 @@ static const struct nla_policy
497497
nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
498498
[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
499499
.len = IEEE80211_MAX_SSID_LEN },
500+
[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID] = { .len = ETH_ALEN },
500501
[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
501502
};
502503

@@ -7036,8 +7037,15 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
70367037
NULL);
70377038
if (err)
70387039
return ERR_PTR(err);
7040+
7041+
/* SSID and BSSID are mutually exclusive */
7042+
if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] &&
7043+
tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID])
7044+
return ERR_PTR(-EINVAL);
7045+
70397046
/* add other standalone attributes here */
7040-
if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]) {
7047+
if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] ||
7048+
tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID]) {
70417049
n_match_sets++;
70427050
continue;
70437051
}
@@ -7208,7 +7216,7 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
72087216
nla_for_each_nested(attr,
72097217
attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
72107218
tmp) {
7211-
struct nlattr *ssid, *rssi;
7219+
struct nlattr *ssid, *bssid, *rssi;
72127220

72137221
err = nla_parse_nested(tb,
72147222
NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
@@ -7217,7 +7225,8 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
72177225
if (err)
72187226
goto out_free;
72197227
ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
7220-
if (ssid) {
7228+
bssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID];
7229+
if (ssid || bssid) {
72217230
if (WARN_ON(i >= n_match_sets)) {
72227231
/* this indicates a programming error,
72237232
* the loop above should have verified
@@ -7227,14 +7236,25 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
72277236
goto out_free;
72287237
}
72297238

7230-
if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
7231-
err = -EINVAL;
7232-
goto out_free;
7239+
if (ssid) {
7240+
if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
7241+
err = -EINVAL;
7242+
goto out_free;
7243+
}
7244+
memcpy(request->match_sets[i].ssid.ssid,
7245+
nla_data(ssid), nla_len(ssid));
7246+
request->match_sets[i].ssid.ssid_len =
7247+
nla_len(ssid);
7248+
}
7249+
if (bssid) {
7250+
if (nla_len(bssid) != ETH_ALEN) {
7251+
err = -EINVAL;
7252+
goto out_free;
7253+
}
7254+
memcpy(request->match_sets[i].bssid,
7255+
nla_data(bssid), ETH_ALEN);
72337256
}
7234-
memcpy(request->match_sets[i].ssid.ssid,
7235-
nla_data(ssid), nla_len(ssid));
7236-
request->match_sets[i].ssid.ssid_len =
7237-
nla_len(ssid);
7257+
72387258
/* special attribute - old implementation w/a */
72397259
request->match_sets[i].rssi_thold =
72407260
default_match_rssi;

0 commit comments

Comments
 (0)