linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] AP mode is coming
@ 2008-01-31 18:48 Johannes Berg
  2008-01-31 18:48 ` [PATCH 1/8] mac80211: split ieee80211_txrx_result Johannes Berg
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Johannes Berg @ 2008-01-31 18:48 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

These patches do some cleanups and introduce new features that
are the last major features for AP mode. Still missing are many
things for basic rate and ERP feature handling, so I'm still
holding back the patch that actually enables AP mode---I want
the code to be at least mostly 802.11 compliant before I allow
that.

johannes

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

* [PATCH 1/8] mac80211: split ieee80211_txrx_result
  2008-01-31 18:48 [PATCH 0/8] AP mode is coming Johannes Berg
@ 2008-01-31 18:48 ` Johannes Berg
  2008-01-31 18:48 ` [PATCH 2/8] mac80211: split RX_DROP Johannes Berg
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Johannes Berg @ 2008-01-31 18:48 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

The _DROP result will need to be split in the RX path but not
in the TX path, so for preparation split up the type into two
types, one for RX and one for TX. Also make sure (via sparse)
that they cannot be confused.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
Not entirely sure about the __bitwise__ stuff, should we do that?

 net/mac80211/ieee80211_i.h   |   23 ++++--
 net/mac80211/ieee80211_sta.c |   14 ++--
 net/mac80211/rx.c            |  150 +++++++++++++++++++++----------------------
 net/mac80211/tx.c            |  110 +++++++++++++++----------------
 net/mac80211/wep.c           |   16 ++--
 net/mac80211/wep.h           |    4 -
 net/mac80211/wpa.c           |   72 ++++++++++----------
 net/mac80211/wpa.h           |   12 +--
 8 files changed, 204 insertions(+), 197 deletions(-)

--- everything.orig/net/mac80211/ieee80211_i.h	2008-01-31 15:46:06.355845920 +0100
+++ everything/net/mac80211/ieee80211_i.h	2008-01-31 15:46:09.015793999 +0100
@@ -108,9 +108,16 @@ struct ieee80211_sta_bss {
 };
 
 
-typedef enum {
-	TXRX_CONTINUE, TXRX_DROP, TXRX_QUEUED
-} ieee80211_txrx_result;
+typedef unsigned __bitwise__ ieee80211_tx_result;
+#define TX_CONTINUE	((__force ieee80211_tx_result) 0u)
+#define TX_DROP		((__force ieee80211_tx_result) 1u)
+#define TX_QUEUED	((__force ieee80211_tx_result) 2u)
+
+typedef unsigned __bitwise__ ieee80211_rx_result;
+#define RX_CONTINUE	((__force ieee80211_rx_result) 0u)
+#define RX_DROP		((__force ieee80211_rx_result) 1u)
+#define RX_QUEUED	((__force ieee80211_rx_result) 2u)
+
 
 /* flags used in struct ieee80211_txrx_data.flags */
 /* whether the MSDU was fragmented */
@@ -182,10 +189,10 @@ struct ieee80211_tx_stored_packet {
 	unsigned int last_frag_rate_ctrl_probe;
 };
 
-typedef ieee80211_txrx_result (*ieee80211_tx_handler)
+typedef ieee80211_tx_result (*ieee80211_tx_handler)
 (struct ieee80211_txrx_data *tx);
 
-typedef ieee80211_txrx_result (*ieee80211_rx_handler)
+typedef ieee80211_rx_result (*ieee80211_rx_handler)
 (struct ieee80211_txrx_data *rx);
 
 struct beacon_data {
@@ -729,9 +736,9 @@ int ieee80211_sta_req_scan(struct net_de
 void ieee80211_sta_req_auth(struct net_device *dev,
 			    struct ieee80211_if_sta *ifsta);
 int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len);
-ieee80211_txrx_result ieee80211_sta_rx_scan(struct net_device *dev,
-					    struct sk_buff *skb,
-			   struct ieee80211_rx_status *rx_status);
+ieee80211_rx_result ieee80211_sta_rx_scan(
+	struct net_device *dev, struct sk_buff *skb,
+	struct ieee80211_rx_status *rx_status);
 void ieee80211_rx_bss_list_init(struct net_device *dev);
 void ieee80211_rx_bss_list_deinit(struct net_device *dev);
 int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len);
--- everything.orig/net/mac80211/wep.h	2008-01-31 15:45:57.875793999 +0100
+++ everything/net/mac80211/wep.h	2008-01-31 15:46:09.015793999 +0100
@@ -28,9 +28,9 @@ int ieee80211_wep_decrypt(struct ieee802
 			  struct ieee80211_key *key);
 u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);
 
-ieee80211_txrx_result
+ieee80211_rx_result
 ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx);
-ieee80211_txrx_result
+ieee80211_tx_result
 ieee80211_crypto_wep_encrypt(struct ieee80211_txrx_data *tx);
 
 #endif /* WEP_H */
--- everything.orig/net/mac80211/wpa.h	2008-01-31 15:45:57.935793890 +0100
+++ everything/net/mac80211/wpa.h	2008-01-31 15:46:09.015793999 +0100
@@ -13,19 +13,19 @@
 #include <linux/types.h>
 #include "ieee80211_i.h"
 
-ieee80211_txrx_result
+ieee80211_tx_result
 ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx);
-ieee80211_txrx_result
+ieee80211_rx_result
 ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx);
 
-ieee80211_txrx_result
+ieee80211_tx_result
 ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data *tx);
-ieee80211_txrx_result
+ieee80211_rx_result
 ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx);
 
-ieee80211_txrx_result
+ieee80211_tx_result
 ieee80211_crypto_ccmp_encrypt(struct ieee80211_txrx_data *tx);
-ieee80211_txrx_result
+ieee80211_rx_result
 ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx);
 
 #endif /* WPA_H */
--- everything.orig/net/mac80211/wep.c	2008-01-31 15:45:57.965793728 +0100
+++ everything/net/mac80211/wep.c	2008-01-31 15:46:09.015793999 +0100
@@ -305,13 +305,13 @@ u8 * ieee80211_wep_is_weak_iv(struct sk_
 	return NULL;
 }
 
-ieee80211_txrx_result
+ieee80211_rx_result
 ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx)
 {
 	if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
 	    ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
 	     (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH))
-		return TXRX_CONTINUE;
+		return RX_CONTINUE;
 
 	if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) {
 		if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) {
@@ -320,7 +320,7 @@ ieee80211_crypto_wep_decrypt(struct ieee
 				printk(KERN_DEBUG "%s: RX WEP frame, decrypt "
 				       "failed\n", rx->dev->name);
 #endif /* CONFIG_MAC80211_DEBUG */
-			return TXRX_DROP;
+			return RX_DROP;
 		}
 	} else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) {
 		ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
@@ -328,7 +328,7 @@ ieee80211_crypto_wep_decrypt(struct ieee
 		skb_trim(rx->skb, rx->skb->len - 4);
 	}
 
-	return TXRX_CONTINUE;
+	return RX_CONTINUE;
 }
 
 static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb)
@@ -346,7 +346,7 @@ static int wep_encrypt_skb(struct ieee80
 	return 0;
 }
 
-ieee80211_txrx_result
+ieee80211_tx_result
 ieee80211_crypto_wep_encrypt(struct ieee80211_txrx_data *tx)
 {
 	tx->u.tx.control->iv_len = WEP_IV_LEN;
@@ -355,7 +355,7 @@ ieee80211_crypto_wep_encrypt(struct ieee
 
 	if (wep_encrypt_skb(tx, tx->skb) < 0) {
 		I802_DEBUG_INC(tx->local->tx_handlers_drop_wep);
-		return TXRX_DROP;
+		return TX_DROP;
 	}
 
 	if (tx->u.tx.extra_frag) {
@@ -364,10 +364,10 @@ ieee80211_crypto_wep_encrypt(struct ieee
 			if (wep_encrypt_skb(tx, tx->u.tx.extra_frag[i]) < 0) {
 				I802_DEBUG_INC(tx->local->
 					       tx_handlers_drop_wep);
-				return TXRX_DROP;
+				return TX_DROP;
 			}
 		}
 	}
 
-	return TXRX_CONTINUE;
+	return TX_CONTINUE;
 }
--- everything.orig/net/mac80211/ieee80211_sta.c	2008-01-31 15:45:58.065794107 +0100
+++ everything/net/mac80211/ieee80211_sta.c	2008-01-31 15:46:09.025793944 +0100
@@ -2558,7 +2558,7 @@ static void ieee80211_sta_rx_queued_mgmt
 }
 
 
-ieee80211_txrx_result
+ieee80211_rx_result
 ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb,
 		      struct ieee80211_rx_status *rx_status)
 {
@@ -2566,31 +2566,31 @@ ieee80211_sta_rx_scan(struct net_device 
 	u16 fc;
 
 	if (skb->len < 2)
-		return TXRX_DROP;
+		return RX_DROP;
 
 	mgmt = (struct ieee80211_mgmt *) skb->data;
 	fc = le16_to_cpu(mgmt->frame_control);
 
 	if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL)
-		return TXRX_CONTINUE;
+		return RX_CONTINUE;
 
 	if (skb->len < 24)
-		return TXRX_DROP;
+		return RX_DROP;
 
 	if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
 		if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP) {
 			ieee80211_rx_mgmt_probe_resp(dev, mgmt,
 						     skb->len, rx_status);
 			dev_kfree_skb(skb);
-			return TXRX_QUEUED;
+			return RX_QUEUED;
 		} else if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) {
 			ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len,
 						 rx_status);
 			dev_kfree_skb(skb);
-			return TXRX_QUEUED;
+			return RX_QUEUED;
 		}
 	}
-	return TXRX_CONTINUE;
+	return RX_CONTINUE;
 }
 
 
--- everything.orig/net/mac80211/wpa.c	2008-01-31 15:45:58.015796658 +0100
+++ everything/net/mac80211/wpa.c	2008-01-31 15:46:09.025793944 +0100
@@ -70,7 +70,7 @@ static int ieee80211_get_hdr_info(const 
 }
 
 
-ieee80211_txrx_result
+ieee80211_tx_result
 ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx)
 {
 	u8 *data, *sa, *da, *key, *mic, qos_tid;
@@ -84,10 +84,10 @@ ieee80211_tx_h_michael_mic_add(struct ie
 
 	if (!tx->key || tx->key->conf.alg != ALG_TKIP || skb->len < 24 ||
 	    !WLAN_FC_DATA_PRESENT(fc))
-		return TXRX_CONTINUE;
+		return TX_CONTINUE;
 
 	if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len))
-		return TXRX_DROP;
+		return TX_DROP;
 
 	if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
 	    !(tx->flags & IEEE80211_TXRXD_FRAGMENTED) &&
@@ -95,7 +95,7 @@ ieee80211_tx_h_michael_mic_add(struct ie
 	    !wpa_test) {
 		/* hwaccel - with no need for preallocated room for Michael MIC
 		 */
-		return TXRX_CONTINUE;
+		return TX_CONTINUE;
 	}
 
 	if (skb_tailroom(skb) < MICHAEL_MIC_LEN) {
@@ -105,7 +105,7 @@ ieee80211_tx_h_michael_mic_add(struct ie
 					      GFP_ATOMIC))) {
 			printk(KERN_DEBUG "%s: failed to allocate more memory "
 			       "for Michael MIC\n", tx->dev->name);
-			return TXRX_DROP;
+			return TX_DROP;
 		}
 	}
 
@@ -119,11 +119,11 @@ ieee80211_tx_h_michael_mic_add(struct ie
 	mic = skb_put(skb, MICHAEL_MIC_LEN);
 	michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic);
 
-	return TXRX_CONTINUE;
+	return TX_CONTINUE;
 }
 
 
-ieee80211_txrx_result
+ieee80211_rx_result
 ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx)
 {
 	u8 *data, *sa, *da, *key = NULL, qos_tid;
@@ -140,15 +140,15 @@ ieee80211_rx_h_michael_mic_verify(struct
 	 * No way to verify the MIC if the hardware stripped it
 	 */
 	if (rx->u.rx.status->flag & RX_FLAG_MMIC_STRIPPED)
-		return TXRX_CONTINUE;
+		return RX_CONTINUE;
 
 	if (!rx->key || rx->key->conf.alg != ALG_TKIP ||
 	    !(rx->fc & IEEE80211_FCTL_PROTECTED) || !WLAN_FC_DATA_PRESENT(fc))
-		return TXRX_CONTINUE;
+		return RX_CONTINUE;
 
 	if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len)
 	    || data_len < MICHAEL_MIC_LEN)
-		return TXRX_DROP;
+		return RX_DROP;
 
 	data_len -= MICHAEL_MIC_LEN;
 
@@ -162,14 +162,14 @@ ieee80211_rx_h_michael_mic_verify(struct
 	michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic);
 	if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) {
 		if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
-			return TXRX_DROP;
+			return RX_DROP;
 
 		printk(KERN_DEBUG "%s: invalid Michael MIC in data frame from "
 		       "%s\n", rx->dev->name, print_mac(mac, sa));
 
 		mac80211_ev_michael_mic_failure(rx->dev, rx->key->conf.keyidx,
 						(void *) skb->data);
-		return TXRX_DROP;
+		return RX_DROP;
 	}
 
 	/* remove Michael MIC from payload */
@@ -179,7 +179,7 @@ ieee80211_rx_h_michael_mic_verify(struct
 	rx->key->u.tkip.iv32_rx[rx->u.rx.queue] = rx->u.rx.tkip_iv32;
 	rx->key->u.tkip.iv16_rx[rx->u.rx.queue] = rx->u.rx.tkip_iv16;
 
-	return TXRX_CONTINUE;
+	return RX_CONTINUE;
 }
 
 
@@ -242,7 +242,7 @@ static int tkip_encrypt_skb(struct ieee8
 }
 
 
-ieee80211_txrx_result
+ieee80211_tx_result
 ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data *tx)
 {
 	struct sk_buff *skb = tx->skb;
@@ -257,26 +257,26 @@ ieee80211_crypto_tkip_encrypt(struct iee
 	    !wpa_test) {
 		/* hwaccel - with no need for preallocated room for IV/ICV */
 		tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
-		return TXRX_CONTINUE;
+		return TX_CONTINUE;
 	}
 
 	if (tkip_encrypt_skb(tx, skb, test) < 0)
-		return TXRX_DROP;
+		return TX_DROP;
 
 	if (tx->u.tx.extra_frag) {
 		int i;
 		for (i = 0; i < tx->u.tx.num_extra_frag; i++) {
 			if (tkip_encrypt_skb(tx, tx->u.tx.extra_frag[i], test)
 			    < 0)
-				return TXRX_DROP;
+				return TX_DROP;
 		}
 	}
 
-	return TXRX_CONTINUE;
+	return TX_CONTINUE;
 }
 
 
-ieee80211_txrx_result
+ieee80211_rx_result
 ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
@@ -290,10 +290,10 @@ ieee80211_crypto_tkip_decrypt(struct iee
 	hdrlen = ieee80211_get_hdrlen(fc);
 
 	if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
-		return TXRX_CONTINUE;
+		return RX_CONTINUE;
 
 	if (!rx->sta || skb->len - hdrlen < 12)
-		return TXRX_DROP;
+		return RX_DROP;
 
 	if (rx->u.rx.status->flag & RX_FLAG_DECRYPTED) {
 		if (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED) {
@@ -302,7 +302,7 @@ ieee80211_crypto_tkip_decrypt(struct iee
 			 * replay protection, and stripped the ICV/IV so
 			 * we cannot do any checks here.
 			 */
-			return TXRX_CONTINUE;
+			return RX_CONTINUE;
 		}
 
 		/* let TKIP code verify IV, but skip decryption */
@@ -322,7 +322,7 @@ ieee80211_crypto_tkip_decrypt(struct iee
 			       "frame from %s (res=%d)\n", rx->dev->name,
 			       print_mac(mac, rx->sta->addr), res);
 #endif /* CONFIG_MAC80211_DEBUG */
-		return TXRX_DROP;
+		return RX_DROP;
 	}
 
 	/* Trim ICV */
@@ -332,7 +332,7 @@ ieee80211_crypto_tkip_decrypt(struct iee
 	memmove(skb->data + TKIP_IV_LEN, skb->data, hdrlen);
 	skb_pull(skb, TKIP_IV_LEN);
 
-	return TXRX_CONTINUE;
+	return RX_CONTINUE;
 }
 
 
@@ -491,7 +491,7 @@ static int ccmp_encrypt_skb(struct ieee8
 }
 
 
-ieee80211_txrx_result
+ieee80211_tx_result
 ieee80211_crypto_ccmp_encrypt(struct ieee80211_txrx_data *tx)
 {
 	struct sk_buff *skb = tx->skb;
@@ -506,26 +506,26 @@ ieee80211_crypto_ccmp_encrypt(struct iee
 		/* hwaccel - with no need for preallocated room for CCMP "
 		 * header or MIC fields */
 		tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
-		return TXRX_CONTINUE;
+		return TX_CONTINUE;
 	}
 
 	if (ccmp_encrypt_skb(tx, skb, test) < 0)
-		return TXRX_DROP;
+		return TX_DROP;
 
 	if (tx->u.tx.extra_frag) {
 		int i;
 		for (i = 0; i < tx->u.tx.num_extra_frag; i++) {
 			if (ccmp_encrypt_skb(tx, tx->u.tx.extra_frag[i], test)
 			    < 0)
-				return TXRX_DROP;
+				return TX_DROP;
 		}
 	}
 
-	return TXRX_CONTINUE;
+	return TX_CONTINUE;
 }
 
 
-ieee80211_txrx_result
+ieee80211_rx_result
 ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
@@ -541,15 +541,15 @@ ieee80211_crypto_ccmp_decrypt(struct iee
 	hdrlen = ieee80211_get_hdrlen(fc);
 
 	if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
-		return TXRX_CONTINUE;
+		return RX_CONTINUE;
 
 	data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN;
 	if (!rx->sta || data_len < 0)
-		return TXRX_DROP;
+		return RX_DROP;
 
 	if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
 	    (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED))
-		return TXRX_CONTINUE;
+		return RX_CONTINUE;
 
 	(void) ccmp_hdr2pn(pn, skb->data + hdrlen);
 
@@ -565,7 +565,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
 		       ppn[0], ppn[1], ppn[2], ppn[3], ppn[4], ppn[5]);
 #endif /* CONFIG_MAC80211_DEBUG */
 		key->u.ccmp.replays++;
-		return TXRX_DROP;
+		return RX_DROP;
 	}
 
 	if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) {
@@ -589,7 +589,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
 				       "for RX frame from %s\n", rx->dev->name,
 				       print_mac(mac, rx->sta->addr));
 #endif /* CONFIG_MAC80211_DEBUG */
-			return TXRX_DROP;
+			return RX_DROP;
 		}
 	}
 
@@ -600,5 +600,5 @@ ieee80211_crypto_ccmp_decrypt(struct iee
 	memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen);
 	skb_pull(skb, CCMP_HDR_LEN);
 
-	return TXRX_CONTINUE;
+	return RX_CONTINUE;
 }
--- everything.orig/net/mac80211/rx.c	2008-01-31 15:46:06.355845920 +0100
+++ everything/net/mac80211/rx.c	2008-01-31 15:46:09.035794161 +0100
@@ -351,16 +351,16 @@ static u32 ieee80211_rx_load_stats(struc
 
 /* rx handlers */
 
-static ieee80211_txrx_result
+static ieee80211_rx_result
 ieee80211_rx_h_if_stats(struct ieee80211_txrx_data *rx)
 {
 	if (rx->sta)
 		rx->sta->channel_use_raw += rx->u.rx.load;
 	rx->sdata->channel_use_raw += rx->u.rx.load;
-	return TXRX_CONTINUE;
+	return RX_CONTINUE;
 }
 
-static ieee80211_txrx_result
+static ieee80211_rx_result
 ieee80211_rx_h_passive_scan(struct ieee80211_txrx_data *rx)
 {
 	struct ieee80211_local *local = rx->local;
@@ -372,21 +372,21 @@ ieee80211_rx_h_passive_scan(struct ieee8
 	if (unlikely(local->sta_sw_scanning)) {
 		/* drop all the other packets during a software scan anyway */
 		if (ieee80211_sta_rx_scan(rx->dev, skb, rx->u.rx.status)
-		    != TXRX_QUEUED)
+		    != RX_QUEUED)
 			dev_kfree_skb(skb);
-		return TXRX_QUEUED;
+		return RX_QUEUED;
 	}
 
 	if (unlikely(rx->flags & IEEE80211_TXRXD_RXIN_SCAN)) {
 		/* scanning finished during invoking of handlers */
 		I802_DEBUG_INC(local->rx_handlers_drop_passive_scan);
-		return TXRX_DROP;
+		return RX_DROP;
 	}
 
-	return TXRX_CONTINUE;
+	return RX_CONTINUE;
 }
 
-static ieee80211_txrx_result
+static ieee80211_rx_result
 ieee80211_rx_h_check(struct ieee80211_txrx_data *rx)
 {
 	struct ieee80211_hdr *hdr;
@@ -401,14 +401,14 @@ ieee80211_rx_h_check(struct ieee80211_tx
 				rx->local->dot11FrameDuplicateCount++;
 				rx->sta->num_duplicates++;
 			}
-			return TXRX_DROP;
+			return RX_DROP;
 		} else
 			rx->sta->last_seq_ctrl[rx->u.rx.queue] = hdr->seq_ctrl;
 	}
 
 	if (unlikely(rx->skb->len < 16)) {
 		I802_DEBUG_INC(rx->local->rx_handlers_drop_short);
-		return TXRX_DROP;
+		return RX_DROP;
 	}
 
 	/* Drop disallowed frame classes based on STA auth/assoc state;
@@ -430,23 +430,23 @@ ieee80211_rx_h_check(struct ieee80211_tx
 		    || !(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) {
 			/* Drop IBSS frames and frames for other hosts
 			 * silently. */
-			return TXRX_DROP;
+			return RX_DROP;
 		}
 
-		return TXRX_DROP;
+		return RX_DROP;
 	}
 
-	return TXRX_CONTINUE;
+	return RX_CONTINUE;
 }
 
 
-static ieee80211_txrx_result
+static ieee80211_rx_result
 ieee80211_rx_h_decrypt(struct ieee80211_txrx_data *rx)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
 	int keyidx;
 	int hdrlen;
-	ieee80211_txrx_result result = TXRX_DROP;
+	ieee80211_rx_result result = RX_DROP;
 	struct ieee80211_key *stakey = NULL;
 
 	/*
@@ -476,14 +476,14 @@ ieee80211_rx_h_decrypt(struct ieee80211_
 	 */
 
 	if (!(rx->fc & IEEE80211_FCTL_PROTECTED))
-		return TXRX_CONTINUE;
+		return RX_CONTINUE;
 
 	/*
 	 * No point in finding a key and decrypting if the frame is neither
 	 * addressed to us nor a multicast frame.
 	 */
 	if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
-		return TXRX_CONTINUE;
+		return RX_CONTINUE;
 
 	if (rx->sta)
 		stakey = rcu_dereference(rx->sta->key);
@@ -502,12 +502,12 @@ ieee80211_rx_h_decrypt(struct ieee80211_
 		 */
 		if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
 		    (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED))
-			return TXRX_CONTINUE;
+			return RX_CONTINUE;
 
 		hdrlen = ieee80211_get_hdrlen(rx->fc);
 
 		if (rx->skb->len < 8 + hdrlen)
-			return TXRX_DROP; /* TODO: count this? */
+			return RX_DROP; /* TODO: count this? */
 
 		/*
 		 * no need to call ieee80211_wep_get_keyidx,
@@ -536,7 +536,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_
 			printk(KERN_DEBUG "%s: RX protected frame,"
 			       " but have no key\n", rx->dev->name);
 #endif /* CONFIG_MAC80211_DEBUG */
-		return TXRX_DROP;
+		return RX_DROP;
 	}
 
 	/* Check for weak IVs if possible */
@@ -629,7 +629,7 @@ static int ap_sta_ps_end(struct net_devi
 	return sent;
 }
 
-static ieee80211_txrx_result
+static ieee80211_rx_result
 ieee80211_rx_h_sta_process(struct ieee80211_txrx_data *rx)
 {
 	struct sta_info *sta = rx->sta;
@@ -637,7 +637,7 @@ ieee80211_rx_h_sta_process(struct ieee80
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
 
 	if (!sta)
-		return TXRX_CONTINUE;
+		return RX_CONTINUE;
 
 	/* Update last_rx only for IBSS packets which are for the current
 	 * BSSID to avoid keeping the current IBSS network alive in cases where
@@ -658,7 +658,7 @@ ieee80211_rx_h_sta_process(struct ieee80
 	}
 
 	if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
-		return TXRX_CONTINUE;
+		return RX_CONTINUE;
 
 	sta->rx_fragments++;
 	sta->rx_bytes += rx->skb->len;
@@ -685,10 +685,10 @@ ieee80211_rx_h_sta_process(struct ieee80
 		 * as a dropped packed. */
 		sta->rx_packets++;
 		dev_kfree_skb(rx->skb);
-		return TXRX_QUEUED;
+		return RX_QUEUED;
 	}
 
-	return TXRX_CONTINUE;
+	return RX_CONTINUE;
 } /* ieee80211_rx_h_sta_process */
 
 static inline struct ieee80211_fragment_entry *
@@ -774,7 +774,7 @@ ieee80211_reassemble_find(struct ieee802
 	return NULL;
 }
 
-static ieee80211_txrx_result
+static ieee80211_rx_result
 ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx)
 {
 	struct ieee80211_hdr *hdr;
@@ -811,7 +811,7 @@ ieee80211_rx_h_defragment(struct ieee802
 			       rx->key->u.ccmp.rx_pn[rx->u.rx.queue],
 			       CCMP_PN_LEN);
 		}
-		return TXRX_QUEUED;
+		return RX_QUEUED;
 	}
 
 	/* This is a fragment for a frame that should already be pending in
@@ -821,7 +821,7 @@ ieee80211_rx_h_defragment(struct ieee802
 					  rx->u.rx.queue, hdr);
 	if (!entry) {
 		I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag);
-		return TXRX_DROP;
+		return RX_DROP;
 	}
 
 	/* Verify that MPDUs within one MSDU have sequential PN values.
@@ -830,7 +830,7 @@ ieee80211_rx_h_defragment(struct ieee802
 		int i;
 		u8 pn[CCMP_PN_LEN], *rpn;
 		if (!rx->key || rx->key->conf.alg != ALG_CCMP)
-			return TXRX_DROP;
+			return RX_DROP;
 		memcpy(pn, entry->last_pn, CCMP_PN_LEN);
 		for (i = CCMP_PN_LEN - 1; i >= 0; i--) {
 			pn[i]++;
@@ -848,7 +848,7 @@ ieee80211_rx_h_defragment(struct ieee802
 				       rpn[0], rpn[1], rpn[2], rpn[3], rpn[4],
 				       rpn[5], pn[0], pn[1], pn[2], pn[3],
 				       pn[4], pn[5]);
-			return TXRX_DROP;
+			return RX_DROP;
 		}
 		memcpy(entry->last_pn, pn, CCMP_PN_LEN);
 	}
@@ -859,7 +859,7 @@ ieee80211_rx_h_defragment(struct ieee802
 	entry->extra_len += rx->skb->len;
 	if (rx->fc & IEEE80211_FCTL_MOREFRAGS) {
 		rx->skb = NULL;
-		return TXRX_QUEUED;
+		return RX_QUEUED;
 	}
 
 	rx->skb = __skb_dequeue(&entry->skb_list);
@@ -869,7 +869,7 @@ ieee80211_rx_h_defragment(struct ieee802
 					      GFP_ATOMIC))) {
 			I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag);
 			__skb_queue_purge(&entry->skb_list);
-			return TXRX_DROP;
+			return RX_DROP;
 		}
 	}
 	while ((skb = __skb_dequeue(&entry->skb_list))) {
@@ -887,10 +887,10 @@ ieee80211_rx_h_defragment(struct ieee802
 		rx->local->dot11MulticastReceivedFrameCount++;
 	else
 		ieee80211_led_rx(rx->local);
-	return TXRX_CONTINUE;
+	return RX_CONTINUE;
 }
 
-static ieee80211_txrx_result
+static ieee80211_rx_result
 ieee80211_rx_h_ps_poll(struct ieee80211_txrx_data *rx)
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
@@ -902,11 +902,11 @@ ieee80211_rx_h_ps_poll(struct ieee80211_
 		   (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_CTL ||
 		   (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PSPOLL ||
 		   !(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)))
-		return TXRX_CONTINUE;
+		return RX_CONTINUE;
 
 	if ((sdata->vif.type != IEEE80211_IF_TYPE_AP) &&
 	    (sdata->vif.type != IEEE80211_IF_TYPE_VLAN))
-		return TXRX_DROP;
+		return RX_DROP;
 
 	skb = skb_dequeue(&rx->sta->tx_filtered);
 	if (!skb) {
@@ -957,14 +957,14 @@ ieee80211_rx_h_ps_poll(struct ieee80211_
 
 	}
 
-	/* Free PS Poll skb here instead of returning TXRX_DROP that would
+	/* Free PS Poll skb here instead of returning RX_DROP that would
 	 * count as an dropped frame. */
 	dev_kfree_skb(rx->skb);
 
-	return TXRX_QUEUED;
+	return RX_QUEUED;
 }
 
-static ieee80211_txrx_result
+static ieee80211_rx_result
 ieee80211_rx_h_remove_qos_control(struct ieee80211_txrx_data *rx)
 {
 	u16 fc = rx->fc;
@@ -972,7 +972,7 @@ ieee80211_rx_h_remove_qos_control(struct
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) data;
 
 	if (!WLAN_FC_IS_QOS_DATA(fc))
-		return TXRX_CONTINUE;
+		return RX_CONTINUE;
 
 	/* remove the qos control field, update frame type and meta-data */
 	memmove(data + 2, data, ieee80211_get_hdrlen(fc) - 2);
@@ -981,7 +981,7 @@ ieee80211_rx_h_remove_qos_control(struct
 	rx->fc = fc &= ~IEEE80211_STYPE_QOS_DATA;
 	hdr->frame_control = cpu_to_le16(fc);
 
-	return TXRX_CONTINUE;
+	return RX_CONTINUE;
 }
 
 static int
@@ -1238,7 +1238,7 @@ ieee80211_deliver_skb(struct ieee80211_t
 	}
 }
 
-static ieee80211_txrx_result
+static ieee80211_rx_result
 ieee80211_rx_h_amsdu(struct ieee80211_txrx_data *rx)
 {
 	struct net_device *dev = rx->dev;
@@ -1254,17 +1254,17 @@ ieee80211_rx_h_amsdu(struct ieee80211_tx
 
 	fc = rx->fc;
 	if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA))
-		return TXRX_CONTINUE;
+		return RX_CONTINUE;
 
 	if (unlikely(!WLAN_FC_DATA_PRESENT(fc)))
-		return TXRX_DROP;
+		return RX_DROP;
 
 	if (!(rx->flags & IEEE80211_TXRXD_RX_AMSDU))
-		return TXRX_CONTINUE;
+		return RX_CONTINUE;
 
 	err = ieee80211_data_to_8023(rx);
 	if (unlikely(err))
-		return TXRX_DROP;
+		return RX_DROP;
 
 	skb->dev = dev;
 
@@ -1274,7 +1274,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_tx
 	/* skip the wrapping header */
 	eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr));
 	if (!eth)
-		return TXRX_DROP;
+		return RX_DROP;
 
 	while (skb != frame) {
 		u8 padding;
@@ -1289,7 +1289,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_tx
 		/* the last MSDU has no padding */
 		if (subframe_len > remaining) {
 			printk(KERN_DEBUG "%s: wrong buffer size", dev->name);
-			return TXRX_DROP;
+			return RX_DROP;
 		}
 
 		skb_pull(skb, sizeof(struct ethhdr));
@@ -1301,7 +1301,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_tx
 					      subframe_len);
 
 			if (frame == NULL)
-				return TXRX_DROP;
+				return RX_DROP;
 
 			skb_reserve(frame, local->hw.extra_tx_headroom +
 				    sizeof(struct ethhdr));
@@ -1314,7 +1314,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_tx
 				printk(KERN_DEBUG "%s: wrong buffer size ",
 				       dev->name);
 				dev_kfree_skb(frame);
-				return TXRX_DROP;
+				return RX_DROP;
 			}
 		}
 
@@ -1344,7 +1344,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_tx
 
 		if (!ieee80211_frame_allowed(rx)) {
 			if (skb == frame) /* last frame */
-				return TXRX_DROP;
+				return RX_DROP;
 			dev_kfree_skb(frame);
 			continue;
 		}
@@ -1352,10 +1352,10 @@ ieee80211_rx_h_amsdu(struct ieee80211_tx
 		ieee80211_deliver_skb(rx);
 	}
 
-	return TXRX_QUEUED;
+	return RX_QUEUED;
 }
 
-static ieee80211_txrx_result
+static ieee80211_rx_result
 ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
 {
 	struct net_device *dev = rx->dev;
@@ -1364,17 +1364,17 @@ ieee80211_rx_h_data(struct ieee80211_txr
 
 	fc = rx->fc;
 	if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA))
-		return TXRX_CONTINUE;
+		return RX_CONTINUE;
 
 	if (unlikely(!WLAN_FC_DATA_PRESENT(fc)))
-		return TXRX_DROP;
+		return RX_DROP;
 
 	err = ieee80211_data_to_8023(rx);
 	if (unlikely(err))
-		return TXRX_DROP;
+		return RX_DROP;
 
 	if (!ieee80211_frame_allowed(rx))
-		return TXRX_DROP;
+		return RX_DROP;
 
 	rx->skb->dev = dev;
 
@@ -1383,10 +1383,10 @@ ieee80211_rx_h_data(struct ieee80211_txr
 
 	ieee80211_deliver_skb(rx);
 
-	return TXRX_QUEUED;
+	return RX_QUEUED;
 }
 
-static ieee80211_txrx_result
+static ieee80211_rx_result
 ieee80211_rx_h_ctrl(struct ieee80211_txrx_data *rx)
 {
 	struct ieee80211_local *local = rx->local;
@@ -1398,15 +1398,15 @@ ieee80211_rx_h_ctrl(struct ieee80211_txr
 	u16 tid;
 
 	if (likely((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_CTL))
-		return TXRX_CONTINUE;
+		return RX_CONTINUE;
 
 	if ((rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BACK_REQ) {
 		if (!rx->sta)
-			return TXRX_CONTINUE;
+			return RX_CONTINUE;
 		tid = le16_to_cpu(bar->control) >> 12;
 		tid_agg_rx = &(rx->sta->ampdu_mlme.tid_rx[tid]);
 		if (tid_agg_rx->state != HT_AGG_STATE_OPERATIONAL)
-			return TXRX_CONTINUE;
+			return RX_CONTINUE;
 
 		start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4;
 
@@ -1423,19 +1423,19 @@ ieee80211_rx_h_ctrl(struct ieee80211_txr
 		ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, NULL,
 						 start_seq_num, 1);
 		rcu_read_unlock();
-		return TXRX_DROP;
+		return RX_DROP;
 	}
 
-	return TXRX_CONTINUE;
+	return RX_CONTINUE;
 }
 
-static ieee80211_txrx_result
+static ieee80211_rx_result
 ieee80211_rx_h_mgmt(struct ieee80211_txrx_data *rx)
 {
 	struct ieee80211_sub_if_data *sdata;
 
 	if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
-		return TXRX_DROP;
+		return RX_DROP;
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
 	if ((sdata->vif.type == IEEE80211_IF_TYPE_STA ||
@@ -1443,39 +1443,39 @@ ieee80211_rx_h_mgmt(struct ieee80211_txr
 	    !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME))
 		ieee80211_sta_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status);
 	else
-		return TXRX_DROP;
+		return RX_DROP;
 
-	return TXRX_QUEUED;
+	return RX_QUEUED;
 }
 
-static inline ieee80211_txrx_result __ieee80211_invoke_rx_handlers(
+static inline ieee80211_rx_result __ieee80211_invoke_rx_handlers(
 				struct ieee80211_local *local,
 				ieee80211_rx_handler *handlers,
 				struct ieee80211_txrx_data *rx,
 				struct sta_info *sta)
 {
 	ieee80211_rx_handler *handler;
-	ieee80211_txrx_result res = TXRX_DROP;
+	ieee80211_rx_result res = RX_DROP;
 
 	for (handler = handlers; *handler != NULL; handler++) {
 		res = (*handler)(rx);
 
 		switch (res) {
-		case TXRX_CONTINUE:
+		case RX_CONTINUE:
 			continue;
-		case TXRX_DROP:
+		case RX_DROP:
 			I802_DEBUG_INC(local->rx_handlers_drop);
 			if (sta)
 				sta->rx_dropped++;
 			break;
-		case TXRX_QUEUED:
+		case RX_QUEUED:
 			I802_DEBUG_INC(local->rx_handlers_queued);
 			break;
 		}
 		break;
 	}
 
-	if (res == TXRX_DROP)
+	if (res == RX_DROP)
 		dev_kfree_skb(rx->skb);
 	return res;
 }
@@ -1486,7 +1486,7 @@ static inline void ieee80211_invoke_rx_h
 						struct sta_info *sta)
 {
 	if (__ieee80211_invoke_rx_handlers(local, handlers, rx, sta) ==
-	    TXRX_CONTINUE)
+	    RX_CONTINUE)
 		dev_kfree_skb(rx->skb);
 }
 
--- everything.orig/net/mac80211/tx.c	2008-01-31 15:45:58.145795247 +0100
+++ everything/net/mac80211/tx.c	2008-01-31 15:46:09.035794161 +0100
@@ -232,7 +232,7 @@ static int inline is_ieee80211_device(st
 
 /* tx handlers */
 
-static ieee80211_txrx_result
+static ieee80211_tx_result
 ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx)
 {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -242,15 +242,15 @@ ieee80211_tx_h_check_assoc(struct ieee80
 	u32 sta_flags;
 
 	if (unlikely(tx->flags & IEEE80211_TXRXD_TX_INJECTED))
-		return TXRX_CONTINUE;
+		return TX_CONTINUE;
 
 	if (unlikely(tx->local->sta_sw_scanning) &&
 	    ((tx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
 	     (tx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PROBE_REQ))
-		return TXRX_DROP;
+		return TX_DROP;
 
 	if (tx->flags & IEEE80211_TXRXD_TXPS_BUFFERED)
-		return TXRX_CONTINUE;
+		return TX_CONTINUE;
 
 	sta_flags = tx->sta ? tx->sta->flags : 0;
 
@@ -265,7 +265,7 @@ ieee80211_tx_h_check_assoc(struct ieee80
 			       tx->dev->name, print_mac(mac, hdr->addr1));
 #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
 			I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc);
-			return TXRX_DROP;
+			return TX_DROP;
 		}
 	} else {
 		if (unlikely((tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
@@ -275,15 +275,15 @@ ieee80211_tx_h_check_assoc(struct ieee80
 			 * No associated STAs - no need to send multicast
 			 * frames.
 			 */
-			return TXRX_DROP;
+			return TX_DROP;
 		}
-		return TXRX_CONTINUE;
+		return TX_CONTINUE;
 	}
 
-	return TXRX_CONTINUE;
+	return TX_CONTINUE;
 }
 
-static ieee80211_txrx_result
+static ieee80211_tx_result
 ieee80211_tx_h_sequence(struct ieee80211_txrx_data *tx)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
@@ -291,7 +291,7 @@ ieee80211_tx_h_sequence(struct ieee80211
 	if (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)) >= 24)
 		ieee80211_include_sequence(tx->sdata, hdr);
 
-	return TXRX_CONTINUE;
+	return TX_CONTINUE;
 }
 
 /* This function is called whenever the AP is about to exceed the maximum limit
@@ -341,7 +341,7 @@ static void purge_old_ps_buffers(struct 
 	       wiphy_name(local->hw.wiphy), purged);
 }
 
-static ieee80211_txrx_result
+static ieee80211_tx_result
 ieee80211_tx_h_multicast_ps_buf(struct ieee80211_txrx_data *tx)
 {
 	/*
@@ -354,11 +354,11 @@ ieee80211_tx_h_multicast_ps_buf(struct i
 
 	/* not AP/IBSS or ordered frame */
 	if (!tx->sdata->bss || (tx->fc & IEEE80211_FCTL_ORDER))
-		return TXRX_CONTINUE;
+		return TX_CONTINUE;
 
 	/* no stations in PS mode */
 	if (!atomic_read(&tx->sdata->bss->num_sta_ps))
-		return TXRX_CONTINUE;
+		return TX_CONTINUE;
 
 	/* buffered in mac80211 */
 	if (tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING) {
@@ -375,16 +375,16 @@ ieee80211_tx_h_multicast_ps_buf(struct i
 		} else
 			tx->local->total_ps_buffered++;
 		skb_queue_tail(&tx->sdata->bss->ps_bc_buf, tx->skb);
-		return TXRX_QUEUED;
+		return TX_QUEUED;
 	}
 
 	/* buffered in hardware */
 	tx->u.tx.control->flags |= IEEE80211_TXCTL_SEND_AFTER_DTIM;
 
-	return TXRX_CONTINUE;
+	return TX_CONTINUE;
 }
 
-static ieee80211_txrx_result
+static ieee80211_tx_result
 ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx)
 {
 	struct sta_info *sta = tx->sta;
@@ -393,7 +393,7 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
 	if (unlikely(!sta ||
 		     ((tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT &&
 		      (tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP)))
-		return TXRX_CONTINUE;
+		return TX_CONTINUE;
 
 	if (unlikely((sta->flags & WLAN_STA_PS) && !sta->pspoll)) {
 		struct ieee80211_tx_packet_data *pkt_data;
@@ -427,7 +427,7 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
 		pkt_data = (struct ieee80211_tx_packet_data *)tx->skb->cb;
 		pkt_data->jiffies = jiffies;
 		skb_queue_tail(&sta->ps_tx_buf, tx->skb);
-		return TXRX_QUEUED;
+		return TX_QUEUED;
 	}
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
 	else if (unlikely(sta->flags & WLAN_STA_PS)) {
@@ -438,14 +438,14 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
 	sta->pspoll = 0;
 
-	return TXRX_CONTINUE;
+	return TX_CONTINUE;
 }
 
-static ieee80211_txrx_result
+static ieee80211_tx_result
 ieee80211_tx_h_ps_buf(struct ieee80211_txrx_data *tx)
 {
 	if (unlikely(tx->flags & IEEE80211_TXRXD_TXPS_BUFFERED))
-		return TXRX_CONTINUE;
+		return TX_CONTINUE;
 
 	if (tx->flags & IEEE80211_TXRXD_TXUNICAST)
 		return ieee80211_tx_h_unicast_ps_buf(tx);
@@ -453,7 +453,7 @@ ieee80211_tx_h_ps_buf(struct ieee80211_t
 		return ieee80211_tx_h_multicast_ps_buf(tx);
 }
 
-static ieee80211_txrx_result
+static ieee80211_tx_result
 ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx)
 {
 	struct ieee80211_key *key;
@@ -469,7 +469,7 @@ ieee80211_tx_h_select_key(struct ieee802
 		 !(tx->u.tx.control->flags & IEEE80211_TXCTL_EAPOL_FRAME) &&
 		 !(tx->flags & IEEE80211_TXRXD_TX_INJECTED)) {
 		I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
-		return TXRX_DROP;
+		return TX_DROP;
 	} else
 		tx->key = NULL;
 
@@ -498,10 +498,10 @@ ieee80211_tx_h_select_key(struct ieee802
 	if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
 		tx->u.tx.control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
 
-	return TXRX_CONTINUE;
+	return TX_CONTINUE;
 }
 
-static ieee80211_txrx_result
+static ieee80211_tx_result
 ieee80211_tx_h_fragment(struct ieee80211_txrx_data *tx)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
@@ -513,7 +513,7 @@ ieee80211_tx_h_fragment(struct ieee80211
 	int frag_threshold = tx->local->fragmentation_threshold;
 
 	if (!(tx->flags & IEEE80211_TXRXD_FRAGMENTED))
-		return TXRX_CONTINUE;
+		return TX_CONTINUE;
 
 	first = tx->skb;
 
@@ -567,7 +567,7 @@ ieee80211_tx_h_fragment(struct ieee80211
 	tx->u.tx.num_extra_frag = num_fragm - 1;
 	tx->u.tx.extra_frag = frags;
 
-	return TXRX_CONTINUE;
+	return TX_CONTINUE;
 
  fail:
 	printk(KERN_DEBUG "%s: failed to fragment frame\n", tx->dev->name);
@@ -578,14 +578,14 @@ ieee80211_tx_h_fragment(struct ieee80211
 		kfree(frags);
 	}
 	I802_DEBUG_INC(tx->local->tx_handlers_drop_fragment);
-	return TXRX_DROP;
+	return TX_DROP;
 }
 
-static ieee80211_txrx_result
+static ieee80211_tx_result
 ieee80211_tx_h_encrypt(struct ieee80211_txrx_data *tx)
 {
 	if (!tx->key)
-		return TXRX_CONTINUE;
+		return TX_CONTINUE;
 
 	switch (tx->key->conf.alg) {
 	case ALG_WEP:
@@ -598,10 +598,10 @@ ieee80211_tx_h_encrypt(struct ieee80211_
 
 	/* not reached */
 	WARN_ON(1);
-	return TXRX_DROP;
+	return TX_DROP;
 }
 
-static ieee80211_txrx_result
+static ieee80211_tx_result
 ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx)
 {
 	struct rate_selection rsel;
@@ -622,7 +622,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
 			tx->u.tx.control->alt_retry_rate = NULL;
 
 		if (!tx->u.tx.rate)
-			return TXRX_DROP;
+			return TX_DROP;
 	} else
 		tx->u.tx.control->alt_retry_rate = NULL;
 
@@ -642,10 +642,10 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
 	}
 	tx->u.tx.control->tx_rate = tx->u.tx.rate;
 
-	return TXRX_CONTINUE;
+	return TX_CONTINUE;
 }
 
-static ieee80211_txrx_result
+static ieee80211_tx_result
 ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
@@ -754,10 +754,10 @@ ieee80211_tx_h_misc(struct ieee80211_txr
 		}
 	}
 
-	return TXRX_CONTINUE;
+	return TX_CONTINUE;
 }
 
-static ieee80211_txrx_result
+static ieee80211_tx_result
 ieee80211_tx_h_load_stats(struct ieee80211_txrx_data *tx)
 {
 	struct ieee80211_local *local = tx->local;
@@ -810,7 +810,7 @@ ieee80211_tx_h_load_stats(struct ieee802
 		tx->sta->channel_use_raw += load;
 	tx->sdata->channel_use_raw += load;
 
-	return TXRX_CONTINUE;
+	return TX_CONTINUE;
 }
 
 /* TODO: implement register/unregister functions for adding TX/RX handlers
@@ -837,7 +837,7 @@ ieee80211_tx_handler ieee80211_tx_handle
  * deal with packet injection down monitor interface
  * with Radiotap Header -- only called for monitor mode interface
  */
-static ieee80211_txrx_result
+static ieee80211_tx_result
 __ieee80211_parse_tx_radiotap(struct ieee80211_txrx_data *tx,
 			      struct sk_buff *skb)
 {
@@ -926,7 +926,7 @@ __ieee80211_parse_tx_radiotap(struct iee
 				 * on transmission
 				 */
 				if (skb->len < (iterator.max_length + FCS_LEN))
-					return TXRX_DROP;
+					return TX_DROP;
 
 				skb_trim(skb, skb->len - FCS_LEN);
 			}
@@ -949,7 +949,7 @@ __ieee80211_parse_tx_radiotap(struct iee
 	}
 
 	if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */
-		return TXRX_DROP;
+		return TX_DROP;
 
 	/*
 	 * remove the radiotap header
@@ -958,13 +958,13 @@ __ieee80211_parse_tx_radiotap(struct iee
 	 */
 	skb_pull(skb, iterator.max_length);
 
-	return TXRX_CONTINUE;
+	return TX_CONTINUE;
 }
 
 /*
  * initialises @tx
  */
-static ieee80211_txrx_result
+static ieee80211_tx_result
 __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
 		       struct sk_buff *skb,
 		       struct net_device *dev,
@@ -991,8 +991,8 @@ __ieee80211_tx_prepare(struct ieee80211_
 	/* process and remove the injection radiotap header */
 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	if (unlikely(sdata->vif.type == IEEE80211_IF_TYPE_MNTR)) {
-		if (__ieee80211_parse_tx_radiotap(tx, skb) == TXRX_DROP)
-			return TXRX_DROP;
+		if (__ieee80211_parse_tx_radiotap(tx, skb) == TX_DROP)
+			return TX_DROP;
 
 		/*
 		 * __ieee80211_parse_tx_radiotap has now removed
@@ -1037,7 +1037,7 @@ __ieee80211_tx_prepare(struct ieee80211_
 	}
 	control->flags |= IEEE80211_TXCTL_FIRST_FRAGMENT;
 
-	return TXRX_CONTINUE;
+	return TX_CONTINUE;
 }
 
 /*
@@ -1131,7 +1131,7 @@ static int ieee80211_tx(struct net_devic
 	struct sta_info *sta;
 	ieee80211_tx_handler *handler;
 	struct ieee80211_txrx_data tx;
-	ieee80211_txrx_result res = TXRX_DROP, res_prepare;
+	ieee80211_tx_result res = TX_DROP, res_prepare;
 	int ret, i;
 
 	WARN_ON(__ieee80211_queue_pending(local, control->queue));
@@ -1144,7 +1144,7 @@ static int ieee80211_tx(struct net_devic
 	/* initialises tx */
 	res_prepare = __ieee80211_tx_prepare(&tx, skb, dev, control);
 
-	if (res_prepare == TXRX_DROP) {
+	if (res_prepare == TX_DROP) {
 		dev_kfree_skb(skb);
 		return 0;
 	}
@@ -1161,7 +1161,7 @@ static int ieee80211_tx(struct net_devic
 	for (handler = local->tx_handlers; *handler != NULL;
 	     handler++) {
 		res = (*handler)(&tx);
-		if (res != TXRX_CONTINUE)
+		if (res != TX_CONTINUE)
 			break;
 	}
 
@@ -1170,12 +1170,12 @@ static int ieee80211_tx(struct net_devic
 	if (sta)
 		sta_info_put(sta);
 
-	if (unlikely(res == TXRX_DROP)) {
+	if (unlikely(res == TX_DROP)) {
 		I802_DEBUG_INC(local->tx_handlers_drop);
 		goto drop;
 	}
 
-	if (unlikely(res == TXRX_QUEUED)) {
+	if (unlikely(res == TX_QUEUED)) {
 		I802_DEBUG_INC(local->tx_handlers_queued);
 		rcu_read_unlock();
 		return 0;
@@ -1864,7 +1864,7 @@ ieee80211_get_buffered_bc(struct ieee802
 	struct sta_info *sta;
 	ieee80211_tx_handler *handler;
 	struct ieee80211_txrx_data tx;
-	ieee80211_txrx_result res = TXRX_DROP;
+	ieee80211_tx_result res = TX_DROP;
 	struct net_device *bdev;
 	struct ieee80211_sub_if_data *sdata;
 	struct ieee80211_if_ap *bss = NULL;
@@ -1916,16 +1916,16 @@ ieee80211_get_buffered_bc(struct ieee802
 
 	for (handler = local->tx_handlers; *handler != NULL; handler++) {
 		res = (*handler)(&tx);
-		if (res == TXRX_DROP || res == TXRX_QUEUED)
+		if (res == TX_DROP || res == TX_QUEUED)
 			break;
 	}
 	skb = tx.skb; /* handlers are allowed to change skb */
 
-	if (res == TXRX_DROP) {
+	if (res == TX_DROP) {
 		I802_DEBUG_INC(local->tx_handlers_drop);
 		dev_kfree_skb(skb);
 		skb = NULL;
-	} else if (res == TXRX_QUEUED) {
+	} else if (res == TX_QUEUED) {
 		I802_DEBUG_INC(local->tx_handlers_queued);
 		skb = NULL;
 	}

-- 


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

* [PATCH 2/8] mac80211: split RX_DROP
  2008-01-31 18:48 [PATCH 0/8] AP mode is coming Johannes Berg
  2008-01-31 18:48 ` [PATCH 1/8] mac80211: split ieee80211_txrx_result Johannes Berg
