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