All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] nl80211: Add notification for dropped Deauth/Disassoc
@ 2010-12-13 22:00 Jouni Malinen
  2010-12-14  7:15 ` Johannes Berg
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Jouni Malinen @ 2010-12-13 22:00 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless

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     |   26 ++++++++++++++++++++++++++
 net/wireless/nl80211.c  |   16 ++++++++++++++++
 net/wireless/nl80211.h  |    6 ++++++
 5 files changed, 78 insertions(+), 2 deletions(-)

--- 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-13 23:47:48.000000000 -0800
@@ -263,6 +263,32 @@ 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);
+
+	wdev_lock(wdev);
+	nl80211_send_unprot_deauth(rdev, dev, buf, len, GFP_KERNEL);
+	wdev_unlock(wdev);
+}
+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);
+
+	wdev_lock(wdev);
+	nl80211_send_unprot_disassoc(rdev, dev, buf, len, GFP_KERNEL);
+	wdev_unlock(wdev);
+}
+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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] nl80211: Add notification for dropped Deauth/Disassoc
  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:51 ` Johannes Berg
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Johannes Berg @ 2010-12-14  7:15 UTC (permalink / raw)
  To: Jouni Malinen; +Cc: John W. Linville, linux-wireless

On Tue, 2010-12-14 at 00:00 +0200, Jouni Malinen wrote:

> + * @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.
> + *

I don't mind, but if we add the frame body should we really have two
commands? Or should we have just one? Are we likely to need similar
functionality for other frames? The only ones I can think of are class 3
frames from unassociated stations, but that seems like it should be
separate anyway.

johannes


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] nl80211: Add notification for dropped Deauth/Disassoc
  2010-12-14  7:15 ` Johannes Berg
@ 2010-12-14  7:46   ` Jouni Malinen
  2010-12-14  7:48     ` Johannes Berg
  0 siblings, 1 reply; 10+ messages in thread
From: Jouni Malinen @ 2010-12-14  7:46 UTC (permalink / raw)
  To: Johannes Berg; +Cc: John W. Linville, linux-wireless

On Tue, Dec 14, 2010 at 08:15:07AM +0100, Johannes Berg wrote:
> On Tue, 2010-12-14 at 00:00 +0200, Jouni Malinen wrote:
> > + * @NL80211_CMD_UNPROT_DEAUTHENTICATE: Unprotected deauthentication frame
> > + * @NL80211_CMD_UNPROT_DISASSOCIATE: Unprotected disassociation frame
> 
> I don't mind, but if we add the frame body should we really have two
> commands? Or should we have just one? Are we likely to need similar
> functionality for other frames? The only ones I can think of are class 3
> frames from unassociated stations, but that seems like it should be
> separate anyway.

This one followed the existing example of NL80211_CMD_DEAUTH/DISASSOC,
but well, those are for both notification and requests, so I can see the
difference there.. For these notification-only ones, I would be fine
having a single command if that is desirable. Though, I would probably
not go as far as merging any other frames to this list since
deauth/disassoc are special case for the AP starting to send these as
replies to any Class 2 or 3 frame.

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] nl80211: Add notification for dropped Deauth/Disassoc
  2010-12-14  7:46   ` Jouni Malinen