@ 2008-01-31 18:48 ` Johannes Berg
  2008-01-31 18:48 ` [PATCH 3/8] nl80211: Add monitor interface configuration flags Johannes Berg
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Johannes Berg @ 2008-01-31 18:48 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

Some instances of RX_DROP mean that the frame was useless,
others mean that the frame should be visible in userspace
on "cooked" monitor interfaces. This patch splits up RX_DROP
and changes each instance appropriately.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/mac80211/ieee80211_i.h   |    7 ++---
 net/mac80211/ieee80211_sta.c |    4 +-
 net/mac80211/rx.c            |   59 +++++++++++++++++++++----------------------
 net/mac80211/wep.c           |    2 -
 net/mac80211/wpa.c           |   16 +++++------
 5 files changed, 45 insertions(+), 43 deletions(-)

--- everything.orig/net/mac80211/ieee80211_i.h	2008-01-31 15:46:09.015793999 +0100
+++ everything/net/mac80211/ieee80211_i.h	2008-01-31 15:46:09.975794650 +0100
@@ -114,9 +114,10 @@ typedef unsigned __bitwise__ ieee80211_t
 #define TX_QUEUED	((__force ieee80211_tx_result) 2u)
 
 typedef unsigned __bitwise__ ieee80211_rx_result;
