Skip to content

Commit 76ee65b

Browse files
Ron Rindjunskydavem330
Ron Rindjunsky
authored andcommitted
mac80211: restructuring data Rx handlers
This patch restructures the Rx handlers chain by incorporating previously handlers ieee80211_rx_h_802_1x_pae and ieee80211_rx_h_drop_unencrypted into ieee80211_rx_h_data, already in 802.3 form. this scheme follows more precisely after the IEEE802.11 data plane archituecture, and will prevent code duplication to IEEE8021.11n A-MSDU handler. added function: - ieee80211_data_to_8023: transfering 802.11 data frames to 802.3 frame - ieee80211_deliver_skb: delivering the 802.3 frames to upper stack eliminated handlers: - ieee80211_rx_h_drop_unencrypted: now function ieee80211_drop_unencrypted - ieee80211_rx_h_802_1x_pae: now function ieee80211_802_1x_pae changed handlers: - ieee80211_rx_h_data: now contains calls to four above function Signed-off-by: Ron Rindjunsky <ron.rindjunsky@intel.com> Acked-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent ece8edd commit 76ee65b

File tree

4 files changed

+86
-66
lines changed

4 files changed

+86
-66
lines changed

net/mac80211/ieee80211_i.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,7 @@ extern void *mac80211_wiphy_privid; /* for wiphy privid */
792792
extern const unsigned char rfc1042_header[6];
793793
extern const unsigned char bridge_tunnel_header[6];
794794
u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len);
795-
int ieee80211_is_eapol(const struct sk_buff *skb);
795+
int ieee80211_is_eapol(const struct sk_buff *skb, int hdrlen);
796796
int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
797797
int rate, int erp, int short_preamble);
798798
void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx,

net/mac80211/rx.c

+77-47
Original file line numberDiff line numberDiff line change
@@ -962,80 +962,74 @@ ieee80211_rx_h_remove_qos_control(struct ieee80211_txrx_data *rx)
962962
return TXRX_CONTINUE;
963963
}
964964

965-
static ieee80211_txrx_result
966-
ieee80211_rx_h_802_1x_pae(struct ieee80211_txrx_data *rx)
965+
static int
966+
ieee80211_drop_802_1x_pae(struct ieee80211_txrx_data *rx, int hdrlen)
967967
{
968-
if (rx->sdata->eapol && ieee80211_is_eapol(rx->skb) &&
968+
if (rx->sdata->eapol && ieee80211_is_eapol(rx->skb, hdrlen) &&
969969
rx->sdata->type != IEEE80211_IF_TYPE_STA &&
970970
(rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
971-
return TXRX_CONTINUE;
971+
return 0;
972972

973973
if (unlikely(rx->sdata->ieee802_1x &&
974974
(rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
975975
(rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_NULLFUNC &&
976976
(!rx->sta || !(rx->sta->flags & WLAN_STA_AUTHORIZED)) &&
977-
!ieee80211_is_eapol(rx->skb))) {
977+
!ieee80211_is_eapol(rx->skb, hdrlen))) {
978978
#ifdef CONFIG_MAC80211_DEBUG
979-
struct ieee80211_hdr *hdr =
980-
(struct ieee80211_hdr *) rx->skb->data;
981-
DECLARE_MAC_BUF(mac);
982-
printk(KERN_DEBUG "%s: dropped frame from %s"
983-
" (unauthorized port)\n", rx->dev->name,
984-
print_mac(mac, hdr->addr2));
979+
printk(KERN_DEBUG "%s: dropped frame "
980+
"(unauthorized port)\n", rx->dev->name);
985981
#endif /* CONFIG_MAC80211_DEBUG */
986-
return TXRX_DROP;
982+
return -EACCES;
987983
}
988984

989-
return TXRX_CONTINUE;
985+
return 0;
990986
}
991987

992-
static ieee80211_txrx_result
993-
ieee80211_rx_h_drop_unencrypted(struct ieee80211_txrx_data *rx)
988+
static int
989+
ieee80211_drop_unencrypted(struct ieee80211_txrx_data *rx, int hdrlen)
994990
{
995991
/*
996992
* Pass through unencrypted frames if the hardware has
997993
* decrypted them already.
998994
*/
999995
if (rx->u.rx.status->flag & RX_FLAG_DECRYPTED)
1000-
return TXRX_CONTINUE;
996+
return 0;
1001997

1002998
/* Drop unencrypted frames if key is set. */
1003999
if (unlikely(!(rx->fc & IEEE80211_FCTL_PROTECTED) &&
10041000
(rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
10051001
(rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_NULLFUNC &&
10061002
(rx->key || rx->sdata->drop_unencrypted) &&
1007-
(rx->sdata->eapol == 0 || !ieee80211_is_eapol(rx->skb)))) {
1003+
(rx->sdata->eapol == 0 ||
1004+
!ieee80211_is_eapol(rx->skb, hdrlen)))) {
10081005
if (net_ratelimit())
10091006
printk(KERN_DEBUG "%s: RX non-WEP frame, but expected "
10101007
"encryption\n", rx->dev->name);
1011-
return TXRX_DROP;
1008+
return -EACCES;
10121009
}
1013-
return TXRX_CONTINUE;
1010+
return 0;
10141011
}
10151012

1016-
static ieee80211_txrx_result
1017-
ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
1013+
static int
1014+
ieee80211_data_to_8023(struct ieee80211_txrx_data *rx)
10181015
{
10191016
struct net_device *dev = rx->dev;
1020-
struct ieee80211_local *local = rx->local;
10211017
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
10221018
u16 fc, hdrlen, ethertype;
10231019
u8 *payload;
10241020
u8 dst[ETH_ALEN];
10251021
u8 src[ETH_ALEN];
1026-
struct sk_buff *skb = rx->skb, *skb2;
1022+
struct sk_buff *skb = rx->skb;
10271023
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
10281024
DECLARE_MAC_BUF(mac);
10291025
DECLARE_MAC_BUF(mac2);
10301026
DECLARE_MAC_BUF(mac3);
10311027
DECLARE_MAC_BUF(mac4);
10321028

10331029
fc = rx->fc;
1034-
if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA))
1035-
return TXRX_CONTINUE;
10361030

10371031
if (unlikely(!WLAN_FC_DATA_PRESENT(fc)))
1038-
return TXRX_DROP;
1032+
return -1;
10391033

10401034
hdrlen = ieee80211_get_hdrlen(fc);
10411035

@@ -1064,7 +1058,7 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
10641058
print_mac(mac, hdr->addr1),
10651059
print_mac(mac2, hdr->addr2),
10661060
print_mac(mac3, hdr->addr3));
1067-
return TXRX_DROP;
1061+
return -1;
10681062
}
10691063
break;
10701064
case (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS):
@@ -1081,7 +1075,7 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
10811075
print_mac(mac2, hdr->addr2),
10821076
print_mac(mac3, hdr->addr3),
10831077
print_mac(mac4, hdr->addr4));
1084-
return TXRX_DROP;
1078+
return -1;
10851079
}
10861080
break;
10871081
case IEEE80211_FCTL_FROMDS:
@@ -1092,7 +1086,7 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
10921086
if (sdata->type != IEEE80211_IF_TYPE_STA ||
10931087
(is_multicast_ether_addr(dst) &&
10941088
!compare_ether_addr(src, dev->dev_addr)))
1095-
return TXRX_DROP;
1089+
return -1;
10961090
break;
10971091
case 0:
10981092
/* DA SA BSSID */
@@ -1108,21 +1102,20 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
11081102
print_mac(mac2, hdr->addr2),
11091103
print_mac(mac3, hdr->addr3));
11101104
}
1111-
return TXRX_DROP;
1105+
return -1;
11121106
}
11131107
break;
11141108
}
11151109

