aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2007-12-18 19:31:23 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:59:46 -0500
commit678f5f7117d5780d3a51b201c9f44b7bf90f6a76 (patch)
treeddf555061ec729e3e14eabc506d0c3b8f32f25b8 /net/mac80211
parentce3edf6d0b979fa4d5da7204fd8c6f77f2b8622a (diff)
mac80211: clean up eapol handling in TX path
The previous patch left only one user of the ieee80211_is_eapol() function and that user can be eliminated easily by introducing a new "frame is EAPOL" flag to handle the frame specially (we already have this information) instead of doing the (expensive) ieee80211_is_eapol() all the time. Also, allow unencrypted frames to be sent when they are injected. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ieee80211.c2
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/tx.c7
-rw-r--r--net/mac80211/util.c17
4 files changed, 9 insertions, 19 deletions
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index c0dbf77547f7..9c14e3d303c5 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -732,6 +732,8 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
732 pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; 732 pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT;
733 if (control->flags & IEEE80211_TXCTL_REQUEUE) 733 if (control->flags & IEEE80211_TXCTL_REQUEUE)
734 pkt_data->flags |= IEEE80211_TXPD_REQUEUE; 734 pkt_data->flags |= IEEE80211_TXPD_REQUEUE;
735 if (control->flags & IEEE80211_TXCTL_EAPOL_FRAME)
736 pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME;
735 pkt_data->queue = control->queue; 737 pkt_data->queue = control->queue;
736 738
737 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 739 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 214109b8d95a..baf53c047127 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -164,6 +164,7 @@ struct ieee80211_txrx_data {
164#define IEEE80211_TXPD_REQ_TX_STATUS BIT(0) 164#define IEEE80211_TXPD_REQ_TX_STATUS BIT(0)
165#define IEEE80211_TXPD_DO_NOT_ENCRYPT BIT(1) 165#define IEEE80211_TXPD_DO_NOT_ENCRYPT BIT(1)
166#define IEEE80211_TXPD_REQUEUE BIT(2) 166#define IEEE80211_TXPD_REQUEUE BIT(2)
167#define IEEE80211_TXPD_EAPOL_FRAME BIT(3)
167/* Stored in sk_buff->cb */ 168/* Stored in sk_buff->cb */
168struct ieee80211_tx_packet_data { 169struct ieee80211_tx_packet_data {
169 int ifindex; 170 int ifindex;
@@ -798,7 +799,6 @@ extern void *mac80211_wiphy_privid; /* for wiphy privid */
798extern const unsigned char rfc1042_header[6]; 799extern const unsigned char rfc1042_header[6];
799extern const unsigned char bridge_tunnel_header[6]; 800extern const unsigned char bridge_tunnel_header[6];
800u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len); 801u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len);
801int ieee80211_is_eapol(const struct sk_buff *skb, int hdrlen);
802int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, 802int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
803 int rate, int erp, int short_preamble); 803 int rate, int erp, int short_preamble);
804void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx, 804void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 6dbd91842881..e177a8dc23b9 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -437,7 +437,8 @@ ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx)
437 else if ((key = rcu_dereference(tx->sdata->default_key))) 437 else if ((key = rcu_dereference(tx->sdata->default_key)))
438 tx->key = key; 438 tx->key = key;
439 else if (tx->sdata->drop_unencrypted && 439 else if (tx->sdata->drop_unencrypted &&
440 !ieee80211_is_eapol(tx->skb, ieee80211_get_hdrlen(fc))) { 440 !(tx->u.tx.control->flags & IEEE80211_TXCTL_EAPOL_FRAME) &&
441 !(tx->flags & IEEE80211_TXRXD_TX_INJECTED)) {
441 I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); 442 I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
442 return TXRX_DROP; 443 return TXRX_DROP;
443 } else { 444 } else {
@@ -1241,6 +1242,8 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
1241 control.flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; 1242 control.flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
1242 if (pkt_data->flags & IEEE80211_TXPD_REQUEUE) 1243 if (pkt_data->flags & IEEE80211_TXPD_REQUEUE)
1243 control.flags |= IEEE80211_TXCTL_REQUEUE; 1244 control.flags |= IEEE80211_TXCTL_REQUEUE;
1245 if (pkt_data->flags & IEEE80211_TXPD_EAPOL_FRAME)
1246 control.flags |= IEEE80211_TXCTL_EAPOL_FRAME;
1244 control.queue = pkt_data->queue; 1247 control.queue = pkt_data->queue;
1245 1248
1246 ret = ieee80211_tx(odev, skb, &control); 1249 ret = ieee80211_tx(odev, skb, &control);
@@ -1514,6 +1517,8 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1514 pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; 1517 pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
1515 memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); 1518 memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
1516 pkt_data->ifindex = dev->ifindex; 1519 pkt_data->ifindex = dev->ifindex;
1520 if (ethertype == ETH_P_PAE)
1521 pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME;
1517 1522
1518 skb->dev = local->mdev; 1523 skb->dev = local->mdev;
1519 dev->stats.tx_packets++; 1524 dev->stats.tx_packets++;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index fb7fd896cd0d..2b02b2b9d645 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -40,10 +40,6 @@ const unsigned char rfc1042_header[] =
40const unsigned char bridge_tunnel_header[] = 40const unsigned char bridge_tunnel_header[] =
41 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; 41 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
42 42
43/* No encapsulation header if EtherType < 0x600 (=length) */
44static const unsigned char eapol_header[] =
45 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e };
46
47 43
48static int rate_list_match(const int *rate_list, int rate) 44static int rate_list_match(const int *rate_list, int rate)
49{ 45{
@@ -223,19 +219,6 @@ int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)
223} 219}
224EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); 220EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
225 221
226int ieee80211_is_eapol(const struct sk_buff *skb, int hdrlen)
227{
228 if (unlikely(skb->len < 10))
229 return 0;
230
231 if (unlikely(skb->len >= hdrlen + sizeof(eapol_header) &&
232 memcmp(skb->data + hdrlen, eapol_header,
233 sizeof(eapol_header)) == 0))
234 return 1;
235
236 return 0;
237}
238
239void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx) 222void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx)
240{ 223{
241 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; 224 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;