Commit 7852e36186d2a1983c215836d7e3d7b8927c930d

Authored by Johannes Berg
Committed by John W. Linville
1 parent a4ec45a421

mac80211: remove dummy STA support

The dummy STA support was added because I didn't
want to change the driver API at the time. Now
that we have state transitions triggering station
add/remove in the driver, we only call add once a
station reaches ASSOCIATED, so we can remove the
dummy station stuff again.

While at it, tighten the RX check and accept only
port control (EAP) frames from the AP station if
it's not associated yet -- in other cases there's
no race.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

Showing 4 changed files with 38 additions and 155 deletions Side-by-side Diff

... ... @@ -1581,7 +1581,7 @@
1581 1581 * station info was already allocated and inserted before
1582 1582 * the association and should be available to us
1583 1583 */
1584   - sta = sta_info_get_rx(sdata, cbss->bssid);
  1584 + sta = sta_info_get(sdata, cbss->bssid);
1585 1585 if (WARN_ON(!sta)) {
1586 1586 mutex_unlock(&sdata->local->sta_mtx);
1587 1587 return false;
... ... @@ -1648,14 +1648,7 @@
1648 1648 return false;
1649 1649 }
1650 1650  
1651   - /* sta_info_reinsert will also unlock the mutex lock */
1652   - err = sta_info_reinsert(sta);
1653   - sta = NULL;
1654   - if (err) {
1655   - printk(KERN_DEBUG "%s: failed to insert STA entry for"
1656   - " the AP (error %d)\n", sdata->name, err);
1657   - return false;
1658   - }
  1651 + mutex_unlock(&sdata->local->sta_mtx);
1659 1652  
1660 1653 /*
1661 1654 * Always handle WMM once after association regardless
1662 1655  
... ... @@ -2536,12 +2529,10 @@
2536 2529 if (!sta)
2537 2530 return -ENOMEM;
2538 2531  
2539   - sta->dummy = true;
2540   -
2541 2532 err = sta_info_insert(sta);
2542 2533 sta = NULL;
2543 2534 if (err) {
2544   - printk(KERN_DEBUG "%s: failed to insert Dummy STA entry for"
  2535 + printk(KERN_DEBUG "%s: failed to insert STA entry for"
2545 2536 " the AP (error %d)\n", sdata->name, err);
2546 2537 return err;
2547 2538 }
... ... @@ -859,7 +859,12 @@
859 859 rx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
860 860 rx->sdata->vif.type != NL80211_IFTYPE_WDS &&
861 861 (!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC)))) {
862   - if (rx->sta && rx->sta->dummy &&
  862 + /*
  863 + * accept port control frames from the AP even when it's not
  864 + * yet marked ASSOC to prevent a race where we don't set the
  865 + * assoc bit quickly enough before it sends the first frame
  866 + */
  867 + if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
