Commit 678f5f71 authored by Johannes Berg's avatar Johannes Berg Committed by David S. Miller

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: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ce3edf6d
...@@ -307,6 +307,7 @@ struct ieee80211_tx_control { ...@@ -307,6 +307,7 @@ struct ieee80211_tx_control {
* using the through * using the through
* set_retry_limit configured * set_retry_limit configured
* long retry value */ * long retry value */
#define IEEE80211_TXCTL_EAPOL_FRAME (1<<11) /* internal to mac80211 */
u32 flags; /* tx control flags defined u32 flags; /* tx control flags defined
* above */ * above */
u8 key_idx; /* keyidx from hw->set_key(), undefined if u8 key_idx; /* keyidx from hw->set_key(), undefined if
......
...@@ -732,6 +732,8 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local, ...@@ -732,6 +732,8 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT;
if (control->flags & IEEE80211_TXCTL_REQUEUE) if (control->flags & IEEE80211_TXCTL_REQUEUE)
pkt_data->flags |= IEEE80211_TXPD_REQUEUE; pkt_data->flags |= IEEE80211_TXPD_REQUEUE;
if (control->flags & IEEE80211_TXCTL_EAPOL_FRAME)
pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME;
pkt_data->queue = control->queue; pkt_data->queue = control->queue;
hdrlen = ieee80211_get_hdrlen_from_skb(skb); hdrlen = ieee80211_get_hdrlen_from_skb(skb);
......
...@@ -164,6 +164,7 @@ struct ieee80211_txrx_data { ...@@ -164,6 +164,7 @@ struct ieee80211_txrx_data {
#define IEEE80211_TXPD_REQ_TX_STATUS BIT(0) #define IEEE80211_TXPD_REQ_TX_STATUS BIT(0)
#define IEEE80211_TXPD_DO_NOT_ENCRYPT BIT(1) #define IEEE80211_TXPD_DO_NOT_ENCRYPT BIT(1)
#define IEEE80211_TXPD_REQUEUE BIT(2) #define IEEE80211_TXPD_REQUEUE BIT(2)
#define IEEE80211_TXPD_EAPOL_FRAME BIT(3)
/* Stored in sk_buff->cb */ /* Stored in sk_buff->cb */
struct ieee80211_tx_packet_data { struct ieee80211_tx_packet_data {
int ifindex; int ifindex;
...@@ -798,7 +799,6 @@ extern void *mac80211_wiphy_privid; /* for wiphy privid */ ...@@ -798,7 +799,6 @@ extern void *mac80211_wiphy_privid; /* for wiphy privid */
extern const unsigned char rfc1042_header[6]; extern const unsigned char rfc1042_header[6];
extern const unsigned char bridge_tunnel_header[6]; extern const unsigned char bridge_tunnel_header[6];
u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len); u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len);
int ieee80211_is_eapol(const struct sk_buff *skb, int hdrlen);
int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
int rate, int erp, int short_preamble); int rate, int erp, int short_preamble);
void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx, void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx,
......
...@@ -437,7 +437,8 @@ ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx) ...@@ -437,7 +437,8 @@ ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx)
else if ((key = rcu_dereference(tx->sdata->default_key))) else if ((key = rcu_dereference(tx->sdata->default_key)))
tx->key = key; tx->key = key;
else if (tx->sdata->drop_unencrypted && else if (tx->sdata->drop_unencrypted &&
!ieee80211_is_eapol(tx->skb, ieee80211_get_hdrlen(fc))) { !(tx->u.tx.control->flags & IEEE80211_TXCTL_EAPOL_FRAME) &&
!(tx->flags & IEEE80211_TXRXD_TX_INJECTED)) {
I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
return TXRX_DROP; return TXRX_DROP;
} else { } else {
...@@ -1241,6 +1242,8 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, ...@@ -1241,6 +1242,8 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
control.flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; control.flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
if (pkt_data->flags & IEEE80211_TXPD_REQUEUE) if (pkt_data->flags & IEEE80211_TXPD_REQUEUE)
control.flags |= IEEE80211_TXCTL_REQUEUE; control.flags |= IEEE80211_TXCTL_REQUEUE;
if (pkt_data->flags & IEEE80211_TXPD_EAPOL_FRAME)
control.flags |= IEEE80211_TXCTL_EAPOL_FRAME;
control.queue = pkt_data->queue; control.queue = pkt_data->queue;
ret = ieee80211_tx(odev, skb, &control); ret = ieee80211_tx(odev, skb, &control);
...@@ -1514,6 +1517,8 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, ...@@ -1514,6 +1517,8 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
pkt_data->ifindex = dev->ifindex; pkt_data->ifindex = dev->ifindex;
if (ethertype == ETH_P_PAE)
pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME;
skb->dev = local->mdev; skb->dev = local->mdev;
dev->stats.tx_packets++; dev->stats.tx_packets++;
......
...@@ -40,10 +40,6 @@ const unsigned char rfc1042_header[] = ...@@ -40,10 +40,6 @@ const unsigned char rfc1042_header[] =
const unsigned char bridge_tunnel_header[] = const unsigned char bridge_tunnel_header[] =
{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
/* No encapsulation header if EtherType < 0x600 (=length) */
static const unsigned char eapol_header[] =
{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e };
static int rate_list_match(const int *rate_list, int rate) static int rate_list_match(const int *rate_list, int rate)
{ {
...@@ -223,19 +219,6 @@ int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) ...@@ -223,19 +219,6 @@ int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)
} }
EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
int ieee80211_is_eapol(const struct sk_buff *skb, int hdrlen)
{
if (unlikely(skb->len < 10))
return 0;
if (unlikely(skb->len >= hdrlen + sizeof(eapol_header) &&
memcmp(skb->data + hdrlen, eapol_header,
sizeof(eapol_header)) == 0))
return 1;
return 0;
}
void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx) void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx)
{ {
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment