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