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>
This commit is contained in:
parent
ca986ad9bc
commit
3007e3529c
@ -1613,11 +1613,15 @@ static inline void get_random_mask_addr(u8 *buf, const u8 *addr, const u8 *mask)
|
|||||||
/**
|
/**
|
||||||
* struct cfg80211_match_set - sets of attributes to match
|
* struct cfg80211_match_set - sets of attributes to match
|
||||||
*
|
*
|
||||||
* @ssid: SSID to be matched; may be zero-length for no match (RSSI only)
|
* @ssid: SSID to be matched; may be zero-length in case of BSSID match
|
||||||
|
* or no match (RSSI only)
|
||||||
|
* @bssid: BSSID to be matched; may be all-zero BSSID in case of SSID match
|
||||||
|
* or no match (RSSI only)
|
||||||
* @rssi_thold: don't report scan results below this threshold (in s32 dBm)
|
* @rssi_thold: don't report scan results below this threshold (in s32 dBm)
|
||||||
*/
|
*/
|
||||||
struct cfg80211_match_set {
|
struct cfg80211_match_set {
|
||||||
struct cfg80211_ssid ssid;
|
struct cfg80211_ssid ssid;
|
||||||
|
u8 bssid[ETH_ALEN];
|
||||||
s32 rssi_thold;
|
s32 rssi_thold;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3194,6 +3194,7 @@ enum nl80211_reg_rule_attr {
|
|||||||
* @__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: attribute number 0 is reserved
|
* @__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: attribute number 0 is reserved
|
||||||
* @NL80211_SCHED_SCAN_MATCH_ATTR_SSID: SSID to be used for matching,
|
* @NL80211_SCHED_SCAN_MATCH_ATTR_SSID: SSID to be used for matching,
|
||||||
* only report BSS with matching SSID.
|
* only report BSS with matching SSID.
|
||||||
|
* (This cannot be used together with BSSID.)
|
||||||
* @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI: RSSI threshold (in dBm) for reporting a
|
* @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI: RSSI threshold (in dBm) for reporting a
|
||||||
* BSS in scan results. Filtering is turned off if not specified. Note that
|
* BSS in scan results. Filtering is turned off if not specified. Note that
|
||||||
* if this attribute is in a match set of its own, then it is treated as
|
* 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 {
|
|||||||
* BSS-es in the specified band is to be adjusted before doing
|
* BSS-es in the specified band is to be adjusted before doing
|
||||||
* RSSI-based BSS selection. The attribute value is a packed structure
|
* RSSI-based BSS selection. The attribute value is a packed structure
|
||||||
* value as specified by &struct nl80211_bss_select_rssi_adjust.
|
* value as specified by &struct nl80211_bss_select_rssi_adjust.
|
||||||
|
* @NL80211_SCHED_SCAN_MATCH_ATTR_BSSID: BSSID to be used for matching
|
||||||
|
* (this cannot be used together with SSID).
|
||||||
* @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter
|
* @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter
|
||||||
* attribute number currently defined
|
* attribute number currently defined
|
||||||
* @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use
|
* @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use
|
||||||
@ -3220,6 +3223,7 @@ enum nl80211_sched_scan_match_attr {
|
|||||||
NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
|
NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
|
||||||
NL80211_SCHED_SCAN_MATCH_ATTR_RELATIVE_RSSI,
|
NL80211_SCHED_SCAN_MATCH_ATTR_RELATIVE_RSSI,
|
||||||
NL80211_SCHED_SCAN_MATCH_ATTR_RSSI_ADJUST,
|
NL80211_SCHED_SCAN_MATCH_ATTR_RSSI_ADJUST,
|
||||||
|
NL80211_SCHED_SCAN_MATCH_ATTR_BSSID,
|
||||||
|
|
||||||
/* keep last */
|
/* keep last */
|
||||||
__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST,
|
__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST,
|
||||||
|
@ -497,6 +497,7 @@ static const struct nla_policy
|
|||||||
nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
|
nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
|
||||||
[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
|
[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
|
||||||
.len = IEEE80211_MAX_SSID_LEN },
|
.len = IEEE80211_MAX_SSID_LEN },
|
||||||
|
[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID] = { .len = ETH_ALEN },
|
||||||
[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
|
[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);
|
NULL);
|
||||||
if (err)
|
if (err)
|
||||||
return ERR_PTR(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 */
|
/* 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++;
|
n_match_sets++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -7208,7 +7216,7 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|||||||
nla_for_each_nested(attr,
|
nla_for_each_nested(attr,
|
||||||
attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
|
attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
|
||||||
tmp) {
|
tmp) {
|
||||||
struct nlattr *ssid, *rssi;
|
struct nlattr *ssid, *bssid, *rssi;
|
||||||
|
|
||||||
err = nla_parse_nested(tb,
|
err = nla_parse_nested(tb,
|
||||||
NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
|
NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
|
||||||
@ -7217,7 +7225,8 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|||||||
if (err)
|
if (err)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
|
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)) {
|
if (WARN_ON(i >= n_match_sets)) {
|
||||||
/* this indicates a programming error,
|
/* this indicates a programming error,
|
||||||
* the loop above should have verified
|
* the loop above should have verified
|
||||||
@ -7227,6 +7236,7 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ssid) {
|
||||||
if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
|
if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
@ -7235,6 +7245,16 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|||||||
nla_data(ssid), nla_len(ssid));
|
nla_data(ssid), nla_len(ssid));
|
||||||
request->match_sets[i].ssid.ssid_len =
|
request->match_sets[i].ssid.ssid_len =
|
||||||
nla_len(ssid);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
/* special attribute - old implementation w/a */
|
/* special attribute - old implementation w/a */
|
||||||
request->match_sets[i].rssi_thold =
|
request->match_sets[i].rssi_thold =
|
||||||
default_match_rssi;
|
default_match_rssi;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user