Skip to contentSkip to conversation

mac80211 fixes, updates, preparations for hostapd tree

PATCH In review Johannes Berg 2 participants 17 messages Sep 26, 2007 – Sep 28, 2007

Subsystems (3)
lore
Share & tools
lore

Johannes Berg

author maintainer
#0 lore raw

cover mac80211 fixes, updates, preparations for hostapd tree

Here's a set of fixes, optimisations, updates and preparations for the hostapd tree I intend to maintain.

johannes

author maintainer
#1 lore raw

PATCH 1/12 mac80211: pass frames to monitor interfaces early

This makes mac80211 pass all frames to monitor interfaces early before all receive processing with the benefit that only a single copy needs to be made, all monitors can receive clones of the skb and if the frame will be discarded we don't even need to make a single copy.

---
 net/mac80211/rx.c |  350 ++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 226 insertions(+), 124 deletions(-)
net/mac80211/rx.c +226 -124
@@ -25,6 +25,207 @@
 #include "tkip.h"
 #include "wme.h"
 
+/*
+ * monitor mode reception
+ *
+ * This function cleans up the SKB, i.e. it removes all the stuff
+ * only useful for monitoring.
+ */
+static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
+					   struct sk_buff *skb,
+					   int rtap_len)
+{
+	skb_pull(skb, rtap_len);
+
+	if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) {
+		if (likely(skb->len > FCS_LEN))
+			skb_trim(skb, skb->len - FCS_LEN);
+		else {
+			/* driver bug */
+			WARN_ON(1);
+			dev_kfree_skb(skb);
+			skb = NULL;
+		}
+	}
+
+	return skb;
+}
+
+static inline int should_drop_frame(struct ieee80211_rx_status *status,
+				    struct sk_buff *skb,
+				    int present_fcs_len,
+				    int radiotap_len)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+
+	if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))
+		return 1;
+	if (unlikely(skb->len < 16 + present_fcs_len + radiotap_len))
+		return 1;
+	if ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==
+			cpu_to_le16(IEEE80211_FTYPE_CTL))
+		return 1;
+	return 0;
+}
+
+/*
+ * This function copies a received frame to all monitor interfaces and
+ * returns a cleaned-up SKB that no longer includes the FCS nor the
+ * radiotap header the driver might have added.
+ */
+static struct sk_buff *
+ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
+		     struct ieee80211_rx_status *status)
+{
+	struct ieee80211_sub_if_data *sdata;
+	struct ieee80211_rate *rate;
+	int needed_headroom = 0;
+	struct ieee80211_rtap_hdr {
+		struct ieee80211_radiotap_header hdr;
+		u8 flags;
+		u8 rate;
+		__le16 chan_freq;
+		__le16 chan_flags;
+		u8 antsignal;
+		u8 padding_for_rxflags;
+		__le16 rx_flags;
+	} __attribute__ ((packed)) *rthdr;
+	struct sk_buff *skb, *skb2;
+	struct net_device *prev_dev = NULL;
+	int present_fcs_len = 0;
+	int rtap_len = 0;
+
+	/*
+	 * First, we may need to make a copy of the skb because
+	 *  (1) we need to modify it for radiotap (if not present), and
+	 *  (2) the other RX handlers will modify the skb we got.
+	 *
+	 * We don't need to, of course, if we aren't going to return
+	 * the SKB because it has a bad FCS/PLCP checksum.
+	 */
+	if (status->flag & RX_FLAG_RADIOTAP)
+		rtap_len = ieee80211_get_radiotap_len(origskb->data);
+	else
+		needed_headroom = sizeof(*rthdr);
+
+	if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
+		present_fcs_len = FCS_LEN;
+
+	if (!local->monitors) {
+		if (should_drop_frame(status, origskb, present_fcs_len,
+				      rtap_len)) {
+			dev_kfree_skb(origskb);
+			return NULL;
+		}
+
+		return remove_monitor_info(local, origskb, rtap_len);
+	}
+
+	if (should_drop_frame(status, origskb, present_fcs_len, rtap_len)) {
+		/* only need to expand headroom if necessary */
+		skb = origskb;
+		origskb = NULL;
+
+		/*
+		 * This shouldn't trigger often because most devices have an
+		 * RX header they pull before we get here, and that should
+		 * be big enough for our radiotap information. We should
+		 * probably export the length to drivers so that we can have
+		 * them allocate enough headroom to start with.
+		 */
+		if (skb_headroom(skb) < needed_headroom &&
+		    pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) {
+		    	dev_kfree_skb(skb);
+			return NULL;
+		}
+	} else {
+		/*
+		 * Need to make a copy and possibly remove radiotap header
+		 * and FCS from the original.
+		 */
+		skb = skb_copy_expand(origskb, needed_headroom, 0, GFP_ATOMIC);
+
+		origskb = remove_monitor_info(local, origskb, rtap_len);
+
+		if (!skb)
+			return origskb;
+	}
+
+	/* if necessary, prepend radiotap information */
+	if (!(status->flag & RX_FLAG_RADIOTAP)) {
+		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) |
+				    (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) |
+				    (1 << IEEE80211_RADIOTAP_RX_FLAGS));
+		rthdr->flags = local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS ?
+			       IEEE80211_RADIOTAP_F_FCS : 0;
+
+		/* FIXME: when radiotap gets a 'bad PLCP' flag use it here */
+		rthdr->rx_flags = 0;
+		if (status->flag &
+		    (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))
+			rthdr->rx_flags |=
+				cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS);
+
+		rate = ieee80211_get_rate(local, status->phymode,
+					  status->rate);
+		if (rate)
+			rthdr->rate = rate->rate / 5;
+
+		rthdr->chan_freq = cpu_to_le16(status->freq);
+
+		if (status->phymode == MODE_IEEE80211A)
+			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);
+
+		rthdr->antsignal = status->ssi;
+	}
+
+	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->type != IEEE80211_IF_TYPE_MNTR)
+			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);
+	} else
+		dev_kfree_skb(skb);
+
+	return origskb;
+}
+
+
 /* pre-rx handlers
  *
  * these don't have dev/sdata fields in the rx data
@@ -132,100 +333,6 @@ ieee80211_rx_h_if_stats(struct ieee80211
 	return TXRX_CONTINUE;
 }
 
-static void
-ieee80211_rx_monitor(struct net_device *dev, struct sk_buff *skb,
-		     struct ieee80211_rx_status *status)
-{
-	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-	struct ieee80211_rate *rate;
-	struct ieee80211_rtap_hdr {
-		struct ieee80211_radiotap_header hdr;
-		u8 flags;
-		u8 rate;
-		__le16 chan_freq;
-		__le16 chan_flags;
-		u8 antsignal;
-		u8 padding_for_rxflags;
-		__le16 rx_flags;
-	} __attribute__ ((packed)) *rthdr;
-
-	skb->dev = dev;
-
-	if (status->flag & RX_FLAG_RADIOTAP)
-		goto out;
-
-	if (skb_headroom(skb) < sizeof(*rthdr)) {
-		I802_DEBUG_INC(local->rx_expand_skb_head);
-		if (pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) {
-			dev_kfree_skb(skb);
-			return;
-		}
-	}
-
-	rthdr = (struct ieee80211_rtap_hdr *) 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) |
-			    (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) |
-			    (1 << IEEE80211_RADIOTAP_RX_FLAGS));
-	rthdr->flags = local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS ?
-		       IEEE80211_RADIOTAP_F_FCS : 0;
-
-	/* FIXME: when radiotap gets a 'bad PLCP' flag use it here */
-	rthdr->rx_flags = 0;
-	if (status->flag &
-	    (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))
-		rthdr->rx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS);
-
-	rate = ieee80211_get_rate(local, status->phymode, status->rate);
-	if (rate)
-		rthdr->rate = rate->rate / 5;
-
-	rthdr->chan_freq = cpu_to_le16(status->freq);
-	rthdr->chan_flags =
-		status->phymode == MODE_IEEE80211A ?
-		cpu_to_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ) :
-		cpu_to_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ);
-	rthdr->antsignal = status->ssi;
-
- out:
-	dev->stats.rx_packets++;
-	dev->stats.rx_bytes += skb->len;
-
-	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);
-}
-
-static ieee80211_txrx_result
-ieee80211_rx_h_monitor(struct ieee80211_txrx_data *rx)
-{
-	if (rx->sdata->type == IEEE80211_IF_TYPE_MNTR) {
-		ieee80211_rx_monitor(rx->dev, rx->skb, rx->u.rx.status);
-		return TXRX_QUEUED;
-	}
-
-	/*
-	 * Drop frames with failed FCS/PLCP checksums here, they are only
-	 * relevant for monitor mode, the rest of the stack should never
-	 * see them.
-	 */
-	if (rx->u.rx.status->flag &
-	    (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))
-		return TXRX_DROP;
-
-	if (rx->u.rx.status->flag & RX_FLAG_RADIOTAP)
-		skb_pull(rx->skb, ieee80211_get_radiotap_len(rx->skb->data));
-
-	return TXRX_CONTINUE;
-}
-
 static ieee80211_txrx_result
 ieee80211_rx_h_passive_scan(struct ieee80211_txrx_data *rx)
 {
@@ -266,10 +373,6 @@ ieee80211_rx_h_check(struct ieee80211_tx
 			rx->sta->last_seq_ctrl[rx->u.rx.queue] = hdr->seq_ctrl;
 	}
 
-	if ((rx->local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) &&
-	    rx->skb->len > FCS_LEN)
-		skb_trim(rx->skb, rx->skb->len - FCS_LEN);
-
 	if (unlikely(rx->skb->len < 16)) {
 		I802_DEBUG_INC(rx->local->rx_handlers_drop_short);
 		return TXRX_DROP;
@@ -1264,7 +1367,6 @@ static void ieee80211_rx_michael_mic_rep
 ieee80211_rx_handler ieee80211_rx_handlers[] =
 {
 	ieee80211_rx_h_if_stats,
-	ieee80211_rx_h_monitor,
 	ieee80211_rx_h_passive_scan,
 	ieee80211_rx_h_check,
 	ieee80211_rx_h_load_key,
@@ -1371,16 +1473,10 @@ void __ieee80211_rx(struct ieee80211_hw 
 	struct ieee80211_hdr *hdr;
 	struct ieee80211_txrx_data rx;
 	u16 type;
-	int radiotap_len = 0, prepres;
+	int prepres;
 	struct ieee80211_sub_if_data *prev = NULL;
 	struct sk_buff *skb_new;
 	u8 *bssid;
-	int bogon;
-
-	if (status->flag & RX_FLAG_RADIOTAP) {
-		radiotap_len = ieee80211_get_radiotap_len(skb->data);
-		skb_pull(skb, radiotap_len);
-	}
 
 	/*
 	 * key references and virtual interfaces are protected using RCU
@@ -1389,30 +1485,35 @@ void __ieee80211_rx(struct ieee80211_hw 
 	 */
 	rcu_read_lock();
 
+	/*
+	 * Frames with failed FCS/PLCP checksum are not returned,
+	 * all other frames are returned without radiotap header
+	 * if it was previously present.
+	 * Also, frames with less than 16 bytes are dropped.
+	 */
+	skb = ieee80211_rx_monitor(local, skb, status);
+	if (!skb) {
+		rcu_read_unlock();
+		return;
+	}
+
 	hdr = (struct ieee80211_hdr *) skb->data;
 	memset(&rx, 0, sizeof(rx));
 	rx.skb = skb;
 	rx.local = local;
 
 	rx.u.rx.status = status;
-	rx.fc = skb->len >= 2 ? le16_to_cpu(hdr->frame_control) : 0;
+	rx.fc = le16_to_cpu(hdr->frame_control);
 	type = rx.fc & IEEE80211_FCTL_FTYPE;
 
-	bogon = status->flag & (RX_FLAG_FAILED_FCS_CRC |
-				RX_FLAG_FAILED_PLCP_CRC);
-
-	if (!bogon && (type == IEEE80211_FTYPE_DATA ||
-		       type == IEEE80211_FTYPE_MGMT))
+	if (type == IEEE80211_FTYPE_DATA || type == IEEE80211_FTYPE_MGMT)
 		local->dot11ReceivedFragmentCount++;
 
-	if (!bogon && skb->len >= 16) {
-		sta = rx.sta = sta_info_get(local, hdr->addr2);
-		if (sta) {
-			rx.dev = rx.sta->dev;
-			rx.sdata = IEEE80211_DEV_TO_SUB_IF(rx.dev);
-		}
-	} else
-		sta = rx.sta = NULL;
+	sta = rx.sta = sta_info_get(local, hdr->addr2);
+	if (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);
@@ -1427,7 +1528,6 @@ void __ieee80211_rx(struct ieee80211_hw 
 		goto end;
 	skb = rx.skb;
 
-	skb_push(skb, radiotap_len);
 	if (sta && !(sta->flags & (WLAN_STA_WDS | WLAN_STA_ASSOC_AP)) &&
 	    !local->iff_promiscs && !is_multicast_ether_addr(hdr->addr1)) {
 		rx.flags |= IEEE80211_TXRXD_RXRA_MATCH;
@@ -1438,14 +1538,16 @@ void __ieee80211_rx(struct ieee80211_hw 
 		return;
 	}
 
-	bssid = ieee80211_get_bssid(hdr, skb->len - radiotap_len);
+	bssid = ieee80211_get_bssid(hdr, skb->len);
 
 	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
-		rx.flags |= IEEE80211_TXRXD_RXRA_MATCH;
-
 		if (!netif_running(sdata->dev))
 			continue;
 
+		if (sdata->type == IEEE80211_IF_TYPE_MNTR)
+			continue;
+
+		rx.flags |= IEEE80211_TXRXD_RXRA_MATCH;
 		prepres = prepare_for_handlers(sdata, bssid, &rx, hdr);
 		/* prepare_for_handlers can change sta */
 		sta = rx.sta;
author maintainer
#2 lore raw

PATCH 2/12 mac80211: consolidate decryption

In reply to Johannes Berg

Currently, we run through all three crypto algorithms for each received frame even though we have previously determined which key we have and as such already know which algorithm will be used. Change it to invoke only the needed function. Also move the WEP decrypt handler to wep.c so that fewer functions need to be non-static.

---
 net/mac80211/rx.c  |   40 +++++++++++++++++-----------------------
 net/mac80211/wep.c |   34 +++++++++++++++++++++++++++++-----
 net/mac80211/wep.h |    8 +++-----
 net/mac80211/wpa.c |   12 ++++--------
 net/mac80211/wpa.h |    4 ++--
 5 files changed, 55 insertions(+), 43 deletions(-)
net/mac80211/rx.c +17 -23
@@ -662,36 +662,32 @@ ieee80211_rx_h_wep_weak_iv_detection(str
 }
 
 static ieee80211_txrx_result
-ieee80211_rx_h_wep_decrypt(struct ieee80211_txrx_data *rx)
+ieee80211_rx_h_decrypt(struct ieee80211_txrx_data *rx)
 {
-	if ((rx->key && rx->key->conf.alg != ALG_WEP) ||
-	    !(rx->fc & IEEE80211_FCTL_PROTECTED) ||
-	    ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
-	     ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
-	      (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)))
+	if (!(rx->fc & IEEE80211_FCTL_PROTECTED))
 		return TXRX_CONTINUE;
 
 	if (!rx->key) {
 		if (net_ratelimit())
-			printk(KERN_DEBUG "%s: RX WEP frame, but no key set\n",
-			       rx->dev->name);
+			printk(KERN_DEBUG "%s: RX protected frame,"
+			       " but have no key\n", rx->dev->name);
 		return TXRX_DROP;
 	}
 
-	if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) {
-		if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) {
-			if (net_ratelimit())
-				printk(KERN_DEBUG "%s: RX WEP frame, decrypt "
-				       "failed\n", rx->dev->name);
-			return TXRX_DROP;
-		}
-	} else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) {
-		ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
-		/* remove ICV */
-		skb_trim(rx->skb, rx->skb->len - 4);
+	switch (rx->key->conf.alg) {
+	case ALG_WEP:
+		return ieee80211_crypto_wep_decrypt(rx);
+	case ALG_TKIP:
+		return ieee80211_crypto_tkip_decrypt(rx);
+	case ALG_CCMP:
+		return ieee80211_crypto_ccmp_decrypt(rx);
+	case ALG_NONE:
+		return TXRX_CONTINUE;
 	}
 
-	return TXRX_CONTINUE;
+	/* not reached */
+	WARN_ON(1);
+	return TXRX_DROP;
 }
 
 static inline struct ieee80211_fragment_entry *
@@ -1371,10 +1367,8 @@ ieee80211_rx_handler ieee80211_rx_handle
 	ieee80211_rx_h_check,
 	ieee80211_rx_h_load_key,
 	ieee80211_rx_h_sta_process,
-	ieee80211_rx_h_ccmp_decrypt,
-	ieee80211_rx_h_tkip_decrypt,
 	ieee80211_rx_h_wep_weak_iv_detection,
-	ieee80211_rx_h_wep_decrypt,
+	ieee80211_rx_h_decrypt,
 	ieee80211_rx_h_defragment,
 	ieee80211_rx_h_ps_poll,
 	ieee80211_rx_h_michael_mic_verify,
net/mac80211/wpa.c +4 -8
@@ -281,7 +281,7 @@ ieee80211_tx_h_tkip_encrypt(struct ieee8
 
 
 ieee80211_txrx_result
-ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx)
+ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
 	u16 fc;
@@ -293,9 +293,7 @@ ieee80211_rx_h_tkip_decrypt(struct ieee8
 	fc = le16_to_cpu(hdr->frame_control);
 	hdrlen = ieee80211_get_hdrlen(fc);
 
-	if (!rx->key || rx->key->conf.alg != ALG_TKIP ||
-	    !(rx->fc & IEEE80211_FCTL_PROTECTED) ||
-	    (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
+	if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
 		return TXRX_CONTINUE;
 
 	if (!rx->sta || skb->len - hdrlen < 12)
@@ -535,7 +533,7 @@ ieee80211_tx_h_ccmp_encrypt(struct ieee8
 
 
 ieee80211_txrx_result
-ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
+ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
 	u16 fc;
@@ -549,9 +547,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee8
 	fc = le16_to_cpu(hdr->frame_control);
 	hdrlen = ieee80211_get_hdrlen(fc);
 
-	if (!key || key->conf.alg != ALG_CCMP ||
-	    !(rx->fc & IEEE80211_FCTL_PROTECTED) ||
-	    (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
+	if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
 		return TXRX_CONTINUE;
 
 	data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN;
net/mac80211/wpa.h +2 -2
@@ -21,11 +21,11 @@ ieee80211_rx_h_michael_mic_verify(struct
 ieee80211_txrx_result
 ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx);
 ieee80211_txrx_result
-ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx);
+ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx);
 
 ieee80211_txrx_result
 ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx);
 ieee80211_txrx_result
-ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx);
+ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx);
 
 #endif /* WPA_H */
net/mac80211/wep.c +29 -5
@@ -63,8 +63,8 @@ static inline int ieee80211_wep_weak_iv(
 }
 
 
-void ieee80211_wep_get_iv(struct ieee80211_local *local,
-			  struct ieee80211_key *key, u8 *iv)
+static void ieee80211_wep_get_iv(struct ieee80211_local *local,
+				 struct ieee80211_key *key, u8 *iv)
 {
 	local->wep_iv++;
 	if (ieee80211_wep_weak_iv(local->wep_iv, key->conf.keylen))
@@ -109,9 +109,9 @@ u8 * ieee80211_wep_add_iv(struct ieee802
 }
 
 
-void ieee80211_wep_remove_iv(struct ieee80211_local *local,
-			     struct sk_buff *skb,
-			     struct ieee80211_key *key)
+static void ieee80211_wep_remove_iv(struct ieee80211_local *local,
+				    struct sk_buff *skb,
+				    struct ieee80211_key *key)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	u16 fc;
@@ -326,3 +326,27 @@ u8 * ieee80211_wep_is_weak_iv(struct sk_
 
 	return NULL;
 }
+
+ieee80211_txrx_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;
+
+	if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) {
+		if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) {
+			if (net_ratelimit())
+				printk(KERN_DEBUG "%s: RX WEP frame, decrypt "
+				       "failed\n", rx->dev->name);
+			return TXRX_DROP;
+		}
+	} else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) {
+		ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
+		/* remove ICV */
+		skb_trim(rx->skb, rx->skb->len - 4);
+	}
+
+	return TXRX_CONTINUE;
+}
net/mac80211/wep.h +3 -5
@@ -18,14 +18,9 @@
 
 int ieee80211_wep_init(struct ieee80211_local *local);
 void ieee80211_wep_free(struct ieee80211_local *local);
-void ieee80211_wep_get_iv(struct ieee80211_local *local,
-			  struct ieee80211_key *key, u8 *iv);
 u8 * ieee80211_wep_add_iv(struct ieee80211_local *local,
 			  struct sk_buff *skb,
 			  struct ieee80211_key *key);
-void ieee80211_wep_remove_iv(struct ieee80211_local *local,
-			     struct sk_buff *skb,
-			     struct ieee80211_key *key);
 void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 				size_t klen, u8 *data, size_t data_len);
 int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
@@ -37,4 +32,7 @@ int ieee80211_wep_decrypt(struct ieee802
 int ieee80211_wep_get_keyidx(struct sk_buff *skb);
 u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);
 
+ieee80211_txrx_result
+ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx);
+
 #endif /* WEP_H */
author maintainer
#3 lore raw

PATCH 3/12 mac80211: consolidate encryption

In reply to Johannes Berg

Currently we run through all crypto handlers for each transmitted frame although we already know which one will be used. This changes the code to invoke only the needed handler. It also moves the wep code into wep.c.

---
 net/mac80211/tx.c  |   62 ++++++++++++-----------------------------------------
 net/mac80211/wep.c |   57 ++++++++++++++++++++++++++++++++++++++++++++++--
 net/mac80211/wep.h |    5 +---
 net/mac80211/wpa.c |   10 +++-----
 net/mac80211/wpa.h |    4 +--
 5 files changed, 77 insertions(+), 61 deletions(-)
net/mac80211/tx.c +15 -47
@@ -541,56 +541,26 @@ ieee80211_tx_h_fragment(struct ieee80211
 	return TXRX_DROP;
 }
 
-static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb)
-{
-	if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
-		if (ieee80211_wep_encrypt(tx->local, skb, tx->key))
-			return -1;
-	} else {
-		tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
-		if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) {
-			if (!ieee80211_wep_add_iv(tx->local, skb, tx->key))
-				return -1;
-		}
-	}
-	return 0;
-}
-
 static ieee80211_txrx_result
-ieee80211_tx_h_wep_encrypt(struct ieee80211_txrx_data *tx)
+ieee80211_tx_h_encrypt(struct ieee80211_txrx_data *tx)
 {
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
-	u16 fc;
-
-	fc = le16_to_cpu(hdr->frame_control);
-
-	if (!tx->key || tx->key->conf.alg != ALG_WEP ||
-	    ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
-	     ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
-	      (fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)))
+	if (!tx->key)
 		return TXRX_CONTINUE;
 
-	tx->u.tx.control->iv_len = WEP_IV_LEN;
-	tx->u.tx.control->icv_len = WEP_ICV_LEN;
-	ieee80211_tx_set_iswep(tx);
-
-	if (wep_encrypt_skb(tx, tx->skb) < 0) {
-		I802_DEBUG_INC(tx->local->tx_handlers_drop_wep);
-		return TXRX_DROP;
-	}
-
-	if (tx->u.tx.extra_frag) {
-		int i;
-		for (i = 0; i < tx->u.tx.num_extra_frag; i++) {
-			if (wep_encrypt_skb(tx, tx->u.tx.extra_frag[i]) < 0) {
-				I802_DEBUG_INC(tx->local->
-					       tx_handlers_drop_wep);
-				return TXRX_DROP;
-			}
-		}
+	switch (tx->key->conf.alg) {
+	case ALG_WEP:
+		return ieee80211_crypto_wep_encrypt(tx);
+	case ALG_TKIP:
+		return ieee80211_crypto_tkip_encrypt(tx);
+	case ALG_CCMP:
+		return ieee80211_crypto_ccmp_encrypt(tx);
+	case ALG_NONE:
+		return TXRX_CONTINUE;
 	}
 
-	return TXRX_CONTINUE;
+	/* not reached */
+	WARN_ON(1);
+	return TXRX_DROP;
 }
 
 static ieee80211_txrx_result
@@ -805,9 +775,7 @@ ieee80211_tx_handler ieee80211_tx_handle
 	ieee80211_tx_h_select_key,
 	ieee80211_tx_h_michael_mic_add,
 	ieee80211_tx_h_fragment,
-	ieee80211_tx_h_tkip_encrypt,
-	ieee80211_tx_h_ccmp_encrypt,
-	ieee80211_tx_h_wep_encrypt,
+	ieee80211_tx_h_encrypt,
 	ieee80211_tx_h_rate_ctrl,
 	ieee80211_tx_h_misc,
 	ieee80211_tx_h_load_stats,
net/mac80211/wpa.c +4 -6
@@ -239,17 +239,16 @@ static int tkip_encrypt_skb(struct ieee8
 
 
 ieee80211_txrx_result
-ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx)
+ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data *tx)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
 	u16 fc;
-	struct ieee80211_key *key = tx->key;
 	struct sk_buff *skb = tx->skb;
 	int wpa_test = 0, test = 0;
 
 	fc = le16_to_cpu(hdr->frame_control);
 
-	if (!key || key->conf.alg != ALG_TKIP || !WLAN_FC_DATA_PRESENT(fc))
+	if (!WLAN_FC_DATA_PRESENT(fc))
 		return TXRX_CONTINUE;
 
 	tx->u.tx.control->icv_len = TKIP_ICV_LEN;
@@ -491,17 +490,16 @@ static int ccmp_encrypt_skb(struct ieee8
 
 
 ieee80211_txrx_result
-ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx)
+ieee80211_crypto_ccmp_encrypt(struct ieee80211_txrx_data *tx)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
-	struct ieee80211_key *key = tx->key;
 	u16 fc;
 	struct sk_buff *skb = tx->skb;
 	int test = 0;
 
 	fc = le16_to_cpu(hdr->frame_control);
 
-	if (!key || key->conf.alg != ALG_CCMP || !WLAN_FC_DATA_PRESENT(fc))
+	if (!WLAN_FC_DATA_PRESENT(fc))
 		return TXRX_CONTINUE;
 
 	tx->u.tx.control->icv_len = CCMP_MIC_LEN;
net/mac80211/wpa.h +2 -2
@@ -19,12 +19,12 @@ ieee80211_txrx_result
 ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx);
 
 ieee80211_txrx_result
-ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx);
+ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data *tx);
 ieee80211_txrx_result
 ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx);
 
 ieee80211_txrx_result
-ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx);
+ieee80211_crypto_ccmp_encrypt(struct ieee80211_txrx_data *tx);
 ieee80211_txrx_result
 ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx);
 
net/mac80211/wep.c +54 -3

66 lines not on this page · raw message

net/mac80211/wep.h +2 -3
@@ -18,9 +18,6 @@
 
 int ieee80211_wep_init(struct ieee80211_local *local);
 void ieee80211_wep_free(struct ieee80211_local *local);
-u8 * ieee80211_wep_add_iv(struct ieee80211_local *local,
-			  struct sk_buff *skb,
-			  struct ieee80211_key *key);
 void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 				size_t klen, u8 *data, size_t data_len);
 int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
@@ -34,5 +31,7 @@ u8 * ieee80211_wep_is_weak_iv(struct sk_
 
 ieee80211_txrx_result
 ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx);
+ieee80211_txrx_result
+ieee80211_crypto_wep_encrypt(struct ieee80211_txrx_data *tx);
 
 #endif /* WEP_H */
author maintainer
#4 lore raw

PATCH 4/12 mac80211: remove ieee80211_wep_get_keyidx

In reply to Johannes Berg

This function is not used any more.

---
 net/mac80211/wep.c |   19 -------------------
 net/mac80211/wep.h |    1 -
 2 files changed, 20 deletions(-)
net/mac80211/wep.c +0 -19
@@ -286,25 +286,6 @@ int ieee80211_wep_decrypt(struct ieee802
 }
 
 
-int ieee80211_wep_get_keyidx(struct sk_buff *skb)
-{
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-	u16 fc;
-	int hdrlen;
-
-	fc = le16_to_cpu(hdr->frame_control);
-	if (!(fc & IEEE80211_FCTL_PROTECTED))
-		return -1;
-
-	hdrlen = ieee80211_get_hdrlen(fc);
-
-	if (skb->len < 8 + hdrlen)
-		return -1;
-
-	return skb->data[hdrlen + 3] >> 6;
-}
-
-
 u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
net/mac80211/wep.h +0 -1
@@ -26,7 +26,6 @@ int ieee80211_wep_encrypt(struct ieee802
 			  struct ieee80211_key *key);
 int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
 			  struct ieee80211_key *key);
-int ieee80211_wep_get_keyidx(struct sk_buff *skb);
 u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);
 
 ieee80211_txrx_result
author maintainer
#5 lore raw

PATCH 5/12 mac80211: fix vlan bug

In reply to Johannes Berg

VLAN interfaces have yet another bug: they aren't accounted for properly in the receive path in prepare_for_handlers(). I noticed this by code inspection, but it would be easy for the compiler to catch such things if we'd just use the proper enum where appropriate.

---
 net/mac80211/ieee80211.c       |    7 +++++++
 net/mac80211/ieee80211_i.h     |    2 +-
 net/mac80211/ieee80211_iface.c |    3 +++
 net/mac80211/rx.c              |    8 ++++++++
 4 files changed, 19 insertions(+), 1 deletion(-)
net/mac80211/ieee80211.c +7 -0
@@ -345,6 +345,13 @@ static int ieee80211_open(struct net_dev
 		if (!sdata->u.vlan.ap)
 			return -ENOLINK;
 		break;
+	case IEEE80211_IF_TYPE_AP:
+	case IEEE80211_IF_TYPE_MGMT:
+	case IEEE80211_IF_TYPE_STA:
+	case IEEE80211_IF_TYPE_MNTR:
+	case IEEE80211_IF_TYPE_IBSS:
+		/* no special treatment */
+		break;
 	}
 
 	if (local->open_count == 0) {
net/mac80211/ieee80211_i.h +1 -1
@@ -290,7 +290,7 @@ struct ieee80211_if_sta {
 #define IEEE80211_SDATA_SHORT_PREAMBLE	BIT(3)
 struct ieee80211_sub_if_data {
 	struct list_head list;
-	unsigned int type;
+	enum ieee80211_if_types type;
 
 	struct wireless_dev wdev;
 
net/mac80211/ieee80211_iface.c +3 -0
@@ -239,6 +239,9 @@ void ieee80211_if_reinit(struct net_devi
 	ieee80211_if_sdata_deinit(sdata);
 
 	switch (sdata->type) {
+	case IEEE80211_IF_TYPE_MGMT:
+		/* nothing to do */
+		break;
 	case IEEE80211_IF_TYPE_AP: {
 		/* Remove all virtual interfaces that use this BSS
 		 * as their sdata->bss */
net/mac80211/rx.c +8 -0
@@ -1425,6 +1425,7 @@ static int prepare_for_handlers(struct i
 			rx->sta = ieee80211_ibss_add_sta(sdata->dev, rx->skb,
 							 bssid, hdr->addr2);
 		break;
+	case IEEE80211_IF_TYPE_VLAN:
 	case IEEE80211_IF_TYPE_AP:
 		if (!bssid) {
 			if (compare_ether_addr(sdata->dev->dev_addr,
@@ -1449,6 +1450,13 @@ static int prepare_for_handlers(struct i
 		if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
 			return 0;
 		break;
+	case IEEE80211_IF_TYPE_MNTR:
+		/* take everything */
+		break;
+	case IEEE80211_IF_TYPE_MGMT:
+		/* should never get here */
+		WARN_ON(1);
+		break;
 	}
 
 	return 1;
author maintainer
#6 lore raw

PATCH 6/12 mac80211: fix sparse warning

In reply to Johannes Berg

wme.c triggers a sparse warning; it wasn't noticed before because until recently ARRAY_SIZE triggered a sparse error.

---
 net/mac80211/wme.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/mac80211/wme.c +1 -1
@@ -359,7 +359,7 @@ static int wme_qdiscop_init(struct Qdisc
 		skb_queue_head_init(&q->requeued[i]);
 		q->queues[i] = qdisc_create_dflt(qd->dev, &pfifo_qdisc_ops,
 						 qd->handle);
-		if (q->queues[i] == 0) {
+		if (!q->queues[i]) {
 			q->queues[i] = &noop_qdisc;
 			printk(KERN_ERR "%s child qdisc %i creation failed", dev->name, i);
 		}
author maintainer
#7 lore raw

PATCH 7/12 mac80211: fix TKIP IV update

In reply to Johannes Berg

The TKIP IV should be updated only after MMIC verification, this patch changes it to be at that spot.

---
 net/mac80211/ieee80211_i.h |    2 ++
 net/mac80211/tkip.c        |   16 ++++++++++------
 net/mac80211/tkip.h        |    3 ++-
 net/mac80211/wpa.c         |    8 +++++++-
 4 files changed, 21 insertions(+), 8 deletions(-)
net/mac80211/ieee80211_i.h +2 -0
@@ -153,6 +153,8 @@ struct ieee80211_txrx_data {
 			int sent_ps_buffered;
 			int queue;
 			int load;
+			u32 tkip_iv32;
+			u16 tkip_iv16;
 		} rx;
 	} u;
 };
net/mac80211/tkip.c +10 -6
@@ -238,7 +238,8 @@ void ieee80211_tkip_encrypt_data(struct 
 int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
 				struct ieee80211_key *key,
 				u8 *payload, size_t payload_len, u8 *ta,
-				int only_iv, int queue)
+				int only_iv, int queue,
+				u32 *out_iv32, u16 *out_iv16)
 {
 	u32 iv32;
 	u32 iv16;
@@ -332,11 +333,14 @@ int ieee80211_tkip_decrypt_data(struct c
 	res = ieee80211_wep_decrypt_data(tfm, rc4key, 16, pos, payload_len - 12);
  done:
 	if (res == TKIP_DECRYPT_OK) {
-		/* FIX: these should be updated only after Michael MIC has been
-		 * verified */
-		/* Record previously received IV */
-		key->u.tkip.iv32_rx[queue] = iv32;
-		key->u.tkip.iv16_rx[queue] = iv16;
+		/*
+		 * Record previously received IV, will be copied into the
+		 * key information after MIC verification. It is possible
+		 * that we don't catch replays of fragments but that's ok
+		 * because the Michael MIC verication will then fail.
+		 */
+		*out_iv32 = iv32;
+		*out_iv16 = iv16;
 	}
 
 	return res;
net/mac80211/tkip.h +2 -1
@@ -31,6 +31,7 @@ enum {
 int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
 				struct ieee80211_key *key,
 				u8 *payload, size_t payload_len, u8 *ta,
-				int only_iv, int queue);
+				int only_iv, int queue,
+				u32 *out_iv32, u16 *out_iv16);
 
 #endif /* TKIP_H */
net/mac80211/wpa.c +7 -1
@@ -175,6 +175,10 @@ ieee80211_rx_h_michael_mic_verify(struct
 	/* remove Michael MIC from payload */
 	skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
 
+	/* update IV in key information to be able to detect replays */
+	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;
 }
 
@@ -315,7 +319,9 @@ ieee80211_crypto_tkip_decrypt(struct iee
 	res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm,
 					  key, skb->data + hdrlen,
 					  skb->len - hdrlen, rx->sta->addr,
-					  hwaccel, rx->u.rx.queue);
+					  hwaccel, rx->u.rx.queue,
+					  &rx->u.rx.tkip_iv32,
+					  &rx->u.rx.tkip_iv16);
 	if (res != TKIP_DECRYPT_OK || wpa_test) {
 		printk(KERN_DEBUG "%s: TKIP decrypt failed for RX frame from "
 		       "%s (res=%d)\n",
author maintainer
#8 lore raw

PATCH 8/12 cfg80211: fix initialisation if built-in

In reply to Johannes Berg

When cfg80211 is built into the kernel it needs to init earlier so that device registrations are run after it has initialised.

---
 net/wireless/core.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/wireless/core.c +1 -1
@@ -360,7 +360,7 @@ out_fail_notifier:
 out_fail_sysfs:
 	return err;
 }
-module_init(cfg80211_init);
+subsys_initcall(cfg80211_init);
 
 static void cfg80211_exit(void)
 {
author maintainer
#9 lore raw

PATCH 9/12 mac80211: fix iff_promiscs, iff_allmultis race

In reply to Johannes Berg

When we update the counters iff_promiscs and iff_allmultis in struct ieee80211_local we have no common lock held to protect them. The problem is that the update to each counter may not be atomic, so we could end up with iff_promiscs == -1 in unfortunate conditions. To fix it, use atomic_t values. It doesn't matter whether the two counters are updated together atomically or not, if there are two invocations of set_multicast_list we will end up with multiple configure_filter() invocations of which the latter will always be correct.

---
 net/mac80211/ieee80211.c   |   12 ++++++------
 net/mac80211/ieee80211_i.h |    5 ++---
 net/mac80211/rx.c          |    3 ++-
 3 files changed, 10 insertions(+), 10 deletions(-)
net/mac80211/ieee80211.c +6 -6
@@ -59,10 +59,10 @@ static void ieee80211_configure_filter(s
 	unsigned int changed_flags;
 	unsigned int new_flags = 0;
 
-	if (local->iff_promiscs)
+	if (atomic_read(&local->iff_promiscs))
 		new_flags |= FIF_PROMISC_IN_BSS;
 
-	if (local->iff_allmultis)
+	if (atomic_read(&local->iff_allmultis))
 		new_flags |= FIF_ALLMULTI;
 
 	if (local->monitors)
@@ -522,17 +522,17 @@ static void ieee80211_set_multicast_list
 
 	if (allmulti != sdata_allmulti) {
 		if (dev->flags & IFF_ALLMULTI)
-			local->iff_allmultis++;
+			atomic_inc(&local->iff_allmultis);
 		else
-			local->iff_allmultis--;
+			atomic_dec(&local->iff_allmultis);
 		sdata->flags ^= IEEE80211_SDATA_ALLMULTI;
 	}
 
 	if (promisc != sdata_promisc) {
 		if (dev->flags & IFF_PROMISC)
-			local->iff_promiscs++;
+			atomic_inc(&local->iff_promiscs);
 		else
-			local->iff_promiscs--;
+			atomic_dec(&local->iff_promiscs);
 		sdata->flags ^= IEEE80211_SDATA_PROMISC;
 	}
 
net/mac80211/ieee80211_i.h +2 -3
@@ -444,9 +444,8 @@ struct ieee80211_local {
 	struct ieee80211_tx_stored_packet pending_packet[NUM_TX_DATA_QUEUES];
 	struct tasklet_struct tx_pending_tasklet;
 
-	int mc_count;	/* total count of multicast entries in all interfaces */
-	int iff_allmultis, iff_promiscs;
-			/* number of interfaces with corresponding IFF_ flags */
+	/* number of interfaces with corresponding IFF_ flags */
+	atomic_t iff_allmultis, iff_promiscs;
 
 	struct rate_control_ref *rate_ctrl;
 
net/mac80211/rx.c +2 -1
@@ -1531,7 +1531,8 @@ void __ieee80211_rx(struct ieee80211_hw 
 	skb = rx.skb;
 
 	if (sta && !(sta->flags & (WLAN_STA_WDS | WLAN_STA_ASSOC_AP)) &&
-	    !local->iff_promiscs && !is_multicast_ether_addr(hdr->addr1)) {
+	    !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);
author maintainer
#10 lore raw

PATCH 10/12 mac80211: remove all prism2 ioctls

In reply to Johannes Berg

This patch removes all prism2 ioctls.

---
I intend to maintain a quilt or git tree that has the necessary code to get hostapd working, but having this in wireless-2.6 at the same time is a bit icky since I will end up removing it piece by piece.

 net/mac80211/hostapd_ioctl.h   |   61 ---------
 net/mac80211/ieee80211_i.h     |    5 
 net/mac80211/ieee80211_ioctl.c |  272 -----------------------------------------
 net/mac80211/ieee80211_sta.c   |    1 
 4 files changed, 339 deletions(-)
net/mac80211/ieee80211_ioctl.c +0 -272
@@ -21,46 +21,11 @@
 
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
-#include "hostapd_ioctl.h"
 #include "ieee80211_rate.h"
 #include "wpa.h"
 #include "aes_ccm.h"
 
 
-/*
- * Wow. This ioctl interface is such crap, it's tied
- * to internal definitions. I hope it dies soon.
- */
-static int mode_to_hostapd_mode(enum ieee80211_phymode mode)
-{
-	switch (mode) {
-	case MODE_IEEE80211A:
-		return 0;
-	case MODE_IEEE80211B:
-		return 1;
-	case MODE_IEEE80211G:
-		return 3;
-	case NUM_IEEE80211_MODES:
-		WARN_ON(1);
-		break;
-	}
-	WARN_ON(1);
-	return -1;
-}
-
-static enum ieee80211_phymode hostapd_mode_to_mode(int hostapd_mode)
-{
-	switch (hostapd_mode) {
-	case 0:
-		return MODE_IEEE80211A;
-	case 1:
-		return MODE_IEEE80211B;
-	case 3:
-		return MODE_IEEE80211G;
-	}
-	return NUM_IEEE80211_MODES;
-}
-
 static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
 				    int idx, int alg, int set_tx_key,
 				    const u8 *_key, size_t key_len)
@@ -347,11 +312,6 @@ int ieee80211_set_channel(struct ieee802
 			struct ieee80211_channel *chan = &mode->channels[c];
 			if (chan->flag & IEEE80211_CHAN_W_SCAN &&
 			    ((chan->chan == channel) || (chan->freq == freq))) {
-				/* Use next_mode as the mode preference to
-				 * resolve non-unique channel numbers. */
-				if (set && mode->mode != local->next_mode)
-					continue;
-
 				local->oper_channel = chan;
 				local->oper_hw_mode = mode;
 				set++;
@@ -844,220 +804,6 @@ static int ieee80211_ioctl_giwretry(stru
 	return 0;
 }
 
-static int ieee80211_ioctl_prism2_param(struct net_device *dev,
-					struct iw_request_info *info,
-					void *wrqu, char *extra)
-{
-	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-	struct ieee80211_sub_if_data *sdata;
-	int *i = (int *) extra;
-	int param = *i;
-	int value = *(i + 1);
-	int ret = 0;
-	int mode;
-
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-
-	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	switch (param) {
-	case PRISM2_PARAM_IEEE_802_1X:
-		if (local->ops->set_ieee8021x)
-			ret = local->ops->set_ieee8021x(local_to_hw(local),
-							value);
-		if (ret)
-			printk(KERN_DEBUG "%s: failed to set IEEE 802.1X (%d) "
-			       "for low-level driver\n", dev->name, value);
-		else
-			sdata->ieee802_1x = value;
-		break;
-
-	case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES:
-		if (sdata->type == IEEE80211_IF_TYPE_AP) {
-			if (value)
-				sdata->flags |= IEEE80211_SDATA_USE_PROTECTION;
-			else
-				sdata->flags &= ~IEEE80211_SDATA_USE_PROTECTION;
-			ieee80211_erp_info_change_notify(dev,
-					IEEE80211_ERP_CHANGE_PROTECTION);
-		} else {
-			ret = -ENOENT;
-		}
-		break;
-
-	case PRISM2_PARAM_PREAMBLE:
-		if (sdata->type == IEEE80211_IF_TYPE_AP) {
-			if (value)
-				sdata->flags |= IEEE80211_SDATA_SHORT_PREAMBLE;
-			else
-				sdata->flags &= ~IEEE80211_SDATA_SHORT_PREAMBLE;
-			ieee80211_erp_info_change_notify(dev,
-					IEEE80211_ERP_CHANGE_PREAMBLE);
-		} else {
-			ret = -ENOENT;
-		}
-		break;
-
-	case PRISM2_PARAM_SHORT_SLOT_TIME:
-		if (value)
-			local->hw.conf.flags |= IEEE80211_CONF_SHORT_SLOT_TIME;
-		else
-			local->hw.conf.flags &= ~IEEE80211_CONF_SHORT_SLOT_TIME;
-		if (ieee80211_hw_config(local))
-			ret = -EINVAL;
-		break;
-
-	case PRISM2_PARAM_NEXT_MODE:
-		local->next_mode = hostapd_mode_to_mode(value);
-		break;
-
-	case PRISM2_PARAM_WIFI_WME_NOACK_TEST:
-		local->wifi_wme_noack_test = value;
-		break;
-
-	case PRISM2_PARAM_SCAN_FLAGS:
-		local->scan_flags = value;
-		break;
-
-	case PRISM2_PARAM_MIXED_CELL:
-		if (sdata->type != IEEE80211_IF_TYPE_STA &&
-		    sdata->type != IEEE80211_IF_TYPE_IBSS)
-			ret = -EINVAL;
-		else {
-			if (value)
-				sdata->u.sta.flags |= IEEE80211_STA_MIXED_CELL;
-			else
-				sdata->u.sta.flags &= ~IEEE80211_STA_MIXED_CELL;
-		}
-		break;
-
-	case PRISM2_PARAM_HW_MODES:
-		mode = 1;
-		local->enabled_modes = 0;
-		while (value) {
-			if (value & 1)
-				local->enabled_modes |=
-					hostapd_mode_to_mode(mode);
-			mode <<= 1;
-			value >>= 1;
-		}
-		break;
-
-	case PRISM2_PARAM_CREATE_IBSS:
-		if (sdata->type != IEEE80211_IF_TYPE_IBSS)
-			ret = -EINVAL;
-		else {
-			if (value)
-				sdata->u.sta.flags |= IEEE80211_STA_CREATE_IBSS;
-			else
-				sdata->u.sta.flags &= ~IEEE80211_STA_CREATE_IBSS;
-		}
-		break;
-	case PRISM2_PARAM_WMM_ENABLED:
-		if (sdata->type != IEEE80211_IF_TYPE_STA &&
-		    sdata->type != IEEE80211_IF_TYPE_IBSS)
-			ret = -EINVAL;
-		else {
-			if (value)
-				sdata->u.sta.flags |= IEEE80211_STA_WMM_ENABLED;
-			else
-				sdata->u.sta.flags &= ~IEEE80211_STA_WMM_ENABLED;
-		}
-		break;
-	default:
-		ret = -EOPNOTSUPP;
-		break;
-	}
-
-	return ret;
-}
-
-
-static int ieee80211_ioctl_get_prism2_param(struct net_device *dev,
-					    struct iw_request_info *info,
-					    void *wrqu, char *extra)
-{
-	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-	struct ieee80211_sub_if_data *sdata;
-	int *param = (int *) extra;
-	int ret = 0;
-	int mode;
-
-	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	switch (*param) {
-	case PRISM2_PARAM_IEEE_802_1X:
-		*param = sdata->ieee802_1x;
-		break;
-
-	case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES:
-		*param = !!(sdata->flags & IEEE80211_SDATA_USE_PROTECTION);
-		break;
-
-	case PRISM2_PARAM_PREAMBLE:
-		*param = !!(sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE);
-		break;
-
-	case PRISM2_PARAM_SHORT_SLOT_TIME:
-		*param = !!(local->hw.conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME);
-		break;
-
-	case PRISM2_PARAM_NEXT_MODE:
-		*param = local->next_mode;
-		break;
-
-	case PRISM2_PARAM_WIFI_WME_NOACK_TEST:
-		*param = local->wifi_wme_noack_test;
-		break;
-
-	case PRISM2_PARAM_SCAN_FLAGS:
-		*param = local->scan_flags;
-		break;
-
-	case PRISM2_PARAM_HW_MODES:
-		mode = 0;
-		*param = 0;
-		while (mode < NUM_IEEE80211_MODES) {
-			if (local->enabled_modes & (1<<mode))
-				*param |= mode_to_hostapd_mode(1<<mode);
-			mode++;
-		}
-		break;
-
-	case PRISM2_PARAM_CREATE_IBSS:
-		if (sdata->type != IEEE80211_IF_TYPE_IBSS)
-			ret = -EINVAL;
-		else
-			*param = !!(sdata->u.sta.flags &
-					IEEE80211_STA_CREATE_IBSS);
-		break;
-
-	case PRISM2_PARAM_MIXED_CELL:
-		if (sdata->type != IEEE80211_IF_TYPE_STA &&
-		    sdata->type != IEEE80211_IF_TYPE_IBSS)
-			ret = -EINVAL;
-		else
-			*param = !!(sdata->u.sta.flags &
-					IEEE80211_STA_MIXED_CELL);
-		break;
-
-	case PRISM2_PARAM_WMM_ENABLED:
-		if (sdata->type != IEEE80211_IF_TYPE_STA &&
-		    sdata->type != IEEE80211_IF_TYPE_IBSS)
-			ret = -EINVAL;
-		else
-			*param = !!(sdata->u.sta.flags &
-					IEEE80211_STA_WMM_ENABLED);
-		break;
-	default:
-		ret = -EOPNOTSUPP;
-		break;
-	}
-
-	return ret;
-}
-
 static int ieee80211_ioctl_siwmlme(struct net_device *dev,
 				   struct iw_request_info *info,
 				   struct iw_point *data, char *extra)
@@ -1313,14 +1059,6 @@ static int ieee80211_ioctl_siwencodeext(
 }
 
 
-static const struct iw_priv_args ieee80211_ioctl_priv[] = {
-	{ PRISM2_IOCTL_PRISM2_PARAM,
-	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "param" },
-	{ PRISM2_IOCTL_GET_PRISM2_PARAM,
-	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_param" },
-};
-
 /* Structures to export the Wireless Handlers */
 
 static const iw_handler ieee80211_handler[] =
@@ -1383,19 +1121,9 @@ static const iw_handler ieee80211_handle
 	(iw_handler) NULL,				/* -- hole -- */
 };
 
-static const iw_handler ieee80211_private_handler[] =
-{							/* SIOCIWFIRSTPRIV + */
-	(iw_handler) ieee80211_ioctl_prism2_param,	/* 0 */
-	(iw_handler) ieee80211_ioctl_get_prism2_param,	/* 1 */
-};
-
 const struct iw_handler_def ieee80211_iw_handler_def =
 {
 	.num_standard	= ARRAY_SIZE(ieee80211_handler),
-	.num_private	= ARRAY_SIZE(ieee80211_private_handler),
-	.num_private_args = ARRAY_SIZE(ieee80211_ioctl_priv),
 	.standard	= (iw_handler *) ieee80211_handler,
-	.private	= (iw_handler *) ieee80211_private_handler,
-	.private_args	= (struct iw_priv_args *) ieee80211_ioctl_priv,
 	.get_wireless_stats = ieee80211_get_wireless_stats,
 };
net/mac80211/hostapd_ioctl.h deleted +0 -61

61 lines not on this page · raw message

net/mac80211/ieee80211_i.h +0 -5
@@ -449,11 +449,6 @@ struct ieee80211_local {
 
 	struct rate_control_ref *rate_ctrl;
 
-	int next_mode; /* MODE_IEEE80211*
-			* The mode preference for next channel change. This is
-			* used to select .11g vs. .11b channels (or 4.9 GHz vs.
-			* .11a) when the channel number is not unique. */
-
 	/* Supported and basic rate filters for different modes. These are
 	 * pointers to -1 terminated lists and rates in 100 kbps units. */
 	int *supp_rates[NUM_IEEE80211_MODES];
net/mac80211/ieee80211_sta.c +0 -1
@@ -31,7 +31,6 @@
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
 #include "ieee80211_rate.h"
-#include "hostapd_ioctl.h"
 
 #define IEEE80211_AUTH_TIMEOUT (HZ / 5)
 #define IEEE80211_AUTH_MAX_TRIES 3
author maintainer
#11 lore raw

PATCH 11/12 mac80211: remove management interface

In reply to Johannes Berg

Similar to the previous patch

---
 include/net/mac80211.h          |    1 
 net/mac80211/ieee80211.c        |  182 ----------------------------------------
 net/mac80211/ieee80211_common.h |   91 --------------------
 net/mac80211/ieee80211_i.h      |    9 -
 net/mac80211/ieee80211_iface.c  |   66 --------------
 net/mac80211/ieee80211_rate.c   |    3 
 net/mac80211/ieee80211_rate.h   |    2 
 net/mac80211/ieee80211_sta.c    |    2 
 net/mac80211/rx.c               |   35 +------
 net/mac80211/tx.c               |   14 ---
 net/mac80211/wme.c              |   10 --
 11 files changed, 14 insertions(+), 401 deletions(-)
include/net/mac80211.h +0 -1
@@ -469,7 +469,6 @@ struct ieee80211_conf {
  */
 enum ieee80211_if_types {
 	IEEE80211_IF_TYPE_AP,
-	IEEE80211_IF_TYPE_MGMT,
 	IEEE80211_IF_TYPE_STA,
 	IEEE80211_IF_TYPE_IBSS,
 	IEEE80211_IF_TYPE_MNTR,
net/mac80211/ieee80211.c +1 -181

245 lines not on this page · raw message

net/mac80211/ieee80211_common.h deleted +0 -91

91 lines not on this page · raw message

net/mac80211/ieee80211_i.h +0 -9
@@ -141,7 +141,6 @@ struct ieee80211_txrx_data {
 			 * when using CTS protection with IEEE 802.11g. */
 			struct ieee80211_rate *last_frag_rate;
 			int last_frag_hwrate;
-			int mgmt_interface;
 
 			/* Extra fragments (in addition to the first fragment
 			 * in skb) */
@@ -163,7 +162,6 @@ struct ieee80211_txrx_data {
 #define IEEE80211_TXPD_REQ_TX_STATUS	BIT(0)
 #define IEEE80211_TXPD_DO_NOT_ENCRYPT	BIT(1)
 #define IEEE80211_TXPD_REQUEUE		BIT(2)
-#define IEEE80211_TXPD_MGMT_IFACE	BIT(3)
 /* Stored in sk_buff->cb */
 struct ieee80211_tx_packet_data {
 	int ifindex;
@@ -410,7 +408,6 @@ struct ieee80211_local {
 	struct list_head modes_list;
 
 	struct net_device *mdev; /* wmaster# - "master" 802.11 device */
-	struct net_device *apdev; /* wlan#ap - management frames (hostapd) */
 	int open_count;
 	int monitors;
 	unsigned int filter_flags; /* FIF_* */
@@ -706,14 +703,11 @@ static inline int ieee80211_bssid_match(
 int ieee80211_hw_config(struct ieee80211_local *local);
 int ieee80211_if_config(struct net_device *dev);
 int ieee80211_if_config_beacon(struct net_device *dev);
-void ieee80211_rx_mgmt(struct ieee80211_local *local, struct sk_buff *skb,
-		       struct ieee80211_rx_status *status, u32 msg_type);
 void ieee80211_prepare_rates(struct ieee80211_local *local,
 			     struct ieee80211_hw_mode *mode);
 void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx);
 int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr);
 void ieee80211_if_setup(struct net_device *dev);
-void ieee80211_if_mgmt_setup(struct net_device *dev);
 struct ieee80211_rate *ieee80211_get_rate(struct ieee80211_local *local,
 					  int phymode, int hwrate);
 
@@ -780,8 +774,6 @@ void __ieee80211_if_del(struct ieee80211
 int ieee80211_if_remove(struct net_device *dev, const char *name, int id);
 void ieee80211_if_free(struct net_device *dev);
 void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata);
-int ieee80211_if_add_mgmt(struct ieee80211_local *local);
-void ieee80211_if_del_mgmt(struct ieee80211_local *local);
 
 /* regdomain.c */
 void ieee80211_regdomain_init(void);
@@ -798,7 +790,6 @@ void ieee80211_tx_pending(unsigned long 
 int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev);
 int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);
 int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
-int ieee80211_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev);
 
 /* utility functions/constants */
 extern void *mac80211_wiphy_privid; /* for wiphy privid */
net/mac80211/ieee80211_iface.c +0 -66

86 lines not on this page · raw message

net/mac80211/tx.c +3 -11
@@ -258,7 +258,7 @@ ieee80211_tx_h_check_assoc(struct ieee80
 		return TXRX_CONTINUE;
 	}
 
-	if (unlikely(!tx->u.tx.mgmt_interface && tx->sdata->ieee802_1x &&
+	if (unlikely(/* !injected && */ tx->sdata->ieee802_1x &&
 		     !(sta_flags & WLAN_STA_AUTHORIZED))) {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
 		DECLARE_MAC_BUF(mac);
@@ -570,8 +570,6 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
 
 	memset(&extra, 0, sizeof(extra));
 	extra.mode = tx->u.tx.mode;
-	extra.mgmt_data = tx->sdata &&
-		tx->sdata->type == IEEE80211_IF_TYPE_MGMT;
 	extra.ethertype = tx->ethertype;
 
 	tx->u.tx.rate = rate_control_get_rate(tx->local, tx->dev, tx->skb,
@@ -1069,7 +1067,7 @@ static int __ieee80211_tx(struct ieee802
 }
 
 static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
-			struct ieee80211_tx_control *control, int mgmt)
+			struct ieee80211_tx_control *control)
 {
 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sta_info *sta;
@@ -1099,7 +1097,6 @@ static int ieee80211_tx(struct net_devic
 	rcu_read_lock();
 
 	sta = tx.sta;
-	tx.u.tx.mgmt_interface = mgmt;
 	tx.u.tx.mode = local->hw.conf.mode;
 
 	if (res_prepare == TXRX_QUEUED) { /* if it was an injected packet */
@@ -1250,8 +1247,7 @@ int ieee80211_master_start_xmit(struct s
 		control.flags |= IEEE80211_TXCTL_REQUEUE;
 	control.queue = pkt_data->queue;
 
-	ret = ieee80211_tx(odev, skb, &control,
-			   control.type == IEEE80211_IF_TYPE_MGMT);
+	ret = ieee80211_tx(odev, skb, &control);
 	dev_put(odev);
 
 	return ret;
@@ -1496,8 +1492,6 @@ int ieee80211_subif_start_xmit(struct sk
 	pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
 	memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
 	pkt_data->ifindex = dev->ifindex;
-	if (sdata->type == IEEE80211_IF_TYPE_MGMT)
-		pkt_data->flags |= IEEE80211_TXPD_MGMT_IFACE;
 
 	skb->dev = local->mdev;
 	dev->stats.tx_packets++;
@@ -1555,8 +1549,6 @@ int ieee80211_mgmt_start_xmit(struct sk_
 	pkt_data = (struct ieee80211_tx_packet_data *) skb->cb;
 	memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
 	pkt_data->ifindex = sdata->dev->ifindex;
-	if (sdata->type == IEEE80211_IF_TYPE_MGMT)
-		pkt_data->flags |= IEEE80211_TXPD_MGMT_IFACE;
 
 	skb->priority = 20; /* use hardcoded priority for mgmt TX queue */
 	skb->dev = sdata->local->mdev;
net/mac80211/ieee80211_rate.c +1 -2
@@ -145,8 +145,7 @@ int ieee80211_init_rate_ctrl_alg(struct 
 	struct rate_control_ref *ref, *old;
 
 	ASSERT_RTNL();
-	if (local->open_count || netif_running(local->mdev) ||
-	    (local->apdev && netif_running(local->apdev)))
+	if (local->open_count || netif_running(local->mdev))
 		return -EBUSY;
 
 	ref = rate_control_alloc(name, local);
net/mac80211/ieee80211_sta.c +0 -2
@@ -473,8 +473,6 @@ static void ieee80211_sta_tx(struct net_
 	pkt_data = (struct ieee80211_tx_packet_data *) skb->cb;
 	memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
 	pkt_data->ifindex = sdata->dev->ifindex;
-	if (sdata->type == IEEE80211_IF_TYPE_MGMT)
-		pkt_data->flags |= IEEE80211_TXPD_MGMT_IFACE;
 	if (!encrypt)
 		pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT;
 
net/mac80211/rx.c +7 -28
@@ -19,7 +19,6 @@
 
 #include "ieee80211_i.h"
 #include "ieee80211_led.h"
-#include "ieee80211_common.h"
 #include "wep.h"
 #include "wpa.h"
 #include "tkip.h"
@@ -412,12 +411,7 @@ ieee80211_rx_h_check(struct ieee80211_tx
 			return TXRX_DROP;
 		}
 
-		if (!rx->local->apdev)
-			return TXRX_DROP;
-
-		ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status,
-				  ieee80211_msg_sta_not_assoc);
-		return TXRX_QUEUED;
+		return TXRX_DROP;
 	}
 
 	return TXRX_CONTINUE;
@@ -983,15 +977,8 @@ ieee80211_rx_h_802_1x_pae(struct ieee802
 {
 	if (rx->sdata->eapol && ieee80211_is_eapol(rx->skb) &&
 	    rx->sdata->type != IEEE80211_IF_TYPE_STA &&
-	    (rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) {
-		/* Pass both encrypted and unencrypted EAPOL frames to user
-		 * space for processing. */
-		if (!rx->local->apdev)
-			return TXRX_DROP;
-		ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status,
-				  ieee80211_msg_normal);
-		return TXRX_QUEUED;
-	}
+	    (rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
+		return TXRX_CONTINUE;
 
 	if (unlikely(rx->sdata->ieee802_1x &&
 		     (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
@@ -1233,15 +1220,11 @@ ieee80211_rx_h_mgmt(struct ieee80211_txr
 	sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
 	if ((sdata->type == IEEE80211_IF_TYPE_STA ||
 	     sdata->type == IEEE80211_IF_TYPE_IBSS) &&
-	    !rx->local->user_space_mlme) {
+	    !rx->local->user_space_mlme)
 		ieee80211_sta_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status);
-	} else {
-		/* Management frames are sent to hostapd for processing */
-		if (!rx->local->apdev)
-			return TXRX_DROP;
-		ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status,
-				  ieee80211_msg_normal);
-	}
+	else
+		return TXRX_DROP;
+
 	return TXRX_QUEUED;
 }
 
@@ -1453,10 +1436,6 @@ static int prepare_for_handlers(struct i
 	case IEEE80211_IF_TYPE_MNTR:
 		/* take everything */
 		break;
-	case IEEE80211_IF_TYPE_MGMT:
-		/* should never get here */
-		WARN_ON(1);
-		break;
 	}
 
 	return 1;
net/mac80211/ieee80211_rate.h +0 -2
@@ -30,8 +30,6 @@ struct rate_control_extra {
 
 	/* parameters from the caller to rate_control_get_rate(): */
 	struct ieee80211_hw_mode *mode;
-	int mgmt_data; /* this is data frame that is used for management
-			* (e.g., IEEE 802.1X EAPOL) */
 	u16 ethertype;
 };
 
net/mac80211/wme.c +2 -8
@@ -94,8 +94,6 @@ static inline int wme_downgrade_ac(struc
 static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd)
 {
 	struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
-	struct ieee80211_tx_packet_data *pkt_data =
-		(struct ieee80211_tx_packet_data *) skb->cb;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	unsigned short fc = le16_to_cpu(hdr->frame_control);
 	int qos;
@@ -108,12 +106,8 @@ static inline int classify80211(struct s
 		return IEEE80211_TX_QUEUE_DATA0;
 	}
 
-	if (unlikely(pkt_data->flags & IEEE80211_TXPD_MGMT_IFACE)) {
-		/* Data frames from hostapd (mainly, EAPOL) use AC_VO
-		* and they will include QoS control fields if
-		* the target STA is using WME. */
-		skb->priority = 7;
-		return ieee802_1d_to_ac[skb->priority];
+	if (0 /* injected */) {
+		/* use AC from radiotap */
 	}
 
 	/* is this a QoS frame? */
#12 lore raw

Re: [patch 11/12] mac80211: remove management interface

Please fixup this patch for at least the drivers already merged to net-2.6.24. Also, don't forget the Signed-off-by:...

Thanks,

John

Quoted 15 lines · Johannes Berg

Similar to the previous patch

---
 include/net/mac80211.h          |    1 
 net/mac80211/ieee80211.c        |  182 ----------------------------------------
 net/mac80211/ieee80211_common.h |   91 --------------------
 net/mac80211/ieee80211_i.h      |    9 -
 net/mac80211/ieee80211_iface.c  |   66 --------------
 net/mac80211/ieee80211_rate.c   |    3 
 net/mac80211/ieee80211_rate.h   |    2 
 net/mac80211/ieee80211_sta.c    |    2 
 net/mac80211/rx.c               |   35 +------
 net/mac80211/tx.c               |   14 ---
 net/mac80211/wme.c              |   10 --
 11 files changed, 14 insertions(+), 401 deletions(-)
Signature · 2 lines
John W. Linville
[email protected]
author maintainer
#13 lore raw

Re: [patch 11/12] mac80211: remove management interface

Quoted 2 lines · John W. Linville

Please fixup this patch for at least the drivers already merged to net-2.6.24. Also, don't forget the Signed-off-by:...

Oops, sorry.

johannes

author maintainer
#14 lore raw

PATCH 1/1 mac80211: add "invalid" interface type

Since I cannot convince the lazy driver authors (hello Michael) to stop (ab)using the MGMT interface type internally in their drivers, this patch introduces a new _INVALID type especially for their use and changes all affected drivers to use it.

---
 drivers/net/wireless/adm8211.c                  |    8 ++++----
 drivers/net/wireless/p54common.c                |    4 ++--
 drivers/net/wireless/p54pci.c                   |    4 ++--
 drivers/net/wireless/rt2x00/rt2x00.h            |    2 +-
 drivers/net/wireless/zd1211rw-mac80211/zd_mac.c |    8 ++++----
 include/net/mac80211.h                          |    3 +++
 net/mac80211/ieee80211.c                        |    4 ++++
 net/mac80211/ieee80211_iface.c                  |    4 ++++
 net/mac80211/rx.c                               |    1 +
 9 files changed, 25 insertions(+), 13 deletions(-)
include/net/mac80211.h +3 -0
@@ -457,6 +457,8 @@ struct ieee80211_conf {
 /**
  * enum ieee80211_if_types - types of 802.11 network interfaces
  *
+ * @IEEE80211_IF_TYPE_INVALID: invalid interface type, not used
+ *	by mac80211 itself
  * @IEEE80211_IF_TYPE_AP: interface in AP mode.
  * @IEEE80211_IF_TYPE_MGMT: special interface for communication with hostap
  *	daemon. Drivers should never see this type.
@@ -468,6 +470,7 @@ struct ieee80211_conf {
  *	will never see this type.
  */
 enum ieee80211_if_types {
+	IEEE80211_IF_TYPE_INVALID,
 	IEEE80211_IF_TYPE_AP,
 	IEEE80211_IF_TYPE_MGMT,
 	IEEE80211_IF_TYPE_STA,
drivers/net/wireless/adm8211.c +4 -4
@@ -1555,7 +1555,7 @@ static void adm8211_stop(struct ieee8021
 {
 	struct adm8211_priv *priv = dev->priv;
 
-	priv->mode = IEEE80211_IF_TYPE_MGMT;
+	priv->mode = IEEE80211_IF_TYPE_INVALID;
 	priv->nar = 0;
 	ADM8211_CSR_WRITE(NAR, 0);
 	ADM8211_CSR_WRITE(IER, 0);
@@ -1897,7 +1897,7 @@ static int __devinit adm8211_probe(struc
 	priv->tx_power = 0x40;
 	priv->lpf_cutoff = 0xFF;
 	priv->lnags_threshold = 0xFF;
-	priv->mode = IEEE80211_IF_TYPE_MGMT;
+	priv->mode = IEEE80211_IF_TYPE_INVALID;
 
 	/* Power-on issue. EEPROM won't read correctly without */
 	if (pdev->revision >= ADM8211_REV_BA) {
@@ -1992,7 +1992,7 @@ static int adm8211_suspend(struct pci_de
 	struct ieee80211_hw *dev = pci_get_drvdata(pdev);
 	struct adm8211_priv *priv = dev->priv;
 
-	if (priv->mode != IEEE80211_IF_TYPE_MGMT) {
+	if (priv->mode != IEEE80211_IF_TYPE_INVALID) {
 		ieee80211_stop_queues(dev);
 		adm8211_stop(dev);
 	}
@@ -2010,7 +2010,7 @@ static int adm8211_resume(struct pci_dev
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 
-	if (priv->mode != IEEE80211_IF_TYPE_MGMT) {
+	if (priv->mode != IEEE80211_IF_TYPE_INVALID) {
 		adm8211_start(dev);
 		ieee80211_start_queues(dev);
 	}
drivers/net/wireless/p54common.c +2 -2
@@ -797,7 +797,7 @@ static void p54_stop(struct ieee80211_hw
 		kfree_skb(skb);
 	}
 	priv->stop(dev);
-	priv->mode = IEEE80211_IF_TYPE_MGMT;
+	priv->mode = IEEE80211_IF_TYPE_INVALID;
 }
 
 static int p54_add_interface(struct ieee80211_hw *dev,
@@ -949,7 +949,7 @@ struct ieee80211_hw *p54_init_common(siz
 		return NULL;
 
 	priv = dev->priv;
-	priv->mode = IEEE80211_IF_TYPE_MGMT;
+	priv->mode = IEEE80211_IF_TYPE_INVALID;
 	skb_queue_head_init(&priv->tx_queue);
 	memcpy(priv->channels, p54_channels, sizeof(p54_channels));
 	memcpy(priv->rates, p54_rates, sizeof(p54_rates));
drivers/net/wireless/p54pci.c +2 -2
@@ -638,7 +638,7 @@ static int p54p_suspend(struct pci_dev *
 	struct ieee80211_hw *dev = pci_get_drvdata(pdev);
 	struct p54p_priv *priv = dev->priv;
 
-	if (priv->common.mode != IEEE80211_IF_TYPE_MGMT) {
+	if (priv->common.mode != IEEE80211_IF_TYPE_INVALID) {
 		ieee80211_stop_queues(dev);
 		p54p_stop(dev);
 	}
@@ -656,7 +656,7 @@ static int p54p_resume(struct pci_dev *p
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 
-	if (priv->common.mode != IEEE80211_IF_TYPE_MGMT) {
+	if (priv->common.mode != IEEE80211_IF_TYPE_INVALID) {
 		p54p_open(dev);
 		ieee80211_start_queues(dev);
 	}
drivers/net/wireless/rt2x00/rt2x00.h +1 -1
@@ -297,7 +297,7 @@ struct interface {
 	 * When set to INVALID_INTERFACE, no interface is configured.
 	 */
 	int type;
-#define INVALID_INTERFACE	IEEE80211_IF_TYPE_MGMT
+#define INVALID_INTERFACE	IEEE80211_IF_TYPE_INVALID
 
 	/*
 	 * MAC of the device.
drivers/net/wireless/zd1211rw-mac80211/zd_mac.c +4 -4
@@ -710,8 +710,8 @@ static int zd_op_add_interface(struct ie
 {
 	struct zd_mac *mac = zd_hw_mac(hw);
 
-	/* NOTE: using IEEE80211_IF_TYPE_MGMT to indicate no mode selected */
-	if (mac->type != IEEE80211_IF_TYPE_MGMT)
+	/* using IEEE80211_IF_TYPE_INVALID to indicate no mode selected */
+	if (mac->type != IEEE80211_IF_TYPE_INVALID)
 		return -1;
 
 	switch (conf->type) {
@@ -732,7 +732,7 @@ static void zd_op_remove_interface(struc
 				    struct ieee80211_if_init_conf *conf)
 {
 	struct zd_mac *mac = zd_hw_mac(hw);
-	mac->type = IEEE80211_IF_TYPE_MGMT;
+	mac->type = IEEE80211_IF_TYPE_INVALID;
 }
 
 static int zd_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
@@ -864,7 +864,7 @@ struct ieee80211_hw *zd_mac_alloc_hw(str
 	spin_lock_init(&mac->lock);
 	mac->hw = hw;
 
-	mac->type = IEEE80211_IF_TYPE_MGMT;
+	mac->type = IEEE80211_IF_TYPE_INVALID;
 	mac->hwaddr = hw->wiphy->perm_addr;
 
 	memcpy(mac->channels, zd_channels, sizeof(zd_channels));
net/mac80211/ieee80211.c +4 -0
@@ -351,6 +351,10 @@ static int ieee80211_open(struct net_dev
 	case IEEE80211_IF_TYPE_IBSS:
 		/* no special treatment */
 		break;
+	case IEEE80211_IF_TYPE_INVALID:
+		/* cannot happen */
+		WARN_ON(1);
+		break;
 	}
 
 	if (local->open_count == 0) {
net/mac80211/ieee80211_iface.c +4 -0
@@ -243,6 +243,10 @@ void ieee80211_if_reinit(struct net_devi
 	ieee80211_if_sdata_deinit(sdata);
 
 	switch (sdata->type) {
+	case IEEE80211_IF_TYPE_INVALID:
+		/* cannot happen */
+		WARN_ON(1);
+		break;
 	case IEEE80211_IF_TYPE_MGMT:
 		/* nothing to do */
 		break;
net/mac80211/rx.c +1 -0
@@ -1444,6 +1444,7 @@ static int prepare_for_handlers(struct i
 	case IEEE80211_IF_TYPE_MNTR:
 		/* take everything */
 		break;
+	case IEEE80211_IF_TYPE_INVALID:
 	case IEEE80211_IF_TYPE_MGMT:
 		/* should never get here */
 		WARN_ON(1);
author maintainer
#15 lore raw

PATCH 1/1 mac80211: remove management interface

In reply to Johannes Berg

Removes the management interface since it is only required for hostapd/userspace MLME, will not be in the final tree at least in this form and hostapd/userspace MLME currently do not work against this tree anyway.

---
 include/net/mac80211.h         |    1 
 net/mac80211/ieee80211.c       |  182 -----------------------------------------
 net/mac80211/ieee80211_i.h     |    9 --
 net/mac80211/ieee80211_iface.c |   66 --------------
 net/mac80211/ieee80211_rate.c  |    3 
 net/mac80211/ieee80211_rate.h  |    2 
 net/mac80211/ieee80211_sta.c   |    2 
 net/mac80211/rx.c              |   32 +------
 net/mac80211/tx.c              |   14 ---
 net/mac80211/wme.c             |   10 --
 10 files changed, 14 insertions(+), 307 deletions(-)
include/net/mac80211.h +0 -1
@@ -472,7 +472,6 @@ struct ieee80211_conf {
 enum ieee80211_if_types {
 	IEEE80211_IF_TYPE_INVALID,
 	IEEE80211_IF_TYPE_AP,
-	IEEE80211_IF_TYPE_MGMT,
 	IEEE80211_IF_TYPE_STA,
 	IEEE80211_IF_TYPE_IBSS,
 	IEEE80211_IF_TYPE_MNTR,
net/mac80211/ieee80211.c +1 -181

245 lines not on this page · raw message

net/mac80211/ieee80211_i.h +0 -9
@@ -141,7 +141,6 @@ struct ieee80211_txrx_data {
 			 * when using CTS protection with IEEE 802.11g. */
 			struct ieee80211_rate *last_frag_rate;
 			int last_frag_hwrate;
-			int mgmt_interface;
 
 			/* Extra fragments (in addition to the first fragment
 			 * in skb) */
@@ -163,7 +162,6 @@ struct ieee80211_txrx_data {
 #define IEEE80211_TXPD_REQ_TX_STATUS	BIT(0)
 #define IEEE80211_TXPD_DO_NOT_ENCRYPT	BIT(1)
 #define IEEE80211_TXPD_REQUEUE		BIT(2)
-#define IEEE80211_TXPD_MGMT_IFACE	BIT(3)
 /* Stored in sk_buff->cb */
 struct ieee80211_tx_packet_data {
 	int ifindex;
@@ -408,7 +406,6 @@ struct ieee80211_local {
 	struct list_head modes_list;
 
 	struct net_device *mdev; /* wmaster# - "master" 802.11 device */
-	struct net_device *apdev; /* wlan#ap - management frames (hostapd) */
 	int open_count;
 	int monitors;
 	unsigned int filter_flags; /* FIF_* */
@@ -704,14 +701,11 @@ static inline int ieee80211_bssid_match(
 int ieee80211_hw_config(struct ieee80211_local *local);
 int ieee80211_if_config(struct net_device *dev);
 int ieee80211_if_config_beacon(struct net_device *dev);
-void ieee80211_rx_mgmt(struct ieee80211_local *local, struct sk_buff *skb,
-		       struct ieee80211_rx_status *status, u32 msg_type);
 void ieee80211_prepare_rates(struct ieee80211_local *local,
 			     struct ieee80211_hw_mode *mode);
 void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx);
 int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr);
 void ieee80211_if_setup(struct net_device *dev);
-void ieee80211_if_mgmt_setup(struct net_device *dev);
 struct ieee80211_rate *ieee80211_get_rate(struct ieee80211_local *local,
 					  int phymode, int hwrate);
 
@@ -778,8 +772,6 @@ void __ieee80211_if_del(struct ieee80211
 int ieee80211_if_remove(struct net_device *dev, const char *name, int id);
 void ieee80211_if_free(struct net_device *dev);
 void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata);
-int ieee80211_if_add_mgmt(struct ieee80211_local *local);
-void ieee80211_if_del_mgmt(struct ieee80211_local *local);
 
 /* regdomain.c */
 void ieee80211_regdomain_init(void);
@@ -796,7 +788,6 @@ void ieee80211_tx_pending(unsigned long 
 int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev);
 int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);
 int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
-int ieee80211_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev);
 
 /* utility functions/constants */
 extern void *mac80211_wiphy_privid; /* for wiphy privid */
net/mac80211/ieee80211_iface.c +0 -66

86 lines not on this page · raw message

net/mac80211/tx.c +3 -11
@@ -255,7 +255,7 @@ ieee80211_tx_h_check_assoc(struct ieee80
 		return TXRX_CONTINUE;
 	}
 
-	if (unlikely(!tx->u.tx.mgmt_interface && tx->sdata->ieee802_1x &&
+	if (unlikely(/* !injected && */ tx->sdata->ieee802_1x &&
 		     !(sta_flags & WLAN_STA_AUTHORIZED))) {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
 		printk(KERN_DEBUG "%s: dropped frame to " MAC_FMT
@@ -565,8 +565,6 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
 
 	memset(&extra, 0, sizeof(extra));
 	extra.mode = tx->u.tx.mode;
-	extra.mgmt_data = tx->sdata &&
-		tx->sdata->type == IEEE80211_IF_TYPE_MGMT;
 	extra.ethertype = tx->ethertype;
 
 	tx->u.tx.rate = rate_control_get_rate(tx->local, tx->dev, tx->skb,
@@ -1064,7 +1062,7 @@ static int __ieee80211_tx(struct ieee802
 }
 
 static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
-			struct ieee80211_tx_control *control, int mgmt)
+			struct ieee80211_tx_control *control)
 {
 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sta_info *sta;
@@ -1094,7 +1092,6 @@ static int ieee80211_tx(struct net_devic
 	rcu_read_lock();
 
 	sta = tx.sta;
-	tx.u.tx.mgmt_interface = mgmt;
 	tx.u.tx.mode = local->hw.conf.mode;
 
 	if (res_prepare == TXRX_QUEUED) { /* if it was an injected packet */
@@ -1245,8 +1242,7 @@ int ieee80211_master_start_xmit(struct s
 		control.flags |= IEEE80211_TXCTL_REQUEUE;
 	control.queue = pkt_data->queue;
 
-	ret = ieee80211_tx(odev, skb, &control,
-			   control.type == IEEE80211_IF_TYPE_MGMT);
+	ret = ieee80211_tx(odev, skb, &control);
 	dev_put(odev);
 
 	return ret;
@@ -1491,8 +1487,6 @@ int ieee80211_subif_start_xmit(struct sk
 	pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
 	memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
 	pkt_data->ifindex = dev->ifindex;
-	if (sdata->type == IEEE80211_IF_TYPE_MGMT)
-		pkt_data->flags |= IEEE80211_TXPD_MGMT_IFACE;
 
 	skb->dev = local->mdev;
 	dev->stats.tx_packets++;
@@ -1550,8 +1544,6 @@ int ieee80211_mgmt_start_xmit(struct sk_
 	pkt_data = (struct ieee80211_tx_packet_data *) skb->cb;
 	memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
 	pkt_data->ifindex = sdata->dev->ifindex;
-	if (sdata->type == IEEE80211_IF_TYPE_MGMT)
-		pkt_data->flags |= IEEE80211_TXPD_MGMT_IFACE;
 
 	skb->priority = 20; /* use hardcoded priority for mgmt TX queue */
 	skb->dev = sdata->local->mdev;
net/mac80211/ieee80211_rate.c +1 -2
@@ -145,8 +145,7 @@ int ieee80211_init_rate_ctrl_alg(struct 
 	struct rate_control_ref *ref, *old;
 
 	ASSERT_RTNL();
-	if (local->open_count || netif_running(local->mdev) ||
-	    (local->apdev && netif_running(local->apdev)))
+	if (local->open_count || netif_running(local->mdev))
 		return -EBUSY;
 
 	ref = rate_control_alloc(name, local);
net/mac80211/ieee80211_sta.c +0 -2
@@ -472,8 +472,6 @@ static void ieee80211_sta_tx(struct net_
 	pkt_data = (struct ieee80211_tx_packet_data *) skb->cb;
 	memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
 	pkt_data->ifindex = sdata->dev->ifindex;
-	if (sdata->type == IEEE80211_IF_TYPE_MGMT)
-		pkt_data->flags |= IEEE80211_TXPD_MGMT_IFACE;
 	if (!encrypt)
 		pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT;
 
net/mac80211/rx.c +7 -25
@@ -19,7 +19,6 @@
 
 #include "ieee80211_i.h"
 #include "ieee80211_led.h"
-#include "ieee80211_common.h"
 #include "wep.h"
 #include "wpa.h"
 #include "tkip.h"
@@ -412,12 +411,7 @@ ieee80211_rx_h_check(struct ieee80211_tx
 			return TXRX_DROP;
 		}
 
-		if (!rx->local->apdev)
-			return TXRX_DROP;
-
-		ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status,
-				  ieee80211_msg_sta_not_assoc);
-		return TXRX_QUEUED;
+		return TXRX_DROP;
 	}
 
 	return TXRX_CONTINUE;
@@ -977,15 +971,8 @@ ieee80211_rx_h_802_1x_pae(struct ieee802
 {
 	if (rx->sdata->eapol && ieee80211_is_eapol(rx->skb) &&
 	    rx->sdata->type != IEEE80211_IF_TYPE_STA &&
-	    (rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) {
-		/* Pass both encrypted and unencrypted EAPOL frames to user
-		 * space for processing. */
-		if (!rx->local->apdev)
-			return TXRX_DROP;
-		ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status,
-				  ieee80211_msg_normal);
-		return TXRX_QUEUED;
-	}
+	    (rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
+		return TXRX_CONTINUE;
 
 	if (unlikely(rx->sdata->ieee802_1x &&
 		     (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
@@ -1226,15 +1213,11 @@ ieee80211_rx_h_mgmt(struct ieee80211_txr
 	sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
 	if ((sdata->type == IEEE80211_IF_TYPE_STA ||
 	     sdata->type == IEEE80211_IF_TYPE_IBSS) &&
-	    !rx->local->user_space_mlme) {
+	    !rx->local->user_space_mlme)
 		ieee80211_sta_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status);
-	} else {
-		/* Management frames are sent to hostapd for processing */
-		if (!rx->local->apdev)
-			return TXRX_DROP;
-		ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status,
-				  ieee80211_msg_normal);
-	}
+	else
+		return TXRX_DROP;
+
 	return TXRX_QUEUED;
 }
 
@@ -1445,7 +1428,6 @@ static int prepare_for_handlers(struct i
 		/* take everything */
 		break;
 	case IEEE80211_IF_TYPE_INVALID:
-	case IEEE80211_IF_TYPE_MGMT:
 		/* should never get here */
 		WARN_ON(1);
 		break;
net/mac80211/ieee80211_rate.h +0 -2
@@ -30,8 +30,6 @@ struct rate_control_extra {
 
 	/* parameters from the caller to rate_control_get_rate(): */
 	struct ieee80211_hw_mode *mode;
-	int mgmt_data; /* this is data frame that is used for management
-			* (e.g., IEEE 802.1X EAPOL) */
 	u16 ethertype;
 };
 
net/mac80211/wme.c +2 -8
@@ -94,8 +94,6 @@ static inline int wme_downgrade_ac(struc
 static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd)
 {
 	struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
-	struct ieee80211_tx_packet_data *pkt_data =
-		(struct ieee80211_tx_packet_data *) skb->cb;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	unsigned short fc = le16_to_cpu(hdr->frame_control);
 	int qos;
@@ -108,12 +106,8 @@ static inline int classify80211(struct s
 		return IEEE80211_TX_QUEUE_DATA0;
 	}
 
-	if (unlikely(pkt_data->flags & IEEE80211_TXPD_MGMT_IFACE)) {
-		/* Data frames from hostapd (mainly, EAPOL) use AC_VO
-		* and they will include QoS control fields if
-		* the target STA is using WME. */
-		skb->priority = 7;
-		return ieee802_1d_to_ac[skb->priority];
+	if (0 /* injected */) {
+		/* use AC from radiotap */
 	}
 
 	/* is this a QoS frame? */
author maintainer
#16 lore raw

PATCH 12/12 mac80211: remove generic IE for AP interfaces

In reply to Johannes Berg

This is not useful since we do not support probe response offload to hardware at this time and beacons are set in another way.

---
 include/net/mac80211.h         |    7 -------
 net/mac80211/ieee80211.c       |    4 ----
 net/mac80211/ieee80211_i.h     |    2 --
 net/mac80211/ieee80211_iface.c |    1 -
 net/mac80211/ieee80211_ioctl.c |    9 ---------
 5 files changed, 23 deletions(-)
include/net/mac80211.h +0 -7
@@ -518,11 +518,6 @@ struct ieee80211_if_init_conf {
  *	config_interface() call, so copy the value somewhere if you need
  *	it.
  * @ssid_len: length of the @ssid field.
- * @generic_elem: used (together with @generic_elem_len) by drivers for
- *	hardware that generate beacons independently. The pointer is valid
- *	only during the config_interface() call, so copy the value somewhere
- *	if you need it.
- * @generic_elem_len: length of the generic element.
  * @beacon: beacon template. Valid only if @host_gen_beacon_template in
  *	&struct ieee80211_hw is set. The driver is responsible of freeing
  *	the sk_buff.
@@ -537,8 +532,6 @@ struct ieee80211_if_conf {
 	u8 *bssid;
 	u8 *ssid;
 	size_t ssid_len;
-	u8 *generic_elem;
-	size_t generic_elem_len;
 	struct sk_buff *beacon;
 	struct ieee80211_tx_control *beacon_control;
 };
net/mac80211/ieee80211.c +0 -4
@@ -452,13 +452,9 @@ static int __ieee80211_if_config(struct 
 		conf.bssid = sdata->u.sta.bssid;
 		conf.ssid = sdata->u.sta.ssid;
 		conf.ssid_len = sdata->u.sta.ssid_len;
-		conf.generic_elem = sdata->u.sta.extra_ie;
-		conf.generic_elem_len = sdata->u.sta.extra_ie_len;
 	} else if (sdata->type == IEEE80211_IF_TYPE_AP) {
 		conf.ssid = sdata->u.ap.ssid;
 		conf.ssid_len = sdata->u.ap.ssid_len;
-		conf.generic_elem = sdata->u.ap.generic_elem;
-		conf.generic_elem_len = sdata->u.ap.generic_elem_len;
 		conf.beacon = beacon;
 		conf.beacon_control = control;
 	}
net/mac80211/ieee80211_i.h +0 -2
@@ -195,8 +195,6 @@ struct ieee80211_if_ap {
 
 	u8 ssid[IEEE80211_MAX_SSID_LEN];
 	size_t ssid_len;
-	u8 *generic_elem;
-	size_t generic_elem_len;
 
 	/* yes, this looks ugly, but guarantees that we can later use
 	 * bitmap_empty :)
net/mac80211/ieee80211_ioctl.c +0 -9
@@ -120,15 +120,6 @@ static int ieee80211_ioctl_siwgenie(stru
 		return 0;
 	}
 
-	if (sdata->type == IEEE80211_IF_TYPE_AP) {
-		kfree(sdata->u.ap.generic_elem);
-		sdata->u.ap.generic_elem = kmalloc(data->length, GFP_KERNEL);
-		if (!sdata->u.ap.generic_elem)
-			return -ENOMEM;
-		memcpy(sdata->u.ap.generic_elem, extra, data->length);
-		sdata->u.ap.generic_elem_len = data->length;
-		return ieee80211_if_config(dev);
-	}
 	return -EOPNOTSUPP;
 }
 
net/mac80211/ieee80211_iface.c +0 -1
@@ -206,7 +206,6 @@ void ieee80211_if_reinit(struct net_devi
 
 		kfree(sdata->u.ap.beacon_head);
 		kfree(sdata->u.ap.beacon_tail);
-		kfree(sdata->u.ap.generic_elem);
 
 		while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) {
 			local->total_ps_buffered--;