|
@@ -6619,6 +6619,77 @@ static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev)
|
|
return regulatory_pre_cac_allowed(wdev->wiphy);
|
|
return regulatory_pre_cac_allowed(wdev->wiphy);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int
|
|
|
|
+nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|
|
|
+ void *request, struct nlattr **attrs,
|
|
|
|
+ bool is_sched_scan)
|
|
|
|
+{
|
|
|
|
+ u8 *mac_addr, *mac_addr_mask;
|
|
|
|
+ u32 *flags;
|
|
|
|
+ enum nl80211_feature_flags randomness_flag;
|
|
|
|
+
|
|
|
|
+ if (!attrs[NL80211_ATTR_SCAN_FLAGS])
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ if (is_sched_scan) {
|
|
|
|
+ struct cfg80211_sched_scan_request *req = request;
|
|
|
|
+
|
|
|
|
+ randomness_flag = wdev ?
|
|
|
|
+ NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR :
|
|
|
|
+ NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
|
|
|
|
+ flags = &req->flags;
|
|
|
|
+ mac_addr = req->mac_addr;
|
|
|
|
+ mac_addr_mask = req->mac_addr_mask;
|
|
|
|
+ } else {
|
|
|
|
+ struct cfg80211_scan_request *req = request;
|
|
|
|
+
|
|
|
|
+ randomness_flag = NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
|
|
|
|
+ flags = &req->flags;
|
|
|
|
+ mac_addr = req->mac_addr;
|
|
|
|
+ mac_addr_mask = req->mac_addr_mask;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ *flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]);
|
|
|
|
+
|
|
|
|
+ if ((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
|
|
|
|
+ !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN))
|
|
|
|
+ return -EOPNOTSUPP;
|
|
|
|
+
|
|
|
|
+ if (*flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
|
|
|
|
+ int err;
|
|
|
|
+
|
|
|
|
+ if (!(wiphy->features & randomness_flag) ||
|
|
|
|
+ (wdev && wdev->current_bss))
|
|
|
|
+ return -EOPNOTSUPP;
|
|
|
|
+
|
|
|
|
+ err = nl80211_parse_random_mac(attrs, mac_addr, mac_addr_mask);
|
|
|
|
+ if (err)
|
|
|
|
+ return err;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ((*flags & NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME) &&
|
|
|
|
+ !wiphy_ext_feature_isset(wiphy,
|
|
|
|
+ NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME))
|
|
|
|
+ return -EOPNOTSUPP;
|
|
|
|
+
|
|
|
|
+ if ((*flags & NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP) &&
|
|
|
|
+ !wiphy_ext_feature_isset(wiphy,
|
|
|
|
+ NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP))
|
|
|
|
+ return -EOPNOTSUPP;
|
|
|
|
+
|
|
|
|
+ if ((*flags & NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION) &&
|
|
|
|
+ !wiphy_ext_feature_isset(wiphy,
|
|
|
|
+ NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION))
|
|
|
|
+ return -EOPNOTSUPP;
|
|
|
|
+
|
|
|
|
+ if ((*flags & NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE) &&
|
|
|
|
+ !wiphy_ext_feature_isset(wiphy,
|
|
|
|
+ NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE))
|
|
|
|
+ return -EOPNOTSUPP;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
|
static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
|
{
|
|
{
|
|
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
|
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
|
@@ -6824,34 +6895,10 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
|
nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
|
|
nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
|
|
}
|
|
}
|
|
|
|
|
|
- if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) {
|
|
|
|
- request->flags = nla_get_u32(
|
|
|
|
- info->attrs[NL80211_ATTR_SCAN_FLAGS]);
|
|
|
|
- if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
|
|
|
|
- !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
|
|
|
|
- err = -EOPNOTSUPP;
|
|
|
|
- goto out_free;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
|
|
|
|
- if (!(wiphy->features &
|
|
|
|
- NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR)) {
|
|
|
|
- err = -EOPNOTSUPP;
|
|
|
|
- goto out_free;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (wdev->current_bss) {
|
|
|
|
- err = -EOPNOTSUPP;
|
|
|
|
- goto out_free;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- err = nl80211_parse_random_mac(info->attrs,
|
|
|
|
- request->mac_addr,
|
|
|
|
- request->mac_addr_mask);
|
|
|
|
- if (err)
|
|
|
|
- goto out_free;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ err = nl80211_check_scan_flags(wiphy, wdev, request, info->attrs,
|
|
|
|
+ false);
|
|
|
|
+ if (err)
|
|
|
|
+ goto out_free;
|
|
|
|
|
|
request->no_cck =
|
|
request->no_cck =
|
|
nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
|
|
nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
|
|
@@ -7299,37 +7346,9 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|
request->ie_len);
|
|
request->ie_len);
|
|
}
|
|
}
|
|
|
|
|
|
- if (attrs[NL80211_ATTR_SCAN_FLAGS]) {
|
|
|
|
- request->flags = nla_get_u32(
|
|
|
|
- attrs[NL80211_ATTR_SCAN_FLAGS]);
|
|
|
|
- if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
|
|
|
|
- !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
|
|
|
|
- err = -EOPNOTSUPP;
|
|
|
|
- goto out_free;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
|
|
|
|
- u32 flg = NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
|
|
|
|
-
|
|
|
|
- if (!wdev) /* must be net-detect */
|
|
|
|
- flg = NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
|
|
|
|
-
|
|
|
|
- if (!(wiphy->features & flg)) {
|
|
|
|
- err = -EOPNOTSUPP;
|
|
|
|
- goto out_free;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (wdev && wdev->current_bss) {
|
|
|
|
- err = -EOPNOTSUPP;
|
|
|
|
- goto out_free;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- err = nl80211_parse_random_mac(attrs, request->mac_addr,
|
|
|
|
- request->mac_addr_mask);
|
|
|
|
- if (err)
|
|
|
|
- goto out_free;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ err = nl80211_check_scan_flags(wiphy, wdev, request, attrs, true);
|
|
|
|
+ if (err)
|
|
|
|
+ goto out_free;
|
|
|
|
|
|
if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY])
|
|
if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY])
|
|
request->delay =
|
|
request->delay =
|