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