aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-11-25 11:46:18 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-12-21 18:38:51 -0500
commitabe60632f311d515b082b450504ee24006023951 (patch)
treea51fc3b135fa8a31cc0d7953be43502ecc6433c6 /net/mac80211/rx.c
parent15920d8afc87861672e16fa95ae2764b065d6dd3 (diff)
mac80211: make station management completely depend on vif
The station management currently uses the virtual interface, but you cannot add the same station to multiple virtual interfaces if you're communicating with it in multiple ways. This restriction should be lifted so that in the future we can, for instance, support bluetooth 3 with an access point that mac80211 is already associated to. We can do that by requiring all sta_info_get users to provide the virtual interface and making the RX code aware that an address may match more than one station struct. Thanks to the previous patches this one isn't all that large and except for the RX and TX status paths changes has low complexity. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
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);