summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2014-10-20 13:20:45 +0300
committerJohannes Berg <johannes.berg@intel.com>2014-10-20 16:39:23 +0200
commit988568669d171774b96e59fe35ef575df7f8cffd (patch)
tree177772b25c1cc75c298d8cf1a4245dcffe38d691
parent89c771e5a62b856f4705f189892c489190edaec1 (diff)
cfg80211: Specify frame and reason code for NL80211_CMD_DEL_STATION
The optional NL80211_ATTR_MGMT_SUBTYPE and NL80211_ATTR_REASON_CODE attributes can now be included in NL80211_CMD_DEL_STATION to indicate to the driver which frame (Deauthentication/Disassociation) and reason code in that frame should be used to indicate removal to the specific station. This is used by drivers that implement AP SME and generate those frames internally. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/cfg80211.h5
-rw-r--r--include/uapi/linux/nl80211.h6
-rw-r--r--net/wireless/nl80211.c21
-rw-r--r--net/wireless/trace.h10
4 files changed, 39 insertions, 3 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ebb69f671979..ed896c0b5b8b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -804,9 +804,14 @@ struct station_parameters {
* Used to delete a station entry (or all stations).
*
* @mac: MAC address of the station to remove or NULL to remove all stations
+ * @subtype: Management frame subtype to use for indicating removal
+ * (10 = Disassociation, 12 = Deauthentication)
+ * @reason_code: Reason code for the Disassociation/Deauthentication frame
*/
struct station_del_parameters {
const u8 *mac;
+ u8 subtype;
+ u16 reason_code;
};
/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 846071b0cde9..b553c48404d3 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -227,7 +227,11 @@
* the interface identified by %NL80211_ATTR_IFINDEX.
* @NL80211_CMD_DEL_STATION: Remove a station identified by %NL80211_ATTR_MAC
* or, if no MAC address given, all stations, on the interface identified
- * by %NL80211_ATTR_IFINDEX.
+ * by %NL80211_ATTR_IFINDEX. %NL80211_ATTR_MGMT_SUBTYPE and
+ * %NL80211_ATTR_REASON_CODE can optionally be used to specify which type
+ * of disconnection indication should be sent to the station
+ * (Deauthentication or Disassociation frame and reason code for that
+ * frame).
*
* @NL80211_CMD_GET_MPATH: Get mesh path attributes for mesh path to
* destination %NL80211_ATTR_MAC on the interface identified by
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 40cf7b937926..0c0f2045e1f8 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4414,6 +4414,27 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
if (!rdev->ops->del_station)
return -EOPNOTSUPP;
+ if (info->attrs[NL80211_ATTR_MGMT_SUBTYPE]) {
+ params.subtype =
+ nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
+ if (params.subtype != IEEE80211_STYPE_DISASSOC >> 4 &&
+ params.subtype != IEEE80211_STYPE_DEAUTH >> 4)
+ return -EINVAL;
+ } else {
+ /* Default to Deauthentication frame */
+ params.subtype = IEEE80211_STYPE_DEAUTH >> 4;
+ }
+
+ if (info->attrs[NL80211_ATTR_REASON_CODE]) {
+ params.reason_code =
+ nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
+ if (params.reason_code == 0)
+ return -EINVAL; /* 0 is reserved */
+ } else {
+ /* Default to reason code 2 */
+ params.reason_code = WLAN_REASON_PREV_AUTH_NOT_VALID;
+ }
+
return rdev_del_station(rdev, dev, &params);
}
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index b1339400631d..cdb2c2ef1ae1 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -688,14 +688,20 @@ DECLARE_EVENT_CLASS(station_del,
WIPHY_ENTRY
NETDEV_ENTRY
MAC_ENTRY(sta_mac)
+ __field(u8, subtype)
+ __field(u16, reason_code)
),
TP_fast_assign(
WIPHY_ASSIGN;
NETDEV_ASSIGN;
MAC_ASSIGN(sta_mac, params->mac);
+ __entry->subtype = params->subtype;
+ __entry->reason_code = params->reason_code;
),
- TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT,
- WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac))
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT
+ ", subtype: %u, reason_code: %u",
+ WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac),
+ __entry->subtype, __entry->reason_code)
);
DEFINE_EVENT(station_del, rdev_del_station,