summaryrefslogtreecommitdiff
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2007-12-19 03:31:22 +0300
committerDavid S. Miller <davem@davemloft.net>2008-01-29 01:59:45 +0300
commitce3edf6d0b979fa4d5da7204fd8c6f77f2b8622a (patch)
tree3608f59fa3c437edfe132a603775111a03dce453 /net/mac80211/tx.c
parent1946b74ce03c4edecabde80d027da00a7eab56ca (diff)
downloadlinux-ce3edf6d0b979fa4d5da7204fd8c6f77f2b8622a.tar.xz
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.c53
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)
return TXRX_CONTINUE;
}
- if (unlikely(/* !injected && */ tx->sdata->ieee802_1x &&
- !(sta_flags & WLAN_STA_AUTHORIZED))) {
-#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
- DECLARE_MAC_BUF(mac);
- printk(KERN_DEBUG "%s: dropped frame to %s"
- " (unauthorized port)\n", tx->dev->name,
- print_mac(mac, hdr->addr1));
-#endif
- I802_DEBUG_INC(tx->local->tx_handlers_drop_unauth_port);
- return TXRX_DROP;
- }
-
return TXRX_CONTINUE;
}
@@ -449,8 +437,7 @@ ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx)
else if ((key = rcu_dereference(tx->sdata->default_key)))
tx->key = key;
else if (tx->sdata->drop_unencrypted &&
- !(tx->sdata->eapol &&
- ieee80211_is_eapol(tx->skb, ieee80211_get_hdrlen(fc)))) {
+ !ieee80211_is_eapol(tx->skb, ieee80211_get_hdrlen(fc))) {
I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
return TXRX_DROP;
} else {
@@ -1346,6 +1333,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
int encaps_len, skip_header_bytes;
int nh_pos, h_pos;
struct sta_info *sta;
+ u32 sta_flags = 0;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
if (unlikely(skb->len < ETH_HLEN)) {
@@ -1361,7 +1349,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
/* convert Ethernet header to proper 802.11 header (based on
* operation mode) */
ethertype = (skb->data[12] << 8) | skb->data[13];
- /* TODO: handling for 802.1x authorized/unauthorized port */
fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
switch (sdata->type) {
@@ -1403,16 +1390,42 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
goto fail;
}
- /* receiver is QoS enabled, use a QoS type frame */
sta = sta_info_get(local, hdr.addr1);
if (sta) {
- if (sta->flags & WLAN_STA_WME) {
- fc |= IEEE80211_STYPE_QOS_DATA;
- hdrlen += 2;
- }
+ sta_flags = sta->flags;
sta_info_put(sta);
}
+ /* receiver is QoS enabled, use a QoS type frame */
+ if (sta_flags & WLAN_STA_WME) {
+ fc |= IEEE80211_STYPE_QOS_DATA;
+ hdrlen += 2;
+ }
+
+ /*
+ * If port access control is enabled, drop frames to unauthorised
+ * stations unless they are EAPOL frames from the local station.
+ */
+ if (unlikely(sdata->ieee802_1x_pac &&
+ !(sta_flags & WLAN_STA_AUTHORIZED) &&
+ !(ethertype == ETH_P_PAE &&
+ compare_ether_addr(dev->dev_addr,
+ skb->data + ETH_ALEN) == 0))) {
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+ DECLARE_MAC_BUF(mac);
+
+ if (net_ratelimit())
+ printk(KERN_DEBUG "%s: dropped frame to %s"
+ " (unauthorized port)\n", dev->name,
+ print_mac(mac, hdr.addr1));
+#endif
+
+ I802_DEBUG_INC(local->tx_handlers_drop_unauth_port);
+
+ ret = 0;
+ goto fail;
+ }
+
hdr.frame_control = cpu_to_le16(fc);
hdr.duration_id = 0;
hdr.seq_ctrl = 0;