1116-
payload = skb->data + hdrlen;
1117-
11181110
if (unlikely(skb->len - hdrlen < 8)) {
11191111
if (net_ratelimit()) {
11201112
printk(KERN_DEBUG "%s: RX too short data frame "
11211113
"payload\n", dev->name);
11221114
}
1123-
return TXRX_DROP;
1115+
return -1;
11241116
}
11251117

1118+
payload = skb->data + hdrlen;
11261119
ethertype = (payload[6] << 8) | payload[7];
11271120

11281121
if (likely((compare_ether_addr(payload, rfc1042_header) == 0 &&
@@ -1143,21 +1136,28 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
11431136
memcpy(ehdr->h_source, src, ETH_ALEN);
11441137
ehdr->h_proto = len;
11451138
}
1146-
skb->dev = dev;
1139+
return 0;
1140+
}
11471141

1148-
skb2 = NULL;
1142+
static void
1143+
ieee80211_deliver_skb(struct ieee80211_txrx_data *rx)
1144+
{
1145+
struct net_device *dev = rx->dev;
1146+
struct ieee80211_local *local = rx->local;
1147+
struct sk_buff *skb, *xmit_skb;
1148+
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
11491149

1150-
dev->stats.rx_packets++;
1151-
dev->stats.rx_bytes += skb->len;
1150+
skb = rx->skb;
1151+
xmit_skb = NULL;
11521152

11531153
if (local->bridge_packets && (sdata->type == IEEE80211_IF_TYPE_AP
11541154
|| sdata->type == IEEE80211_IF_TYPE_VLAN) &&
11551155
(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) {
11561156
if (is_multicast_ether_addr(skb->data)) {
11571157
/* send multicast frames both to higher layers in
11581158
* local net stack and back to the wireless media */
1159-
skb2 = skb_copy(skb, GFP_ATOMIC);
1160-
if (!skb2 && net_ratelimit())
1159+
xmit_skb = skb_copy(skb, GFP_ATOMIC);
1160+
if (!xmit_skb && net_ratelimit())
11611161
printk(KERN_DEBUG "%s: failed to clone "
11621162
"multicast frame\n", dev->name);
11631163
} else {
@@ -1172,7 +1172,7 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
11721172
* AP, so send the frame directly to it and
11731173
* do not pass the frame to local net stack.
11741174
*/
1175-
skb2 = skb;
1175+
xmit_skb = skb;
11761176
skb = NULL;
11771177
}
11781178
if (dsta)
@@ -1187,13 +1187,45 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
11871187
netif_rx(skb);
11881188
}
11891189

1190-
if (skb2) {
1190+
if (xmit_skb) {
11911191
/* send to wireless media */
1192-
skb2->protocol = __constant_htons(ETH_P_802_3);
1193-
skb_set_network_header(skb2, 0);
1194-
skb_set_mac_header(skb2, 0);
1195-
dev_queue_xmit(skb2);
1192+
xmit_skb->protocol = __constant_htons(ETH_P_802_3);
1193+
skb_set_network_header(xmit_skb, 0);
1194+
skb_set_mac_header(xmit_skb, 0);
1195+
dev_queue_xmit(xmit_skb);
11961196
}
1197+
}
1198+
1199+
static ieee80211_txrx_result
1200+
ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
1201+
{
1202+
struct net_device *dev = rx->dev;
1203+
u16 fc;
1204+
int err, hdrlen;
1205+
1206+
fc = rx->fc;
1207+
if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA))
1208+
return TXRX_CONTINUE;
1209+
1210+
if (unlikely(!WLAN_FC_DATA_PRESENT(fc)))
1211+
return TXRX_DROP;
1212+
1213+
hdrlen = ieee80211_get_hdrlen(fc);
1214+
1215+
if ((ieee80211_drop_802_1x_pae(rx, hdrlen)) ||
1216+
(ieee80211_drop_unencrypted(rx, hdrlen)))
1217+
return TXRX_DROP;
1218+
1219+
err = ieee80211_data_to_8023(rx);
1220+
if (unlikely(err))
1221+
return TXRX_DROP;
1222+
1223+
rx->skb->dev = dev;
1224+
1225+
dev->stats.rx_packets++;
1226+
dev->stats.rx_bytes += rx->skb->len;
1227+
1228+
ieee80211_deliver_skb(rx);
11971229

11981230
return TXRX_QUEUED;
11991231
}
@@ -1347,8 +1379,6 @@ ieee80211_rx_handler ieee80211_rx_handlers[] =
13471379
* are not passed to user space by these functions
13481380
*/
13491381
ieee80211_rx_h_remove_qos_control,
1350-
ieee80211_rx_h_802_1x_pae,
1351-
ieee80211_rx_h_drop_unencrypted,
13521382
ieee80211_rx_h_data,
13531383
ieee80211_rx_h_mgmt,
13541384
NULL

net/mac80211/tx.c

+7-5
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,6 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx)
420420
return TXRX_CONTINUE;
421421
}
422422

