diff options
-rw-r--r-- | include/net/cfg80211.h | 2 | ||||
-rw-r--r-- | include/uapi/linux/nl80211.h | 4 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 10 |
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 | */ |
965 | enum monitor_flags { | 966 | enum 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 | ||
2232 | static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags) | 2233 | static 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, ¶ms); | 2347 | err = cfg80211_change_iface(rdev, dev, ntype, flags, ¶ms); |
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, ¶ms); | 2410 | type, err ? NULL : &flags, ¶ms); |