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