aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mesh_plink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mesh_plink.c')
-rw-r--r--net/mac80211/mesh_plink.c101
1 files changed, 52 insertions, 49 deletions
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index b5fbe970e48f..c2b80500ae72 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -65,14 +65,14 @@ static inline
65void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata) 65void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
66{ 66{
67 atomic_inc(&sdata->u.sta.mshstats.estab_plinks); 67 atomic_inc(&sdata->u.sta.mshstats.estab_plinks);
68 mesh_accept_plinks_update(sdata->dev); 68 mesh_accept_plinks_update(sdata);
69} 69}
70 70
71static inline 71static inline
72void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) 72void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
73{ 73{
74 atomic_dec(&sdata->u.sta.mshstats.estab_plinks); 74 atomic_dec(&sdata->u.sta.mshstats.estab_plinks);
75 mesh_accept_plinks_update(sdata->dev); 75 mesh_accept_plinks_update(sdata);
76} 76}
77 77
78/** 78/**
@@ -99,12 +99,13 @@ static inline void mesh_plink_fsm_restart(struct sta_info *sta)
99 * 99 *
100 * Returns: non-NULL on success, ERR_PTR() on error. 100 * Returns: non-NULL on success, ERR_PTR() on error.
101 */ 101 */
102struct sta_info *mesh_plink_add(u8 *hw_addr, u64 rates, struct net_device *dev) 102struct sta_info *mesh_plink_add(u8 *hw_addr, u64 rates,
103 struct ieee80211_sub_if_data *sdata)
103{ 104{
104 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 105 struct ieee80211_local *local = sdata->local;
105 struct sta_info *sta; 106 struct sta_info *sta;
106 107
107 if (memcmp(hw_addr, dev->dev_addr, ETH_ALEN) == 0) 108 if (compare_ether_addr(hw_addr, sdata->dev->dev_addr) == 0)
108 /* never add ourselves as neighbours */ 109 /* never add ourselves as neighbours */
109 return ERR_PTR(-EINVAL); 110 return ERR_PTR(-EINVAL);
110 111
@@ -114,7 +115,7 @@ struct sta_info *mesh_plink_add(u8 *hw_addr, u64 rates, struct net_device *dev)
114 if (local->num_sta >= MESH_MAX_PLINKS) 115 if (local->num_sta >= MESH_MAX_PLINKS)
115 return ERR_PTR(-ENOSPC); 116 return ERR_PTR(-ENOSPC);
116 117
117 sta = sta_info_add(local, dev, hw_addr, GFP_KERNEL); 118 sta = sta_info_add(sdata, hw_addr);
118 if (IS_ERR(sta)) 119 if (IS_ERR(sta))
119 return sta; 120 return sta;
120 121
@@ -125,7 +126,7 @@ struct sta_info *mesh_plink_add(u8 *hw_addr, u64 rates, struct net_device *dev)
125 sta->supp_rates[local->hw.conf.channel->band] = rates; 126 sta->supp_rates[local->hw.conf.channel->band] = rates;
126 rate_control_rate_init(sta, local); 127 rate_control_rate_init(sta, local);
127 128
128 mesh_accept_plinks_update(dev); 129 mesh_accept_plinks_update(sdata);
129 130
130 return sta; 131 return sta;
131} 132}
@@ -141,7 +142,8 @@ struct sta_info *mesh_plink_add(u8 *hw_addr, u64 rates, struct net_device *dev)
141 */ 142 */
142static void __mesh_plink_deactivate(struct sta_info *sta) 143static void __mesh_plink_deactivate(struct sta_info *sta)
143{ 144{
144 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); 145 struct ieee80211_sub_if_data *sdata = sta->sdata;
146
145 if (sta->plink_state == ESTAB) 147 if (sta->plink_state == ESTAB)
146 mesh_plink_dec_estab_count(sdata); 148 mesh_plink_dec_estab_count(sdata);
147 sta->plink_state = BLOCKED; 149 sta->plink_state = BLOCKED;
@@ -246,11 +248,15 @@ void mesh_neighbour_update(u8 *hw_addr, u64 rates, struct net_device *dev,
246 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 248 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
247 struct sta_info *sta; 249 struct sta_info *sta;
248 250
251 rcu_read_lock();
252
249 sta = sta_info_get(local, hw_addr); 253 sta = sta_info_get(local, hw_addr);
250 if (!sta) { 254 if (!sta) {
251 sta = mesh_plink_add(hw_addr, rates, dev); 255 sta = mesh_plink_add(hw_addr, rates, sdata);
252 if (IS_ERR(sta)) 256 if (IS_ERR(sta)) {
257 rcu_read_unlock();
253 return; 258 return;
259 }
254 } 260 }
255 261
256 sta->last_rx = jiffies; 262 sta->last_rx = jiffies;
@@ -260,7 +266,7 @@ void mesh_neighbour_update(u8 *hw_addr, u64 rates, struct net_device *dev,
260 sdata->u.sta.mshcfg.auto_open_plinks) 266 sdata->u.sta.mshcfg.auto_open_plinks)
261 mesh_plink_open(sta); 267 mesh_plink_open(sta);
262 268
263 sta_info_put(sta); 269 rcu_read_unlock();
264} 270}
265 271
266static void mesh_plink_timer(unsigned long data) 272static void mesh_plink_timer(unsigned long data)
@@ -273,6 +279,11 @@ static void mesh_plink_timer(unsigned long data)
273 DECLARE_MAC_BUF(mac); 279 DECLARE_MAC_BUF(mac);
274#endif 280#endif
275 281
282 /*
283 * This STA is valid because sta_info_destroy() will
284 * del_timer_sync() this timer after having made sure
285 * it cannot be readded (by deleting the plink.)
286 */
276 sta = (struct sta_info *) data; 287 sta = (struct sta_info *) data;
277 288
278 spin_lock_bh(&sta->plink_lock); 289 spin_lock_bh(&sta->plink_lock);
@@ -286,8 +297,8 @@ static void mesh_plink_timer(unsigned long data)
286 reason = 0; 297 reason = 0;
287 llid = sta->llid; 298 llid = sta->llid;
288 plid = sta->plid; 299 plid = sta->plid;
289 dev = sta->dev; 300 sdata = sta->sdata;
290 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 301 dev = sdata->dev;
291 302
292 switch (sta->plink_state) { 303 switch (sta->plink_state) {
293 case OPN_RCVD: 304 case OPN_RCVD:
@@ -302,8 +313,7 @@ static void mesh_plink_timer(unsigned long data)
302 sta->plink_timeout = sta->plink_timeout + 313 sta->plink_timeout = sta->plink_timeout +
303 rand % sta->plink_timeout; 314 rand % sta->plink_timeout;
304 ++sta->plink_retries; 315 ++sta->plink_retries;
305 if (!mod_plink_timer(sta, sta->plink_timeout)) 316 mod_plink_timer(sta, sta->plink_timeout);
306 __sta_info_get(sta);
307 spin_unlock_bh(&sta->plink_lock); 317 spin_unlock_bh(&sta->plink_lock);
308 mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, 318 mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid,
309 0, 0); 319 0, 0);
@@ -316,16 +326,14 @@ static void mesh_plink_timer(unsigned long data)
316 if (!reason) 326 if (!reason)
317 reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT); 327 reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT);
318 sta->plink_state = HOLDING; 328 sta->plink_state = HOLDING;
319 if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata))) 329 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
320 __sta_info_get(sta);
321 spin_unlock_bh(&sta->plink_lock); 330 spin_unlock_bh(&sta->plink_lock);
322 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid, 331 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid,
323 reason); 332 reason);
324 break; 333 break;
325 case HOLDING: 334 case HOLDING:
326 /* holding timer */ 335 /* holding timer */
327 if (del_timer(&sta->plink_timer)) 336 del_timer(&sta->plink_timer);
328 sta_info_put(sta);
329 mesh_plink_fsm_restart(sta); 337 mesh_plink_fsm_restart(sta);
330 spin_unlock_bh(&sta->plink_lock); 338 spin_unlock_bh(&sta->plink_lock);
331 break; 339 break;
@@ -333,8 +341,6 @@ static void mesh_plink_timer(unsigned long data)
333 spin_unlock_bh(&sta->plink_lock); 341 spin_unlock_bh(&sta->plink_lock);
334 break; 342 break;
335 } 343 }
336
337 sta_info_put(sta);
338} 344}
339 345
340static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout) 346static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout)
@@ -343,14 +349,13 @@ static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout)
343 sta->plink_timer.data = (unsigned long) sta; 349 sta->plink_timer.data = (unsigned long) sta;
344 sta->plink_timer.function = mesh_plink_timer; 350 sta->plink_timer.function = mesh_plink_timer;
345 sta->plink_timeout = timeout; 351 sta->plink_timeout = timeout;
346 __sta_info_get(sta);
347 add_timer(&sta->plink_timer); 352 add_timer(&sta->plink_timer);
348} 353}
349 354
350int mesh_plink_open(struct sta_info *sta) 355int mesh_plink_open(struct sta_info *sta)
351{ 356{
352 __le16 llid; 357 __le16 llid;
353 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); 358 struct ieee80211_sub_if_data *sdata = sta->sdata;
354#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG 359#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
355 DECLARE_MAC_BUF(mac); 360 DECLARE_MAC_BUF(mac);
356#endif 361#endif
@@ -360,7 +365,6 @@ int mesh_plink_open(struct sta_info *sta)
360 sta->llid = llid; 365 sta->llid = llid;
361 if (sta->plink_state != LISTEN) { 366 if (sta->plink_state != LISTEN) {
362 spin_unlock_bh(&sta->plink_lock); 367 spin_unlock_bh(&sta->plink_lock);
363 sta_info_put(sta);
364 return -EBUSY; 368 return -EBUSY;
365 } 369 }
366 sta->plink_state = OPN_SNT; 370 sta->plink_state = OPN_SNT;
@@ -369,7 +373,8 @@ int mesh_plink_open(struct sta_info *sta)
369 mpl_dbg("Mesh plink: starting establishment with %s\n", 373 mpl_dbg("Mesh plink: starting establishment with %s\n",
370 print_mac(mac, sta->addr)); 374 print_mac(mac, sta->addr));
371 375
372 return mesh_plink_frame_tx(sta->dev, PLINK_OPEN, sta->addr, llid, 0, 0); 376 return mesh_plink_frame_tx(sdata->dev, PLINK_OPEN,
377 sta->addr, llid, 0, 0);
373} 378}
374 379
375void mesh_plink_block(struct sta_info *sta) 380void mesh_plink_block(struct sta_info *sta)
@@ -386,7 +391,7 @@ void mesh_plink_block(struct sta_info *sta)
386 391
387int mesh_plink_close(struct sta_info *sta) 392int mesh_plink_close(struct sta_info *sta)
388{ 393{
389 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); 394 struct ieee80211_sub_if_data *sdata = sta->sdata;
390 int llid, plid, reason; 395 int llid, plid, reason;
391#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG 396#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
392 DECLARE_MAC_BUF(mac); 397 DECLARE_MAC_BUF(mac);
@@ -401,13 +406,11 @@ int mesh_plink_close(struct sta_info *sta)
401 if (sta->plink_state == LISTEN || sta->plink_state == BLOCKED) { 406 if (sta->plink_state == LISTEN || sta->plink_state == BLOCKED) {
402 mesh_plink_fsm_restart(sta); 407 mesh_plink_fsm_restart(sta);
403 spin_unlock_bh(&sta->plink_lock); 408 spin_unlock_bh(&sta->plink_lock);
404 sta_info_put(sta);
405 return 0; 409 return 0;
406 } else if (sta->plink_state == ESTAB) { 410 } else if (sta->plink_state == ESTAB) {
407 __mesh_plink_deactivate(sta); 411 __mesh_plink_deactivate(sta);
408 /* The timer should not be running */ 412 /* The timer should not be running */
409 if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata))) 413 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
410 __sta_info_get(sta);
411 } else if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata))) 414 } else if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)))
412 sta->ignore_plink_timer = true; 415 sta->ignore_plink_timer = true;
413 416
@@ -415,15 +418,16 @@ int mesh_plink_close(struct sta_info *sta)
415 llid = sta->llid; 418 llid = sta->llid;
416 plid = sta->plid; 419 plid = sta->plid;
417 spin_unlock_bh(&sta->plink_lock); 420 spin_unlock_bh(&sta->plink_lock);
418 mesh_plink_frame_tx(sta->dev, PLINK_CLOSE, sta->addr, llid, plid, 421 mesh_plink_frame_tx(sta->sdata->dev, PLINK_CLOSE, sta->addr, llid,
419 reason); 422 plid, reason);
420 return 0; 423 return 0;
421} 424}
422 425
423void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, 426void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
424 size_t len, struct ieee80211_rx_status *rx_status) 427 size_t len, struct ieee80211_rx_status *rx_status)
425{ 428{
426 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 429 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
430 struct ieee80211_local *local = sdata->local;
427 struct ieee802_11_elems elems; 431 struct ieee802_11_elems elems;
428 struct sta_info *sta; 432 struct sta_info *sta;
429 enum plink_event event; 433 enum plink_event event;
@@ -435,7 +439,6 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
435#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG 439#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
436 DECLARE_MAC_BUF(mac); 440 DECLARE_MAC_BUF(mac);
437#endif 441#endif
438 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
439 442
440 if (is_multicast_ether_addr(mgmt->da)) { 443 if (is_multicast_ether_addr(mgmt->da)) {
441 mpl_dbg("Mesh plink: ignore frame from multicast address"); 444 mpl_dbg("Mesh plink: ignore frame from multicast address");
@@ -474,14 +477,17 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
474 if (ftype == PLINK_CONFIRM || (ftype == PLINK_CLOSE && ie_len == 7)) 477 if (ftype == PLINK_CONFIRM || (ftype == PLINK_CLOSE && ie_len == 7))
475 memcpy(&llid, PLINK_GET_PLID(elems.peer_link), 2); 478 memcpy(&llid, PLINK_GET_PLID(elems.peer_link), 2);
476 479
480 rcu_read_lock();
481
477 sta = sta_info_get(local, mgmt->sa); 482 sta = sta_info_get(local, mgmt->sa);
478 if (!sta && ftype != PLINK_OPEN) { 483 if (!sta && ftype != PLINK_OPEN) {
479 mpl_dbg("Mesh plink: cls or cnf from unknown peer\n"); 484 mpl_dbg("Mesh plink: cls or cnf from unknown peer\n");
485 rcu_read_unlock();
480 return; 486 return;
481 } 487 }
482 488
483 if (sta && sta->plink_state == BLOCKED) { 489 if (sta && sta->plink_state == BLOCKED) {
484 sta_info_put(sta); 490 rcu_read_unlock();
485 return; 491 return;
486 } 492 }
487 493
@@ -505,13 +511,15 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
505 u64 rates; 511 u64 rates;
506 if (!mesh_plink_free_count(sdata)) { 512 if (!mesh_plink_free_count(sdata)) {
507 mpl_dbg("Mesh plink error: no more free plinks\n"); 513 mpl_dbg("Mesh plink error: no more free plinks\n");
514 rcu_read_unlock();
508 return; 515 return;
509 } 516 }
510 517
511 rates = ieee80211_sta_get_rates(local, &elems, rx_status->band); 518 rates = ieee80211_sta_get_rates(local, &elems, rx_status->band);
512 sta = mesh_plink_add(mgmt->sa, rates, dev); 519 sta = mesh_plink_add(mgmt->sa, rates, sdata);
513 if (IS_ERR(sta)) { 520 if (IS_ERR(sta)) {
514 mpl_dbg("Mesh plink error: plink table full\n"); 521 mpl_dbg("Mesh plink error: plink table full\n");
522 rcu_read_unlock();
515 return; 523 return;
516 } 524 }
517 event = OPN_ACPT; 525 event = OPN_ACPT;
@@ -521,14 +529,14 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
521 switch (ftype) { 529 switch (ftype) {
522 case PLINK_OPEN: 530 case PLINK_OPEN:
523 if (!mesh_plink_free_count(sdata) || 531 if (!mesh_plink_free_count(sdata) ||
524 (sta->plid && sta->plid != plid)) 532 (sta->plid && sta->plid != plid))
525 event = OPN_IGNR; 533 event = OPN_IGNR;
526 else 534 else
527 event = OPN_ACPT; 535 event = OPN_ACPT;
528 break; 536 break;
529 case PLINK_CONFIRM: 537 case PLINK_CONFIRM:
530 if (!mesh_plink_free_count(sdata) || 538 if (!mesh_plink_free_count(sdata) ||
531 (sta->llid != llid || sta->plid != plid)) 539 (sta->llid != llid || sta->plid != plid))
532 event = CNF_IGNR; 540 event = CNF_IGNR;
533 else 541 else
534 event = CNF_ACPT; 542 event = CNF_ACPT;
@@ -555,7 +563,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
555 default: 563 default:
556 mpl_dbg("Mesh plink: unknown frame subtype\n"); 564 mpl_dbg("Mesh plink: unknown frame subtype\n");
557 spin_unlock_bh(&sta->plink_lock); 565 spin_unlock_bh(&sta->plink_lock);
558 sta_info_put(sta); 566 rcu_read_unlock();
559 return; 567 return;
560 } 568 }
561 } 569 }
@@ -659,8 +667,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
659 plid, 0); 667 plid, 0);
660 break; 668 break;
661 case CNF_ACPT: 669 case CNF_ACPT:
662 if (del_timer(&sta->plink_timer)) 670 del_timer(&sta->plink_timer);
663 sta_info_put(sta);
664 sta->plink_state = ESTAB; 671 sta->plink_state = ESTAB;
665 mesh_plink_inc_estab_count(sdata); 672 mesh_plink_inc_estab_count(sdata);
666 spin_unlock_bh(&sta->plink_lock); 673 spin_unlock_bh(&sta->plink_lock);
@@ -693,8 +700,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
693 plid, reason); 700 plid, reason);
694 break; 701 break;
695 case OPN_ACPT: 702 case OPN_ACPT:
696 if (del_timer(&sta->plink_timer)) 703 del_timer(&sta->plink_timer);
697 sta_info_put(sta);
698 sta->plink_state = ESTAB; 704 sta->plink_state = ESTAB;
699 mesh_plink_inc_estab_count(sdata); 705 mesh_plink_inc_estab_count(sdata);
700 spin_unlock_bh(&sta->plink_lock); 706 spin_unlock_bh(&sta->plink_lock);
@@ -717,9 +723,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
717 __mesh_plink_deactivate(sta); 723 __mesh_plink_deactivate(sta);
718 sta->plink_state = HOLDING; 724 sta->plink_state = HOLDING;
719 llid = sta->llid; 725 llid = sta->llid;
720 if (!mod_plink_timer(sta, 726 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
721 dot11MeshHoldingTimeout(sdata)))
722 __sta_info_get(sta);
723 spin_unlock_bh(&sta->plink_lock); 727 spin_unlock_bh(&sta->plink_lock);
724 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, 728 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
725 plid, reason); 729 plid, reason);
@@ -738,10 +742,8 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
738 case HOLDING: 742 case HOLDING:
739 switch (event) { 743 switch (event) {
740 case CLS_ACPT: 744 case CLS_ACPT:
741 if (del_timer(&sta->plink_timer)) { 745 if (del_timer(&sta->plink_timer))
742 sta->ignore_plink_timer = 1; 746 sta->ignore_plink_timer = 1;
743 sta_info_put(sta);
744 }
745 mesh_plink_fsm_restart(sta); 747 mesh_plink_fsm_restart(sta);
746 spin_unlock_bh(&sta->plink_lock); 748 spin_unlock_bh(&sta->plink_lock);
747 break; 749 break;
@@ -766,5 +768,6 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
766 spin_unlock_bh(&sta->plink_lock); 768 spin_unlock_bh(&sta->plink_lock);
767 break; 769 break;
768 } 770 }
769 sta_info_put(sta); 771
772 rcu_read_unlock();
770} 773}