@ 2010-12-14  7:48     ` Johannes Berg
  0 siblings, 0 replies; 10+ messages in thread
From: Johannes Berg @ 2010-12-14  7:48 UTC (permalink / raw)
  To: Jouni Malinen; +Cc: John W. Linville, linux-wireless

On Tue, 2010-12-14 at 09:46 +0200, Jouni Malinen wrote:
> On Tue, Dec 14, 2010 at 08:15:07AM +0100, Johannes Berg wrote:
> > On Tue, 2010-12-14 at 00:00 +0200, Jouni Malinen wrote:
> > > + * @NL80211_CMD_UNPROT_DEAUTHENTICATE: Unprotected deauthentication frame
> > > + * @NL80211_CMD_UNPROT_DISASSOCIATE: Unprotected disassociation frame
> > 
> > I don't mind, but if we add the frame body should we really have two
> > commands? Or should we have just one? Are we likely to need similar
> > functionality for other frames? The only ones I can think of are class 3
> > frames from unassociated stations, but that seems like it should be
> > separate anyway.
> 
> This one followed the existing example of NL80211_CMD_DEAUTH/DISASSOC,
> but well, those are for both notification and requests, so I can see the
> difference there.. For these notification-only ones, I would be fine
> having a single command if that is desirable. Though, I would probably
> not go as far as merging any other frames to this list since
> deauth/disassoc are special case for the AP starting to send these as
> replies to any Class 2 or 3 frame.

Ok. I don't think we really need to go to a single command, and this may
be more helpful for drivers that might not be able to give us the frame
at all due to firmware implementation, so maybe it's better to keep it
as is and not rely on the frame in wpa_s.

johannes


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] nl80211: Add notification for dropped Deauth/Disassoc
  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:51 ` Johannes Berg
  2010-12-14  7:54   ` Johannes Berg
  2010-12-14  8:41 ` [PATCH v2] " Jouni Malinen
  2010-12-15 22:52 ` [PATCH v3] " Jouni Malinen
  3 siblings, 1 reply; 10+ messages in thread
From: Johannes Berg @ 2010-12-14  7:51 UTC (permalink / raw)
  To: Jouni Malinen; +Cc: John W. Linville, linux-wireless

On Tue, 2010-12-14 at 00:00 +0200, Jouni Malinen wrote:

> @@ -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);

This is the RX path.

> +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);
> +
> +	wdev_lock(wdev);
> +	nl80211_send_unprot_disassoc(rdev, dev, buf, len, GFP_KERNEL);

And this uses GFP_KERNEL. Surely that can't be right?

johannes


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] nl80211: Add notification for dropped Deauth/Disassoc
  2010-12-14  7:51 ` Johannes Berg
@ 2010-12-14  7:54   ` Johannes Berg
  0 siblings, 0 replies; 10+ messages in thread
From: Johannes Berg @ 2010-12-14  7:54 UTC (permalink / raw)
  To: Jouni Malinen; +Cc: John W. Linville, linux-wireless

On Tue, 2010-12-14 at 08:51 +0100, Johannes Berg wrote:
> On Tue, 2010-12-14 at 00:00 +0200, Jouni Malinen wrote:
> 
> > @@ -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);
> 
> This is the RX path.
> 
> > +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);
> > +
> > +	wdev_lock(wdev);
> > +	nl80211_send_unprot_disassoc(rdev, dev, buf, len, GFP_KERNEL);
> 
> And this uses GFP_KERNEL. Surely that can't be right?

And the mutex too, for that matter, which seems unnecessary anyway.

johannes


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2] nl80211: Add notification for dropped Deauth/Disassoc
  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:51 ` Johannes Berg
@ 2010-12-14  8:41 ` Jouni Malinen
  2010-12-15 21:56   ` John W. Linville
  2010-12-15 22:52 ` [PATCH v3] " Jouni Malinen
  3 siblings, 1 reply; 10+ messages in thread
From: Jouni Malinen @ 2010-12-14  8:41 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] nl80211: Add notification for dropped Deauth/Disassoc
  2010-12-14  8:41 ` [PATCH v2] " Jouni Malinen
@ 2010-12-15 21:56   ` John W. Linville
  2010-12-15 22:49     ` Jouni Malinen
  0 siblings, 1 reply; 10+ messages in thread
From: John W. Linville @ 2010-12-15 21:56 UTC (permalink / raw)
  To: Jouni Malinen; +Cc: Johannes Berg, linux-wireless

On Tue, Dec 14, 2010 at 10:41:33AM +0200, Jouni Malinen wrote:
> 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(-)


> --- 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;

Need cfg80211.h bits for these, no?

-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] nl80211: Add notification for dropped Deauth/Disassoc
  2010-12-15 21:56   ` John W. Linville
@ 2010-12-15 22:49     ` Jouni Malinen
  0 siblings, 0 replies; 10+ messages in thread