863 868 ieee80211_is_data_present(hdr->frame_control)) {
864 869 u16 ethertype;
865 870 u8 *payload;
... ... @@ -2949,7 +2954,7 @@
2949 2954 if (ieee80211_is_data(fc)) {
2950 2955 prev_sta = NULL;
2951 2956  
2952   - for_each_sta_info_rx(local, hdr->addr2, sta, tmp) {
  2957 + for_each_sta_info(local, hdr->addr2, sta, tmp) {
2953 2958 if (!prev_sta) {
2954 2959 prev_sta = sta;
2955 2960 continue;
... ... @@ -2993,7 +2998,7 @@
2993 2998 continue;
2994 2999 }
2995 3000  
2996   - rx.sta = sta_info_get_bss_rx(prev, hdr->addr2);
  3001 + rx.sta = sta_info_get_bss(prev, hdr->addr2);
2997 3002 rx.sdata = prev;
2998 3003 ieee80211_prepare_and_rx_handle(&rx, skb, false);
2999 3004  
... ... @@ -3001,7 +3006,7 @@
3001 3006 }
3002 3007  
3003 3008 if (prev) {
3004   - rx.sta = sta_info_get_bss_rx(prev, hdr->addr2);
  3009 + rx.sta = sta_info_get_bss(prev, hdr->addr2);
3005 3010 rx.sdata = prev;
3006 3011  
3007 3012 if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
net/mac80211/sta_info.c
... ... @@ -100,25 +100,6 @@
100 100 sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
101 101 lockdep_is_held(&local->sta_mtx));
102 102 while (sta) {
103   - if (sta->sdata == sdata && !sta->dummy &&
104   - memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
105   - break;
106   - sta = rcu_dereference_check(sta->hnext,
107   - lockdep_is_held(&local->sta_mtx));
108   - }
109   - return sta;
110   -}
111   -
112   -/* get a station info entry even if it is a dummy station*/
113   -struct sta_info *sta_info_get_rx(struct ieee80211_sub_if_data *sdata,
114   - const u8 *addr)
115   -{
116   - struct ieee80211_local *local = sdata->local;
117   - struct sta_info *sta;
118   -
119   - sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
120   - lockdep_is_held(&local->sta_mtx));
121   - while (sta) {
122 103 if (sta->sdata == sdata &&
123 104 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
124 105 break;
... ... @@ -143,7 +124,6 @@
143 124 while (sta) {
144 125 if ((sta->sdata == sdata ||
145 126 (sta->sdata->bss && sta->sdata->bss == sdata->bss)) &&
146   - !sta->dummy &&
147 127 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
148 128 break;
149 129 sta = rcu_dereference_check(sta->hnext,
... ... @@ -152,29 +132,6 @@
152 132 return sta;
153 133 }
154 134  
155   -/*
156   - * Get sta info either from the specified interface
157   - * or from one of its vlans (including dummy stations)
158   - */
159   -struct sta_info *sta_info_get_bss_rx(struct ieee80211_sub_if_data *sdata,
160   - const u8 *addr)
161   -{
162   - struct ieee80211_local *local = sdata->local;
163   - struct sta_info *sta;
164   -
165   - sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
166   - lockdep_is_held(&local->sta_mtx));
167   - while (sta) {
168   - if ((sta->sdata == sdata ||
169   - (sta->sdata->bss && sta->sdata->bss == sdata->bss)) &&
170   - memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
171   - break;
172   - sta = rcu_dereference_check(sta->hnext,
173   - lockdep_is_held(&local->sta_mtx));
174   - }
175   - return sta;
176   -}
177   -
178 135 struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata,
179 136 int idx)
180 137 {
181 138  
182 139  
183 140  
184 141  
185 142  
186 143  
187 144  
188 145  
189 146  
190 147  
... ... @@ -397,66 +354,43 @@
397 354 {
398 355 struct ieee80211_local *local = sta->local;
399 356 struct ieee80211_sub_if_data *sdata = sta->sdata;
400   - struct sta_info *exist_sta;
401   - bool dummy_reinsert = false;
  357 + struct station_info sinfo;
402 358 int err = 0;
403 359  
404 360 lockdep_assert_held(&local->sta_mtx);
405 361  
406   - /*
407   - * check if STA exists already.
408   - * only accept a scenario of a second call to sta_info_insert_finish
409   - * with a dummy station entry that was inserted earlier
410   - * in that case - assume that the dummy station flag should
411   - * be removed.
412   - */
413   - exist_sta = sta_info_get_bss_rx(sdata, sta->sta.addr);
414   - if (exist_sta) {
415   - if (exist_sta == sta && sta->dummy) {
416   - dummy_reinsert = true;
417   - } else {
418   - err = -EEXIST;
419   - goto out_err;
420   - }
  362 + /* check if STA exists already */
  363 + if (sta_info_get_bss(sdata, sta->sta.addr)) {
  364 + err = -EEXIST;
  365 + goto out_err;
421 366 }
422 367  
423   - if (!sta->dummy || dummy_reinsert) {
424   - /* notify driver */
425   - err = sta_info_insert_drv_state(local, sdata, sta);
426   - if (err)
427   - goto out_err;
428   - }
  368 + /* notify driver */
  369 + err = sta_info_insert_drv_state(local, sdata, sta);
  370 + if (err)
  371 + goto out_err;
429 372  
430   - if (!dummy_reinsert) {
431   - local->num_sta++;
432   - local->sta_generation++;
433   - smp_mb();
  373 + local->num_sta++;
  374 + local->sta_generation++;
  375 + smp_mb();
434 376  
435   - /* make the station visible */
436   - sta_info_hash_add(local, sta);
  377 + /* make the station visible */
  378 + sta_info_hash_add(local, sta);
437 379  
438   - list_add(&sta->list, &local->sta_list);
  380 + list_add(&sta->list, &local->sta_list);
439 381  
440   - set_sta_flag(sta, WLAN_STA_INSERTED);
441   - } else {
442   - sta->dummy = false;
443   - }
  382 + set_sta_flag(sta, WLAN_STA_INSERTED);
444 383  
445   - if (!sta->dummy) {
446   - struct station_info sinfo;
  384 + ieee80211_sta_debugfs_add(sta);
  385 + rate_control_add_sta_debugfs(sta);
447 386  
448   - ieee80211_sta_debugfs_add(sta);
449   - rate_control_add_sta_debugfs(sta);
  387 + memset(&sinfo, 0, sizeof(sinfo));
  388 + sinfo.filled = 0;
  389 + sinfo.generation = local->sta_generation;
  390 + cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
450 391  
451   - memset(&sinfo, 0, sizeof(sinfo));
452   - sinfo.filled = 0;
453   - sinfo.generation = local->sta_generation;
454   - cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
455   - }
456   -
457 392 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
458   - wiphy_debug(local->hw.wiphy, "Inserted %sSTA %pM\n",
459   - sta->dummy ? "dummy " : "", sta->sta.addr);
  393 + wiphy_debug(local->hw.wiphy, "Inserted STA %pM\n", sta->sta.addr);
460 394 #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
461 395  
462 396 /* move reference to rcu-protected */
... ... @@ -508,25 +442,6 @@
508 442 return err;
509 443 }
510 444  
511   -/* Caller must hold sta->local->sta_mtx */
512   -int sta_info_reinsert(struct sta_info *sta)
513   -{
514   - struct ieee80211_local *local = sta->local;
515   - int err = 0;
516   -
517   - err = sta_info_insert_check(sta);
518   - if (err) {
519   - mutex_unlock(&local->sta_mtx);
520   - return err;
521   - }
522   -
523   - might_sleep();
524   -
525   - err = sta_info_insert_finish(sta);
526   - rcu_read_unlock();
527   - return err;
528   -}
529   -
530 445 static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid)
531 446 {
532 447 /*
... ... @@ -873,7 +788,7 @@
873 788 int ret;
874 789  
875 790 mutex_lock(&sdata->local->sta_mtx);
876   - sta = sta_info_get_rx(sdata, addr);
  791 + sta = sta_info_get(sdata, addr);
877 792 ret = __sta_info_destroy(sta);
878 793 mutex_unlock(&sdata->local->sta_mtx);
879 794  
... ... @@ -887,7 +802,7 @@
887 802 int ret;
888 803  
889 804 mutex_lock(&sdata->local->sta_mtx);
890   - sta = sta_info_get_bss_rx(sdata, addr);
  805 + sta = sta_info_get_bss(sdata, addr);
891 806 ret = __sta_info_destroy(sta);
892 807 mutex_unlock(&sdata->local->sta_mtx);
893 808  
net/mac80211/sta_info.h
... ... @@ -265,8 +265,6 @@
265 265 * @dead: set to true when sta is unlinked
266 266 * @uploaded: set to true when sta is uploaded to the driver
267 267 * @lost_packets: number of consecutive lost packets
268   - * @dummy: indicate a dummy station created for receiving
269   - * EAP frames before association
270 268 * @sta: station information we share with the driver
271 269 * @sta_state: duplicates information about station state (for debug)
272 270 * @beacon_loss_count: number of times beacon loss has triggered
... ... @@ -364,9 +362,6 @@
364 362 unsigned int lost_packets;
365 363 unsigned int beacon_loss_count;
366 364  
367   - /* should be right in front of sta to be in the same cache line */
368   - bool dummy;
369   -
370 365 /* keep last! */
371 366 struct ieee80211_sta sta;
372 367 };
373 368  
... ... @@ -468,15 +463,9 @@
468 463 struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
469 464 const u8 *addr);
470 465  
471   -struct sta_info *sta_info_get_rx(struct ieee80211_sub_if_data *sdata,
472   - const u8 *addr);
473   -
474 466 struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
475 467 const u8 *addr);
476 468  
477   -struct sta_info *sta_info_get_bss_rx(struct ieee80211_sub_if_data *sdata,
478   - const u8 *addr);
479   -
480 469 static inline
481 470 void for_each_sta_info_type_check(struct ieee80211_local *local,
482 471 const u8 *addr,
... ... @@ -485,7 +474,7 @@
485 474 {
486 475 }
487 476  
488   -#define for_each_sta_info(local, _addr, _sta, nxt) \
  477 +#define for_each_sta_info(local, _addr, _sta, nxt) \
489 478 for ( /* initialise loop */ \
490 479 _sta = rcu_dereference(local->sta_hash[STA_HASH(_addr)]),\
491 480 nxt = _sta ? rcu_dereference(_sta->hnext) : NULL; \
... ... @@ -497,22 +486,6 @@
497 486 _sta = nxt, \
498 487 nxt = _sta ? rcu_dereference(_sta->hnext) : NULL \
499 488 ) \
500   - /* run code only if address matches and it's not a dummy sta */ \
501   - if (memcmp(_sta->sta.addr, (_addr), ETH_ALEN) == 0 && \
502   - !_sta->dummy)
503   -
504   -#define for_each_sta_info_rx(local, _addr, _sta, nxt) \
505   - for ( /* initialise loop */ \
506   - _sta = rcu_dereference(local->sta_hash[STA_HASH(_addr)]),\
507   - nxt = _sta ? rcu_dereference(_sta->hnext) : NULL; \
508   - /* typecheck */ \
509   - for_each_sta_info_type_check(local, (_addr), _sta, nxt),\
510   - /* continue condition */ \
511   - _sta; \
512   - /* advance loop */ \
513   - _sta = nxt, \
514   - nxt = _sta ? rcu_dereference(_sta->hnext) : NULL \
515   - ) \
516 489 /* compare address and run code only if it matches */ \
517 490 if (memcmp(_sta->sta.addr, (_addr), ETH_ALEN) == 0)
518 491  
... ... @@ -540,7 +513,6 @@
540 513 */
541 514 int sta_info_insert(struct sta_info *sta);
542 515 int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU);
543   -int sta_info_reinsert(struct sta_info *sta);
544 516  
545 517 int __must_check __sta_info_destroy(struct sta_info *sta);
546 518 int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata,