linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Johannes Berg <johannes@sipsolutions.net>
To: John Linville <linville@tuxdriver.com>
Cc: linux-wireless@vger.kernel.org
Subject: [PATCH 27/27] mac80211: split managed/ibss code a little more
Date: Tue, 10 Feb 2009 21:26:03 +0100	[thread overview]
Message-ID: <20090210202557.918427159@sipsolutions.net> (raw)
In-Reply-To: 20090210202536.425266119@sipsolutions.net

It appears that you can completely mess up mac80211 in IBSS
mode by sending it a disassoc or deauth: it'll stop queues
and do a lot more but not ever do anything again. Fix this
by not handling all those frames in IBSS mode,=20

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/mac80211/mlme.c |  254 +++++++++++++++++++++++++++++------------------=
-----
 1 file changed, 146 insertions(+), 108 deletions(-)

--- wireless-testing.orig/net/mac80211/mlme.c	2009-02-10 20:59:39.000000000=
 +0100
+++ wireless-testing/net/mac80211/mlme.c	2009-02-10 20:59:40.000000000 +010=
0
@@ -778,9 +778,6 @@ static void ieee80211_set_associated(str
 	bss_info_changed |=3D BSS_CHANGED_ASSOC;
 	ifsta->flags |=3D IEEE80211_STA_ASSOCIATED;
=20
-	if (sdata->vif.type !=3D NL80211_IFTYPE_STATION)
-		return;
-
 	bss =3D ieee80211_rx_bss_get(local, ifsta->bssid,
 				   conf->channel->center_freq,
 				   ifsta->ssid, ifsta->ssid_len);
@@ -1139,6 +1136,30 @@ static void ieee80211_auth_challenge(str
 			    elems.challenge_len + 2, 1);
 }
=20
+static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdat=
a,
+					struct ieee80211_if_sta *ifsta,
+					struct ieee80211_mgmt *mgmt,
+					size_t len)
+{
+	u16 auth_alg, auth_transaction, status_code;
+
+	if (len < 24 + 6)
+		return;
+
+	auth_alg =3D le16_to_cpu(mgmt->u.auth.auth_alg);
+	auth_transaction =3D le16_to_cpu(mgmt->u.auth.auth_transaction);
+	status_code =3D le16_to_cpu(mgmt->u.auth.status_code);
+
+	/*
+	 * IEEE 802.11 standard does not require authentication in IBSS
+	 * networks and most implementations do not seem to use it.
+	 * However, try to reply to authentication attempts if someone
+	 * has actually implemented this.
+	 */
+	if (auth_alg =3D=3D WLAN_AUTH_OPEN && auth_transaction =3D=3D 1)
+		ieee80211_send_auth(sdata, ifsta, 2, NULL, 0, 0);
+}
+
 static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
 				   struct ieee80211_if_sta *ifsta,
 				   struct ieee80211_mgmt *mgmt,
@@ -1146,38 +1167,22 @@ static void ieee80211_rx_mgmt_auth(struc
 {
 	u16 auth_alg, auth_transaction, status_code;
=20
-	if (ifsta->state !=3D IEEE80211_STA_MLME_AUTHENTICATE &&
-	    sdata->vif.type !=3D NL80211_IFTYPE_ADHOC)
+	if (ifsta->state !=3D IEEE80211_STA_MLME_AUTHENTICATE)
 		return;
=20
 	if (len < 24 + 6)
 		return;
=20
-	if (sdata->vif.type !=3D NL80211_IFTYPE_ADHOC &&
-	    memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) !=3D 0)
+	if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) !=3D 0)
 		return;
=20
-	if (sdata->vif.type !=3D NL80211_IFTYPE_ADHOC &&
-	    memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) !=3D 0)
+	if (memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) !=3D 0)
 		return;
=20
 	auth_alg =3D le16_to_cpu(mgmt->u.auth.auth_alg);
 	auth_transaction =3D le16_to_cpu(mgmt->u.auth.auth_transaction);
 	status_code =3D le16_to_cpu(mgmt->u.auth.status_code);
=20
-	if (sdata->vif.type =3D=3D NL80211_IFTYPE_ADHOC) {
-		/*
-		 * IEEE 802.11 standard does not require authentication in IBSS
-		 * networks and most implementations do not seem to use it.
-		 * However, try to reply to authentication attempts if someone
-		 * has actually implemented this.
-		 */
-		if (auth_alg !=3D WLAN_AUTH_OPEN || auth_transaction !=3D 1)
-			return;
-		ieee80211_send_auth(sdata, ifsta, 2, NULL, 0, 0);
-		return;
-	}
-
 	if (auth_alg !=3D ifsta->auth_alg ||
 	    auth_transaction !=3D ifsta->auth_transaction)
 		return;
