aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2013-05-28 07:01:52 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-05-29 03:11:44 -0400
commite057d3c31bdf87616b415c4b2cbf7310f54b9219 (patch)
treeae87f09df131d03baf389b3179083a06bac039fe
parent6abb9cb99f33b20c2f32f18a3ae9cc7543e46edb (diff)
cfg80211: support an active monitor interface flag
An active monitor interface is one that is used for communication (via injection). It is expected to ACK incoming unicast packets. This is useful for running various 802.11 testing utilities that associate to an AP via injection and manage the state in user space. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-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);