diff mbox

[PATCHv2,1/2] mac80211: export ieee80211_send_deauth_disassoc for usage outside of mlme.c

Message ID 1346951275-32081-1-git-send-email-ordex@autistici.org (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Antonio Quartulli Sept. 6, 2012, 5:07 p.m. UTC
ieee80211_send_deauth_disassoc() is now defined in util.c and it is available
for usage in the rest of the mac80211 code.

Signed-off-by: Antonio Quartulli <ordex@autistici.org>
---

v2:
- in ieee80211_send_deauth_disassoc(), limit check for IEEE80211_STA_MFP_ENABLED
  to the case of vif.type equal to STA


 net/mac80211/ieee80211_i.h |  5 ++++
 net/mac80211/mlme.c        | 60 ++++++++--------------------------------------
 net/mac80211/util.c        | 40 +++++++++++++++++++++++++++++++
 3 files changed, 55 insertions(+), 50 deletions(-)

Comments

Johannes Berg Sept. 7, 2012, 8:25 a.m. UTC | #1
On Thu, 2012-09-06 at 19:07 +0200, Antonio Quartulli wrote:

> -		if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED))
> -			IEEE80211_SKB_CB(skb)->flags |=
> -				IEEE80211_TX_INTFL_DONT_ENCRYPT;


> +		if (sdata->vif.type == NL80211_IFTYPE_STATION &&
> +		    !(sdata->u.mgd.flags & IEEE80211_STA_MFP_ENABLED))
> +			IEEE80211_SKB_CB(skb)->flags |=
> +				IEEE80211_TX_INTFL_DONT_ENCRYPT;

It would seem that this should be 

	if (sdata->vif.type != NL80211_IFTYPE_STATION ||
	    !(flags & MFP_ENABLED))

?

johannes

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Nicolas Cavallari Sept. 7, 2012, 9:50 a.m. UTC | #2
On 07/09/2012 10:25, Johannes Berg wrote:
> On Thu, 2012-09-06 at 19:07 +0200, Antonio Quartulli wrote:
> 
>> -		if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED))
>> -			IEEE80211_SKB_CB(skb)->flags |=
>> -				IEEE80211_TX_INTFL_DONT_ENCRYPT;
> 
> 
>> +		if (sdata->vif.type == NL80211_IFTYPE_STATION &&
>> +		    !(sdata->u.mgd.flags & IEEE80211_STA_MFP_ENABLED))
>> +			IEEE80211_SKB_CB(skb)->flags |=
>> +				IEEE80211_TX_INTFL_DONT_ENCRYPT;
> 
> It would seem that this should be 
> 
> 	if (sdata->vif.type != NL80211_IFTYPE_STATION ||
> 	    !(flags & MFP_ENABLED))
> 
> ?

Or just never set TX_INTFL_DONT_ENCRYPT at all and rely on
ieee80211_tx_h_select_key() to do the right thing ?
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Johannes Berg Sept. 7, 2012, 11:18 a.m. UTC | #3
On Fri, 2012-09-07 at 11:50 +0200, Nicolas Cavallari wrote:
> On 07/09/2012 10:25, Johannes Berg wrote:
> > On Thu, 2012-09-06 at 19:07 +0200, Antonio Quartulli wrote:
> > 
> >> -		if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED))
> >> -			IEEE80211_SKB_CB(skb)->flags |=
> >> -				IEEE80211_TX_INTFL_DONT_ENCRYPT;
> > 
> > 
> >> +		if (sdata->vif.type == NL80211_IFTYPE_STATION &&
> >> +		    !(sdata->u.mgd.flags & IEEE80211_STA_MFP_ENABLED))
> >> +			IEEE80211_SKB_CB(skb)->flags |=
> >> +				IEEE80211_TX_INTFL_DONT_ENCRYPT;
> > 
> > It would seem that this should be 
> > 
> > 	if (sdata->vif.type != NL80211_IFTYPE_STATION ||
> > 	    !(flags & MFP_ENABLED))
> > 
> > ?
> 
> Or just never set TX_INTFL_DONT_ENCRYPT at all and rely on
> ieee80211_tx_h_select_key() to do the right thing ?

I don't think it can do the right thing, it doesn't check whether MFP is
enabled or not... unless you want to test all those cases I'd rather not
change it :)

johannes

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Antonio Quartulli Sept. 7, 2012, 11:21 a.m. UTC | #4
On Fri, Sep 07, 2012 at 01:18:09 +0200, Johannes Berg wrote:
> On Fri, 2012-09-07 at 11:50 +0200, Nicolas Cavallari wrote:
> > On 07/09/2012 10:25, Johannes Berg wrote:
> > > On Thu, 2012-09-06 at 19:07 +0200, Antonio Quartulli wrote:
> > > 
> > >> -		if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED))
> > >> -			IEEE80211_SKB_CB(skb)->flags |=
> > >> -				IEEE80211_TX_INTFL_DONT_ENCRYPT;
> > > 
> > > 
> > >> +		if (sdata->vif.type == NL80211_IFTYPE_STATION &&
> > >> +		    !(sdata->u.mgd.flags & IEEE80211_STA_MFP_ENABLED))
> > >> +			IEEE80211_SKB_CB(skb)->flags |=
> > >> +				IEEE80211_TX_INTFL_DONT_ENCRYPT;
> > > 
> > > It would seem that this should be 
> > > 
> > > 	if (sdata->vif.type != NL80211_IFTYPE_STATION ||
> > > 	    !(flags & MFP_ENABLED))
> > > 
> > > ?
> > 
> > Or just never set TX_INTFL_DONT_ENCRYPT at all and rely on
> > ieee80211_tx_h_select_key() to do the right thing ?
> 
> I don't think it can do the right thing, it doesn't check whether MFP is
> enabled or not... unless you want to test all those cases I'd rather not
> change it :)

Ok, then I will send v3 with the modified if-condition.

Thank you all,
Nicolas Cavallari Sept. 7, 2012, 12:01 p.m. UTC | #5
On 07/09/2012 13:18, Johannes Berg wrote:
> On Fri, 2012-09-07 at 11:50 +0200, Nicolas Cavallari wrote:
>> On 07/09/2012 10:25, Johannes Berg wrote:
>>> On Thu, 2012-09-06 at 19:07 +0200, Antonio Quartulli wrote:
>>>
>>>> -		if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED))
>>>> -			IEEE80211_SKB_CB(skb)->flags |=
>>>> -				IEEE80211_TX_INTFL_DONT_ENCRYPT;
>>>
>>>
>>>> +		if (sdata->vif.type == NL80211_IFTYPE_STATION &&
>>>> +		    !(sdata->u.mgd.flags & IEEE80211_STA_MFP_ENABLED))
>>>> +			IEEE80211_SKB_CB(skb)->flags |=
>>>> +				IEEE80211_TX_INTFL_DONT_ENCRYPT;
>>>
>>> It would seem that this should be 
>>>
>>> 	if (sdata->vif.type != NL80211_IFTYPE_STATION ||
>>> 	    !(flags & MFP_ENABLED))
>>>
>>> ?
>>
>> Or just never set TX_INTFL_DONT_ENCRYPT at all and rely on
>> ieee80211_tx_h_select_key() to do the right thing ?
> 
> I don't think it can do the right thing, it doesn't check whether MFP is
> enabled or not...

It does; The first part try to encrypt everything, the second part
disable encryption if ccmp is selected and !ieee80211_is_data_present &&
!ieee80211_use_mfp,
which test, among other things, for the sta's WLAN_STA_MFP flag if sta
!= null.

If tx_h_select_key does not select the right key in this case, i think
we have bigger problems.

> unless you want to test all those cases I'd rather not
> change it :)

Not worth the trouble in this case, but i think there is too much code
that sets TX_INTFL_DONT_ENCRYPT when it shouldn't.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Johannes Berg Sept. 7, 2012, 12:05 p.m. UTC | #6
On Fri, 2012-09-07 at 14:01 +0200, Nicolas Cavallari wrote:

> >> Or just never set TX_INTFL_DONT_ENCRYPT at all and rely on
> >> ieee80211_tx_h_select_key() to do the right thing ?
> > 
> > I don't think it can do the right thing, it doesn't check whether MFP is
> > enabled or not...
> 
> It does; The first part try to encrypt everything, the second part
> disable encryption if ccmp is selected and !ieee80211_is_data_present &&
> !ieee80211_use_mfp,
> which test, among other things, for the sta's WLAN_STA_MFP flag if sta
> != null.

Good point.

> If tx_h_select_key does not select the right key in this case, i think
> we have bigger problems.

Maybe, maybe not. But it looks like it would be safe.

> > unless you want to test all those cases I'd rather not
> > change it :)
> 
> Not worth the trouble in this case, but i think there is too much code
> that sets TX_INTFL_DONT_ENCRYPT when it shouldn't.

I already applied the v3 patchset, but even if I hadn't I'd say it
should be a separate patch(set), want to send some patches to remove
them? :)