@@ -1732,74 +1737,85 @@ static void ieee80211_rx_bss_info(struct
 	/* was just updated in ieee80211_bss_info_update */
 	beacon_timestamp =3D bss->cbss.tsf;
=20
-	/*
-	 * In STA mode, the remaining parameters should not be overridden
-	 * by beacons because they're not necessarily accurate there.
-	 */
-	if (sdata->vif.type !=3D NL80211_IFTYPE_ADHOC &&
-	    bss->last_probe_resp && beacon) {
-		ieee80211_rx_bss_put(local, bss);
-		return;
-	}
+	if (sdata->vif.type !=3D NL80211_IFTYPE_ADHOC)
+		goto put_bss;
=20
 	/* check if we need to merge IBSS */
-	if (sdata->vif.type =3D=3D NL80211_IFTYPE_ADHOC && beacon &&
-	    (!(sdata->u.sta.flags & IEEE80211_STA_BSSID_SET)) &&
-	    bss->cbss.capability & WLAN_CAPABILITY_IBSS &&
-	    bss->cbss.channel =3D=3D local->oper_channel &&
-	    elems->ssid_len =3D=3D sdata->u.sta.ssid_len &&
+
+	/* merge only on beacons (???) */
+	if (!beacon)
+		goto put_bss;
+
+	/* we use a fixed BSSID */
+	if (sdata->u.sta.flags & IEEE80211_STA_BSSID_SET)
+		goto put_bss;
+
+	/* not an IBSS */
+	if (!(bss->cbss.capability & WLAN_CAPABILITY_IBSS))
+		goto put_bss;
+
+	/* different channel */
+	if (bss->cbss.channel !=3D local->oper_channel)
+		goto put_bss;
+
+	/* different SSID */
+	if (elems->ssid_len !=3D sdata->u.sta.ssid_len ||
 	    memcmp(elems->ssid, sdata->u.sta.ssid,
-				sdata->u.sta.ssid_len) =3D=3D 0) {
-		if (rx_status->flag & RX_FLAG_TSFT) {
-			/* in order for correct IBSS merging we need mactime
-			 *
-			 * since mactime is defined as the time the first data
-			 * symbol of the frame hits the PHY, and the timestamp
-			 * of the beacon is defined as "the time that the data
-			 * symbol containing the first bit of the timestamp is
-			 * transmitted to the PHY plus the transmitting STA=E2=80=99s
-			 * delays through its local PHY from the MAC-PHY
-			 * interface to its interface with the WM"
-			 * (802.11 11.1.2) - equals the time this bit arrives at
-			 * the receiver - we have to take into account the
-			 * offset between the two.
-			 * e.g: at 1 MBit that means mactime is 192 usec earlier
-			 * (=3D24 bytes * 8 usecs/byte) than the beacon timestamp.
-			 */
-			int rate;
-			if (rx_status->flag & RX_FLAG_HT) {
-				rate =3D 65; /* TODO: HT rates */
-			} else {
-				rate =3D local->hw.wiphy->bands[band]->
-					bitrates[rx_status->rate_idx].bitrate;
-			}
-			rx_timestamp =3D rx_status->mactime + (24 * 8 * 10 / rate);
-		} else if (local && local->ops && local->ops->get_tsf)
-			/* second best option: get current TSF */
-			rx_timestamp =3D local->ops->get_tsf(local_to_hw(local));
+				sdata->u.sta.ssid_len))
+		goto put_bss;
+
+	if (rx_status->flag & RX_FLAG_TSFT) {
+		/*
+		 * For correct IBSS merging we need mactime; since mactime is
+		 * defined as the time the first data symbol of the frame hits
+		 * the PHY, and the timestamp of the beacon is defined as "the
+		 * time that the data symbol containing the first bit of the
+		 * timestamp is transmitted to the PHY plus the transmitting
+		 * STA's delays through its local PHY from the MAC-PHY
+		 * interface to its interface with the WM" (802.11 11.1.2)
+		 * - equals the time this bit arrives at the receiver - we have
+		 * to take into account the offset between the two.
+		 *
+		 * E.g. at 1 MBit that means mactime is 192 usec earlier
+		 * (=3D24 bytes * 8 usecs/byte) than the beacon timestamp.
+		 */
+		int rate;
+
+		if (rx_status->flag & RX_FLAG_HT)
+			rate =3D 65; /* TODO: HT rates */
 		else
-			/* can't merge without knowing the TSF */
-			rx_timestamp =3D -1LLU;
+			rate =3D local->hw.wiphy->bands[band]->
+				bitrates[rx_status->rate_idx].bitrate;
+
+		rx_timestamp =3D rx_status->mactime + (24 * 8 * 10 / rate);
+	} else if (local && local->ops && local->ops->get_tsf)
+		/* second best option: get current TSF */
+		rx_timestamp =3D local->ops->get_tsf(local_to_hw(local));
+	else
+		/* can't merge without knowing the TSF */
+		rx_timestamp =3D -1LLU;
+
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
-		printk(KERN_DEBUG "RX beacon SA=3D%pM BSSID=3D"
-		       "%pM TSF=3D0x%llx BCN=3D0x%llx diff=3D%lld @%lu\n",
-		       mgmt->sa, mgmt->bssid,
-		       (unsigned long long)rx_timestamp,
-		       (unsigned long long)beacon_timestamp,
-		       (unsigned long long)(rx_timestamp - beacon_timestamp),
-		       jiffies);
-#endif /* CONFIG_MAC80211_IBSS_DEBUG */
-		if (beacon_timestamp > rx_timestamp) {
+	printk(KERN_DEBUG "RX beacon SA=3D%pM BSSID=3D"
+	       "%pM TSF=3D0x%llx BCN=3D0x%llx diff=3D%lld @%lu\n",
+	       mgmt->sa, mgmt->bssid,
+	       (unsigned long long)rx_timestamp,
+	       (unsigned long long)beacon_timestamp,
+	       (unsigned long long)(rx_timestamp - beacon_timestamp),
+	       jiffies);
+#endif
+
+	if (beacon_timestamp > rx_timestamp) {
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
-			printk(KERN_DEBUG "%s: beacon TSF higher than "
-			       "local TSF - IBSS merge with BSSID %pM\n",
-			       sdata->dev->name, mgmt->bssid);
+		printk(KERN_DEBUG "%s: beacon TSF higher than "
+		       "local TSF - IBSS merge with BSSID %pM\n",
+		       sdata->dev->name, mgmt->bssid);
 #endif
-			ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss);
-			ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates);
-		}
+		ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss);
+		ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates);
 	}
=20
+ put_bss:
 	ieee80211_rx_bss_put(local, bss);
 }
=20
@@ -1948,8 +1964,7 @@ static void ieee80211_rx_mgmt_probe_req(
 	struct ieee80211_mgmt *resp;
 	u8 *pos, *end;
=20
-	if (sdata->vif.type !=3D NL80211_IFTYPE_ADHOC ||
-	    ifsta->state !=3D IEEE80211_STA_MLME_IBSS_JOINED ||
+	if (ifsta->state !=3D IEEE80211_STA_MLME_IBSS_JOINED ||
 	    len < 24 + 2 || !ifsta->probe_resp)
 		return;
=20
@@ -2053,31 +2068,54 @@ static void ieee80211_sta_rx_queued_mgmt
 	mgmt =3D (struct ieee80211_mgmt *) skb->data;
 	fc =3D le16_to_cpu(mgmt->frame_control);
=20
-	switch (fc & IEEE80211_FCTL_STYPE) {
-	case IEEE80211_STYPE_PROBE_REQ:
-		ieee80211_rx_mgmt_probe_req(sdata, ifsta, mgmt, skb->len);
-		break;
-	case IEEE80211_STYPE_PROBE_RESP:
-		ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len, rx_status);
-		break;
-	case IEEE80211_STYPE_BEACON:
-		ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status);
-		break;
-	case IEEE80211_STYPE_AUTH:
-		ieee80211_rx_mgmt_auth(sdata, ifsta, mgmt, skb->len);
-		break;
-	case IEEE80211_STYPE_ASSOC_RESP:
-		ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 0);
-		break;
-	case IEEE80211_STYPE_REASSOC_RESP:
-		ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 1);
-		break;
-	case IEEE80211_STYPE_DEAUTH:
-		ieee80211_rx_mgmt_deauth(sdata, ifsta, mgmt, skb->len);
-		break;
-	case IEEE80211_STYPE_DISASSOC:
-		ieee80211_rx_mgmt_disassoc(sdata, ifsta, mgmt, skb->len);
-		break;
+	if (sdata->vif.type =3D=3D NL80211_IFTYPE_ADHOC) {
+		switch (fc & IEEE80211_FCTL_STYPE) {
+		case IEEE80211_STYPE_PROBE_REQ:
+			ieee80211_rx_mgmt_probe_req(sdata, ifsta, mgmt,
+						    skb->len);
+			break;
+		case IEEE80211_STYPE_PROBE_RESP:
+			ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len,
+						     rx_status);
+			break;
+		case IEEE80211_STYPE_BEACON:
+			ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len,
+						 rx_status);
+			break;
+		case IEEE80211_STYPE_AUTH:
+			ieee80211_rx_mgmt_auth_ibss(sdata, ifsta, mgmt,
+						    skb->len);
+			break;
+		}
+	} else { /* NL80211_IFTYPE_STATION */
+		switch (fc & IEEE80211_FCTL_STYPE) {
+		case IEEE80211_STYPE_PROBE_RESP:
+			ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len,
+						     rx_status);
+			break;
+		case IEEE80211_STYPE_BEACON:
+			ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len,
+						 rx_status);
+			break;
+		case IEEE80211_STYPE_AUTH:
+			ieee80211_rx_mgmt_auth(sdata, ifsta, mgmt, skb->len);
+			break;
+		case IEEE80211_STYPE_ASSOC_RESP:
+			ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt,
+						     skb->len, 0);
+			break;
+		case IEEE80211_STYPE_REASSOC_RESP:
+			ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt,
+						     skb->len, 1);
+			break;
+		case IEEE80211_STYPE_DEAUTH:
+			ieee80211_rx_mgmt_deauth(sdata, ifsta, mgmt, skb->len);
+			break;
+		case IEEE80211_STYPE_DISASSOC:
+			ieee80211_rx_mgmt_disassoc(sdata, ifsta, mgmt,
+						   skb->len);
+			break;
+		}
 	}
