aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/cfg80211.h2
-rw-r--r--include/uapi/linux/nl80211.h4
-rw-r--r--net/wireless/nl80211.c10
3 files changed, 16 insertions, 0 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index b3b076a46d50..13b247d26544 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -961,6 +961,7 @@ struct station_info {
961 * @MONITOR_FLAG_CONTROL: pass control frames 961 * @MONITOR_FLAG_CONTROL: pass control frames
962 * @MONITOR_FLAG_OTHER_BSS: disable BSSID filtering 962 * @MONITOR_FLAG_OTHER_BSS: disable BSSID filtering
963 * @MONITOR_FLAG_COOK_FRAMES: report frames after processing 963 * @MONITOR_FLAG_COOK_FRAMES: report frames after processing
964 * @MONITOR_FLAG_ACTIVE: active monitor, ACKs frames on its MAC address
964 */ 965 */
965enum monitor_flags { 966enum monitor_flags {
966 MONITOR_FLAG_FCSFAIL = 1<<NL80211_MNTR_FLAG_FCSFAIL, 967 MONITOR_FLAG_FCSFAIL = 1<<NL80211_MNTR_FLAG_FCSFAIL,
@@ -968,6 +969,7 @@ enum monitor_flags {
968 MONITOR_FLAG_CONTROL = 1<<NL80211_MNTR_FLAG_CONTROL, 969 MONITOR_FLAG_CONTROL = 1<<NL80211_MNTR_FLAG_CONTROL,
969 MONITOR_FLAG_OTHER_BSS = 1<<NL80211_MNTR_FLAG_OTHER_BSS, 970 MONITOR_FLAG_OTHER_BSS = 1<<NL80211_MNTR_FLAG_OTHER_BSS,
970 MONITOR_FLAG_COOK_FRAMES = 1<<NL80211_MNTR_FLAG_COOK_FRAMES, 971 MONITOR_FLAG_COOK_FRAMES = 1<<NL80211_MNTR_FLAG_COOK_FRAMES,
972 MONITOR_FLAG_ACTIVE = 1<<NL80211_MNTR_FLAG_ACTIVE,
971}; 973};
972 974
973/** 975/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 32b060ea5266..5920715278c2 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2428,6 +2428,8 @@ enum nl80211_survey_info {
2428 * @NL80211_MNTR_FLAG_OTHER_BSS: disable BSSID filtering 2428 * @NL80211_MNTR_FLAG_OTHER_BSS: disable BSSID filtering
2429 * @NL80211_MNTR_FLAG_COOK_FRAMES: report frames after processing. 2429 * @NL80211_MNTR_FLAG_COOK_FRAMES: report frames after processing.
2430 * overrides all other flags. 2430 * overrides all other flags.
2431 * @NL80211_MNTR_FLAG_ACTIVE: use the configured MAC address
2432 * and ACK incoming unicast packets.
2431 * 2433 *
2432 * @__NL80211_MNTR_FLAG_AFTER_LAST: internal use 2434 * @__NL80211_MNTR_FLAG_AFTER_LAST: internal use
2433 * @NL80211_MNTR_FLAG_MAX: highest possible monitor flag 2435 * @NL80211_MNTR_FLAG_MAX: highest possible monitor flag
@@ -2439,6 +2441,7 @@ enum nl80211_mntr_flags {
2439 NL80211_MNTR_FLAG_CONTROL, 2441 NL80211_MNTR_FLAG_CONTROL,
2440 NL80211_MNTR_FLAG_OTHER_BSS, 2442 NL80211_MNTR_FLAG_OTHER_BSS,
2441 NL80211_MNTR_FLAG_COOK_FRAMES, 2443 NL80211_MNTR_FLAG_COOK_FRAMES,
2444 NL80211_MNTR_FLAG_ACTIVE,
2442 2445
2443 /* keep last */ 2446 /* keep last */
2444 __NL80211_MNTR_FLAG_AFTER_LAST, 2447 __NL80211_MNTR_FLAG_AFTER_LAST,
@@ -3595,6 +3598,7 @@ enum nl80211_feature_flags {
3595 NL80211_FEATURE_ADVERTISE_CHAN_LIMITS = 1 << 14, 3598 NL80211_FEATURE_ADVERTISE_CHAN_LIMITS = 1 << 14,
3596 NL80211_FEATURE_FULL_AP_CLIENT_STATE = 1 << 15, 3599 NL80211_FEATURE_FULL_AP_CLIENT_STATE = 1 << 15,
3597 NL80211_FEATURE_USERSPACE_MPM = 1 << 16, 3600 NL80211_FEATURE_USERSPACE_MPM = 1 << 16,
3601 NL80211_FEATURE_ACTIVE_MONITOR = 1 << 17,
3598}; 3602};
3599 3603
3600/** 3604/**
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index fb6abcb359a1..31d265f36d2c 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2227,6 +2227,7 @@ static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
2227 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG }, 2227 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
2228 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG }, 2228 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
2229 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG }, 2229 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
2230 [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
2230}; 2231};
2231 2232
2232static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags) 2233static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
@@ -2338,6 +2339,10 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
2338 change = true; 2339 change = true;
2339 } 2340 }
2340 2341
2342 if (flags && (*flags & NL80211_MNTR_FLAG_ACTIVE) &&
2343 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
2344 return -EOPNOTSUPP;
2345
2341 if (change) 2346 if (change)
2342 err = cfg80211_change_iface(rdev, dev, ntype, flags, &params); 2347 err = cfg80211_change_iface(rdev, dev, ntype, flags, &params);
2343 else 2348 else
@@ -2395,6 +2400,11 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
2395 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? 2400 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
2396 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, 2401 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
2397 &flags); 2402 &flags);
2403
2404 if (!err && (flags & NL80211_MNTR_FLAG_ACTIVE) &&
2405 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
2406 return -EOPNOTSUPP;
2407
2398 wdev = rdev_add_virtual_intf(rdev, 2408 wdev = rdev_add_virtual_intf(rdev,
2399 nla_data(info->attrs[NL80211_ATTR_IFNAME]), 2409 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
2400 type, err ? NULL : &flags, &params); 2410 type, err ? NULL : &flags, &params);