From: Jouni Malinen @ 2010-12-15 22:49 UTC (permalink / raw)
  To: John W. Linville; +Cc: Johannes Berg, linux-wireless

On Wed, Dec 15, 2010 at 04:56:11PM -0500, John W. Linville wrote:
> On Tue, Dec 14, 2010 at 10:41:33AM +0200, Jouni Malinen wrote:
> > +void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
> > +				   size_t len)

> > +EXPORT_SYMBOL(cfg80211_send_unprot_disassoc);

> Need cfg80211.h bits for these, no?

Yes, indeed. Looks like a missing "quilt add" since I obviously do have
those prototypes for the build to go through without warnings... I'll
post a fixed version.
 
-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v3] nl80211: Add notification for dropped Deauth/Disassoc
  2010-12-13 22:00 [PATCH] nl80211: Add notification for dropped Deauth/Disassoc Jouni Malinen
                   ` (2 preceding siblings ...)
  2010-12-14  8:41 ` [PATCH v2] " Jouni Malinen
@ 2010-12-15 22:52 ` Jouni Malinen
  3 siblings, 0 replies; 10+ messages in thread
From: Jouni Malinen @ 2010-12-15 22:52 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless

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 ++++++++++
 include/net/cfg80211.h  |   26 ++++++++++++++++++++++++++
 net/mac80211/rx.c       |   22 ++++++++++++++++++++--
 net/wireless/mlme.c     |   22 ++++++++++++++++++++++
 net/wireless/nl80211.c  |   16 ++++++++++++++++
 net/wireless/nl80211.h  |    6 ++++++
 6 files changed, 100 insertions(+), 2 deletions(-)

v3: Include the forgotten include/net/cfg80211.h changes


--- wireless-testing.orig/include/linux/nl80211.h	2010-12-16 00:45:15.000000000 +0200
+++ wireless-testing/include/linux/nl80211.h	2010-12-16 00:45:18.000000000 +0200
@@ -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-16 00:44:31.000000000 +0200
+++ wireless-testing/net/mac80211/rx.c	2010-12-16 00:45:18.000000000 +0200
@@ -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-16 00:44:31.000000000 +0200
+++ wireless-testing/net/wireless/mlme.c	2010-12-16 00:45:18.000000000 +0200
@@ -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-16 00:45:15.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.c	2010-12-16 00:45:18.000000000 +0200
@@ -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-16 00:44:31.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.h	2010-12-16 00:45:18.000000000 +0200
@@ -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);
--- wireless-testing.orig/include/net/cfg80211.h	2010-12-16 00:45:15.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2010-12-16 00:45:18.000000000 +0200
@@ -2318,6 +2318,32 @@ void __cfg80211_send_disassoc(struct net
 	size_t len);
 
 /**
+ * cfg80211_send_unprot_deauth - notification of unprotected deauthentication
+ * @dev: network device
+ * @buf: deauthentication frame (header + body)
+ * @len: length of the frame data
+ *
+ * This function is called whenever a received Deauthentication frame has been
+ * dropped in station mode because of MFP being used but the Deauthentication
+ * frame was not protected. This function may sleep.
+ */
+void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf,
+				 size_t len);
+
+/**
+ * cfg80211_send_unprot_disassoc - notification of unprotected disassociation
+ * @dev: network device
+ * @buf: disassociation frame (header + body)
+ * @len: length of the frame data
+ *
+ * This function is called whenever a received Disassociation frame has been
+ * dropped in station mode because of MFP being used but the Disassociation
+ * frame was not protected. This function may sleep.
+ */
+void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
+				   size_t len);
+
+/**
  * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP)
  * @dev: network device
  * @addr: The source MAC address of the frame
 
-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2010-12-15 22:52 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH v2] " Jouni Malinen
2010-12-15 21:56   ` John W. Linville
2010-12-15 22:49     ` Jouni Malinen
2010-12-15 22:52 ` [PATCH v3] " Jouni Malinen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.