-#define RX_CONTINUE	((__force ieee80211_rx_result) 0u)
-#define RX_DROP		((__force ieee80211_rx_result) 1u)
-#define RX_QUEUED	((__force ieee80211_rx_result) 2u)
+#define RX_CONTINUE		((__force ieee80211_rx_result) 0u)
+#define RX_DROP_UNUSABLE	((__force ieee80211_rx_result) 1u)
+#define RX_DROP_MONITOR		((__force ieee80211_rx_result) 2u)
+#define RX_QUEUED		((__force ieee80211_rx_result) 3u)
 
 
 /* flags used in struct ieee80211_txrx_data.flags */
--- everything.orig/net/mac80211/ieee80211_sta.c	2008-01-31 15:46:09.025793944 +0100
+++ everything/net/mac80211/ieee80211_sta.c	2008-01-31 15:46:09.985793781 +0100
@@ -2566,7 +2566,7 @@ ieee80211_sta_rx_scan(struct net_device 
 	u16 fc;
 
 	if (skb->len < 2)
-		return RX_DROP;
+		return RX_DROP_UNUSABLE;
 
 	mgmt = (struct ieee80211_mgmt *) skb->data;
 	fc = le16_to_cpu(mgmt->frame_control);
@@ -2575,7 +2575,7 @@ ieee80211_sta_rx_scan(struct net_device 
 		return RX_CONTINUE;
 
 	if (skb->len < 24)
-		return RX_DROP;
+		return RX_DROP_MONITOR;
 
 	if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
 		if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP) {
--- everything.orig/net/mac80211/rx.c	2008-01-31 15:46:09.035794161 +0100
+++ everything/net/mac80211/rx.c	2008-01-31 15:46:09.985793781 +0100
@@ -380,7 +380,7 @@ ieee80211_rx_h_passive_scan(struct ieee8
 	if (unlikely(rx->flags & IEEE80211_TXRXD_RXIN_SCAN)) {
 		/* scanning finished during invoking of handlers */
 		I802_DEBUG_INC(local->rx_handlers_drop_passive_scan);
-		return RX_DROP;
+		return RX_DROP_UNUSABLE;
 	}
 
 	return RX_CONTINUE;
@@ -401,14 +401,14 @@ ieee80211_rx_h_check(struct ieee80211_tx
 				rx->local->dot11FrameDuplicateCount++;
 				rx->sta->num_duplicates++;
 			}
-			return RX_DROP;
+			return RX_DROP_MONITOR;
 		} else
 			rx->sta->last_seq_ctrl[rx->u.rx.queue] = hdr->seq_ctrl;
 	}
 
 	if (unlikely(rx->skb->len < 16)) {
 		I802_DEBUG_INC(rx->local->rx_handlers_drop_short);
-		return RX_DROP;
+		return RX_DROP_MONITOR;
 	}
 
 	/* Drop disallowed frame classes based on STA auth/assoc state;
@@ -430,10 +430,10 @@ ieee80211_rx_h_check(struct ieee80211_tx
 		    || !(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) {
 			/* Drop IBSS frames and frames for other hosts
 			 * silently. */
-			return RX_DROP;
+			return RX_DROP_MONITOR;
 		}
 
-		return RX_DROP;
+		return RX_DROP_MONITOR;
 	}
 
 	return RX_CONTINUE;
@@ -446,7 +446,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
 	int keyidx;
 	int hdrlen;
-	ieee80211_rx_result result = RX_DROP;
+	ieee80211_rx_result result = RX_DROP_UNUSABLE;
 	struct ieee80211_key *stakey = NULL;
 
 	/*
@@ -507,7 +507,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_
 		hdrlen = ieee80211_get_hdrlen(rx->fc);
 
 		if (rx->skb->len < 8 + hdrlen)
-			return RX_DROP; /* TODO: count this? */
+			return RX_DROP_UNUSABLE; /* TODO: count this? */
 
 		/*
 		 * no need to call ieee80211_wep_get_keyidx,
@@ -536,7 +536,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_
 			printk(KERN_DEBUG "%s: RX protected frame,"
 			       " but have no key\n", rx->dev->name);
 #endif /* CONFIG_MAC80211_DEBUG */
-		return RX_DROP;
+		return RX_DROP_MONITOR;
 	}
 
 	/* Check for weak IVs if possible */
@@ -821,7 +821,7 @@ ieee80211_rx_h_defragment(struct ieee802
 					  rx->u.rx.queue, hdr);
 	if (!entry) {
 		I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag);
-		return RX_DROP;
+		return RX_DROP_MONITOR;
 	}
 
 	/* Verify that MPDUs within one MSDU have sequential PN values.
@@ -830,7 +830,7 @@ ieee80211_rx_h_defragment(struct ieee802
 		int i;
 		u8 pn[CCMP_PN_LEN], *rpn;
 		if (!rx->key || rx->key->conf.alg != ALG_CCMP)
-			return RX_DROP;
+			return RX_DROP_UNUSABLE;
 		memcpy(pn, entry->last_pn, CCMP_PN_LEN);
 		for (i = CCMP_PN_LEN - 1; i >= 0; i--) {
 			pn[i]++;
@@ -848,7 +848,7 @@ ieee80211_rx_h_defragment(struct ieee802
 				       rpn[0], rpn[1], rpn[2], rpn[3], rpn[4],
 				       rpn[5], pn[0], pn[1], pn[2], pn[3],
 				       pn[4], pn[5]);
-			return RX_DROP;
+			return RX_DROP_UNUSABLE;
 		}
 		memcpy(entry->last_pn, pn, CCMP_PN_LEN);
 	}
@@ -869,7 +869,7 @@ ieee80211_rx_h_defragment(struct ieee802
 					      GFP_ATOMIC))) {
 			I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag);
 			__skb_queue_purge(&entry->skb_list);
-			return RX_DROP;
+			return RX_DROP_UNUSABLE;
 		}
 	}
 	while ((skb = __skb_dequeue(&entry->skb_list))) {
@@ -906,7 +906,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_
 
 	if ((sdata->vif.type != IEEE80211_IF_TYPE_AP) &&
 	    (sdata->vif.type != IEEE80211_IF_TYPE_VLAN))
-		return RX_DROP;
+		return RX_DROP_UNUSABLE;
 
 	skb = skb_dequeue(&rx->sta->tx_filtered);
 	if (!skb) {
@@ -1257,14 +1257,14 @@ ieee80211_rx_h_amsdu(struct ieee80211_tx
 		return RX_CONTINUE;
 
 	if (unlikely(!WLAN_FC_DATA_PRESENT(fc)))
-		return RX_DROP;
+		return RX_DROP_MONITOR;
 
 	if (!(rx->flags & IEEE80211_TXRXD_RX_AMSDU))
 		return RX_CONTINUE;
 
 	err = ieee80211_data_to_8023(rx);
 	if (unlikely(err))
-		return RX_DROP;
+		return RX_DROP_UNUSABLE;
 
 	skb->dev = dev;
 
@@ -1274,7 +1274,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_tx
 	/* skip the wrapping header */
 	eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr));
 	if (!eth)
-		return RX_DROP;
+		return RX_DROP_UNUSABLE;
 
 	while (skb != frame) {
 		u8 padding;
@@ -1289,7 +1289,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_tx
 		/* the last MSDU has no padding */
 		if (subframe_len > remaining) {
 			printk(KERN_DEBUG "%s: wrong buffer size", dev->name);
-			return RX_DROP;
+			return RX_DROP_UNUSABLE;
 		}
 
 		skb_pull(skb, sizeof(struct ethhdr));
@@ -1301,7 +1301,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_tx
 					      subframe_len);
 
 			if (frame == NULL)
-				return RX_DROP;
+				return RX_DROP_UNUSABLE;
 
 			skb_reserve(frame, local->hw.extra_tx_headroom +
 				    sizeof(struct ethhdr));
@@ -1314,7 +1314,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_tx
 				printk(KERN_DEBUG "%s: wrong buffer size ",
 				       dev->name);
 				dev_kfree_skb(frame);
-				return RX_DROP;
+				return RX_DROP_UNUSABLE;
 			}
 		}
 
@@ -1344,7 +1344,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_tx
 
 		if (!ieee80211_frame_allowed(rx)) {
 			if (skb == frame) /* last frame */
-				return RX_DROP;
+				return RX_DROP_UNUSABLE;
 			dev_kfree_skb(frame);
 			continue;
 		}
@@ -1367,14 +1367,14 @@ ieee80211_rx_h_data(struct ieee80211_txr
 		return RX_CONTINUE;
 
 	if (unlikely(!WLAN_FC_DATA_PRESENT(fc)))
-		return RX_DROP;
+		return RX_DROP_MONITOR;
 
 	err = ieee80211_data_to_8023(rx);
 	if (unlikely(err))
-		return RX_DROP;
+		return RX_DROP_UNUSABLE;
 
 	if (!ieee80211_frame_allowed(rx))
-		return RX_DROP;
+		return RX_DROP_MONITOR;
 
 	rx->skb->dev = dev;
 
@@ -1423,7 +1423,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_txr
 		ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, NULL,
 						 start_seq_num, 1);
 		rcu_read_unlock();
-		return RX_DROP;
+		return RX_DROP_UNUSABLE;
 	}
 
 	return RX_CONTINUE;
@@ -1435,7 +1435,7 @@ ieee80211_rx_h_mgmt(struct ieee80211_txr
 	struct ieee80211_sub_if_data *sdata;
 
 	if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
-		return RX_DROP;
+		return RX_DROP_MONITOR;
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
 	if ((sdata->vif.type == IEEE80211_IF_TYPE_STA ||
@@ -1443,7 +1443,7 @@ ieee80211_rx_h_mgmt(struct ieee80211_txr
 	    !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME))
 		ieee80211_sta_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status);
 	else
-		return RX_DROP;
+		return RX_DROP_MONITOR;
 
 	return RX_QUEUED;
 }
@@ -1455,7 +1455,7 @@ static inline ieee80211_rx_result __ieee
 				struct sta_info *sta)
 {
 	ieee80211_rx_handler *handler;
-	ieee80211_rx_result res = RX_DROP;
+	ieee80211_rx_result res = RX_DROP_MONITOR;
 
 	for (handler = handlers; *handler != NULL; handler++) {
 		res = (*handler)(rx);
@@ -1463,7 +1463,8 @@ static inline ieee80211_rx_result __ieee
 		switch (res) {
 		case RX_CONTINUE:
 			continue;
-		case RX_DROP:
+		case RX_DROP_UNUSABLE:
+		case RX_DROP_MONITOR:
 			I802_DEBUG_INC(local->rx_handlers_drop);
 			if (sta)
 				sta->rx_dropped++;
@@ -1475,7 +1476,7 @@ static inline ieee80211_rx_result __ieee
 		break;
 	}
 
-	if (res == RX_DROP)
+	if (res == RX_DROP_UNUSABLE || res == RX_DROP_MONITOR)
 		dev_kfree_skb(rx->skb);
 	return res;
 }
--- everything.orig/net/mac80211/wep.c	2008-01-31 15:46:09.015793999 +0100
+++ everything/net/mac80211/wep.c	2008-01-31 15:46:09.985793781 +0100
@@ -320,7 +320,7 @@ ieee80211_crypto_wep_decrypt(struct ieee
 				printk(KERN_DEBUG "%s: RX WEP frame, decrypt "
 				       "failed\n", rx->dev->name);
 #endif /* CONFIG_MAC80211_DEBUG */
-			return RX_DROP;
+			return RX_DROP_UNUSABLE;
 		}
 	} else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) {
 		ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
--- everything.orig/net/mac80211/wpa.c	2008-01-31 15:46:09.025793944 +0100
+++ everything/net/mac80211/wpa.c	2008-01-31 15:46:09.995793673 +0100
@@ -148,7 +148,7 @@ ieee80211_rx_h_michael_mic_verify(struct
 
 	if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len)
 	    || data_len < MICHAEL_MIC_LEN)
-		return RX_DROP;
+		return RX_DROP_UNUSABLE;
 
 	data_len -= MICHAEL_MIC_LEN;
 
@@ -162,14 +162,14 @@ ieee80211_rx_h_michael_mic_verify(struct
 	michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic);
 	if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) {
 		if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
-			return RX_DROP;
+			return RX_DROP_UNUSABLE;
 
 		printk(KERN_DEBUG "%s: invalid Michael MIC in data frame from "
 		       "%s\n", rx->dev->name, print_mac(mac, sa));
 
 		mac80211_ev_michael_mic_failure(rx->dev, rx->key->conf.keyidx,
 						(void *) skb->data);
-		return RX_DROP;
+		return RX_DROP_UNUSABLE;
 	}
 
 	/* remove Michael MIC from payload */
@@ -293,7 +293,7 @@ ieee80211_crypto_tkip_decrypt(struct iee
 		return RX_CONTINUE;
 
 	if (!rx->sta || skb->len - hdrlen < 12)
-		return RX_DROP;
+		return RX_DROP_UNUSABLE;
 
 	if (rx->u.rx.status->flag & RX_FLAG_DECRYPTED) {
 		if (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED) {
@@ -322,7 +322,7 @@ ieee80211_crypto_tkip_decrypt(struct iee
 			       "frame from %s (res=%d)\n", rx->dev->name,
 			       print_mac(mac, rx->sta->addr), res);
 #endif /* CONFIG_MAC80211_DEBUG */
-		return RX_DROP;
+		return RX_DROP_UNUSABLE;
 	}
 
 	/* Trim ICV */
@@ -545,7 +545,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
 
 	data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN;
 	if (!rx->sta || data_len < 0)
-		return RX_DROP;
+		return RX_DROP_UNUSABLE;
 
 	if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
 	    (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED))
@@ -565,7 +565,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
 		       ppn[0], ppn[1], ppn[2], ppn[3], ppn[4], ppn[5]);
 #endif /* CONFIG_MAC80211_DEBUG */
 		key->u.ccmp.replays++;
-		return RX_DROP;
+		return RX_DROP_UNUSABLE;
 	}
 
 	if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) {
@@ -589,7 +589,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
 				       "for RX frame from %s\n", rx->dev->name,
 				       print_mac(mac, rx->sta->addr));
 #endif /* CONFIG_MAC80211_DEBUG */
-			return RX_DROP;
+			return RX_DROP_UNUSABLE;
 		}
 	}
 

-- 


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

* [PATCH 3/8] nl80211: Add monitor interface configuration flags
  2008-01-31 18:48 [PATCH 0/8] AP mode is coming Johannes Berg
  2008-01-31 18:48 ` [PATCH 1/8] mac80211: split ieee80211_txrx_result Johannes Berg
  2008-01-31 18:48 ` [PATCH 2/8] mac80211: split RX_DROP Johannes Berg
@ 2008-01-31 18:48 ` Johannes Berg
  2008-01-31 18:48 ` [PATCH 4/8] mac80211: Use monitor " Johannes Berg
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Johannes Berg @ 2008-01-31 18:48 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless, Michael Wu

From: Michael Wu <flamingice@sourmilk.net>

This allows precise control over what a monitor interface shows.

Signed-off-by: Michael Wu <flamingice@sourmilk.net>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net> 
---

 include/linux/nl80211.h |   35 +++++++++++++++++++++++++++++++++++
 include/net/cfg80211.h  |   24 ++++++++++++++++++++++--
 net/mac80211/cfg.c      |    4 ++--
 net/wireless/nl80211.c  |   44 ++++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 101 insertions(+), 6 deletions(-)

