diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2007-12-18 19:31:22 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:59:45 -0500 |
commit | ce3edf6d0b979fa4d5da7204fd8c6f77f2b8622a (patch) | |
tree | 3608f59fa3c437edfe132a603775111a03dce453 /net/mac80211/tx.c | |
parent | 1946b74ce03c4edecabde80d027da00a7eab56ca (diff) |
mac80211: clean up eapol frame handling/port control
This cleans up the eapol frame handling and some related code in the
receive and transmit paths. After this patch
* EAPOL frames addressed to us or the EAPOL group address are
always accepted regardless of whether they are encrypted or not
* other frames from a station are dropped if PAE is enabled and
the station is not authorized
* unencrypted frames (except the EAPOL frames above) are dropped if
drop_unencrypted is enabled
* some superfluous code that eth_type_trans handles anyway is gone
* port control is done for transmitted packets
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/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 4655e3038658..6dbd91842881 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -261,18 +261,6 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx) | |||
261 | return TXRX_CONTINUE; | 261 | return TXRX_CONTINUE; |
262 | } | 262 | } |
263 | 263 | ||
264 | if (unlikely(/* !injected && */ tx->sdata->ieee802_1x && | ||
265 | !(sta_flags & WLAN_STA_AUTHORIZED))) { | ||
266 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
267 | DECLARE_MAC_BUF(mac); | ||
268 | printk(KERN_DEBUG "%s: dropped frame to %s" | ||
269 | " (unauthorized port)\n", tx->dev->name, | ||
270 | print_mac(mac, hdr->addr1)); | ||
271 | #endif | ||
272 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unauth_port); | ||
273 | return TXRX_DROP; | ||
274 | } | ||
275 | |||
276 | return TXRX_CONTINUE; | 264 | return TXRX_CONTINUE; |
277 | } | 265 | } |
278 | 266 | ||
@@ -449,8 +437,7 @@ ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx) | |||
449 | else if ((key = rcu_dereference(tx->sdata->default_key))) | 437 | else if ((key = rcu_dereference(tx->sdata->default_key))) |
450 | tx->key = key; | 438 | tx->key = key; |
451 | else if (tx->sdata->drop_unencrypted && | 439 | else if (tx->sdata->drop_unencrypted && |
452 | !(tx->sdata->eapol && | 440 | !ieee80211_is_eapol(tx->skb, ieee80211_get_hdrlen(fc))) { |
453 | ieee80211_is_eapol(tx->skb, ieee80211_get_hdrlen(fc)))) { | ||
454 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); | 441 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); |
455 | return TXRX_DROP; | 442 | return TXRX_DROP; |
456 | } else { | 443 | } else { |
@@ -1346,6 +1333,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1346 | int encaps_len, skip_header_bytes; | 1333 | int encaps_len, skip_header_bytes; |
1347 | int nh_pos, h_pos; | 1334 | int nh_pos, h_pos; |
1348 | struct sta_info *sta; | 1335 | struct sta_info *sta; |
1336 | u32 sta_flags = 0; | ||
1349 | 1337 | ||
1350 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1338 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1351 | if (unlikely(skb->len < ETH_HLEN)) { | 1339 | if (unlikely(skb->len < ETH_HLEN)) { |
@@ -1361,7 +1349,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1361 | /* convert Ethernet header to proper 802.11 header (based on | 1349 | /* convert Ethernet header to proper 802.11 header (based on |
1362 | * operation mode) */ | 1350 | * operation mode) */ |
1363 | ethertype = (skb->data[12] << 8) | skb->data[13]; | 1351 | ethertype = (skb->data[12] << 8) | skb->data[13]; |
1364 | /* TODO: handling for 802.1x authorized/unauthorized port */ | ||
1365 | fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA; | 1352 | fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA; |
1366 | 1353 | ||
1367 | switch (sdata->type) { | 1354 | switch (sdata->type) { |
@@ -1403,16 +1390,42 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1403 | goto fail; | 1390 | goto fail; |
1404 | } | 1391 | } |
1405 | 1392 | ||
1406 | /* receiver is QoS enabled, use a QoS type frame */ | ||
1407 | sta = sta_info_get(local, hdr.addr1); | 1393 | sta = sta_info_get(local, hdr.addr1); |
1408 | if (sta) { | 1394 | if (sta) { |
1409 | if (sta->flags & WLAN_STA_WME) { | 1395 | sta_flags = sta->flags; |
1410 | fc |= IEEE80211_STYPE_QOS_DATA; | ||
1411 | hdrlen += 2; | ||
1412 | } | ||
1413 | sta_info_put(sta); | 1396 | sta_info_put(sta); |
1414 | } | 1397 | } |
1415 | 1398 | ||
1399 | /* receiver is QoS enabled, use a QoS type frame */ | ||
1400 | if (sta_flags & WLAN_STA_WME) { | ||
1401 | fc |= IEEE80211_STYPE_QOS_DATA; | ||
1402 | hdrlen += 2; | ||
1403 | } | ||
1404 | |||
1405 | /* | ||
1406 | * If port access control is enabled, drop frames to unauthorised | ||
1407 | * stations unless they are EAPOL frames from the local station. | ||
1408 | */ | ||
1409 | if (unlikely(sdata->ieee802_1x_pac && | ||
1410 | !(sta_flags & WLAN_STA_AUTHORIZED) && | ||
1411 | !(ethertype == ETH_P_PAE && | ||
1412 | compare_ether_addr(dev->dev_addr, | ||
1413 | skb->data + ETH_ALEN) == 0))) { | ||
1414 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
1415 | DECLARE_MAC_BUF(mac); | ||
1416 | |||
1417 | if (net_ratelimit()) | ||
1418 | printk(KERN_DEBUG "%s: dropped frame to %s" | ||
1419 | " (unauthorized port)\n", dev->name, | ||
1420 | print_mac(mac, hdr.addr1)); | ||
1421 | #endif | ||
1422 | |||
1423 | I802_DEBUG_INC(local->tx_handlers_drop_unauth_port); | ||
1424 | |||
1425 | ret = 0; | ||
1426 | goto fail; | ||
1427 | } | ||
1428 | |||
1416 | hdr.frame_control = cpu_to_le16(fc); | 1429 | hdr.frame_control = cpu_to_le16(fc); |
1417 | hdr.duration_id = 0; | 1430 | hdr.duration_id = 0; |
1418 | hdr.seq_ctrl = 0; | 1431 | hdr.seq_ctrl = 0; |