mesh_plink.c revision 082ebb0c258d28af7452b19df9ef8b7553f37690
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 45enum plink_frame_type { 46 PLINK_OPEN = 1, 47 PLINK_CONFIRM, 48 PLINK_CLOSE 49}; 50 51enum 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 63static inline 64void 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 70static inline 71void 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 */ 84static 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 */ 95static 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 */ 124static 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 */ 146void 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 159static 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 if (mesh_add_srates_ie(skb, sdata) || 199 mesh_add_ext_srates_ie(skb, sdata) || 200 mesh_add_rsn_ie(skb, sdata) || 201 mesh_add_meshid_ie(skb, sdata) || 202 mesh_add_meshconf_ie(skb, sdata)) 203 return -1; 204 } 205 206 /* Add Peer Link Management element */ 207 switch (action) { 208 case PLINK_OPEN: 209 ie_len = 6; 210 break; 211 case PLINK_CONFIRM: 212 ie_len = 8; 213 include_plid = true; 214 break; 215 case PLINK_CLOSE: 216 default: 217 if (!plid) 218 ie_len = 8; 219 else { 220 ie_len = 10; 221 include_plid = true; 222 } 223 break; 224 } 225 226 pos = skb_put(skb, 2 + ie_len); 227 *pos++ = WLAN_EID_PEER_LINK; 228 *pos++ = ie_len; 229 memcpy(pos, meshpeeringproto, sizeof(meshpeeringproto)); 230 pos += 4; 231 memcpy(pos, &llid, 2); 232 if (include_plid) { 233 pos += 2; 234 memcpy(pos, &plid, 2); 235 } 236 if (action == PLINK_CLOSE) { 237 pos += 2; 238 memcpy(pos, &reason, 2); 239 } 240 241 ieee80211_tx_skb(sdata, skb); 242 return 0; 243} 244 245void mesh_neighbour_update(u8 *hw_addr, u32 rates, 246 struct ieee80211_sub_if_data *sdata, 247 struct ieee802_11_elems *elems) 248{ 249 struct ieee80211_local *local = sdata->local; 250 struct sta_info *sta; 251 252 rcu_read_lock(); 253 254 sta = sta_info_get(sdata, hw_addr); 255 if (!sta) { 256 rcu_read_unlock(); 257 /* Userspace handles peer allocation when security is enabled 258 * */ 259 if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) 260 cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr, 261 elems->ie_start, elems->total_len, 262 GFP_KERNEL); 263 else 264 sta = mesh_plink_alloc(sdata, hw_addr, rates); 265 if (!sta) 266 return; 267 if (sta_info_insert_rcu(sta)) { 268 rcu_read_unlock(); 269 return; 270 } 271 } 272 273 sta->last_rx = jiffies; 274 sta->sta.supp_rates[local->hw.conf.channel->band] = rates; 275 if (mesh_peer_accepts_plinks(elems) && 276 sta->plink_state == NL80211_PLINK_LISTEN && 277 sdata->u.mesh.accepting_plinks && 278 sdata->u.mesh.mshcfg.auto_open_plinks) 279 mesh_plink_open(sta); 280 281 rcu_read_unlock(); 282} 283 284static void mesh_plink_timer(unsigned long data) 285{ 286 struct sta_info *sta; 287 __le16 llid, plid, reason; 288 struct ieee80211_sub_if_data *sdata; 289 290 /* 291 * This STA is valid because sta_info_destroy() will 292 * del_timer_sync() this timer after having made sure 293 * it cannot be readded (by deleting the plink.) 294 */ 295 sta = (struct sta_info *) data; 296 297 if (sta->sdata->local->quiescing) { 298 sta->plink_timer_was_running = true; 299 return; 300 } 301 302 spin_lock_bh(&sta->lock); 303 if (sta->ignore_plink_timer) { 304 sta->ignore_plink_timer = false; 305 spin_unlock_bh(&sta->lock); 306 return; 307 } 308 mpl_dbg("Mesh plink timer for %pM fired on state %d\n", 309 sta->sta.addr, sta->plink_state); 310 reason = 0; 311 llid = sta->llid; 312 plid = sta->plid; 313 sdata = sta->sdata; 314 315 switch (sta->plink_state) { 316 case NL80211_PLINK_OPN_RCVD: 317 case NL80211_PLINK_OPN_SNT: 318 /* retry timer */ 319 if (sta->plink_retries < dot11MeshMaxRetries(sdata)) { 320 u32 rand; 321 mpl_dbg("Mesh plink for %pM (retry, timeout): %d %d\n", 322 sta->sta.addr, sta->plink_retries, 323 sta->plink_timeout); 324 get_random_bytes(&rand, sizeof(u32)); 325 sta->plink_timeout = sta->plink_timeout + 326 rand % sta->plink_timeout; 327 ++sta->plink_retries; 328 mod_plink_timer(sta, sta->plink_timeout); 329 spin_unlock_bh(&sta->lock); 330 mesh_plink_frame_tx(sdata, PLINK_OPEN, sta->sta.addr, llid, 331 0, 0); 332 break; 333 } 334 reason = cpu_to_le16(MESH_MAX_RETRIES); 335 /* fall through on else */ 336 case NL80211_PLINK_CNF_RCVD: 337 /* confirm timer */ 338 if (!reason) 339 reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT); 340 sta->plink_state = NL80211_PLINK_HOLDING; 341 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 342 spin_unlock_bh(&sta->lock); 343 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, plid, 344 reason); 345 break; 346 case NL80211_PLINK_HOLDING: 347 /* holding timer */ 348 del_timer(&sta->plink_timer); 349 mesh_plink_fsm_restart(sta); 350 spin_unlock_bh(&sta->lock); 351 break; 352 default: 353 spin_unlock_bh(&sta->lock); 354 break; 355 } 356} 357 358#ifdef CONFIG_PM 359void mesh_plink_quiesce(struct sta_info *sta) 360{ 361 if (del_timer_sync(&sta->plink_timer)) 362 sta->plink_timer_was_running = true; 363} 364 365void mesh_plink_restart(struct sta_info *sta) 366{ 367 if (sta->plink_timer_was_running) { 368 add_timer(&sta->plink_timer); 369 sta->plink_timer_was_running = false; 370 } 371} 372#endif 373 374static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout) 375{ 376 sta->plink_timer.expires = jiffies + (HZ * timeout / 1000); 377 sta->plink_timer.data = (unsigned long) sta; 378 sta->plink_timer.function = mesh_plink_timer; 379 sta->plink_timeout = timeout; 380 add_timer(&sta->plink_timer); 381} 382 383int mesh_plink_open(struct sta_info *sta) 384{ 385 __le16 llid; 386 struct ieee80211_sub_if_data *sdata = sta->sdata; 387 388 if (!test_sta_flags(sta, WLAN_STA_AUTH)) 389 return -EPERM; 390 391 spin_lock_bh(&sta->lock); 392 get_random_bytes(&llid, 2); 393 sta->llid = llid; 394 if (sta->plink_state != NL80211_PLINK_LISTEN) { 395 spin_unlock_bh(&sta->lock); 396 return -EBUSY; 397 } 398 sta->plink_state = NL80211_PLINK_OPN_SNT; 399 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); 400 spin_unlock_bh(&sta->lock); 401 mpl_dbg("Mesh plink: starting establishment with %pM\n", 402 sta->sta.addr); 403 404 return mesh_plink_frame_tx(sdata, PLINK_OPEN, 405 sta->sta.addr, llid, 0, 0); 406} 407 408void mesh_plink_block(struct sta_info *sta) 409{ 410 struct ieee80211_sub_if_data *sdata = sta->sdata; 411 bool deactivated; 412 413 spin_lock_bh(&sta->lock); 414 deactivated = __mesh_plink_deactivate(sta); 415 sta->plink_state = NL80211_PLINK_BLOCKED; 416 spin_unlock_bh(&sta->lock); 417 418 if (deactivated) 419 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 420} 421 422 423void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, 424 size_t len, struct ieee80211_rx_status *rx_status) 425{ 426 struct ieee80211_local *local = sdata->local; 427 struct ieee802_11_elems elems; 428 struct sta_info *sta; 429 enum plink_event event; 430 enum plink_frame_type ftype; 431 size_t baselen; 432 bool deactivated, matches_local = true; 433 u8 ie_len; 434 u8 *baseaddr; 435 __le16 plid, llid, reason; 436#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG 437 static const char *mplstates[] = { 438 [NL80211_PLINK_LISTEN] = "LISTEN", 439 [NL80211_PLINK_OPN_SNT] = "OPN-SNT", 440 [NL80211_PLINK_OPN_RCVD] = "OPN-RCVD", 441 [NL80211_PLINK_CNF_RCVD] = "CNF_RCVD", 442 [NL80211_PLINK_ESTAB] = "ESTAB", 443 [NL80211_PLINK_HOLDING] = "HOLDING", 444 [NL80211_PLINK_BLOCKED] = "BLOCKED" 445 }; 446#endif 447 448 /* need action_code, aux */ 449 if (len < IEEE80211_MIN_ACTION_SIZE + 3) 450 return; 451 452 if (is_multicast_ether_addr(mgmt->da)) { 453 mpl_dbg("Mesh plink: ignore frame from multicast address"); 454 return; 455 } 456 457 baseaddr = mgmt->u.action.u.plink_action.variable; 458 baselen = (u8 *) mgmt->u.action.u.plink_action.variable - (u8 *) mgmt; 459 if (mgmt->u.action.u.plink_action.action_code == PLINK_CONFIRM) { 460 baseaddr += 4; 461 baselen += 4; 462 } 463 ieee802_11_parse_elems(baseaddr, len - baselen, &elems); 464 if (!elems.peer_link) { 465 mpl_dbg("Mesh plink: missing necessary peer link ie\n"); 466 return; 467 } 468 if (elems.rsn_len && 469 sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) { 470 mpl_dbg("Mesh plink: can't establish link with secure peer\n"); 471 return; 472 } 473 474 ftype = mgmt->u.action.u.plink_action.action_code; 475 ie_len = elems.peer_link_len; 476 if ((ftype == PLINK_OPEN && ie_len != 6) || 477 (ftype == PLINK_CONFIRM && ie_len != 8) || 478 (ftype == PLINK_CLOSE && ie_len != 8 && ie_len != 10)) { 479 mpl_dbg("Mesh plink: incorrect plink ie length %d %d\n", 480 ftype, ie_len); 481 return; 482 } 483 484 if (ftype != PLINK_CLOSE && (!elems.mesh_id || !elems.mesh_config)) { 485 mpl_dbg("Mesh plink: missing necessary ie\n"); 486 return; 487 } 488 /* Note the lines below are correct, the llid in the frame is the plid 489 * from the point of view of this host. 490 */ 491 memcpy(&plid, PLINK_GET_LLID(elems.peer_link), 2); 492 if (ftype == PLINK_CONFIRM || (ftype == PLINK_CLOSE && ie_len == 10)) 493 memcpy(&llid, PLINK_GET_PLID(elems.peer_link), 2); 494 495 rcu_read_lock(); 496 497 sta = sta_info_get(sdata, mgmt->sa); 498 if (!sta && ftype != PLINK_OPEN) { 499 mpl_dbg("Mesh plink: cls or cnf from unknown peer\n"); 500 rcu_read_unlock(); 501 return; 502 } 503 504 if (sta && !test_sta_flags(sta, WLAN_STA_AUTH)) { 505 mpl_dbg("Mesh plink: Action frame from non-authed peer\n"); 506 rcu_read_unlock(); 507 return; 508 } 509 510 if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) { 511 rcu_read_unlock(); 512 return; 513 } 514 515 /* Now we will figure out the appropriate event... */ 516 event = PLINK_UNDEFINED; 517 if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) { 518 matches_local = false; 519 switch (ftype) { 520 case PLINK_OPEN: 521 event = OPN_RJCT; 522 break; 523 case PLINK_CONFIRM: 524 event = CNF_RJCT; 525 break; 526 case PLINK_CLOSE: 527 /* avoid warning */ 528 break; 529 } 530 } 531 532 if (!sta && !matches_local) { 533 rcu_read_unlock(); 534 reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION); 535 llid = 0; 536 mesh_plink_frame_tx(sdata, PLINK_CLOSE, mgmt->sa, llid, 537 plid, reason); 538 return; 539 } else if (!sta) { 540 /* ftype == PLINK_OPEN */ 541 u32 rates; 542 543 rcu_read_unlock(); 544 545 if (!mesh_plink_free_count(sdata)) { 546 mpl_dbg("Mesh plink error: no more free plinks\n"); 547 return; 548 } 549 550 rates = ieee80211_sta_get_rates(local, &elems, rx_status->band); 551 sta = mesh_plink_alloc(sdata, mgmt->sa, rates); 552 if (!sta) { 553 mpl_dbg("Mesh plink error: plink table full\n"); 554 return; 555 } 556 if (sta_info_insert_rcu(sta)) { 557 rcu_read_unlock(); 558 return; 559 } 560 event = OPN_ACPT; 561 spin_lock_bh(&sta->lock); 562 } else if (matches_local) { 563 spin_lock_bh(&sta->lock); 564 switch (ftype) { 565 case PLINK_OPEN: 566 if (!mesh_plink_free_count(sdata) || 567 (sta->plid && sta->plid != plid)) 568 event = OPN_IGNR; 569 else 570 event = OPN_ACPT; 571 break; 572 case PLINK_CONFIRM: 573 if (!mesh_plink_free_count(sdata) || 574 (sta->llid != llid || sta->plid != plid)) 575 event = CNF_IGNR; 576 else 577 event = CNF_ACPT; 578 break; 579 case PLINK_CLOSE: 580 if (sta->plink_state == NL80211_PLINK_ESTAB) 581 /* Do not check for llid or plid. This does not 582 * follow the standard but since multiple plinks 583 * per sta are not supported, it is necessary in 584 * order to avoid a livelock when MP A sees an 585 * establish peer link to MP B but MP B does not 586 * see it. This can be caused by a timeout in 587 * B's peer link establishment or B beign 588 * restarted. 589 */ 590 event = CLS_ACPT; 591 else if (sta->plid != plid) 592 event = CLS_IGNR; 593 else if (ie_len == 7 && sta->llid != llid) 594 event = CLS_IGNR; 595 else 596 event = CLS_ACPT; 597 break; 598 default: 599 mpl_dbg("Mesh plink: unknown frame subtype\n"); 600 spin_unlock_bh(&sta->lock); 601 rcu_read_unlock(); 602 return; 603 } 604 } else { 605 spin_lock_bh(&sta->lock); 606 } 607 608 mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", 609 mgmt->sa, mplstates[sta->plink_state], 610 le16_to_cpu(sta->llid), le16_to_cpu(sta->plid), 611 event); 612 reason = 0; 613 switch (sta->plink_state) { 614 /* spin_unlock as soon as state is updated at each case */ 615 case NL80211_PLINK_LISTEN: 616 switch (event) { 617 case CLS_ACPT: 618 mesh_plink_fsm_restart(sta); 619 spin_unlock_bh(&sta->lock); 620 break; 621 case OPN_ACPT: 622 sta->plink_state = NL80211_PLINK_OPN_RCVD; 623 sta->plid = plid; 624 get_random_bytes(&llid, 2); 625 sta->llid = llid; 626 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); 627 spin_unlock_bh(&sta->lock); 628 mesh_plink_frame_tx(sdata, PLINK_OPEN, sta->sta.addr, llid, 629 0, 0); 630 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, 631 llid, plid, 0); 632 break; 633 default: 634 spin_unlock_bh(&sta->lock); 635 break; 636 } 637 break; 638 639 case NL80211_PLINK_OPN_SNT: 640 switch (event) { 641 case OPN_RJCT: 642 case CNF_RJCT: 643 reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION); 644 case CLS_ACPT: 645 if (!reason) 646 reason = cpu_to_le16(MESH_CLOSE_RCVD); 647 sta->reason = reason; 648 sta->plink_state = NL80211_PLINK_HOLDING; 649 if (!mod_plink_timer(sta, 650 dot11MeshHoldingTimeout(sdata))) 651 sta->ignore_plink_timer = true; 652 653 llid = sta->llid; 654 spin_unlock_bh(&sta->lock); 655 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, 656 plid, reason); 657 break; 658 case OPN_ACPT: 659 /* retry timer is left untouched */ 660 sta->plink_state = NL80211_PLINK_OPN_RCVD; 661 sta->plid = plid; 662 llid = sta->llid; 663 spin_unlock_bh(&sta->lock); 664 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid, 665 plid, 0); 666 break; 667 case CNF_ACPT: 668 sta->plink_state = NL80211_PLINK_CNF_RCVD; 669 if (!mod_plink_timer(sta, 670 dot11MeshConfirmTimeout(sdata))) 671 sta->ignore_plink_timer = true; 672 673 spin_unlock_bh(&sta->lock); 674 break; 675 default: 676 spin_unlock_bh(&sta->lock); 677 break; 678 } 679 break; 680 681 case NL80211_PLINK_OPN_RCVD: 682 switch (event) { 683 case OPN_RJCT: 684 case CNF_RJCT: 685 reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION); 686 case CLS_ACPT: 687 if (!reason) 688 reason = cpu_to_le16(MESH_CLOSE_RCVD); 689 sta->reason = reason; 690 sta->plink_state = NL80211_PLINK_HOLDING; 691 if (!mod_plink_timer(sta, 692 dot11MeshHoldingTimeout(sdata))) 693 sta->ignore_plink_timer = true; 694 695 llid = sta->llid; 696 spin_unlock_bh(&sta->lock); 697 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, 698 plid, reason); 699 break; 700 case OPN_ACPT: 701 llid = sta->llid; 702 spin_unlock_bh(&sta->lock); 703 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid, 704 plid, 0); 705 break; 706 case CNF_ACPT: 707 del_timer(&sta->plink_timer); 708 sta->plink_state = NL80211_PLINK_ESTAB; 709 spin_unlock_bh(&sta->lock); 710 mesh_plink_inc_estab_count(sdata); 711 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 712 mpl_dbg("Mesh plink with %pM ESTABLISHED\n", 713 sta->sta.addr); 714 break; 715 default: 716 spin_unlock_bh(&sta->lock); 717 break; 718 } 719 break; 720 721 case NL80211_PLINK_CNF_RCVD: 722 switch (event) { 723 case OPN_RJCT: 724 case CNF_RJCT: 725 reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION); 726 case CLS_ACPT: 727 if (!reason) 728 reason = cpu_to_le16(MESH_CLOSE_RCVD); 729 sta->reason = reason; 730 sta->plink_state = NL80211_PLINK_HOLDING; 731 if (!mod_plink_timer(sta, 732 dot11MeshHoldingTimeout(sdata))) 733 sta->ignore_plink_timer = true; 734 735 llid = sta->llid; 736 spin_unlock_bh(&sta->lock); 737 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, 738 plid, reason); 739 break; 740 case OPN_ACPT: 741 del_timer(&sta->plink_timer); 742 sta->plink_state = NL80211_PLINK_ESTAB; 743 spin_unlock_bh(&sta->lock); 744 mesh_plink_inc_estab_count(sdata); 745 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 746 mpl_dbg("Mesh plink with %pM ESTABLISHED\n", 747 sta->sta.addr); 748 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid, 749 plid, 0); 750 break; 751 default: 752 spin_unlock_bh(&sta->lock); 753 break; 754 } 755 break; 756 757 case NL80211_PLINK_ESTAB: 758 switch (event) { 759 case CLS_ACPT: 760 reason = cpu_to_le16(MESH_CLOSE_RCVD); 761 sta->reason = reason; 762 deactivated = __mesh_plink_deactivate(sta); 763 sta->plink_state = NL80211_PLINK_HOLDING; 764 llid = sta->llid; 765 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 766 spin_unlock_bh(&sta->lock); 767 if (deactivated) 768 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 769 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, 770 plid, reason); 771 break; 772 case OPN_ACPT: 773 llid = sta->llid; 774 spin_unlock_bh(&sta->lock); 775 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid, 776 plid, 0); 777 break; 778 default: 779 spin_unlock_bh(&sta->lock); 780 break; 781 } 782 break; 783 case NL80211_PLINK_HOLDING: 784 switch (event) { 785 case CLS_ACPT: 786 if (del_timer(&sta->plink_timer)) 787 sta->ignore_plink_timer = 1; 788 mesh_plink_fsm_restart(sta); 789 spin_unlock_bh(&sta->lock); 790 break; 791 case OPN_ACPT: 792 case CNF_ACPT: 793 case OPN_RJCT: 794 case CNF_RJCT: 795 llid = sta->llid; 796 reason = sta->reason; 797 spin_unlock_bh(&sta->lock); 798 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, 799 llid, plid, reason); 800 break; 801 default: 802 spin_unlock_bh(&sta->lock); 803 } 804 break; 805 default: 806 /* should not get here, PLINK_BLOCKED is dealt with at the 807 * beginning of the function 808 */ 809 spin_unlock_bh(&sta->lock); 810 break; 811 } 812 813 rcu_read_unlock(); 814} 815