From: Jouni Malinen <j@w1.fi>
To: "John W. Linville" <linville@tuxdriver.com>,
Johannes Berg <johannes@sipsolutions.net>
Cc: linux-wireless@vger.kernel.org
Subject: [PATCH v2] nl80211: Add notification for dropped Deauth/Disassoc
Date: Tue, 14 Dec 2010 10:41:33 +0200 [thread overview]
Message-ID: <20101214084133.GA28466@jm.kir.nu> (raw)
In-Reply-To: <20101213220048.GA24752@jm.kir.nu>
Add a new notification to indicate that a received, unprotected
Deauthentication or Disassociation frame was dropped due to
management frame protection being in use. This notification is
needed to allow user space (e.g., wpa_supplicant) to implement
SA Query procedure to recover from association state mismatch
between an AP and STA.
This is needed to avoid getting stuck in non-working state when MFP
(IEEE 802.11w) is used and a protected Deauthentication or
Disassociation frame is dropped for any reason. After that, the
station would silently discard any unprotected Deauthentication or
Disassociation frame that could be indicating that the AP does not
have association for the STA (when the Reason Code would be 6 or 7).
IEEE Std 802.11w-2009, 11.13 describes this recovery mechanism.
Signed-off-by: Jouni Malinen <j@w1.fi>
---
include/linux/nl80211.h | 10 ++++++++++
net/mac80211/rx.c | 22 ++++++++++++++++++++--
net/wireless/mlme.c | 22 ++++++++++++++++++++++
net/wireless/nl80211.c | 16 ++++++++++++++++
net/wireless/nl80211.h | 6 ++++++
5 files changed, 74 insertions(+), 2 deletions(-)
v2: Address comments from Johannes: replace GFP_KERNEL with GFP_ATOMIC
since these events are generated from RX handlers. Remove unnecessary
(and not suitable for this context) wdev_lock.
--- wireless-testing.orig/include/linux/nl80211.h 2010-12-13 23:41:17.000000000 -0800
+++ wireless-testing/include/linux/nl80211.h 2010-12-13 23:43:09.000000000 -0800
@@ -394,6 +394,13 @@
*
* @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface.
*
+ * @NL80211_CMD_UNPROT_DEAUTHENTICATE: Unprotected deauthentication frame
+ * notification. This event is used to indicate that an unprotected
+ * deauthentication frame was dropped when MFP is in use.
+ * @NL80211_CMD_UNPROT_DISASSOCIATE: Unprotected disassociation frame
+ * notification. This event is used to indicate that an unprotected
+ * disassociation frame was dropped when MFP is in use.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -500,6 +507,9 @@ enum nl80211_commands {
NL80211_CMD_FRAME_WAIT_CANCEL,
+ NL80211_CMD_UNPROT_DEAUTHENTICATE,
+ NL80211_CMD_UNPROT_DISASSOCIATE,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
--- wireless-testing.orig/net/mac80211/rx.c 2010-12-13 23:29:51.000000000 -0800
+++ wireless-testing/net/mac80211/rx.c 2010-12-13 23:41:05.000000000 -0800
@@ -1539,12 +1539,30 @@ ieee80211_drop_unencrypted_mgmt(struct i
if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) {
if (unlikely(!ieee80211_has_protected(fc) &&
ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
- rx->key))
+ rx->key)) {
+ if (ieee80211_is_deauth(fc))
+ cfg80211_send_unprot_deauth(rx->sdata->dev,
+ rx->skb->data,
+ rx->skb->len);
+ else if (ieee80211_is_disassoc(fc))
+ cfg80211_send_unprot_disassoc(rx->sdata->dev,
+ rx->skb->data,
+ rx->skb->len);
return -EACCES;
+ }
/* BIP does not use Protected field, so need to check MMIE */
if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) &&
- ieee80211_get_mmie_keyidx(rx->skb) < 0))
+ ieee80211_get_mmie_keyidx(rx->skb) < 0)) {
+ if (ieee80211_is_deauth(fc))
+ cfg80211_send_unprot_deauth(rx->sdata->dev,
+ rx->skb->data,
+ rx->skb->len);
+ else if (ieee80211_is_disassoc(fc))
+ cfg80211_send_unprot_disassoc(rx->sdata->dev,
+ rx->skb->data,
+ rx->skb->len);
return -EACCES;
+ }
/*
* When using MFP, Action frames are not allowed prior to
* having configured keys.
--- wireless-testing.orig/net/wireless/mlme.c 2010-12-13 23:35:46.000000000 -0800
+++ wireless-testing/net/wireless/mlme.c 2010-12-14 10:23:56.000000000 -0800
@@ -263,6 +263,28 @@ void cfg80211_send_disassoc(struct net_d
}
EXPORT_SYMBOL(cfg80211_send_disassoc);
+void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf,
+ size_t len)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct wiphy *wiphy = wdev->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
+ nl80211_send_unprot_deauth(rdev, dev, buf, len, GFP_ATOMIC);
+}
+EXPORT_SYMBOL(cfg80211_send_unprot_deauth);
+
+void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
+ size_t len)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct wiphy *wiphy = wdev->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
+ nl80211_send_unprot_disassoc(rdev, dev, buf, len, GFP_ATOMIC);
+}
+EXPORT_SYMBOL(cfg80211_send_unprot_disassoc);
+
static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr)
{
int i;
--- wireless-testing.orig/net/wireless/nl80211.c 2010-12-13 23:39:23.000000000 -0800
+++ wireless-testing/net/wireless/nl80211.c 2010-12-13 23:40:15.000000000 -0800
@@ -5333,6 +5333,22 @@ void nl80211_send_disassoc(struct cfg802
NL80211_CMD_DISASSOCIATE, gfp);
}
+void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, const u8 *buf,
+ size_t len, gfp_t gfp)
+{
+ nl80211_send_mlme_event(rdev, netdev, buf, len,
+ NL80211_CMD_UNPROT_DEAUTHENTICATE, gfp);
+}
+
+void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, const u8 *buf,
+ size_t len, gfp_t gfp)
+{
+ nl80211_send_mlme_event(rdev, netdev, buf, len,
+ NL80211_CMD_UNPROT_DISASSOCIATE, gfp);
+}
+
static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
struct net_device *netdev, int cmd,
const u8 *addr, gfp_t gfp)
--- wireless-testing.orig/net/wireless/nl80211.h 2010-12-13 23:38:49.000000000 -0800
+++ wireless-testing/net/wireless/nl80211.h 2010-12-13 23:39:07.000000000 -0800
@@ -25,6 +25,12 @@ void nl80211_send_deauth(struct cfg80211
void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
const u8 *buf, size_t len, gfp_t gfp);
+void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev,
+ const u8 *buf, size_t len, gfp_t gfp);
+void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev,
+ const u8 *buf, size_t len, gfp_t gfp);
void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
const u8 *addr, gfp_t gfp);
--
Jouni Malinen PGP id EFC895FA
next prev parent reply other threads:[~2010-12-14 8:41 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-13 22:00 [PATCH] nl80211: Add notification for dropped Deauth/Disassoc Jouni Malinen
2010-12-14 7:15 ` Johannes Berg
2010-12-14 7:46 ` Jouni Malinen
2010-12-14 7:48 ` Johannes Berg
2010-12-14 7:51 ` Johannes Berg
2010-12-14 7:54 ` Johannes Berg
2010-12-14 8:41 ` Jouni Malinen [this message]
2010-12-15 21:56 ` [PATCH v2] " John W. Linville
2010-12-15 22:49 ` Jouni Malinen
2010-12-15 22:52 ` [PATCH v3] " Jouni Malinen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20101214084133.GA28466@jm.kir.nu \
--to=j@w1.fi \
--cc=johannes@sipsolutions.net \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).