johannes

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Nicolas Cavallari Sept. 7, 2012, 12:18 p.m. UTC | #7
On 07/09/2012 14:05, Johannes Berg wrote:
> On Fri, 2012-09-07 at 14:01 +0200, Nicolas Cavallari wrote:
> 
>>>> Or just never set TX_INTFL_DONT_ENCRYPT at all and rely on
>>>> ieee80211_tx_h_select_key() to do the right thing ?
>>>
>>> I don't think it can do the right thing, it doesn't check whether MFP is
>>> enabled or not...
>>
>> It does; The first part try to encrypt everything, the second part
>> disable encryption if ccmp is selected and !ieee80211_is_data_present &&
>> !ieee80211_use_mfp,
>> which test, among other things, for the sta's WLAN_STA_MFP flag if sta
>> != null.
> 
> Good point.
> 
>> If tx_h_select_key does not select the right key in this case, i think
>> we have bigger problems.
> 
> Maybe, maybe not. But it looks like it would be safe.
> 
>>> unless you want to test all those cases I'd rather not
>>> change it :)
>>
>> Not worth the trouble in this case, but i think there is too much code
>> that sets TX_INTFL_DONT_ENCRYPT when it shouldn't.
> 
> I already applied the v3 patchset, but even if I hadn't I'd say it
> should be a separate patch(set), want to send some patches to remove
> them? :)

I'll do that later, along with some other 802.11 2012 crypto work.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index b95fa25..8874523 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -68,6 +68,8 @@  struct ieee80211_local;
 #define IEEE80211_DEFAULT_MAX_SP_LEN		\
 	IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL
 
+#define IEEE80211_DEAUTH_FRAME_LEN	(24 /* hdr */ + 2 /* reason */)
+
 struct ieee80211_fragment_entry {
 	unsigned long first_frag_time;
 	unsigned int seq;
@@ -1458,6 +1460,9 @@  void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
 			 u16 transaction, u16 auth_alg,
 			 u8 *extra, size_t extra_len, const u8 *bssid,
 			 const u8 *da, const u8 *key, u8 key_len, u8 key_idx);
+void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
+				    const u8 *bssid, u16 stype, u16 reason,
+				    bool send_frame, u8 *frame_buf);
 int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
 			     const u8 *ie, size_t ie_len,
 			     enum ieee80211_band band, u32 rate_mask,
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 8746694..0ca3413 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -88,8 +88,6 @@  MODULE_PARM_DESC(probe_wait_ms,
 #define TMR_RUNNING_TIMER	0
 #define TMR_RUNNING_CHANSW	1
 
-#define DEAUTH_DISASSOC_LEN	(24 /* hdr */ + 2 /* reason */)
-
 /*
  * All cfg80211 functions have to be called outside a locked
  * section so that they can acquire a lock themselves... This
@@ -574,46 +572,6 @@  static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
 	ieee80211_tx_skb(sdata, skb);
 }
 
-static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
-					   const u8 *bssid, u16 stype,
-					   u16 reason, bool send_frame,
-					   u8 *frame_buf)
-{
-	struct ieee80211_local *local = sdata->local;
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-	struct sk_buff *skb;
-	struct ieee80211_mgmt *mgmt = (void *)frame_buf;
-
-	/* build frame */
-	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
-	mgmt->duration = 0; /* initialize only */
-	mgmt->seq_ctrl = 0; /* initialize only */
-	memcpy(mgmt->da, bssid, ETH_ALEN);
-	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
-	memcpy(mgmt->bssid, bssid, ETH_ALEN);
-	/* u.deauth.reason_code == u.disassoc.reason_code */
-	mgmt->u.deauth.reason_code = cpu_to_le16(reason);
-
-	if (send_frame) {
-		skb = dev_alloc_skb(local->hw.extra_tx_headroom +
-				    DEAUTH_DISASSOC_LEN);
-		if (!skb)
-			return;
-
-		skb_reserve(skb, local->hw.extra_tx_headroom);
-
-		/* copy in frame */
-		memcpy(skb_put(skb, DEAUTH_DISASSOC_LEN),
-		       mgmt, DEAUTH_DISASSOC_LEN);
-
-		if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED))
-			IEEE80211_SKB_CB(skb)->flags |=
-				IEEE80211_TX_INTFL_DONT_ENCRYPT;
-
-		ieee80211_tx_skb(sdata, skb);
-	}
-}
-
 void ieee80211_send_pspoll(struct ieee80211_local *local,
 			   struct ieee80211_sub_if_data *sdata)
 {
@@ -1695,7 +1653,7 @@  static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata,
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct ieee80211_local *local = sdata->local;
-	u8 frame_buf[DEAUTH_DISASSOC_LEN];
+	u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
 
 	mutex_lock(&ifmgd->mtx);
 	if (!ifmgd->associated) {
@@ -1713,7 +1671,7 @@  static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata,
 	 * must be outside lock due to cfg80211,
 	 * but that's not a problem.
 	 */
-	cfg80211_send_deauth(sdata->dev, frame_buf, DEAUTH_DISASSOC_LEN);
+	cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN);
 
 	mutex_lock(&local->mtx);
 	ieee80211_recalc_idle(local);
@@ -2645,7 +2603,7 @@  static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
 {
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-	u8 frame_buf[DEAUTH_DISASSOC_LEN];
+	u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
 
 	ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason,
 			       false, frame_buf);
@@ -2655,7 +2613,7 @@  static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
 	 * must be outside lock due to cfg80211,
 	 * but that's not a problem.
 	 */
-	cfg80211_send_deauth(sdata->dev, frame_buf, DEAUTH_DISASSOC_LEN);
+	cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN);
 
 	mutex_lock(&local->mtx);
 	ieee80211_recalc_idle(local);
