mesh_plink.c revision 54ef656b05103f700ff8fc2aaf0382cfd0e54fe4
1/* 2 * Copyright (c) 2008, 2009 open80211s Ltd. 3 * Author: Luis Carlos Cobo <luisca@cozybit.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 */ 9#include <linux/gfp.h> 10#include <linux/kernel.h> 11#include <linux/random.h> 12#include "ieee80211_i.h" 13#include "rate.h" 14#include "mesh.h" 15 16#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG 17#define mpl_dbg(fmt, args...) printk(KERN_DEBUG fmt, ##args) 18#else 19#define mpl_dbg(fmt, args...) do { (void)(0); } while (0) 20#endif 21 22#define PLINK_GET_LLID(p) (p + 4) 23#define PLINK_GET_PLID(p) (p + 6) 24 25#define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \ 26 jiffies + HZ * t / 1000)) 27 28#define dot11MeshMaxRetries(s) (s->u.mesh.mshcfg.dot11MeshMaxRetries) 29#define dot11MeshRetryTimeout(s) (s->u.mesh.mshcfg.dot11MeshRetryTimeout) 30#define dot11MeshConfirmTimeout(s) (s->u.mesh.mshcfg.dot11MeshConfirmTimeout) 31#define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout) 32#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks) 33 34enum plink_event { 35 PLINK_UNDEFINED, 36 OPN_ACPT, 37 OPN_RJCT, 38 OPN_IGNR, 39 CNF_ACPT, 40 CNF_RJCT, 41 CNF_IGNR, 42 CLS_ACPT, 43 CLS_IGNR 44}; 45 46static inline 47void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata) 48{ 49 atomic_inc(&sdata->u.mesh.mshstats.estab_plinks); 50 mesh_accept_plinks_update(sdata); 51} 52 53static inline 54void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) 55{ 56 atomic_dec(&sdata->u.mesh.mshstats.estab_plinks); 57 mesh_accept_plinks_update(sdata); 58} 59 60/** 61 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine 62 * 63 * @sta: mesh peer link to restart 64 * 65 * Locking: this function must be called holding sta->lock 66 */ 67static inline void mesh_plink_fsm_restart(struct sta_info *sta) 68{ 69 sta->plink_state = NL80211_PLINK_LISTEN; 70 sta->llid = sta->plid = sta->reason = 0; 71 sta->plink_retries = 0; 72} 73 74/* 75 * NOTE: This is just an alias for sta_info_alloc(), see notes 76 * on it in the lifecycle management section! 77 */ 78static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, 79 u8 *hw_addr, u32 rates) 80{ 81 struct ieee80211_local *local = sdata->local; 82 struct sta_info *sta; 83 84 if (local->num_sta >= MESH_MAX_PLINKS) 85 return NULL; 86 87 sta = sta_info_alloc(sdata, hw_addr, GFP_KERNEL); 88 if (!sta) 89 return NULL; 90 91 sta->flags = WLAN_STA_AUTHORIZED | WLAN_STA_AUTH; 92 sta->sta.supp_rates[local->hw.conf.channel->band] = rates; 93 rate_control_rate_init(sta); 94 95 return sta; 96} 97 98/** 99 * __mesh_plink_deactivate - deactivate mesh peer link 100 * 101 * @sta: mesh peer link to deactivate 102 * 103 * All mesh paths with this peer as next hop will be flushed 104 * 105 * Locking: the caller must hold sta->lock 106 */ 107static bool __mesh_plink_deactivate(struct sta_info *sta) 108{ 109 struct ieee80211_sub_if_data *sdata = sta->sdata; 110 bool deactivated = false; 111 112 if (sta->plink_state == NL80211_PLINK_ESTAB) { 113 mesh_plink_dec_estab_count(sdata); 114 deactivated = true; 115 } 116 sta->plink_state = NL80211_PLINK_BLOCKED; 117 mesh_path_flush_by_nexthop(sta); 118 119 return deactivated; 120} 121 122/** 123 * mesh_plink_deactivate - deactivate mesh peer link 124 * 125 * @sta: mesh peer link to deactivate 126 * 127 * All mesh paths with this peer as next hop will be flushed 128 */ 129void mesh_plink_deactivate(struct sta_info *sta) 130{ 131 struct ieee80211_sub_if_data *sdata = sta->sdata; 132 bool deactivated; 133 134 spin_lock_bh(&sta->lock); 135 deactivated = __mesh_plink_deactivate(sta); 136 spin_unlock_bh(&sta->lock); 137 138 if (deactivated) 139 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 140} 141 142static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 143 enum ieee80211_self_protected_actioncode action, 144 u8 *da, __le16 llid, __le16 plid, __le16 reason) { 145 struct ieee80211_local *local = sdata->local; 146 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 + 147 sdata->u.mesh.ie_len); 148 struct ieee80211_mgmt *mgmt; 149 bool include_plid = false; 150 static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A }; 151 u8 *pos; 152 int ie_len; 153 154 if (!skb) 155 return -1; 156 skb_reserve(skb, local->hw.extra_tx_headroom); 157 /* 25 is the size of the common mgmt part (24) plus the size of the 158 * common action part (1) 159 */ 160 mgmt = (struct ieee80211_mgmt *) 161 skb_put(skb, 25 + sizeof(mgmt->u.action.u.plink_action)); 162 memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.plink_action)); 163 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 164 IEEE80211_STYPE_ACTION); 165 memcpy(mgmt->da, da, ETH_ALEN); 166 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 167 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 168 mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION; 169 mgmt->u.action.u.plink_action.action_code = action; 170 171 if (action == WLAN_SP_MESH_PEERING_CLOSE) 172 mgmt->u.action.u.plink_action.aux = reason; 173 else { 174 mgmt->u.action.u.plink_action.aux = cpu_to_le16(0x0); 175 if (action == WLAN_SP_MESH_PEERING_CONFIRM) { 176 pos = skb_put(skb, 4); 177 /* two-byte status code followed by two-byte AID */ 178 memset(pos, 0, 2); 179 memcpy(pos + 2, &plid, 2); 180 } 181 if (mesh_add_srates_ie(skb, sdata) || 182 mesh_add_ext_srates_ie(skb, sdata) || 183 mesh_add_rsn_ie(skb, sdata) || 184 mesh_add_meshid_ie(skb, sdata) || 185 mesh_add_meshconf_ie(skb, sdata)) 186 return -1; 187 } 188 189 /* Add Peer Link Management element */ 190 switch (action) { 191 case WLAN_SP_MESH_PEERING_OPEN: 192 ie_len = 6; 193 break; 194 case WLAN_SP_MESH_PEERING_CONFIRM: 195 ie_len = 8; 196 include_plid = true; 197 break; 198 case WLAN_SP_MESH_PEERING_CLOSE: 199 default: 200 if (!plid) 201 ie_len = 8; 202 else { 203 ie_len = 10; 204 include_plid = true; 205 } 206 break; 207 } 208 209 pos = skb_put(skb, 2 + ie_len); 210 *pos++ = WLAN_EID_PEER_LINK; 211 *pos++ = ie_len; 212 memcpy(pos, meshpeeringproto, sizeof(meshpeeringproto)); 213 pos += 4; 214 memcpy(pos, &llid, 2); 215 if (include_plid) { 216 pos += 2; 217 memcpy(pos, &plid, 2); 218 } 219 if (action == WLAN_SP_MESH_PEERING_CLOSE) { 220 pos += 2; 221 memcpy(pos, &reason, 2); 222 } 223 224 ieee80211_tx_skb(sdata, skb); 225 return 0; 226} 227 228void mesh_neighbour_update(u8 *hw_addr, u32 rates, 229 struct ieee80211_sub_if_data *sdata, 230 struct ieee802_11_elems *elems) 231{ 232 struct ieee80211_local *local = sdata->local; 233 struct sta_info *sta; 234 235 rcu_read_lock(); 236 237 sta = sta_info_get(sdata, hw_addr); 238 if (!sta) { 239 rcu_read_unlock(); 240 /* Userspace handles peer allocation when security is enabled 241 * */ 242 if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) 243 cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr, 244 elems->ie_start, elems->total_len, 245 GFP_KERNEL); 246 else 247 sta = mesh_plink_alloc(sdata, hw_addr, rates); 248 if (!sta) 249 return; 250 if (sta_info_insert_rcu(sta)) { 251 rcu_read_unlock(); 252 return; 253 } 254 } 255 256 sta->last_rx = jiffies; 257 sta->sta.supp_rates[local->hw.conf.channel->band] = rates; 258 if (mesh_peer_accepts_plinks(elems) && 259 sta->plink_state == NL80211_PLINK_LISTEN && 260 sdata->u.mesh.accepting_plinks && 261 sdata->u.mesh.mshcfg.auto_open_plinks) 262 mesh_plink_open(sta); 263 264 rcu_read_unlock(); 265} 266 267static void mesh_plink_timer(unsigned long data) 268{ 269 struct sta_info *sta; 270 __le16 llid, plid, reason; 271 struct ieee80211_sub_if_data *sdata; 272 273 /* 274 * This STA is valid because sta_info_destroy() will 275 * del_timer_sync() this timer after having made sure 276 * it cannot be readded (by deleting the plink.) 277 */ 278 sta = (struct sta_info *) data; 279 280 if (sta->sdata->local->quiescing) { 281 sta->plink_timer_was_running = true; 282 return; 283 } 284 285 spin_lock_bh(&sta->lock); 286 if (sta->ignore_plink_timer) { 287 sta->ignore_plink_timer = false; 288 spin_unlock_bh(&sta->lock); 289 return; 290 } 291 mpl_dbg("Mesh plink timer for %pM fired on state %d\n", 292 sta->sta.addr, sta->plink_state); 293 reason = 0; 294 llid = sta->llid; 295 plid = sta->plid; 296 sdata = sta->sdata; 297 298 switch (sta->plink_state) { 299 case NL80211_PLINK_OPN_RCVD: 300 case NL80211_PLINK_OPN_SNT: 301 /* retry timer */ 302 if (sta->plink_retries < dot11MeshMaxRetries(sdata)) { 303 u32 rand; 304 mpl_dbg("Mesh plink for %pM (retry, timeout): %d %d\n", 305 sta->sta.addr, sta->plink_retries, 306 sta->plink_timeout); 307 get_random_bytes(&rand, sizeof(u32)); 308 sta->plink_timeout = sta->plink_timeout + 309 rand % sta->plink_timeout; 310 ++sta->plink_retries; 311 mod_plink_timer(sta, sta->plink_timeout); 312 spin_unlock_bh(&sta->lock); 313 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, 314 sta->sta.addr, llid, 0, 0); 315 break; 316 } 317 reason = cpu_to_le16(WLAN_REASON_MESH_MAX_RETRIES); 318 /* fall through on else */ 319 case NL80211_PLINK_CNF_RCVD: 320 /* confirm timer */ 321 if (!reason) 322 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT); 323 sta->plink_state = NL80211_PLINK_HOLDING; 324 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 325 spin_unlock_bh(&sta->lock); 326 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 327 sta->sta.addr, llid, plid, reason); 328 break; 329 case NL80211_PLINK_HOLDING: 330 /* holding timer */ 331 del_timer(&sta->plink_timer); 332 mesh_plink_fsm_restart(sta); 333 spin_unlock_bh(&sta->lock); 334 break; 335 default: 336 spin_unlock_bh(&sta->lock); 337 break; 338 } 339} 340 341#ifdef CONFIG_PM 342void mesh_plink_quiesce(struct sta_info *sta) 343{ 344 if (del_timer_sync(&sta->plink_timer)) 345 sta->plink_timer_was_running = true; 346} 347 348void mesh_plink_restart(struct sta_info *sta) 349{ 350 if (sta->plink_timer_was_running) { 351 add_timer(&sta->plink_timer); 352 sta->plink_timer_was_running = false; 353 } 354} 355#endif 356 357static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout) 358{ 359 sta->plink_timer.expires = jiffies + (HZ * timeout / 1000); 360 sta->plink_timer.data = (unsigned long) sta; 361 sta->plink_timer.function = mesh_plink_timer; 362 sta->plink_timeout = timeout; 363 add_timer(&sta->plink_timer); 364} 365 366int mesh_plink_open(struct sta_info *sta) 367{ 368 __le16 llid; 369 struct ieee80211_sub_if_data *sdata = sta->sdata; 370 371 if (!test_sta_flags(sta, WLAN_STA_AUTH)) 372 return -EPERM; 373 374 spin_lock_bh(&sta->lock); 375 get_random_bytes(&llid, 2); 376 sta->llid = llid; 377 if (sta->plink_state != NL80211_PLINK_LISTEN) { 378 spin_unlock_bh(&sta->lock); 379 return -EBUSY; 380 } 381 sta->plink_state = NL80211_PLINK_OPN_SNT; 382 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); 383 spin_unlock_bh(&sta->lock); 384 mpl_dbg("Mesh plink: starting establishment with %pM\n", 385 sta->sta.addr); 386 387 return mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, 388 sta->sta.addr, llid, 0, 0); 389} 390 391void mesh_plink_block(struct sta_info *sta) 392{ 393 struct ieee80211_sub_if_data *sdata = sta->sdata; 394 bool deactivated; 395 396 spin_lock_bh(&sta->lock); 397 deactivated = __mesh_plink_deactivate(sta); 398 sta->plink_state = NL80211_PLINK_BLOCKED; 399 spin_unlock_bh(&sta->lock); 400 401 if (deactivated) 402 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 403} 404 405 406void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, 407 size_t len, struct ieee80211_rx_status *rx_status) 408{ 409 struct ieee80211_local *local = sdata->local; 410 struct ieee802_11_elems elems; 411 struct sta_info *sta; 412 enum plink_event event; 413 enum ieee80211_self_protected_actioncode ftype; 414 size_t baselen; 415 bool deactivated, matches_local = true; 416 u8 ie_len; 417 u8 *baseaddr; 418 __le16 plid, llid, reason; 419#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG 420 static const char *mplstates[] = { 421 [NL80211_PLINK_LISTEN] = "LISTEN", 422 [NL80211_PLINK_OPN_SNT] = "OPN-SNT", 423 [NL80211_PLINK_OPN_RCVD] = "OPN-RCVD", 424 [NL80211_PLINK_CNF_RCVD] = "CNF_RCVD", 425 [NL80211_PLINK_ESTAB] = "ESTAB", 426 [NL80211_PLINK_HOLDING] = "HOLDING", 427 [NL80211_PLINK_BLOCKED] = "BLOCKED" 428 }; 429#endif 430 431 /* need action_code, aux */ 432 if (len < IEEE80211_MIN_ACTION_SIZE + 3) 433 return; 434 435 if (is_multicast_ether_addr(mgmt->da)) { 436 mpl_dbg("Mesh plink: ignore frame from multicast address"); 437 return; 438 } 439 440 baseaddr = mgmt->u.action.u.plink_action.variable; 441 baselen = (u8 *) mgmt->u.action.u.plink_action.variable - (u8 *) mgmt; 442 if (mgmt->u.action.u.plink_action.action_code == 443 WLAN_SP_MESH_PEERING_CONFIRM) { 444 baseaddr += 4; 445 baselen += 4; 446 } 447 ieee802_11_parse_elems(baseaddr, len - baselen, &elems); 448 if (!elems.peer_link) { 449 mpl_dbg("Mesh plink: missing necessary peer link ie\n"); 450 return; 451 } 452 if (elems.rsn_len && 453 sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) { 454 mpl_dbg("Mesh plink: can't establish link with secure peer\n"); 455 return; 456 } 457 458 ftype = mgmt->u.action.u.plink_action.action_code; 459 ie_len = elems.peer_link_len; 460 if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 6) || 461 (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 8) || 462 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 8 463 && ie_len != 10)) { 464 mpl_dbg("Mesh plink: incorrect plink ie length %d %d\n", 465 ftype, ie_len); 466 return; 467 } 468 469 if (ftype != WLAN_SP_MESH_PEERING_CLOSE && 470 (!elems.mesh_id || !elems.mesh_config)) { 471 mpl_dbg("Mesh plink: missing necessary ie\n"); 472 return; 473 } 474 /* Note the lines below are correct, the llid in the frame is the plid 475 * from the point of view of this host. 476 */ 477 memcpy(&plid, PLINK_GET_LLID(elems.peer_link), 2); 478 if (ftype == WLAN_SP_MESH_PEERING_CONFIRM || 479 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 10)) 480 memcpy(&llid, PLINK_GET_PLID(elems.peer_link), 2); 481 482 rcu_read_lock(); 483 484 sta = sta_info_get(sdata, mgmt->sa); 485 if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) { 486 mpl_dbg("Mesh plink: cls or cnf from unknown peer\n"); 487 rcu_read_unlock(); 488 return; 489 } 490 491 if (sta && !test_sta_flags(sta, WLAN_STA_AUTH)) { 492 mpl_dbg("Mesh plink: Action frame from non-authed peer\n"); 493 rcu_read_unlock(); 494 return; 495 } 496 497 if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) { 498 rcu_read_unlock(); 499 return; 500 } 501 502 /* Now we will figure out the appropriate event... */ 503 event = PLINK_UNDEFINED; 504 if (ftype != WLAN_SP_MESH_PEERING_CLOSE && 505 (!mesh_matches_local(&elems, sdata))) { 506 matches_local = false; 507 switch (ftype) { 508 case WLAN_SP_MESH_PEERING_OPEN: 509 event = OPN_RJCT; 510 break; 511 case WLAN_SP_MESH_PEERING_CONFIRM: 512 event = CNF_RJCT; 513 break; 514 default: 515 break; 516 } 517 } 518 519 if (!sta && !matches_local) { 520 rcu_read_unlock(); 521 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); 522 llid = 0; 523 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 524 mgmt->sa, llid, plid, reason); 525 return; 526 } else if (!sta) { 527 /* ftype == WLAN_SP_MESH_PEERING_OPEN */ 528 u32 rates; 529 530 rcu_read_unlock(); 531 532 if (!mesh_plink_free_count(sdata)) { 533 mpl_dbg("Mesh plink error: no more free plinks\n"); 534 return; 535 } 536 537 rates = ieee80211_sta_get_rates(local, &elems, rx_status->band); 538 sta = mesh_plink_alloc(sdata, mgmt->sa, rates); 539 if (!sta) { 540 mpl_dbg("Mesh plink error: plink table full\n"); 541 return; 542 } 543 if (sta_info_insert_rcu(sta)) { 544 rcu_read_unlock(); 545 return; 546 } 547 event = OPN_ACPT; 548 spin_lock_bh(&sta->lock); 549 } else if (matches_local) { 550 spin_lock_bh(&sta->lock); 551 switch (ftype) { 552 case WLAN_SP_MESH_PEERING_OPEN: 553 if (!mesh_plink_free_count(sdata) || 554 (sta->plid && sta->plid != plid)) 555 event = OPN_IGNR; 556 else 557 event = OPN_ACPT; 558 break; 559 case WLAN_SP_MESH_PEERING_CONFIRM: 560 if (!mesh_plink_free_count(sdata) || 561 (sta->llid != llid || sta->plid != plid)) 562 event = CNF_IGNR; 563 else 564 event = CNF_ACPT; 565 break; 566 case WLAN_SP_MESH_PEERING_CLOSE: 567 if (sta->plink_state == NL80211_PLINK_ESTAB) 568 /* Do not check for llid or plid. This does not 569 * follow the standard but since multiple plinks 570 * per sta are not supported, it is necessary in 571 * order to avoid a livelock when MP A sees an 572 * establish peer link to MP B but MP B does not 573 * see it. This can be caused by a timeout in 574 * B's peer link establishment or B beign 575 * restarted. 576 */ 577 event = CLS_ACPT; 578 else if (sta->plid != plid) 579 event = CLS_IGNR; 580 else if (ie_len == 7 && sta->llid != llid) 581 event = CLS_IGNR; 582 else 583 event = CLS_ACPT; 584 break; 585 default: 586 mpl_dbg("Mesh plink: unknown frame subtype\n"); 587 spin_unlock_bh(&sta->lock); 588 rcu_read_unlock(); 589 return; 590 } 591 } else { 592 spin_lock_bh(&sta->lock); 593 } 594 595 mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", 596 mgmt->sa, mplstates[sta->plink_state], 597 le16_to_cpu(sta->llid), le16_to_cpu(sta->plid), 598 event); 599 reason = 0; 600 switch (sta->plink_state) { 601 /* spin_unlock as soon as state is updated at each case */ 602 case NL80211_PLINK_LISTEN: 603 switch (event) { 604 case CLS_ACPT: 605 mesh_plink_fsm_restart(sta); 606 spin_unlock_bh(&sta->lock); 607 break; 608 case OPN_ACPT: 609 sta->plink_state = NL80211_PLINK_OPN_RCVD; 610 sta->plid = plid; 611 get_random_bytes(&llid, 2); 612 sta->llid = llid; 613 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); 614 spin_unlock_bh(&sta->lock); 615 mesh_plink_frame_tx(sdata, 616 WLAN_SP_MESH_PEERING_OPEN, 617 sta->sta.addr, llid, 0, 0); 618 mesh_plink_frame_tx(sdata, 619 WLAN_SP_MESH_PEERING_CONFIRM, 620 sta->sta.addr, llid, plid, 0); 621 break; 622 default: 623 spin_unlock_bh(&sta->lock); 624 break; 625 } 626 break; 627 628 case NL80211_PLINK_OPN_SNT: 629 switch (event) { 630 case OPN_RJCT: 631 case CNF_RJCT: 632 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); 633 case CLS_ACPT: 634 if (!reason) 635 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 636 sta->reason = reason; 637 sta->plink_state = NL80211_PLINK_HOLDING; 638 if (!mod_plink_timer(sta, 639 dot11MeshHoldingTimeout(sdata))) 640 sta->ignore_plink_timer = true; 641 642 llid = sta->llid; 643 spin_unlock_bh(&sta->lock); 644 mesh_plink_frame_tx(sdata, 645 WLAN_SP_MESH_PEERING_CLOSE, 646 sta->sta.addr, llid, plid, reason); 647 break; 648 case OPN_ACPT: 649 /* retry timer is left untouched */ 650 sta->plink_state = NL80211_PLINK_OPN_RCVD; 651 sta->plid = plid; 652 llid = sta->llid; 653 spin_unlock_bh(&sta->lock); 654 mesh_plink_frame_tx(sdata, 655 WLAN_SP_MESH_PEERING_CONFIRM, 656 sta->sta.addr, llid, plid, 0); 657 break; 658 case CNF_ACPT: 659 sta->plink_state = NL80211_PLINK_CNF_RCVD; 660 if (!mod_plink_timer(sta, 661 dot11MeshConfirmTimeout(sdata))) 662 sta->ignore_plink_timer = true; 663 664 spin_unlock_bh(&sta->lock); 665 break; 666 default: 667 spin_unlock_bh(&sta->lock); 668 break; 669 } 670 break; 671 672 case NL80211_PLINK_OPN_RCVD: 673 switch (event) { 674 case OPN_RJCT: 675 case CNF_RJCT: 676 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); 677 case CLS_ACPT: 678 if (!reason) 679 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 680 sta->reason = reason; 681 sta->plink_state = NL80211_PLINK_HOLDING; 682 if (!mod_plink_timer(sta, 683 dot11MeshHoldingTimeout(sdata))) 684 sta->ignore_plink_timer = true; 685 686 llid = sta->llid; 687 spin_unlock_bh(&sta->lock); 688 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 689 sta->sta.addr, llid, plid, reason); 690 break; 691 case OPN_ACPT: 692 llid = sta->llid; 693 spin_unlock_bh(&sta->lock); 694 mesh_plink_frame_tx(sdata, 695 WLAN_SP_MESH_PEERING_CONFIRM, 696 sta->sta.addr, llid, plid, 0); 697 break; 698 case CNF_ACPT: 699 del_timer(&sta->plink_timer); 700 sta->plink_state = NL80211_PLINK_ESTAB; 701 spin_unlock_bh(&sta->lock); 702 mesh_plink_inc_estab_count(sdata); 703 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 704 mpl_dbg("Mesh plink with %pM ESTABLISHED\n", 705 sta->sta.addr); 706 break; 707 default: 708 spin_unlock_bh(&sta->lock); 709 break; 710 } 711 break; 712 713 case NL80211_PLINK_CNF_RCVD: 714 switch (event) { 715 case OPN_RJCT: 716 case CNF_RJCT: 717 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); 718 case CLS_ACPT: 719 if (!reason) 720 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 721 sta->reason = reason; 722 sta->plink_state = NL80211_PLINK_HOLDING; 723 if (!mod_plink_timer(sta, 724 dot11MeshHoldingTimeout(sdata))) 725 sta->ignore_plink_timer = true; 726 727 llid = sta->llid; 728 spin_unlock_bh(&sta->lock); 729 mesh_plink_frame_tx(sdata, 730 WLAN_SP_MESH_PEERING_CLOSE, 731 sta->sta.addr, llid, plid, reason); 732 break; 733 case OPN_ACPT: 734 del_timer(&sta->plink_timer); 735 sta->plink_state = NL80211_PLINK_ESTAB; 736 spin_unlock_bh(&sta->lock); 737 mesh_plink_inc_estab_count(sdata); 738 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 739 mpl_dbg("Mesh plink with %pM ESTABLISHED\n", 740 sta->sta.addr); 741 mesh_plink_frame_tx(sdata, 742 WLAN_SP_MESH_PEERING_CONFIRM, 743 sta->sta.addr, llid, plid, 0); 744 break; 745 default: 746 spin_unlock_bh(&sta->lock); 747 break; 748 } 749 break; 750 751 case NL80211_PLINK_ESTAB: 752 switch (event) { 753 case CLS_ACPT: 754 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 755 sta->reason = reason; 756 deactivated = __mesh_plink_deactivate(sta); 757 sta->plink_state = NL80211_PLINK_HOLDING; 758 llid = sta->llid; 759 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 760 spin_unlock_bh(&sta->lock); 761 if (deactivated) 762 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 763 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 764 sta->sta.addr, llid, plid, reason); 765 break; 766 case OPN_ACPT: 767 llid = sta->llid; 768 spin_unlock_bh(&sta->lock); 769 mesh_plink_frame_tx(sdata, 770 WLAN_SP_MESH_PEERING_CONFIRM, 771 sta->sta.addr, llid, plid, 0); 772 break; 773 default: 774 spin_unlock_bh(&sta->lock); 775 break; 776 } 777 break; 778 case NL80211_PLINK_HOLDING: 779 switch (event) { 780 case CLS_ACPT: 781 if (del_timer(&sta->plink_timer)) 782 sta->ignore_plink_timer = 1; 783 mesh_plink_fsm_restart(sta); 784 spin_unlock_bh(&sta->lock); 785 break; 786 case OPN_ACPT: 787 case CNF_ACPT: 788 case OPN_RJCT: 789 case CNF_RJCT: 790 llid = sta->llid; 791 reason = sta->reason; 792 spin_unlock_bh(&sta->lock); 793 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 794 sta->sta.addr, llid, plid, reason); 795 break; 796 default: 797 spin_unlock_bh(&sta->lock); 798 } 799 break; 800 default: 801 /* should not get here, PLINK_BLOCKED is dealt with at the 802 * beginning of the function 803 */ 804 spin_unlock_bh(&sta->lock); 805 break; 806 } 807 808 rcu_read_unlock(); 809} 810