--- everything.orig/include/linux/nl80211.h	2008-01-31 15:45:56.535794433 +0100
+++ everything/include/linux/nl80211.h	2008-01-31 15:46:10.795795138 +0100
@@ -164,6 +164,9 @@ enum nl80211_commands {
  * @NL80211_ATTR_WIPHY_BANDS: Information about an operating bands,
  *	consisting of a nested array.
  *
+ * @NL80211_ATTR_MNTR_FLAGS: flags, nested element with NLA_FLAG attributes of
+ *      &enum nl80211_mntr_flags.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -200,6 +203,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_WIPHY_BANDS,
 
+	NL80211_ATTR_MNTR_FLAGS,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -344,4 +349,34 @@ enum nl80211_bitrate_attr {
 	NL80211_BITRATE_ATTR_MAX = __NL80211_BITRATE_ATTR_AFTER_LAST - 1
 };
 
+/**
+ * enum nl80211_mntr_flags - monitor configuration flags
+ *
+ * Monitor configuration flags.
+ *
+ * @__NL80211_MNTR_FLAG_INVALID: reserved
+ *
+ * @NL80211_MNTR_FLAG_FCSFAIL: pass frames with bad FCS
+ * @NL80211_MNTR_FLAG_PLCPFAIL: pass frames with bad PLCP
+ * @NL80211_MNTR_FLAG_CONTROL: pass control frames
+ * @NL80211_MNTR_FLAG_OTHER_BSS: disable BSSID filtering
+ * @NL80211_MNTR_FLAG_COOK_FRAMES: report frames after processing.
+ *	overrides all other flags.
+ *
+ * @__NL80211_MNTR_FLAG_AFTER_LAST: internal use
+ * @NL80211_MNTR_FLAG_MAX: highest possible monitor flag
+ */
+enum nl80211_mntr_flags {
+	__NL80211_MNTR_FLAG_INVALID,
+	NL80211_MNTR_FLAG_FCSFAIL,
+	NL80211_MNTR_FLAG_PLCPFAIL,
+	NL80211_MNTR_FLAG_CONTROL,
+	NL80211_MNTR_FLAG_OTHER_BSS,
+	NL80211_MNTR_FLAG_COOK_FRAMES,
+
+	/* keep last */
+	__NL80211_MNTR_FLAG_AFTER_LAST,
+	NL80211_MNTR_FLAG_MAX = __NL80211_MNTR_FLAG_AFTER_LAST - 1
+};
+
 #endif /* __LINUX_NL80211_H */
--- everything.orig/include/net/cfg80211.h	2008-01-31 15:45:56.615793023 +0100
+++ everything/include/net/cfg80211.h	2008-01-31 15:46:10.795795138 +0100
@@ -163,6 +163,26 @@ struct station_stats {
 	u32 tx_bytes;
 };
 
+/**
+ * enum monitor_flags - monitor flags
+ *
+ * Monitor interface configuration flags. Note that these must be the bits
+ * according to the nl80211 flags.
+ *
+ * @MONITOR_FLAG_FCSFAIL: pass frames with bad FCS
+ * @MONITOR_FLAG_PLCPFAIL: pass frames with bad PLCP
+ * @MONITOR_FLAG_CONTROL: pass control frames
+ * @MONITOR_FLAG_OTHER_BSS: disable BSSID filtering
+ * @MONITOR_FLAG_COOK_FRAMES: report frames after processing
+ */
+enum monitor_flags {
+	MONITOR_FLAG_FCSFAIL		= 1<<NL80211_MNTR_FLAG_FCSFAIL,
+	MONITOR_FLAG_PLCPFAIL		= 1<<NL80211_MNTR_FLAG_PLCPFAIL,
+	MONITOR_FLAG_CONTROL		= 1<<NL80211_MNTR_FLAG_CONTROL,
+	MONITOR_FLAG_OTHER_BSS		= 1<<NL80211_MNTR_FLAG_OTHER_BSS,
+	MONITOR_FLAG_COOK_FRAMES	= 1<<NL80211_MNTR_FLAG_COOK_FRAMES,
+};
+
 /* from net/wireless.h */
 struct wiphy;
 
@@ -213,10 +233,10 @@ struct wiphy;
  */
 struct cfg80211_ops {
 	int	(*add_virtual_intf)(struct wiphy *wiphy, char *name,
-				    enum nl80211_iftype type);
+				    enum nl80211_iftype type, u32 *flags);
 	int	(*del_virtual_intf)(struct wiphy *wiphy, int ifindex);
 	int	(*change_virtual_intf)(struct wiphy *wiphy, int ifindex,
-				       enum nl80211_iftype type);
+				       enum nl80211_iftype type, u32 *flags);
 
 	int	(*add_key)(struct wiphy *wiphy, struct net_device *netdev,
 			   u8 key_index, u8 *mac_addr,
--- everything.orig/net/mac80211/cfg.c	2008-01-31 15:45:59.195794920 +0100
+++ everything/net/mac80211/cfg.c	2008-01-31 15:46:10.825789821 +0100
@@ -34,7 +34,7 @@ nl80211_type_to_mac80211_type(enum nl802
 }
 
 static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
-			       enum nl80211_iftype type)
+			       enum nl80211_iftype type, u32 *flags)
 {
 	struct ieee80211_local *local = wiphy_priv(wiphy);
 	enum ieee80211_if_types itype;
@@ -69,7 +69,7 @@ static int ieee80211_del_iface(struct wi
 }
 
 static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
-				  enum nl80211_iftype type)
+				  enum nl80211_iftype type, u32 *flags)
 {
 	struct ieee80211_local *local = wiphy_priv(wiphy);
 	struct net_device *dev;
--- everything.orig/net/wireless/nl80211.c	2008-01-31 15:45:56.725795193 +0100
+++ everything/net/wireless/nl80211.c	2008-01-31 15:46:10.825789821 +0100
@@ -82,6 +82,7 @@ static struct nla_policy nl80211_policy[
 	[NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
 					       .len = NL80211_MAX_SUPP_RATES },
 	[NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
+	[NL80211_ATTR_MNTR_FLAGS] = { .type = NLA_NESTED },
 };
 
 /* message building helper */
@@ -336,12 +337,42 @@ static int nl80211_get_interface(struct 
 	return -ENOBUFS;
 }
 
+static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
+	[NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
+	[NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
+	[NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
+	[NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
+	[NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
+};
+
+static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
+{
+	struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
+	int flag;
+
+	*mntrflags = 0;
+
+	if (!nla)
+		return -EINVAL;
+
+	if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX,
+			     nla, mntr_flags_policy))
+		return -EINVAL;
+
+	for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
+		if (flags[flag])
+			*mntrflags |= (1<<flag);
+
+	return 0;
+}
+
 static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
 {
 	struct cfg80211_registered_device *drv;
 	int err, ifindex;
 	enum nl80211_iftype type;
 	struct net_device *dev;
+	u32 flags;
 
 	if (info->attrs[NL80211_ATTR_IFTYPE]) {
 		type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
@@ -362,7 +393,11 @@ static int nl80211_set_interface(struct 
 	}
 
 	rtnl_lock();
-	err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex, type);
+	err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
+				  info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
+				  &flags);
+	err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
+					    type, err ? NULL : &flags);
 	rtnl_unlock();
 
  unlock:
@@ -375,6 +410,7 @@ static int nl80211_new_interface(struct 
 	struct cfg80211_registered_device *drv;
 	int err;
 	enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
+	u32 flags;
 
 	if (!info->attrs[NL80211_ATTR_IFNAME])
 		return -EINVAL;
@@ -395,8 +431,12 @@ static int nl80211_new_interface(struct 
 	}
 
 	rtnl_lock();
+	err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
+				  info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
+				  &flags);
 	err = drv->ops->add_virtual_intf(&drv->wiphy,
-		nla_data(info->attrs[NL80211_ATTR_IFNAME]), type);
+		nla_data(info->attrs[NL80211_ATTR_IFNAME]),
+		type, err ? NULL : &flags);
 	rtnl_unlock();
 
  unlock:

-- 


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

* [PATCH 4/8] mac80211: Use monitor configuration flags
  2008-01-31 18:48 [PATCH 0/8] AP mode is coming Johannes Berg
                   ` (2 preceding siblings ...)
  2008-01-31 18:48 ` [PATCH 3/8] nl80211: Add monitor interface configuration flags Johannes Berg
@ 2008-01-31 18:48 ` Johannes Berg
  2008-01-31 18:48 ` [PATCH 5/8] mac80211: clean up some things in the RX path Johannes Berg
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Johannes Berg @ 2008-01-31 18:48 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless, Michael Wu

From: Michael Wu <flamingice@sourmilk.net>

Take advantage of the monitor configuration flags now provided by cfg80211.

Signed-off-by: Michael Wu <flamingice@sourmilk.net>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net> 
---

 net/mac80211/cfg.c             |   15 ++++++++++
 net/mac80211/ieee80211.c       |   56 ++++++++++++++++++++++++++++++-----------
 net/mac80211/ieee80211_i.h     |    3 ++
 net/mac80211/ieee80211_iface.c |    2 +
 4 files changed, 60 insertions(+), 16 deletions(-)

--- everything.orig/net/mac80211/cfg.c	2008-01-31 15:46:10.825789821 +0100
+++ everything/net/mac80211/cfg.c	2008-01-31 15:46:11.615800454 +0100
@@ -38,6 +38,9 @@ static int ieee80211_add_iface(struct wi
 {
 	struct ieee80211_local *local = wiphy_priv(wiphy);
 	enum ieee80211_if_types itype;
+	struct net_device *dev;
+	struct ieee80211_sub_if_data *sdata;
+	int err;
 
 	if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
 		return -ENODEV;
@@ -46,7 +49,13 @@ static int ieee80211_add_iface(struct wi
 	if (itype == IEEE80211_IF_TYPE_INVALID)
 		return -EINVAL;
 
-	return ieee80211_if_add(local->mdev, name, NULL, itype);
+	err = ieee80211_if_add(local->mdev, name, &dev, itype);
+	if (err || itype != IEEE80211_IF_TYPE_MNTR || !flags)
+		return err;
+
+	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	sdata->u.mntr_flags = *flags;
+	return 0;
 }
 
 static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex)
@@ -99,6 +108,10 @@ static int ieee80211_change_iface(struct
 	ieee80211_if_reinit(dev);
 	ieee80211_if_set_type(dev, itype);
 
+	if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR || !flags)
+		return 0;
+
+	sdata->u.mntr_flags = *flags;
 	return 0;
 }
 
--- everything.orig/net/mac80211/ieee80211.c	2008-01-31 15:46:06.365796278 +0100
+++ everything/net/mac80211/ieee80211.c	2008-01-31 15:46:11.615800454 +0100
@@ -67,9 +67,19 @@ static void ieee80211_configure_filter(s
 		new_flags |= FIF_ALLMULTI;
 
 	if (local->monitors)
-		new_flags |= FIF_CONTROL |
-			     FIF_OTHER_BSS |
-			     FIF_BCN_PRBRESP_PROMISC;
+		new_flags |= FIF_BCN_PRBRESP_PROMISC;
+
+	if (local->fif_fcsfail)
+		new_flags |= FIF_FCSFAIL;
+
+	if (local->fif_plcpfail)
+		new_flags |= FIF_PLCPFAIL;
+
+	if (local->fif_control)
+		new_flags |= FIF_CONTROL;
+
+	if (local->fif_other_bss)
+		new_flags |= FIF_OTHER_BSS;
 
 	changed_flags = local->filter_flags ^ new_flags;
 
@@ -230,13 +240,21 @@ static int ieee80211_open(struct net_dev
 	case IEEE80211_IF_TYPE_MNTR:
 		/* must be before the call to ieee80211_configure_filter */
 		local->monitors++;
-		if (local->monitors == 1) {
-			netif_tx_lock_bh(local->mdev);
-			ieee80211_configure_filter(local);
-			netif_tx_unlock_bh(local->mdev);
-
+		if (local->monitors == 1)
 			local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP;
-		}
+
+		if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
+			local->fif_fcsfail++;
+		if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
+			local->fif_plcpfail++;
+		if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL)
+			local->fif_control++;
+		if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
+			local->fif_other_bss++;
+
+		netif_tx_lock_bh(local->mdev);
+		ieee80211_configure_filter(local);
+		netif_tx_unlock_bh(local->mdev);
 		break;
 	case IEEE80211_IF_TYPE_STA:
 	case IEEE80211_IF_TYPE_IBSS:
@@ -350,13 +368,21 @@ static int ieee80211_stop(struct net_dev
 		break;
 	case IEEE80211_IF_TYPE_MNTR:
 		local->monitors--;
-		if (local->monitors == 0) {
-			netif_tx_lock_bh(local->mdev);
-			ieee80211_configure_filter(local);
-			netif_tx_unlock_bh(local->mdev);
-
+		if (local->monitors == 0)
 			local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
-		}
+
+		if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
+			local->fif_fcsfail--;
+		if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
+			local->fif_plcpfail--;
+		if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL)
+			local->fif_control--;
+		if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
+			local->fif_other_bss--;
+
+		netif_tx_lock_bh(local->mdev);
+		ieee80211_configure_filter(local);
+		netif_tx_unlock_bh(local->mdev);
 		break;
 	case IEEE80211_IF_TYPE_STA:
 	case IEEE80211_IF_TYPE_IBSS:
--- everything.orig/net/mac80211/ieee80211_i.h	2008-01-31 15:46:09.975794650 +0100
+++ everything/net/mac80211/ieee80211_i.h	2008-01-31 15:46:11.615800454 +0100
@@ -345,6 +345,7 @@ struct ieee80211_sub_if_data {
 		struct ieee80211_if_wds wds;
 		struct ieee80211_if_vlan vlan;
 		struct ieee80211_if_sta sta;
+		u32 mntr_flags;
 	} u;
 	int channel_use;
 	int channel_use_raw;
@@ -425,6 +426,8 @@ struct ieee80211_local {
 	struct net_device *mdev; /* wmaster# - "master" 802.11 device */
 	int open_count;
 	int monitors;
+	/* number of interfaces with corresponding FIF_ flags */
+	int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss;
 	unsigned int filter_flags; /* FIF_* */
 	struct iw_statistics wstats;
 	u8 wstats_flags;
--- everything.orig/net/mac80211/ieee80211_iface.c	2008-01-31 15:45:56.075794649 +0100
+++ everything/net/mac80211/ieee80211_iface.c	2008-01-31 15:46:11.615800454 +0100
@@ -160,6 +160,8 @@ void ieee80211_if_set_type(struct net_de
 	case IEEE80211_IF_TYPE_MNTR:
 		dev->type = ARPHRD_IEEE80211_RADIOTAP;
 		dev->hard_start_xmit = ieee80211_monitor_start_xmit;
+		sdata->u.mntr_flags = MONITOR_FLAG_CONTROL |
+				      MONITOR_FLAG_OTHER_BSS;
 		break;
 	default:
 		printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x",

-- 


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

* [PATCH 5/8] mac80211: clean up some things in the RX path
  2008-01-31 18:48 [PATCH 0/8] AP mode is coming Johannes Berg
                   ` (3 preceding siblings ...)
  2008-01-31 18:48 ` [PATCH 4/8] mac80211: Use monitor " Johannes Berg
@ 2008-01-31 18:48 ` Johannes Berg
  2008-01-31 18:48 ` [PATCH 6/8] mac80211: remove "dynamic" RX/TX handlers Johannes Berg
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Johannes Berg @ 2008-01-31 18:48 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

Uninline ieee80211_invoke_rx_handlers to save .text space,
make the code more readable in some places and remove the
"optimisation" that is hit only very few times and unclear
to start with.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
I have a plan to add back such an optimisation but it is rather
involved requiring a scan handling change and per-sdata sta
structures.

 net/mac80211/rx.c |   37 ++++++++++---------------------------
 1 file changed, 10 insertions(+), 27 deletions(-)

--- everything.orig/net/mac80211/rx.c	2008-01-31 15:46:09.985793781 +0100
+++ everything/net/mac80211/rx.c	2008-01-31 15:46:12.415793891 +0100
@@ -1448,11 +1448,10 @@ ieee80211_rx_h_mgmt(struct ieee80211_txr
 	return RX_QUEUED;
 }
 
-static inline ieee80211_rx_result __ieee80211_invoke_rx_handlers(
-				struct ieee80211_local *local,
-				ieee80211_rx_handler *handlers,
-				struct ieee80211_txrx_data *rx,
-				struct sta_info *sta)
+static void ieee80211_invoke_rx_handlers(struct ieee80211_local *local,
+					 ieee80211_rx_handler *handlers,
+					 struct ieee80211_txrx_data *rx,
+					 struct sta_info *sta)
 {
 	ieee80211_rx_handler *handler;
 	ieee80211_rx_result res = RX_DROP_MONITOR;
@@ -1476,19 +1475,13 @@ static inline ieee80211_rx_result __ieee
 		break;
 	}
 
-	if (res == RX_DROP_UNUSABLE || res == RX_DROP_MONITOR)
-		dev_kfree_skb(rx->skb);
-	return res;
-}
-
-static inline void ieee80211_invoke_rx_handlers(struct ieee80211_local *local,
-						ieee80211_rx_handler *handlers,
-						struct ieee80211_txrx_data *rx,
-						struct sta_info *sta)
-{
-	if (__ieee80211_invoke_rx_handlers(local, handlers, rx, sta) ==
-	    RX_CONTINUE)
+	switch (res) {
+	case RX_DROP_MONITOR:
+	case RX_DROP_UNUSABLE:
+	case RX_CONTINUE:
 		dev_kfree_skb(rx->skb);
+		break;
+	}
 }
 
 static void ieee80211_rx_michael_mic_report(struct net_device *dev,
@@ -1718,16 +1711,6 @@ static void __ieee80211_rx_handle_packet
 
 	skb = rx.skb;
 
-	if (sta && !(sta->flags & (WLAN_STA_WDS | WLAN_STA_ASSOC_AP)) &&
-	    !atomic_read(&local->iff_promiscs) &&
-	    !is_multicast_ether_addr(hdr->addr1)) {
-		rx.flags |= IEEE80211_TXRXD_RXRA_MATCH;
-		ieee80211_invoke_rx_handlers(local, local->rx_handlers, &rx,
-					     rx.sta);
-		sta_info_put(sta);
-		return;
-	}
-
 	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 		if (!netif_running(sdata->dev))
 			continue;

-- 


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

* [PATCH 6/8] mac80211: remove "dynamic" RX/TX handlers
  2008-01-31 18:48 [PATCH 0/8] AP mode is coming Johannes Berg
                   ` (4 preceding siblings ...)
  2008-01-31 18:48 ` [PATCH 5/8] mac80211: clean up some things in the RX path Johannes Berg
@ 2008-01-31 18:48 ` Johannes Berg
  2008-01-31 18:48 ` [PATCH 7/8] mac80211: move some code into ieee80211_invoke_rx_handlers Johannes Berg
  2008-01-31 18:48 ` [PATCH 8/8] mac80211: Add cooked monitor mode support Johannes Berg
  7 siblings, 0 replies; 9+ messages in thread
From: Johannes Berg @ 2008-01-31 18:48 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

It doesn't really make sense to have extra pointers to the RX/TX
handler arrays instead of just using the arrays directly, that
also allows us to make them static.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/mac80211/ieee80211.c   |    2 -
 net/mac80211/ieee80211_i.h |   13 -------
 net/mac80211/rx.c          |   80 +++++++++++++++++++++------------------------
 net/mac80211/tx.c          |    9 ++---
 4 files changed, 43 insertions(+), 61 deletions(-)

--- everything.orig/net/mac80211/ieee80211.c	2008-01-31 15:46:11.615800454 +0100
+++ everything/net/mac80211/ieee80211.c	2008-01-31 15:46:13.125794378 +0100
@@ -1426,8 +1426,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(
 	local->hw.queues = 1; /* default */
 
 	local->mdev = mdev;
-	local->rx_handlers = ieee80211_rx_handlers;
-	local->tx_handlers = ieee80211_tx_handlers;
 
 	local->bridge_packets = 1;
 
--- everything.orig/net/mac80211/ieee80211_i.h	2008-01-31 15:46:11.615800454 +0100
+++ everything/net/mac80211/ieee80211_i.h	2008-01-31 15:46:13.135794379 +0100
@@ -190,12 +190,6 @@ struct ieee80211_tx_stored_packet {
 	unsigned int last_frag_rate_ctrl_probe;
 };
 
-typedef ieee80211_tx_result (*ieee80211_tx_handler)
-(struct ieee80211_txrx_data *tx);
-
-typedef ieee80211_rx_result (*ieee80211_rx_handler)
-(struct ieee80211_txrx_data *rx);
-
 struct beacon_data {
 	u8 *head, *tail;
 	int head_len, tail_len;
@@ -477,9 +471,6 @@ struct ieee80211_local {
 			     * deliver multicast frames both back to wireless
 			     * media and to the local net stack */
 
-	ieee80211_rx_handler *rx_handlers;
-	ieee80211_tx_handler *tx_handlers;
-
 	struct list_head interfaces;
 
 	bool sta_sw_scanning;
@@ -779,11 +770,7 @@ int ieee80211_if_remove(struct net_devic
 void ieee80211_if_free(struct net_device *dev);
 void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata);
 
-/* rx handling */
-extern ieee80211_rx_handler ieee80211_rx_handlers[];
-
 /* tx handling */
-extern ieee80211_tx_handler ieee80211_tx_handlers[];
 void ieee80211_clear_tx_pending(struct ieee80211_local *local);
 void ieee80211_tx_pending(unsigned long data);
 int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev);
--- everything.orig/net/mac80211/rx.c	2008-01-31 15:46:12.415793891 +0100
+++ everything/net/mac80211/rx.c	2008-01-31 15:46:13.135794379 +0100
@@ -1448,42 +1448,6 @@ ieee80211_rx_h_mgmt(struct ieee80211_txr
 	return RX_QUEUED;
 }
 
-static void ieee80211_invoke_rx_handlers(struct ieee80211_local *local,
-					 ieee80211_rx_handler *handlers,
-					 struct ieee80211_txrx_data *rx,
-					 struct sta_info *sta)
-{
-	ieee80211_rx_handler *handler;
-	ieee80211_rx_result res = RX_DROP_MONITOR;
-
-	for (handler = handlers; *handler != NULL; handler++) {
-		res = (*handler)(rx);
-
-		switch (res) {
-		case RX_CONTINUE:
-			continue;
-		case RX_DROP_UNUSABLE:
-		case RX_DROP_MONITOR:
-			I802_DEBUG_INC(local->rx_handlers_drop);
-			if (sta)
-				sta->rx_dropped++;
-			break;
-		case RX_QUEUED:
-			I802_DEBUG_INC(local->rx_handlers_queued);
-			break;
-		}
-		break;
-	}
-
-	switch (res) {
-	case RX_DROP_MONITOR:
-	case RX_DROP_UNUSABLE:
-	case RX_CONTINUE:
-		dev_kfree_skb(rx->skb);
-		break;
-	}
-}
-
 static void ieee80211_rx_michael_mic_report(struct net_device *dev,
 					    struct ieee80211_hdr *hdr,
 					    struct sta_info *sta,
@@ -1557,7 +1521,8 @@ static void ieee80211_rx_michael_mic_rep
 	rx->skb = NULL;
 }
 
-ieee80211_rx_handler ieee80211_rx_handlers[] =
+typedef ieee80211_rx_result (*ieee80211_rx_handler)(struct ieee80211_txrx_data *);
+static ieee80211_rx_handler ieee80211_rx_handlers[] =
 {
 	ieee80211_rx_h_if_stats,
 	ieee80211_rx_h_passive_scan,
@@ -1579,6 +1544,41 @@ ieee80211_rx_handler ieee80211_rx_handle
 	NULL
 };
 
+static void ieee80211_invoke_rx_handlers(struct ieee80211_local *local,
+					 struct ieee80211_txrx_data *rx,
+					 struct sta_info *sta)
+{
+	ieee80211_rx_handler *handler;
+	ieee80211_rx_result res = RX_DROP_MONITOR;
+
+	for (handler = ieee80211_rx_handlers; *handler != NULL; handler++) {
+		res = (*handler)(rx);
+
+		switch (res) {
+		case RX_CONTINUE:
+			continue;
+		case RX_DROP_UNUSABLE:
+		case RX_DROP_MONITOR:
+			I802_DEBUG_INC(local->rx_handlers_drop);
+			if (sta)
+				sta->rx_dropped++;
+			break;
+		case RX_QUEUED:
+			I802_DEBUG_INC(local->rx_handlers_queued);
+			break;
+		}
+		break;
+	}
+
+	switch (res) {
+	case RX_DROP_MONITOR:
+	case RX_DROP_UNUSABLE:
+	case RX_CONTINUE:
+		dev_kfree_skb(rx->skb);
+		break;
+	}
+}
+
 /* main receive path */
 
 static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
@@ -1756,8 +1756,7 @@ static void __ieee80211_rx_handle_packet
 		rx.skb = skb_new;
 		rx.dev = prev->dev;
 		rx.sdata = prev;
-		ieee80211_invoke_rx_handlers(local, local->rx_handlers,
-					     &rx, sta);
+		ieee80211_invoke_rx_handlers(local, &rx, sta);
 		prev = sdata;
 	}
 	if (prev) {
@@ -1765,8 +1764,7 @@ static void __ieee80211_rx_handle_packet
 		rx.skb = skb;
 		rx.dev = prev->dev;
 		rx.sdata = prev;
-		ieee80211_invoke_rx_handlers(local, local->rx_handlers,
-					     &rx, sta);
+		ieee80211_invoke_rx_handlers(local, &rx, sta);
 	} else
 		dev_kfree_skb(skb);
 
--- everything.orig/net/mac80211/tx.c	2008-01-31 15:46:09.035794161 +0100
+++ everything/net/mac80211/tx.c	2008-01-31 15:46:13.135794379 +0100
@@ -813,10 +813,9 @@ ieee80211_tx_h_load_stats(struct ieee802
 	return TX_CONTINUE;
 }
 
-/* TODO: implement register/unregister functions for adding TX/RX handlers
- * into ordered list */
 
-ieee80211_tx_handler ieee80211_tx_handlers[] =
+typedef ieee80211_tx_result (*ieee80211_tx_handler)(struct ieee80211_txrx_data *);
+static ieee80211_tx_handler ieee80211_tx_handlers[] =
 {
 	ieee80211_tx_h_check_assoc,
 	ieee80211_tx_h_sequence,
@@ -1158,7 +1157,7 @@ static int ieee80211_tx(struct net_devic
 	sta = tx.sta;
 	tx.u.tx.channel = local->hw.conf.channel;
 
-	for (handler = local->tx_handlers; *handler != NULL;
+	for (handler = ieee80211_tx_handlers; *handler != NULL;
 	     handler++) {
 		res = (*handler)(&tx);
 		if (res != TX_CONTINUE)
@@ -1914,7 +1913,7 @@ ieee80211_get_buffered_bc(struct ieee802
 	tx.flags |= IEEE80211_TXRXD_TXPS_BUFFERED;
 	tx.u.tx.channel = local->hw.conf.channel;
 
-	for (handler = local->tx_handlers; *handler != NULL; handler++) {
+	for (handler = ieee80211_tx_handlers; *handler != NULL; handler++) {
 		res = (*handler)(&tx);
 		if (res == TX_DROP || res == TX_QUEUED)
 			break;

-- 


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

* [PATCH 7/8] mac80211: move some code into ieee80211_invoke_rx_handlers
  2008-01-31 18:48 [PATCH 0/8] AP mode is coming Johannes Berg
                   ` (5 preceding siblings ...)
  2008-01-31 18:48 ` [PATCH 6/8] mac80211: remove "dynamic" RX/TX handlers Johannes Berg
@ 2008-01-31 18:48 ` Johannes Berg
  2008-01-31 18:48 ` [PATCH 8/8] mac80211: Add cooked monitor mode support Johannes Berg
  7 siblings, 0 replies; 9+ messages in thread
From: Johannes Berg @ 2008-01-31 18:48 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

There is some duplicated code that sits in front of each function
call to ieee80211_invoke_rx_handlers() that can very well be part
of that function if it gets slightly different arguments.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/mac80211/rx.c |   42 ++++++++++++++++++------------------------
 1 file changed, 18 insertions(+), 24 deletions(-)

--- everything.orig/net/mac80211/rx.c	2008-01-31 15:46:13.135794379 +0100
+++ everything/net/mac80211/rx.c	2008-01-31 19:26:11.032266928 +0100
@@ -1450,7 +1450,6 @@ ieee80211_rx_h_mgmt(struct ieee80211_txr
 
 static void ieee80211_rx_michael_mic_report(struct net_device *dev,
 					    struct ieee80211_hdr *hdr,
-					    struct sta_info *sta,
 					    struct ieee80211_txrx_data *rx)
 {
 	int keyidx, hdrlen;
@@ -1469,7 +1468,7 @@ static void ieee80211_rx_michael_mic_rep
 		       dev->name, print_mac(mac, hdr->addr2),
 		       print_mac(mac2, hdr->addr1), keyidx);
 
-	if (!sta) {
+	if (!rx->sta) {
 		/*
 		 * Some hardware seem to generate incorrect Michael MIC
 		 * reports; ignore them to avoid triggering countermeasures.
@@ -1544,13 +1543,17 @@ static ieee80211_rx_handler ieee80211_rx
 	NULL
 };
 
-static void ieee80211_invoke_rx_handlers(struct ieee80211_local *local,
+static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
 					 struct ieee80211_txrx_data *rx,
-					 struct sta_info *sta)
+					 struct sk_buff *skb)
 {
 	ieee80211_rx_handler *handler;
 	ieee80211_rx_result res = RX_DROP_MONITOR;
 
+	rx->skb = skb;
+	rx->sdata = sdata;
+	rx->dev = sdata->dev;
+
 	for (handler = ieee80211_rx_handlers; *handler != NULL; handler++) {
 		res = (*handler)(rx);
 
@@ -1559,12 +1562,12 @@ static void ieee80211_invoke_rx_handlers
 			continue;
 		case RX_DROP_UNUSABLE:
 		case RX_DROP_MONITOR:
-			I802_DEBUG_INC(local->rx_handlers_drop);
-			if (sta)
-				sta->rx_dropped++;
+			I802_DEBUG_INC(sdata->local->rx_handlers_drop);
+			if (rx->sta)
+				rx->sta->rx_dropped++;
 			break;
 		case RX_QUEUED:
-			I802_DEBUG_INC(local->rx_handlers_queued);
+			I802_DEBUG_INC(sdata->local->rx_handlers_queued);
 			break;
 		}
 		break;
@@ -1669,7 +1672,6 @@ static void __ieee80211_rx_handle_packet
 {
 	struct ieee80211_local *local = hw_to_local(hw);
 	struct ieee80211_sub_if_data *sdata;
-	struct sta_info *sta;
 	struct ieee80211_hdr *hdr;
 	struct ieee80211_txrx_data rx;
 	u16 type;
@@ -1692,14 +1694,14 @@ static void __ieee80211_rx_handle_packet
 	if (type == IEEE80211_FTYPE_DATA || type == IEEE80211_FTYPE_MGMT)
 		local->dot11ReceivedFragmentCount++;
 
-	sta = rx.sta = sta_info_get(local, hdr->addr2);
-	if (sta) {
+	rx.sta = sta_info_get(local, hdr->addr2);
+	if (rx.sta) {
 		rx.dev = rx.sta->dev;
 		rx.sdata = IEEE80211_DEV_TO_SUB_IF(rx.dev);
 	}
 
 	if ((status->flag & RX_FLAG_MMIC_ERROR)) {
-		ieee80211_rx_michael_mic_report(local->mdev, hdr, sta, &rx);
+		ieee80211_rx_michael_mic_report(local->mdev, hdr, &rx);
 		goto end;
 	}
 
@@ -1721,8 +1723,6 @@ static void __ieee80211_rx_handle_packet
 		bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type);
 		rx.flags |= IEEE80211_TXRXD_RXRA_MATCH;
 		prepares = prepare_for_handlers(sdata, bssid, &rx, hdr);
-		/* prepare_for_handlers can change sta */
-		sta = rx.sta;
 
 		if (!prepares)
 			continue;
@@ -1753,24 +1753,18 @@ static void __ieee80211_rx_handle_packet
 			continue;
 		}
 		rx.fc = le16_to_cpu(hdr->frame_control);
-		rx.skb = skb_new;
-		rx.dev = prev->dev;
-		rx.sdata = prev;
-		ieee80211_invoke_rx_handlers(local, &rx, sta);
+		ieee80211_invoke_rx_handlers(prev, &rx, skb_new);
 		prev = sdata;
 	}
 	if (prev) {
 		rx.fc = le16_to_cpu(hdr->frame_control);
-		rx.skb = skb;
-		rx.dev = prev->dev;
-		rx.sdata = prev;
-		ieee80211_invoke_rx_handlers(local, &rx, sta);
+		ieee80211_invoke_rx_handlers(prev, &rx, skb);
 	} else
 		dev_kfree_skb(skb);
 
  end:
-	if (sta)
-		sta_info_put(sta);
+	if (rx.sta)
+		sta_info_put(rx.sta);
 }
 
 #define SEQ_MODULO 0x1000

-- 


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

* [PATCH 8/8] mac80211: Add cooked monitor mode support
  2008-01-31 18:48 [PATCH 0/8] AP mode is coming Johannes Berg
                   ` (6 preceding siblings ...)
  2008-01-31 18:48 ` [PATCH 7/8] mac80211: move some code into ieee80211_invoke_rx_handlers Johannes Berg
@ 2008-01-31 18:48 ` Johannes Berg
  7 siblings, 0 replies; 9+ messages in thread
From: Johannes Berg @ 2008-01-31 18:48 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless, Michael Wu

From: Michael Wu <flamingice@sourmilk.net>

This adds "cooked" monitor mode to mac80211. A monitor interface
in "cooked" mode will see all frames that mac80211 has not used
internally.

Signed-off-by: Michael Wu <flamingice@sourmilk.net>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---

 net/mac80211/ieee80211.c   |   67 +++++++++++++++++++---------------
 net/mac80211/ieee80211_i.h |    3 +
 net/mac80211/rx.c          |   87 ++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 126 insertions(+), 31 deletions(-)

--- everything.orig/net/mac80211/ieee80211.c	2008-01-31 19:35:26.042291125 +0100
+++ everything/net/mac80211/ieee80211.c	2008-01-31 19:35:27.942268936 +0100
@@ -238,6 +238,11 @@ static int ieee80211_open(struct net_dev
 		/* no need to tell driver */
 		break;
 	case IEEE80211_IF_TYPE_MNTR:
+		if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) {
+			local->cooked_mntrs++;
+			break;
+		}
+
 		/* must be before the call to ieee80211_configure_filter */
 		local->monitors++;
 		if (local->monitors == 1)
@@ -367,6 +372,11 @@ static int ieee80211_stop(struct net_dev
 		/* no need to tell driver */
 		break;
 	case IEEE80211_IF_TYPE_MNTR:
+		if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) {
+			local->cooked_mntrs--;
+			break;
+		}
+
 		local->monitors--;
 		if (local->monitors == 0)
 			local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
@@ -1174,7 +1184,7 @@ void ieee80211_tx_status(struct ieee8021
 	u16 frag, type;
 	struct ieee80211_tx_status_rtap_hdr *rthdr;
 	struct ieee80211_sub_if_data *sdata;
-	int monitors;
+	struct net_device *prev_dev = NULL;
 
 	if (!status) {
 		printk(KERN_ERR
@@ -1287,7 +1297,11 @@ void ieee80211_tx_status(struct ieee8021
 	/* this was a transmitted frame, but now we want to reuse it */
 	skb_orphan(skb);
 
-	if (!local->monitors) {
+	/*
+	 * This is a bit racy but we can avoid a lot of work
+	 * with this test...
+	 */
+	if (!local->monitors && !local->cooked_mntrs) {
 		dev_kfree_skb(skb);
 		return;
 	}
@@ -1321,42 +1335,37 @@ void ieee80211_tx_status(struct ieee8021
 
 	rthdr->data_retries = status->retry_count;
 
+	/* XXX: is this sufficient for BPF? */
+	skb_set_mac_header(skb, 0);
+	skb->ip_summed = CHECKSUM_UNNECESSARY;
+	skb->pkt_type = PACKET_OTHERHOST;
+	skb->protocol = htons(ETH_P_802_2);
+	memset(skb->cb, 0, sizeof(skb->cb));
+
 	rcu_read_lock();
-	monitors = local->monitors;
 	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
-		/*
-		 * Using the monitors counter is possibly racy, but
-		 * if the value is wrong we simply either clone the skb
-		 * once too much or forget sending it to one monitor iface
-		 * The latter case isn't nice but fixing the race is much
-		 * more complicated.
-		 */
-		if (!monitors || !skb)
-			goto out;
-
 		if (sdata->vif.type == IEEE80211_IF_TYPE_MNTR) {
 			if (!netif_running(sdata->dev))
 				continue;
-			monitors--;
-			if (monitors)
+
+			if (prev_dev) {
 				skb2 = skb_clone(skb, GFP_ATOMIC);
-			else
-				skb2 = NULL;
-			skb->dev = sdata->dev;
-			/* XXX: is this sufficient for BPF? */
-			skb_set_mac_header(skb, 0);
-			skb->ip_summed = CHECKSUM_UNNECESSARY;
-			skb->pkt_type = PACKET_OTHERHOST;
-			skb->protocol = htons(ETH_P_802_2);
-			memset(skb->cb, 0, sizeof(skb->cb));
-			netif_rx(skb);
-			skb = skb2;
+				if (skb2) {
+					skb2->dev = prev_dev;
+					netif_rx(skb2);
+				}
+			}
+
+			prev_dev = sdata->dev;
 		}
 	}
- out:
+	if (prev_dev) {
+		skb->dev = prev_dev;
+		netif_rx(skb);
+		skb = NULL;
+	}
 	rcu_read_unlock();
-	if (skb)
-		dev_kfree_skb(skb);
+	dev_kfree_skb(skb);
 }
 EXPORT_SYMBOL(ieee80211_tx_status);
 
--- everything.orig/net/mac80211/ieee80211_i.h	2008-01-31 19:35:26.042291125 +0100
+++ everything/net/mac80211/ieee80211_i.h	2008-01-31 19:35:27.942268936 +0100
@@ -131,6 +131,7 @@ typedef unsigned __bitwise__ ieee80211_r
 #define IEEE80211_TXRXD_RXRA_MATCH		BIT(5)
 #define IEEE80211_TXRXD_TX_INJECTED		BIT(6)
 #define IEEE80211_TXRXD_RX_AMSDU		BIT(7)
+#define IEEE80211_TXRXD_RX_CMNTR_REPORTED	BIT(8)
 struct ieee80211_txrx_data {
 	struct sk_buff *skb;
 	struct net_device *dev;
@@ -419,7 +420,7 @@ struct ieee80211_local {
 
 	struct net_device *mdev; /* wmaster# - "master" 802.11 device */
 	int open_count;
-	int monitors;
+	int monitors, cooked_mntrs;
 	/* number of interfaces with corresponding FIF_ flags */
 	int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss;
 	unsigned int filter_flags; /* FIF_* */
--- everything.orig/net/mac80211/rx.c	2008-01-31 19:35:27.002268610 +0100
+++ everything/net/mac80211/rx.c	2008-01-31 19:35:27.952268013 +0100
@@ -223,6 +223,9 @@ ieee80211_rx_monitor(struct ieee80211_lo
 		if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR)
 			continue;
 
+		if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES)
+			continue;
+
 		if (prev_dev) {
 			skb2 = skb_clone(skb, GFP_ATOMIC);
 			if (skb2) {
@@ -1520,6 +1523,86 @@ static void ieee80211_rx_michael_mic_rep
 	rx->skb = NULL;
 }
 
+static void ieee80211_rx_cooked_monitor(struct ieee80211_txrx_data *rx)
+{
+	struct ieee80211_sub_if_data *sdata;
+	struct ieee80211_local *local = rx->local;
+	struct ieee80211_rtap_hdr {
+		struct ieee80211_radiotap_header hdr;
+		u8 flags;
+		u8 rate;
+		__le16 chan_freq;
+		__le16 chan_flags;
+	} __attribute__ ((packed)) *rthdr;
+	struct sk_buff *skb = rx->skb, *skb2;
+	struct net_device *prev_dev = NULL;
+	struct ieee80211_rx_status *status = rx->u.rx.status;
+
+	if (rx->flags & IEEE80211_TXRXD_RX_CMNTR_REPORTED)
+		goto out_free_skb;
+
+	if (skb_headroom(skb) < sizeof(*rthdr) &&
+	    pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC))
+		goto out_free_skb;
+
+	rthdr = (void *)skb_push(skb, sizeof(*rthdr));
+	memset(rthdr, 0, sizeof(*rthdr));
+	rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr));
+	rthdr->hdr.it_present =
+		cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
+			    (1 << IEEE80211_RADIOTAP_RATE) |
+			    (1 << IEEE80211_RADIOTAP_CHANNEL));
+
+	rthdr->rate = rx->u.rx.rate->bitrate / 5;
+	rthdr->chan_freq = cpu_to_le16(status->freq);
+
+	if (status->band == IEEE80211_BAND_5GHZ)
+		rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_OFDM |
+						IEEE80211_CHAN_5GHZ);
+	else
+		rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_DYN |
+						IEEE80211_CHAN_2GHZ);
+
+	skb_set_mac_header(skb, 0);
+	skb->ip_summed = CHECKSUM_UNNECESSARY;
+	skb->pkt_type = PACKET_OTHERHOST;
+	skb->protocol = htons(ETH_P_802_2);
+
+	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+		if (!netif_running(sdata->dev))
+			continue;
+
+		if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR ||
+		    !(sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES))
+			continue;
+
+		if (prev_dev) {
+			skb2 = skb_clone(skb, GFP_ATOMIC);
+			if (skb2) {
+				skb2->dev = prev_dev;
+				netif_rx(skb2);
+			}
+		}
+
+		prev_dev = sdata->dev;
+		sdata->dev->stats.rx_packets++;
+		sdata->dev->stats.rx_bytes += skb->len;
+	}
+
+	if (prev_dev) {
+		skb->dev = prev_dev;
+		netif_rx(skb);
+		skb = NULL;
+	} else
+		goto out_free_skb;
+
+	rx->flags |= IEEE80211_TXRXD_RX_CMNTR_REPORTED;
+	return;
+
+ out_free_skb:
+	dev_kfree_skb(skb);
+}
+
 typedef ieee80211_rx_result (*ieee80211_rx_handler)(struct ieee80211_txrx_data *);
 static ieee80211_rx_handler ieee80211_rx_handlers[] =
 {
@@ -1574,9 +1657,11 @@ static void ieee80211_invoke_rx_handlers
 	}
 
 	switch (res) {
+	case RX_CONTINUE:
 	case RX_DROP_MONITOR:
+		ieee80211_rx_cooked_monitor(rx);
+		break;
 	case RX_DROP_UNUSABLE:
-	case RX_CONTINUE:
 		dev_kfree_skb(rx->skb);
 		break;
 	}

-- 


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

end of thread, other threads:[~2008-02-01 12:09 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-31 18:48 [PATCH 0/8] AP mode is coming Johannes Berg
2008-01-31 18:48 ` [PATCH 1/8] mac80211: split ieee80211_txrx_result Johannes Berg
2008-01-31 18:48 ` [PATCH 2/8] mac80211: split RX_DROP Johannes Berg
2008-01-31 18:48 ` [PATCH 3/8] nl80211: Add monitor interface configuration flags Johannes Berg
2008-01-31 18:48 ` [PATCH 4/8] mac80211: Use monitor " Johannes Berg
2008-01-31 18:48 ` [PATCH 5/8] mac80211: clean up some things in the RX path Johannes Berg
2008-01-31 18:48 ` [PATCH 6/8] mac80211: remove "dynamic" RX/TX handlers Johannes Berg
2008-01-31 18:48 ` [PATCH 7/8] mac80211: move some code into ieee80211_invoke_rx_handlers Johannes Berg
2008-01-31 18:48 ` [PATCH 8/8] mac80211: Add cooked monitor mode support Johannes Berg

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).