=20
 	kfree_skb(skb);

--=20


      parent reply	other threads:[~2009-02-10 20:44 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-02-10 20:25 [PATCH 00/27] mac80211 updates Johannes Berg
2009-02-10 20:25 ` [PATCH 01/27] zd1211rw: do not ratelimit no-ops Johannes Berg
2009-02-10 20:25 ` [PATCH 02/27] mac80211: disable IBSS beacon before join Johannes Berg
2009-02-10 20:25 ` [PATCH 03/27] zd1211rw: honour enable_beacon conf Johannes Berg
2009-02-10 20:25 ` [PATCH 04/27] mac80211: properly validate/translate IW_AUTH_MFP values Johannes Berg
2009-02-10 20:25 ` [PATCH 05/27] mac80211: reject extra IEs for probe request when hw_scan Johannes Berg
2009-02-10 20:25 ` [PATCH 06/27] mac80211: fix beacon enable more Johannes Berg
2009-02-10 20:25 ` [PATCH 07/27] mac80211: remove bssid argument from prepare_for_handlers Johannes Berg
2009-02-10 20:25 ` [PATCH 08/27] mac80211: remove stray aggregation debugfs definition Johannes Berg
2009-02-10 20:25 ` [PATCH 09/27] mac80211: fix RX aggregation timeouts Johannes Berg
2009-02-10 20:25 ` [PATCH 10/27] mac80211: restructure HT code Johannes Berg
2009-02-10 20:25 ` [PATCH 11/27] mac80211: restrict aggregation to supported interface modes Johannes Berg
2009-02-10 20:25 ` [PATCH 12/27] mac80211: hardware should not deny going back to legacy Johannes Berg
2009-02-10 20:25 ` [PATCH 13/27] mac80211: document TX aggregation (and small cleanup) Johannes Berg
2009-02-10 20:25 ` [PATCH 14/27] mac80211: fix race in TX aggregation Johannes Berg
2009-02-10 20:25 ` [PATCH 15/27] mac80211: fix aggregation timer lockups Johannes Berg
2009-02-10 20:25 ` [PATCH 16/27] mac80211: clean up BA session teardown Johannes Berg
2009-02-10 20:25 ` [PATCH 17/27] mac80211: RX aggregation: clean up stop session Johannes Berg
2009-02-10 20:25 ` [PATCH 18/27] mac80211: further cleanups to stopping BA sessions Johannes Berg
2009-02-10 20:25 ` [PATCH 19/27] cfg80211/nl80211: scanning (and mac80211 update to use it) Johannes Berg
2009-02-10 20:25 ` [PATCH 20/27] mac80211: dont add BSS when creating IBSS Johannes Berg
2009-02-10 20:25 ` [PATCH 21/27] cfg80211: free_priv for BSS info Johannes Berg
2009-02-10 20:25 ` [PATCH 22/27] cfg80211: allow users to request removing a BSS Johannes Berg
2009-02-10 20:25 ` [PATCH 23/27] cfg80211: add more flexible BSS lookup Johannes Berg
2009-02-10 20:26 ` [PATCH 24/27] mac80211: use cfg80211s BSS infrastructure Johannes Berg
2009-02-10 20:26 ` [PATCH 25/27] mac80211: calculate wstats_flags on the fly Johannes Berg
2009-02-10 20:26 ` [PATCH 26/27] mac80211: fix IBSS auth Johannes Berg
2009-02-10 20:26 ` Johannes Berg [this message]

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=20090210202557.918427159@sipsolutions.net \
    --to=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).