@@ -3538,7 +3496,7 @@  int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
 			 struct cfg80211_deauth_request *req)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-	u8 frame_buf[DEAUTH_DISASSOC_LEN];
+	u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
 
 	mutex_lock(&ifmgd->mtx);
 
@@ -3566,7 +3524,8 @@  int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
 
 	mutex_unlock(&ifmgd->mtx);
 
-	__cfg80211_send_deauth(sdata->dev, frame_buf, DEAUTH_DISASSOC_LEN);
+	__cfg80211_send_deauth(sdata->dev, frame_buf,
+			       IEEE80211_DEAUTH_FRAME_LEN);
 
 	mutex_lock(&sdata->local->mtx);
 	ieee80211_recalc_idle(sdata->local);
@@ -3580,7 +3539,7 @@  int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	u8 bssid[ETH_ALEN];
-	u8 frame_buf[DEAUTH_DISASSOC_LEN];
+	u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
 
 	mutex_lock(&ifmgd->mtx);
 
@@ -3605,7 +3564,8 @@  int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
 			       frame_buf);
 	mutex_unlock(&ifmgd->mtx);
 
-	__cfg80211_send_disassoc(sdata->dev, frame_buf, DEAUTH_DISASSOC_LEN);
+	__cfg80211_send_disassoc(sdata->dev, frame_buf,
+				 IEEE80211_DEAUTH_FRAME_LEN);
 
 	mutex_lock(&sdata->local->mtx);
 	ieee80211_recalc_idle(sdata->local);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index ed75439..2d74fad 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1007,6 +1007,46 @@  void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
 	ieee80211_tx_skb(sdata, skb);
 }
 
+void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
+				    const u8 *bssid, u16 stype, u16 reason,
+				    bool send_frame, u8 *frame_buf)
+{
+	struct ieee80211_local *local = sdata->local;
+	struct sk_buff *skb;
+	struct ieee80211_mgmt *mgmt = (void *)frame_buf;
+
+	/* build frame */
+	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
+	mgmt->duration = 0; /* initialize only */
+	mgmt->seq_ctrl = 0; /* initialize only */
+	memcpy(mgmt->da, bssid, ETH_ALEN);
+	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
+	memcpy(mgmt->bssid, bssid, ETH_ALEN);
+	/* u.deauth.reason_code == u.disassoc.reason_code */
+	mgmt->u.deauth.reason_code = cpu_to_le16(reason);
+
+	if (send_frame) {
+		skb = dev_alloc_skb(local->hw.extra_tx_headroom +
+				    IEEE80211_DEAUTH_FRAME_LEN);
+		if (!skb)
+			return;
+
+		skb_reserve(skb, local->hw.extra_tx_headroom);
+
+		/* copy in frame */
+		memcpy(skb_put(skb, IEEE80211_DEAUTH_FRAME_LEN),
+		       mgmt, IEEE80211_DEAUTH_FRAME_LEN);
+
+		if (sdata->vif.type == NL80211_IFTYPE_STATION &&
+		    !(sdata->u.mgd.flags & IEEE80211_STA_MFP_ENABLED))
+			IEEE80211_SKB_CB(skb)->flags |=
+				IEEE80211_TX_INTFL_DONT_ENCRYPT;
+
+		ieee80211_tx_skb(sdata, skb);
+	}
+}
+
+
 int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
 			     const u8 *ie, size_t ie_len,
 			     enum ieee80211_band band, u32 rate_mask,