aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2007-12-18 19:31:22 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:59:45 -0500
commitce3edf6d0b979fa4d5da7204fd8c6f77f2b8622a (patch)
tree3608f59fa3c437edfe132a603775111a03dce453 /net
parent1946b74ce03c4edecabde80d027da00a7eab56ca (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')
-rw-r--r--net/mac80211/debugfs_netdev.c27
-rw-r--r--net/mac80211/ieee80211_i.h22
-rw-r--r--net/mac80211/ieee80211_iface.c1
-rw-r--r--net/mac80211/rx.c133
-rw-r--r--net/mac80211/tx.c53
5 files changed, 119 insertions, 117 deletions
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index f0e6ab7eb624..bf715d28643b 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -91,8 +91,7 @@ static const struct file_operations name##_ops = { \
91/* common attributes */ 91/* common attributes */
92IEEE80211_IF_FILE(channel_use, channel_use, DEC); 92IEEE80211_IF_FILE(channel_use, channel_use, DEC);
93IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); 93IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC);
94IEEE80211_IF_FILE(eapol, eapol, DEC); 94IEEE80211_IF_FILE(ieee802_1x_pac, ieee802_1x_pac, DEC);
95IEEE80211_IF_FILE(ieee8021_x, ieee802_1x, DEC);
96 95
97/* STA/IBSS attributes */ 96/* STA/IBSS attributes */
98IEEE80211_IF_FILE(state, u.sta.state, DEC); 97IEEE80211_IF_FILE(state, u.sta.state, DEC);
@@ -170,8 +169,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
170{ 169{
171 DEBUGFS_ADD(channel_use, sta); 170 DEBUGFS_ADD(channel_use, sta);
172 DEBUGFS_ADD(drop_unencrypted, sta); 171 DEBUGFS_ADD(drop_unencrypted, sta);
173 DEBUGFS_ADD(eapol, sta); 172 DEBUGFS_ADD(ieee802_1x_pac, sta);
174 DEBUGFS_ADD(ieee8021_x, sta);
175 DEBUGFS_ADD(state, sta); 173 DEBUGFS_ADD(state, sta);
176 DEBUGFS_ADD(bssid, sta); 174 DEBUGFS_ADD(bssid, sta);
177 DEBUGFS_ADD(prev_bssid, sta); 175 DEBUGFS_ADD(prev_bssid, sta);
@@ -192,8 +190,7 @@ static void add_ap_files(struct ieee80211_sub_if_data *sdata)
192{ 190{
193 DEBUGFS_ADD(channel_use, ap); 191 DEBUGFS_ADD(channel_use, ap);
194 DEBUGFS_ADD(drop_unencrypted, ap); 192 DEBUGFS_ADD(drop_unencrypted, ap);
195 DEBUGFS_ADD(eapol, ap); 193 DEBUGFS_ADD(ieee802_1x_pac, ap);
196 DEBUGFS_ADD(ieee8021_x, ap);
197 DEBUGFS_ADD(num_sta_ps, ap); 194 DEBUGFS_ADD(num_sta_ps, ap);
198 DEBUGFS_ADD(dtim_period, ap); 195 DEBUGFS_ADD(dtim_period, ap);
199 DEBUGFS_ADD(dtim_count, ap); 196 DEBUGFS_ADD(dtim_count, ap);
@@ -209,8 +206,7 @@ static void add_wds_files(struct ieee80211_sub_if_data *sdata)
209{ 206{
210 DEBUGFS_ADD(channel_use, wds); 207 DEBUGFS_ADD(channel_use, wds);
211 DEBUGFS_ADD(drop_unencrypted, wds); 208 DEBUGFS_ADD(drop_unencrypted, wds);
212 DEBUGFS_ADD(eapol, wds); 209 DEBUGFS_ADD(ieee802_1x_pac, wds);
213 DEBUGFS_ADD(ieee8021_x, wds);
214 DEBUGFS_ADD(peer, wds); 210 DEBUGFS_ADD(peer, wds);
215} 211}
216 212
@@ -218,8 +214,7 @@ static void add_vlan_files(struct ieee80211_sub_if_data *sdata)
218{ 214{
219 DEBUGFS_ADD(channel_use, vlan); 215 DEBUGFS_ADD(channel_use, vlan);
220 DEBUGFS_ADD(drop_unencrypted, vlan); 216 DEBUGFS_ADD(drop_unencrypted, vlan);
221 DEBUGFS_ADD(eapol, vlan); 217 DEBUGFS_ADD(ieee802_1x_pac, vlan);
222 DEBUGFS_ADD(ieee8021_x, vlan);
223} 218}
224 219
225static void add_monitor_files(struct ieee80211_sub_if_data *sdata) 220static void add_monitor_files(struct ieee80211_sub_if_data *sdata)
@@ -263,8 +258,7 @@ static void del_sta_files(struct ieee80211_sub_if_data *sdata)
263{ 258{
264 DEBUGFS_DEL(channel_use, sta); 259 DEBUGFS_DEL(channel_use, sta);
265 DEBUGFS_DEL(drop_unencrypted, sta); 260 DEBUGFS_DEL(drop_unencrypted, sta);
266 DEBUGFS_DEL(eapol, sta); 261 DEBUGFS_DEL(ieee802_1x_pac, sta);
267 DEBUGFS_DEL(ieee8021_x, sta);
268 DEBUGFS_DEL(state, sta); 262 DEBUGFS_DEL(state, sta);
269 DEBUGFS_DEL(bssid, sta); 263 DEBUGFS_DEL(bssid, sta);
270 DEBUGFS_DEL(prev_bssid, sta); 264 DEBUGFS_DEL(prev_bssid, sta);
@@ -285,8 +279,7 @@ static void del_ap_files(struct ieee80211_sub_if_data *sdata)
285{ 279{
286 DEBUGFS_DEL(channel_use, ap); 280 DEBUGFS_DEL(channel_use, ap);
287 DEBUGFS_DEL(drop_unencrypted, ap); 281 DEBUGFS_DEL(drop_unencrypted, ap);
288 DEBUGFS_DEL(eapol, ap); 282 DEBUGFS_DEL(ieee802_1x_pac, ap);
289 DEBUGFS_DEL(ieee8021_x, ap);
290 DEBUGFS_DEL(num_sta_ps, ap); 283 DEBUGFS_DEL(num_sta_ps, ap);
291 DEBUGFS_DEL(dtim_period, ap); 284 DEBUGFS_DEL(dtim_period, ap);
292 DEBUGFS_DEL(dtim_count, ap); 285 DEBUGFS_DEL(dtim_count, ap);
@@ -302,8 +295,7 @@ static void del_wds_files(struct ieee80211_sub_if_data *sdata)
302{ 295{
303 DEBUGFS_DEL(channel_use, wds); 296 DEBUGFS_DEL(channel_use, wds);
304 DEBUGFS_DEL(drop_unencrypted, wds); 297 DEBUGFS_DEL(drop_unencrypted, wds);
305 DEBUGFS_DEL(eapol, wds); 298 DEBUGFS_DEL(ieee802_1x_pac, wds);
306 DEBUGFS_DEL(ieee8021_x, wds);
307 DEBUGFS_DEL(peer, wds); 299 DEBUGFS_DEL(peer, wds);
308} 300}
309 301
@@ -311,8 +303,7 @@ static void del_vlan_files(struct ieee80211_sub_if_data *sdata)
311{ 303{
312 DEBUGFS_DEL(channel_use, vlan); 304 DEBUGFS_DEL(channel_use, vlan);
313 DEBUGFS_DEL(drop_unencrypted, vlan); 305 DEBUGFS_DEL(drop_unencrypted, vlan);
314 DEBUGFS_DEL(eapol, vlan); 306 DEBUGFS_DEL(ieee802_1x_pac, vlan);
315 DEBUGFS_DEL(ieee8021_x, vlan);
316} 307}
317 308
318static void del_monitor_files(struct ieee80211_sub_if_data *sdata) 309static void del_monitor_files(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index b54ed5fe4aa3..214109b8d95a 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -306,11 +306,11 @@ struct ieee80211_sub_if_data {
306 unsigned int flags; 306 unsigned int flags;
307 307
308 int drop_unencrypted; 308 int drop_unencrypted;
309 int eapol; /* 0 = process EAPOL frames as normal data frames, 309 /*
310 * 1 = send EAPOL frames through wlan#ap to hostapd 310 * IEEE 802.1X Port access control in effect,
311 * (default) */ 311 * drop packets to/from unauthorized port
312 int ieee802_1x; /* IEEE 802.1X PAE - drop packet to/from unauthorized 312 */
313 * port */ 313 int ieee802_1x_pac;
314 314
315 u16 sequence; 315 u16 sequence;
316 316
@@ -339,8 +339,7 @@ struct ieee80211_sub_if_data {
339 struct { 339 struct {
340 struct dentry *channel_use; 340 struct dentry *channel_use;
341 struct dentry *drop_unencrypted; 341 struct dentry *drop_unencrypted;
342 struct dentry *eapol; 342 struct dentry *ieee802_1x_pac;
343 struct dentry *ieee8021_x;
344 struct dentry *state; 343 struct dentry *state;
345 struct dentry *bssid; 344 struct dentry *bssid;
346 struct dentry *prev_bssid; 345 struct dentry *prev_bssid;
@@ -359,8 +358,7 @@ struct ieee80211_sub_if_data {
359 struct { 358 struct {
360 struct dentry *channel_use; 359 struct dentry *channel_use;
361 struct dentry *drop_unencrypted; 360 struct dentry *drop_unencrypted;
362 struct dentry *eapol; 361 struct dentry *ieee802_1x_pac;
363 struct dentry *ieee8021_x;
364 struct dentry *num_sta_ps; 362 struct dentry *num_sta_ps;
365 struct dentry *dtim_period; 363 struct dentry *dtim_period;
366 struct dentry *dtim_count; 364 struct dentry *dtim_count;
@@ -374,15 +372,13 @@ struct ieee80211_sub_if_data {
374 struct { 372 struct {
375 struct dentry *channel_use; 373 struct dentry *channel_use;
376 struct dentry *drop_unencrypted; 374 struct dentry *drop_unencrypted;
377 struct dentry *eapol; 375 struct dentry *ieee802_1x_pac;
378 struct dentry *ieee8021_x;
379 struct dentry *peer; 376 struct dentry *peer;
380 } wds; 377 } wds;
381 struct { 378 struct {
382 struct dentry *channel_use; 379 struct dentry *channel_use;
383 struct dentry *drop_unencrypted; 380 struct dentry *drop_unencrypted;
384 struct dentry *eapol; 381 struct dentry *ieee802_1x_pac;
385 struct dentry *ieee8021_x;
386 } vlan; 382 } vlan;
387 struct { 383 struct {
388 struct dentry *mode; 384 struct dentry *mode;
diff --git a/net/mac80211/ieee80211_iface.c b/net/mac80211/ieee80211_iface.c
index 43e505d29452..7cfd8660b231 100644
--- a/net/mac80211/ieee80211_iface.c
+++ b/net/mac80211/ieee80211_iface.c
@@ -22,7 +22,6 @@ void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata)
22 22
23 /* Default values for sub-interface parameters */ 23 /* Default values for sub-interface parameters */
24 sdata->drop_unencrypted = 0; 24 sdata->drop_unencrypted = 0;
25 sdata->eapol = 1;
26 for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) 25 for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
27 skb_queue_head_init(&sdata->fragments[i].skb_list); 26 skb_queue_head_init(&sdata->fragments[i].skb_list);
28 27
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index e65da5780cd3..505159f8dffc 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -208,7 +208,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
208 rthdr->it_len = cpu_to_le16(rtap_len); 208 rthdr->it_len = cpu_to_le16(rtap_len);
209 } 209 }
210 210
211 skb_set_mac_header(skb, 0); 211 skb_reset_mac_header(skb);
212 skb->ip_summed = CHECKSUM_UNNECESSARY; 212 skb->ip_summed = CHECKSUM_UNNECESSARY;
213 skb->pkt_type = PACKET_OTHERHOST; 213 skb->pkt_type = PACKET_OTHERHOST;
214 skb->protocol = htons(ETH_P_802_2); 214 skb->protocol = htons(ETH_P_802_2);
@@ -405,18 +405,6 @@ ieee80211_rx_h_check(struct ieee80211_txrx_data *rx)
405 return TXRX_DROP; 405 return TXRX_DROP;
406 } 406 }
407 407
408 if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
409 rx->skb->pkt_type = PACKET_OTHERHOST;
410 else if (compare_ether_addr(rx->dev->dev_addr, hdr->addr1) == 0)
411 rx->skb->pkt_type = PACKET_HOST;
412 else if (is_multicast_ether_addr(hdr->addr1)) {
413 if (is_broadcast_ether_addr(hdr->addr1))
414 rx->skb->pkt_type = PACKET_BROADCAST;
415 else
416 rx->skb->pkt_type = PACKET_MULTICAST;
417 } else
418 rx->skb->pkt_type = PACKET_OTHERHOST;
419
420 /* Drop disallowed frame classes based on STA auth/assoc state; 408 /* Drop disallowed frame classes based on STA auth/assoc state;
421 * IEEE 802.11, Chap 5.5. 409 * IEEE 802.11, Chap 5.5.
422 * 410 *
@@ -990,18 +978,10 @@ ieee80211_rx_h_remove_qos_control(struct ieee80211_txrx_data *rx)
990} 978}
991 979
992static int 980static int
993ieee80211_drop_802_1x_pae(struct ieee80211_txrx_data *rx, int hdrlen) 981ieee80211_802_1x_port_control(struct ieee80211_txrx_data *rx)
994{ 982{
995 if (rx->sdata->eapol && ieee80211_is_eapol(rx->skb, hdrlen) && 983 if (unlikely(rx->sdata->ieee802_1x_pac &&
996 rx->sdata->type != IEEE80211_IF_TYPE_STA && 984 (!rx->sta || !(rx->sta->flags & WLAN_STA_AUTHORIZED)))) {
997 (rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
998 return 0;
999
1000 if (unlikely(rx->sdata->ieee802_1x &&
1001 (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
1002 (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_NULLFUNC &&
1003 (!rx->sta || !(rx->sta->flags & WLAN_STA_AUTHORIZED)) &&
1004 !ieee80211_is_eapol(rx->skb, hdrlen))) {
1005#ifdef CONFIG_MAC80211_DEBUG 985#ifdef CONFIG_MAC80211_DEBUG
1006 printk(KERN_DEBUG "%s: dropped frame " 986 printk(KERN_DEBUG "%s: dropped frame "
1007 "(unauthorized port)\n", rx->dev->name); 987 "(unauthorized port)\n", rx->dev->name);
@@ -1013,7 +993,7 @@ ieee80211_drop_802_1x_pae(struct ieee80211_txrx_data *rx, int hdrlen)
1013} 993}
1014 994
1015static int 995static int
1016ieee80211_drop_unencrypted(struct ieee80211_txrx_data *rx, int hdrlen) 996ieee80211_drop_unencrypted(struct ieee80211_txrx_data *rx)
1017{ 997{
1018 /* 998 /*
1019 * Pass through unencrypted frames if the hardware has 999 * Pass through unencrypted frames if the hardware has
@@ -1026,9 +1006,7 @@ ieee80211_drop_unencrypted(struct ieee80211_txrx_data *rx, int hdrlen)
1026 if (unlikely(!(rx->fc & IEEE80211_FCTL_PROTECTED) && 1006 if (unlikely(!(rx->fc & IEEE80211_FCTL_PROTECTED) &&
1027 (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && 1007 (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
1028 (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_NULLFUNC && 1008 (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_NULLFUNC &&
1029 (rx->key || rx->sdata->drop_unencrypted) && 1009 (rx->key || rx->sdata->drop_unencrypted))) {
1030 (rx->sdata->eapol == 0 ||
1031 !ieee80211_is_eapol(rx->skb, hdrlen)))) {
1032 if (net_ratelimit()) 1010 if (net_ratelimit())
1033 printk(KERN_DEBUG "%s: RX non-WEP frame, but expected " 1011 printk(KERN_DEBUG "%s: RX non-WEP frame, but expected "
1034 "encryption\n", rx->dev->name); 1012 "encryption\n", rx->dev->name);
@@ -1156,6 +1134,7 @@ ieee80211_data_to_8023(struct ieee80211_txrx_data *rx)
1156 } else { 1134 } else {
1157 struct ethhdr *ehdr; 1135 struct ethhdr *ehdr;
1158 __be16 len; 1136 __be16 len;
1137
1159 skb_pull(skb, hdrlen); 1138 skb_pull(skb, hdrlen);
1160 len = htons(skb->len); 1139 len = htons(skb->len);
1161 ehdr = (struct ethhdr *) skb_push(skb, sizeof(struct ethhdr)); 1140 ehdr = (struct ethhdr *) skb_push(skb, sizeof(struct ethhdr));
@@ -1166,6 +1145,34 @@ ieee80211_data_to_8023(struct ieee80211_txrx_data *rx)
1166 return 0; 1145 return 0;
1167} 1146}
1168 1147
1148/*
1149 * requires that rx->skb is a frame with ethernet header
1150 */
1151static bool ieee80211_frame_allowed(struct ieee80211_txrx_data *rx)
1152{
1153 static const u8 pae_group_addr[ETH_ALEN]
1154 = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x03 };
1155 struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data;
1156
1157 /*
1158 * Allow EAPOL frames to us/the PAE group address regardless
1159 * of whether the frame was encrypted or not.
1160 */
1161 if (ehdr->h_proto == htons(ETH_P_PAE) &&
1162 (compare_ether_addr(ehdr->h_dest, rx->dev->dev_addr) == 0 ||
1163 compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0))
1164 return true;
1165
1166 if (ieee80211_802_1x_port_control(rx) ||
1167 ieee80211_drop_unencrypted(rx))
1168 return false;
1169
1170 return true;
1171}
1172
1173/*
1174 * requires that rx->skb is a frame with ethernet header
1175 */
1169static void 1176static void
1170ieee80211_deliver_skb(struct ieee80211_txrx_data *rx) 1177ieee80211_deliver_skb(struct ieee80211_txrx_data *rx)
1171{ 1178{
@@ -1173,31 +1180,32 @@ ieee80211_deliver_skb(struct ieee80211_txrx_data *rx)
1173 struct ieee80211_local *local = rx->local; 1180 struct ieee80211_local *local = rx->local;
1174 struct sk_buff *skb, *xmit_skb; 1181 struct sk_buff *skb, *xmit_skb;
1175 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1182 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1183 struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data;
1184 struct sta_info *dsta;
1176 1185
1177 skb = rx->skb; 1186 skb = rx->skb;
1178 xmit_skb = NULL; 1187 xmit_skb = NULL;
1179 1188
1180 if (local->bridge_packets && (sdata->type == IEEE80211_IF_TYPE_AP 1189 if (local->bridge_packets && (sdata->type == IEEE80211_IF_TYPE_AP ||
1181 || sdata->type == IEEE80211_IF_TYPE_VLAN) && 1190 sdata->type == IEEE80211_IF_TYPE_VLAN) &&
1182 (rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) { 1191 (rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) {
1183 if (is_multicast_ether_addr(skb->data)) { 1192 if (is_multicast_ether_addr(ehdr->h_dest)) {
1184 /* send multicast frames both to higher layers in 1193 /*
1185 * local net stack and back to the wireless media */ 1194 * send multicast frames both to higher layers in
1195 * local net stack and back to the wireless medium
1196 */
1186 xmit_skb = skb_copy(skb, GFP_ATOMIC); 1197 xmit_skb = skb_copy(skb, GFP_ATOMIC);
1187 if (!xmit_skb && net_ratelimit()) 1198 if (!xmit_skb && net_ratelimit())
1188 printk(KERN_DEBUG "%s: failed to clone " 1199 printk(KERN_DEBUG "%s: failed to clone "
1189 "multicast frame\n", dev->name); 1200 "multicast frame\n", dev->name);
1190 } else { 1201 } else {
1191 struct sta_info *dsta;
1192 dsta = sta_info_get(local, skb->data); 1202 dsta = sta_info_get(local, skb->data);
1193 if (dsta && !dsta->dev) { 1203 if (dsta && dsta->dev == dev) {
1194 if (net_ratelimit()) 1204 /*
1195 printk(KERN_DEBUG "Station with null " 1205 * The destination station is associated to
1196 "dev structure!\n"); 1206 * this AP (in this VLAN), so send the frame
1197 } else if (dsta && dsta->dev == dev) { 1207 * directly to it and do not pass it to local
1198 /* Destination station is associated to this 1208 * net stack.
1199 * AP, so send the frame directly to it and
1200 * do not pass the frame to local net stack.
1201 */ 1209 */
1202 xmit_skb = skb; 1210 xmit_skb = skb;
1203 skb = NULL; 1211 skb = NULL;
@@ -1217,8 +1225,8 @@ ieee80211_deliver_skb(struct ieee80211_txrx_data *rx)
1217 if (xmit_skb) { 1225 if (xmit_skb) {
1218 /* send to wireless media */ 1226 /* send to wireless media */
1219 xmit_skb->protocol = htons(ETH_P_802_3); 1227 xmit_skb->protocol = htons(ETH_P_802_3);
1220 skb_set_network_header(xmit_skb, 0); 1228 skb_reset_network_header(xmit_skb);
1221 skb_set_mac_header(xmit_skb, 0); 1229 skb_reset_mac_header(xmit_skb);
1222 dev_queue_xmit(xmit_skb); 1230 dev_queue_xmit(xmit_skb);
1223 } 1231 }
1224} 1232}
@@ -1303,38 +1311,36 @@ ieee80211_rx_h_amsdu(struct ieee80211_txrx_data *rx)
1303 } 1311 }
1304 } 1312 }
1305 1313
1306 skb_set_network_header(frame, 0); 1314 skb_reset_network_header(frame);
1307 frame->dev = dev; 1315 frame->dev = dev;
1308 frame->priority = skb->priority; 1316 frame->priority = skb->priority;
1309 rx->skb = frame; 1317 rx->skb = frame;
1310 1318
1311 if ((ieee80211_drop_802_1x_pae(rx, 0)) ||
1312 (ieee80211_drop_unencrypted(rx, 0))) {
1313 if (skb == frame) /* last frame */
1314 return TXRX_DROP;
1315 dev_kfree_skb(frame);
1316 continue;
1317 }
1318
1319 payload = frame->data; 1319 payload = frame->data;
1320 ethertype = (payload[6] << 8) | payload[7]; 1320 ethertype = (payload[6] << 8) | payload[7];
1321 1321
1322 if (likely((compare_ether_addr(payload, rfc1042_header) == 0 && 1322 if (likely((compare_ether_addr(payload, rfc1042_header) == 0 &&
1323 ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || 1323 ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
1324 compare_ether_addr(payload, 1324 compare_ether_addr(payload,
1325 bridge_tunnel_header) == 0)) { 1325 bridge_tunnel_header) == 0)) {
1326 /* remove RFC1042 or Bridge-Tunnel 1326 /* remove RFC1042 or Bridge-Tunnel
1327 * encapsulation and replace EtherType */ 1327 * encapsulation and replace EtherType */
1328 skb_pull(frame, 6); 1328 skb_pull(frame, 6);
1329 memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN); 1329 memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN);
1330 memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN); 1330 memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN);
1331 } else { 1331 } else {
1332 memcpy(skb_push(frame, sizeof(__be16)), &len, 1332 memcpy(skb_push(frame, sizeof(__be16)),
1333 sizeof(__be16)); 1333 &len, sizeof(__be16));
1334 memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN); 1334 memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN);
1335 memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN); 1335 memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN);
1336 } 1336 }
1337 1337
1338 if (!ieee80211_frame_allowed(rx)) {
1339 if (skb == frame) /* last frame */
1340 return TXRX_DROP;
1341 dev_kfree_skb(frame);
1342 continue;
1343 }
1338 1344
1339 ieee80211_deliver_skb(rx); 1345 ieee80211_deliver_skb(rx);
1340 } 1346 }
@@ -1347,7 +1353,7 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
1347{ 1353{
1348 struct net_device *dev = rx->dev; 1354 struct net_device *dev = rx->dev;
1349 u16 fc; 1355 u16 fc;
1350 int err, hdrlen; 1356 int err;
1351 1357
1352 fc = rx->fc; 1358 fc = rx->fc;
1353 if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)) 1359 if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA))
@@ -1356,16 +1362,13 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
1356 if (unlikely(!WLAN_FC_DATA_PRESENT(fc))) 1362 if (unlikely(!WLAN_FC_DATA_PRESENT(fc)))
1357 return TXRX_DROP; 1363 return TXRX_DROP;
1358 1364
1359 hdrlen = ieee80211_get_hdrlen(fc);
1360
1361 if ((ieee80211_drop_802_1x_pae(rx, hdrlen)) ||
1362 (ieee80211_drop_unencrypted(rx, hdrlen)))
1363 return TXRX_DROP;
1364
1365 err = ieee80211_data_to_8023(rx); 1365 err = ieee80211_data_to_8023(rx);
1366 if (unlikely(err)) 1366 if (unlikely(err))
1367 return TXRX_DROP; 1367 return TXRX_DROP;
1368 1368
1369 if (!ieee80211_frame_allowed(rx))
1370 return TXRX_DROP;
1371
1369 rx->skb->dev = dev; 1372 rx->skb->dev = dev;
1370 1373
1371 dev->stats.rx_packets++; 1374 dev->stats.rx_packets++;
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;