diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2007-12-18 19:31:23 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:59:46 -0500 |
commit | 678f5f7117d5780d3a51b201c9f44b7bf90f6a76 (patch) | |
tree | ddf555061ec729e3e14eabc506d0c3b8f32f25b8 | |
parent | ce3edf6d0b979fa4d5da7204fd8c6f77f2b8622a (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>
-rw-r--r-- | include/net/mac80211.h | 1 | ||||
-rw-r--r-- | net/mac80211/ieee80211.c | 2 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/tx.c | 7 | ||||
-rw-r--r-- | net/mac80211/util.c | 17 |
5 files changed, 10 insertions, 19 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 3bd970f29f29..2606ca282c5e 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -307,6 +307,7 @@ struct ieee80211_tx_control { | |||
307 | * using the through | 307 | * using the through |
308 | * set_retry_limit configured | 308 | * set_retry_limit configured |
309 | * long retry value */ | 309 | * long retry value */ |
310 | #define IEEE80211_TXCTL_EAPOL_FRAME (1<<11) /* internal to mac80211 */ | ||
310 | u32 flags; /* tx control flags defined | 311 | u32 flags; /* tx control flags defined |
311 | * above */ | 312 | * above */ |
312 | u8 key_idx; /* keyidx from hw->set_key(), undefined if | 313 | u8 key_idx; /* keyidx from hw->set_key(), undefined if |
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 */ |
168 | struct ieee80211_tx_packet_data { | 169 | struct ieee80211_tx_packet_data { |
169 | int ifindex; | 170 | int ifindex; |
@@ -798,7 +799,6 @@ extern void *mac80211_wiphy_privid; /* for wiphy privid */ | |||
798 | extern const unsigned char rfc1042_header[6]; | 799 | extern const unsigned char rfc1042_header[6]; |
799 | extern const unsigned char bridge_tunnel_header[6]; | 800 | extern const unsigned char bridge_tunnel_header[6]; |
800 | u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len); | 801 | u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len); |
801 | int ieee80211_is_eapol(const struct sk_buff *skb, int hdrlen); | ||
802 | int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, | 802 | int 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); |
804 | void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx, | 804 | void 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[] = | |||
40 | const unsigned char bridge_tunnel_header[] = | 40 | const 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) */ | ||
44 | static const unsigned char eapol_header[] = | ||
45 | { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e }; | ||
46 | |||
47 | 43 | ||
48 | static int rate_list_match(const int *rate_list, int rate) | 44 | static 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 | } |
224 | EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); | 220 | EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); |
225 | 221 | ||
226 | int 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 | |||
239 | void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx) | 222 | void 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; |