aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c119
1 files changed, 64 insertions, 55 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index f237df408378..5bae28693da8 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1472,7 +1472,6 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
1472{ 1472{
1473 struct ieee80211_sub_if_data *sdata = rx->sdata; 1473 struct ieee80211_sub_if_data *sdata = rx->sdata;
1474 struct net_device *dev = sdata->dev; 1474 struct net_device *dev = sdata->dev;
1475 struct ieee80211_local *local = rx->local;
1476 struct sk_buff *skb, *xmit_skb; 1475 struct sk_buff *skb, *xmit_skb;
1477 struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; 1476 struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data;
1478 struct sta_info *dsta; 1477 struct sta_info *dsta;
@@ -1495,8 +1494,8 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
1495 printk(KERN_DEBUG "%s: failed to clone " 1494 printk(KERN_DEBUG "%s: failed to clone "
1496 "multicast frame\n", dev->name); 1495 "multicast frame\n", dev->name);
1497 } else { 1496 } else {
1498 dsta = sta_info_get(local, skb->data); 1497 dsta = sta_info_get(sdata, skb->data);
1499 if (dsta && dsta->sdata->dev == dev) { 1498 if (dsta) {
1500 /* 1499 /*
1501 * The destination station is associated to 1500 * The destination station is associated to
1502 * this AP (in this VLAN), so send the frame 1501 * this AP (in this VLAN), so send the frame
@@ -2363,6 +2362,8 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2363 int prepares; 2362 int prepares;
2364 struct ieee80211_sub_if_data *prev = NULL; 2363 struct ieee80211_sub_if_data *prev = NULL;
2365 struct sk_buff *skb_new; 2364 struct sk_buff *skb_new;
2365 struct sta_info *sta, *tmp;
2366 bool found_sta = false;
2366 2367
2367 hdr = (struct ieee80211_hdr *)skb->data; 2368 hdr = (struct ieee80211_hdr *)skb->data;
2368 memset(&rx, 0, sizeof(rx)); 2369 memset(&rx, 0, sizeof(rx));
@@ -2379,68 +2380,76 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2379 ieee80211_parse_qos(&rx); 2380 ieee80211_parse_qos(&rx);
2380 ieee80211_verify_alignment(&rx); 2381 ieee80211_verify_alignment(&rx);
2381 2382
2382 rx.sta = sta_info_get(local, hdr->addr2); 2383 if (ieee80211_is_data(hdr->frame_control)) {
2383 if (rx.sta) 2384 for_each_sta_info(local, hdr->addr2, sta, tmp) {
2384 rx.sdata = rx.sta->sdata; 2385 rx.sta = sta;
2385 2386 found_sta = true;
2386 if (rx.sdata && ieee80211_is_data(hdr->frame_control)) { 2387 rx.sdata = sta->sdata;
2387 rx.flags |= IEEE80211_RX_RA_MATCH; 2388
2388 prepares = prepare_for_handlers(rx.sdata, &rx, hdr); 2389 rx.flags |= IEEE80211_RX_RA_MATCH;
2389 if (prepares) { 2390 prepares = prepare_for_handlers(rx.sdata, &rx, hdr);
2390 if (status->flag & RX_FLAG_MMIC_ERROR) { 2391 if (prepares) {
2391 if (rx.flags & IEEE80211_RX_RA_MATCH) 2392 if (status->flag & RX_FLAG_MMIC_ERROR) {
2392 ieee80211_rx_michael_mic_report(hdr, &rx); 2393 if (rx.flags & IEEE80211_RX_RA_MATCH)
2393 } else 2394 ieee80211_rx_michael_mic_report(hdr, &rx);
2394 prev = rx.sdata; 2395 } else
2396 prev = rx.sdata;
2397 }
2395 } 2398 }
2396 } else list_for_each_entry_rcu(sdata, &local->interfaces, list) { 2399 }
2397 if (!netif_running(sdata->dev)) 2400 if (!found_sta) {
2398 continue; 2401 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
2402 if (!netif_running(sdata->dev))
2403 continue;
2399 2404
2400 if (sdata->vif.type == NL80211_IFTYPE_MONITOR || 2405 if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
2401 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 2406 sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
2402 continue; 2407 continue;
2403 2408
2404 rx.flags |= IEEE80211_RX_RA_MATCH; 2409 rx.sta = sta_info_get(sdata, hdr->addr2);
2405 prepares = prepare_for_handlers(sdata, &rx, hdr);
2406 2410
2407 if (!prepares) 2411 rx.flags |= IEEE80211_RX_RA_MATCH;
2408 continue; 2412 prepares = prepare_for_handlers(sdata, &rx, hdr);
2409 2413
2410 if (status->flag & RX_FLAG_MMIC_ERROR) { 2414 if (!prepares)
2411 rx.sdata = sdata; 2415 continue;
2412 if (rx.flags & IEEE80211_RX_RA_MATCH)
2413 ieee80211_rx_michael_mic_report(hdr, &rx);
2414 continue;
2415 }
2416 2416
2417 /* 2417 if (status->flag & RX_FLAG_MMIC_ERROR) {
2418 * frame is destined for this interface, but if it's not 2418 rx.sdata = sdata;
2419 * also for the previous one we handle that after the 2419 if (rx.flags & IEEE80211_RX_RA_MATCH)
2420 * loop to avoid copying the SKB once too much 2420 ieee80211_rx_michael_mic_report(hdr,
2421 */ 2421 &rx);
2422 continue;
2423 }
2422 2424
2423 if (!prev) { 2425 /*
2424 prev = sdata; 2426 * frame is destined for this interface, but if it's
2425 continue; 2427 * not also for the previous one we handle that after
2426 } 2428 * the loop to avoid copying the SKB once too much
2429 */
2427 2430
2428 /* 2431 if (!prev) {
2429 * frame was destined for the previous interface 2432 prev = sdata;
2430 * so invoke RX handlers for it 2433 continue;
2431 */ 2434 }
2432 2435
2433 skb_new = skb_copy(skb, GFP_ATOMIC); 2436 /*
2434 if (!skb_new) { 2437 * frame was destined for the previous interface
2435 if (net_ratelimit()) 2438 * so invoke RX handlers for it
2436 printk(KERN_DEBUG "%s: failed to copy " 2439 */
2437 "multicast frame for %s\n", 2440
2438 wiphy_name(local->hw.wiphy), 2441 skb_new = skb_copy(skb, GFP_ATOMIC);
2439 prev->dev->name); 2442 if (!skb_new) {
2440 continue; 2443 if (net_ratelimit())
2444 printk(KERN_DEBUG "%s: failed to copy "
2445 "multicast frame for %s\n",
2446 wiphy_name(local->hw.wiphy),
2447 prev->dev->name);
2448 continue;
2449 }
2450 ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate);
2451 prev = sdata;
2441 } 2452 }
2442 ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate);
2443 prev = sdata;
2444 } 2453 }
2445 if (prev) 2454 if (prev)
2446 ieee80211_invoke_rx_handlers(prev, &rx, skb, rate); 2455 ieee80211_invoke_rx_handlers(prev, &rx, skb, rate);