423-
424423
static ieee80211_txrx_result
425424
ieee80211_tx_h_ps_buf(struct ieee80211_txrx_data *tx)
426425
{
@@ -433,13 +432,15 @@ ieee80211_tx_h_ps_buf(struct ieee80211_txrx_data *tx)
433432
return ieee80211_tx_h_multicast_ps_buf(tx);
434433
}
435434

436-
437-
438-
439435
static ieee80211_txrx_result
440436
ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx)
441437
{
442438
struct ieee80211_key *key;
439+
const struct ieee80211_hdr *hdr;
440+
u16 fc;
441+
442+
hdr = (const struct ieee80211_hdr *) tx->skb->data;
443+
fc = le16_to_cpu(hdr->frame_control);
443444

444445
if (unlikely(tx->u.tx.control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT))
445446
tx->key = NULL;
@@ -448,7 +449,8 @@ ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx)
448449
else if ((key = rcu_dereference(tx->sdata->default_key)))
449450
tx->key = key;
450451
else if (tx->sdata->drop_unencrypted &&
451-
!(tx->sdata->eapol && ieee80211_is_eapol(tx->skb))) {
452+
!(tx->sdata->eapol &&
453+
ieee80211_is_eapol(tx->skb, ieee80211_get_hdrlen(fc)))) {
452454
I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
453455
return TXRX_DROP;
454456
} else {

net/mac80211/util.c

+1-13
Original file line numberDiff line numberDiff line change
@@ -218,23 +218,11 @@ int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)
218218
}
219219
EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
220220

221-
int ieee80211_is_eapol(const struct sk_buff *skb)
221+
int ieee80211_is_eapol(const struct sk_buff *skb, int hdrlen)
222222
{
223-
const struct ieee80211_hdr *hdr;
224-
u16 fc;
225-
int hdrlen;
226-
227223
if (unlikely(skb->len < 10))
228224
return 0;
229225

230-
hdr = (const struct ieee80211_hdr *) skb->data;
231-
fc = le16_to_cpu(hdr->frame_control);
232-
233-
if (unlikely(!WLAN_FC_DATA_PRESENT(fc)))
234-
return 0;
235-
236-
hdrlen = ieee80211_get_hdrlen(fc);
237-
238226
if (unlikely(skb->len >= hdrlen + sizeof(eapol_header) &&
239227
memcmp(skb->data + hdrlen, eapol_header,
240228
sizeof(eapol_header)) == 0))

0 commit comments

Comments
 (0)