mesh_plink.c revision f68d776a04bfcebc426f605c4440ffe38c583a4b
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#define PLINK_GET_LLID(p) (p + 2) 17#define PLINK_GET_PLID(p) (p + 4) 18 19#define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \ 20 jiffies + HZ * t / 1000)) 21 22/* We only need a valid sta if user configured a minimum rssi_threshold. */ 23#define rssi_threshold_check(sta, sdata) \ 24 (sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\ 25 (sta && (s8) -ewma_read(&sta->avg_signal) > \ 26 sdata->u.mesh.mshcfg.rssi_threshold)) 27 28enum plink_event { 29 PLINK_UNDEFINED, 30 OPN_ACPT, 31 OPN_RJCT, 32 OPN_IGNR, 33 CNF_ACPT, 34 CNF_RJCT, 35 CNF_IGNR, 36 CLS_ACPT, 37 CLS_IGNR 38}; 39 40static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 41 enum ieee80211_self_protected_actioncode action, 42 u8 *da, __le16 llid, __le16 plid, __le16 reason); 43 44/** 45 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine 46 * 47 * @sta: mesh peer link to restart 48 * 49 * Locking: this function must be called holding sta->lock 50 */ 51static inline void mesh_plink_fsm_restart(struct sta_info *sta) 52{ 53 sta->plink_state = NL80211_PLINK_LISTEN; 54 sta->llid = sta->plid = sta->reason = 0; 55 sta->plink_retries = 0; 56} 57 58/** 59 * mesh_set_ht_prot_mode - set correct HT protection mode 60 * 61 * Section 9.23.3.5 of IEEE 80211-2012 describes the protection rules for HT 62 * mesh STA in a MBSS. Three HT protection modes are supported for now, non-HT 63 * mixed mode, 20MHz-protection and no-protection mode. non-HT mixed mode is 64 * selected if any non-HT peers are present in our MBSS. 20MHz-protection mode 65 * is selected if all peers in our 20/40MHz MBSS support HT and atleast one 66 * HT20 peer is present. Otherwise no-protection mode is selected. 67 */ 68static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata) 69{ 70 struct ieee80211_local *local = sdata->local; 71 struct sta_info *sta; 72 u32 changed = 0; 73 u16 ht_opmode; 74 bool non_ht_sta = false, ht20_sta = false; 75 76 if (sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) 77 return 0; 78 79 rcu_read_lock(); 80 list_for_each_entry_rcu(sta, &local->sta_list, list) { 81 if (sdata != sta->sdata || 82 sta->plink_state != NL80211_PLINK_ESTAB) 83 continue; 84 85 switch (sta->ch_width) { 86 case NL80211_CHAN_WIDTH_20_NOHT: 87 mpl_dbg(sdata, 88 "mesh_plink %pM: nonHT sta (%pM) is present\n", 89 sdata->vif.addr, sta->sta.addr); 90 non_ht_sta = true; 91 goto out; 92 case NL80211_CHAN_WIDTH_20: 93 mpl_dbg(sdata, 94 "mesh_plink %pM: HT20 sta (%pM) is present\n", 95 sdata->vif.addr, sta->sta.addr); 96 ht20_sta = true; 97 default: 98 break; 99 } 100 } 101out: 102 rcu_read_unlock(); 103 104 if (non_ht_sta) 105 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED; 106 else if (ht20_sta && 107 sdata->vif.bss_conf.chandef.width > NL80211_CHAN_WIDTH_20) 108 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_20MHZ; 109 else 110 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONE; 111 112 if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) { 113 sdata->vif.bss_conf.ht_operation_mode = ht_opmode; 114 sdata->u.mesh.mshcfg.ht_opmode = ht_opmode; 115 changed = BSS_CHANGED_HT; 116 mpl_dbg(sdata, 117 "mesh_plink %pM: protection mode changed to %d\n", 118 sdata->vif.addr, ht_opmode); 119 } 120 121 return changed; 122} 123 124/** 125 * __mesh_plink_deactivate - deactivate mesh peer link 126 * 127 * @sta: mesh peer link to deactivate 128 * 129 * All mesh paths with this peer as next hop will be flushed 130 * Returns beacon changed flag if the beacon content changed. 131 * 132 * Locking: the caller must hold sta->lock 133 */ 134static u32 __mesh_plink_deactivate(struct sta_info *sta) 135{ 136 struct ieee80211_sub_if_data *sdata = sta->sdata; 137 u32 changed = 0; 138 139 if (sta->plink_state == NL80211_PLINK_ESTAB) 140 changed = mesh_plink_dec_estab_count(sdata); 141 sta->plink_state = NL80211_PLINK_BLOCKED; 142 mesh_path_flush_by_nexthop(sta); 143 144 return changed; 145} 146 147/** 148 * mesh_plink_deactivate - deactivate mesh peer link 149 * 150 * @sta: mesh peer link to deactivate 151 * 152 * All mesh paths with this peer as next hop will be flushed 153 */ 154void mesh_plink_deactivate(struct sta_info *sta) 155{ 156 struct ieee80211_sub_if_data *sdata = sta->sdata; 157 u32 changed; 158 159 spin_lock_bh(&sta->lock); 160 changed = __mesh_plink_deactivate(sta); 161 sta->reason = cpu_to_le16(WLAN_REASON_MESH_PEER_CANCELED); 162 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 163 sta->sta.addr, sta->llid, sta->plid, 164 sta->reason); 165 spin_unlock_bh(&sta->lock); 166 167 ieee80211_bss_info_change_notify(sdata, changed); 168} 169 170static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 171 enum ieee80211_self_protected_actioncode action, 172 u8 *da, __le16 llid, __le16 plid, __le16 reason) { 173 struct ieee80211_local *local = sdata->local; 174 struct sk_buff *skb; 175 struct ieee80211_tx_info *info; 176 struct ieee80211_mgmt *mgmt; 177 bool include_plid = false; 178 u16 peering_proto = 0; 179 u8 *pos, ie_len = 4; 180 int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.self_prot) + 181 sizeof(mgmt->u.action.u.self_prot); 182 int err = -ENOMEM; 183 184 skb = dev_alloc_skb(local->tx_headroom + 185 hdr_len + 186 2 + /* capability info */ 187 2 + /* AID */ 188 2 + 8 + /* supported rates */ 189 2 + (IEEE80211_MAX_SUPP_RATES - 8) + 190 2 + sdata->u.mesh.mesh_id_len + 191 2 + sizeof(struct ieee80211_meshconf_ie) + 192 2 + sizeof(struct ieee80211_ht_cap) + 193 2 + sizeof(struct ieee80211_ht_operation) + 194 2 + 8 + /* peering IE */ 195 sdata->u.mesh.ie_len); 196 if (!skb) 197 return -1; 198 info = IEEE80211_SKB_CB(skb); 199 skb_reserve(skb, local->tx_headroom); 200 mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); 201 memset(mgmt, 0, hdr_len); 202 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 203 IEEE80211_STYPE_ACTION); 204 memcpy(mgmt->da, da, ETH_ALEN); 205 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 206 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 207 mgmt->u.action.category = WLAN_CATEGORY_SELF_PROTECTED; 208 mgmt->u.action.u.self_prot.action_code = action; 209 210 if (action != WLAN_SP_MESH_PEERING_CLOSE) { 211 enum ieee80211_band band = ieee80211_get_sdata_band(sdata); 212 213 /* capability info */ 214 pos = skb_put(skb, 2); 215 memset(pos, 0, 2); 216 if (action == WLAN_SP_MESH_PEERING_CONFIRM) { 217 /* AID */ 218 pos = skb_put(skb, 2); 219 memcpy(pos + 2, &plid, 2); 220 } 221 if (ieee80211_add_srates_ie(sdata, skb, true, band) || 222 ieee80211_add_ext_srates_ie(sdata, skb, true, band) || 223 mesh_add_rsn_ie(skb, sdata) || 224 mesh_add_meshid_ie(skb, sdata) || 225 mesh_add_meshconf_ie(skb, sdata)) 226 goto free; 227 } else { /* WLAN_SP_MESH_PEERING_CLOSE */ 228 info->flags |= IEEE80211_TX_CTL_NO_ACK; 229 if (mesh_add_meshid_ie(skb, sdata)) 230 goto free; 231 } 232 233 /* Add Mesh Peering Management element */ 234 switch (action) { 235 case WLAN_SP_MESH_PEERING_OPEN: 236 break; 237 case WLAN_SP_MESH_PEERING_CONFIRM: 238 ie_len += 2; 239 include_plid = true; 240 break; 241 case WLAN_SP_MESH_PEERING_CLOSE: 242 if (plid) { 243 ie_len += 2; 244 include_plid = true; 245 } 246 ie_len += 2; /* reason code */ 247 break; 248 default: 249 err = -EINVAL; 250 goto free; 251 } 252 253 if (WARN_ON(skb_tailroom(skb) < 2 + ie_len)) 254 goto free; 255 256 pos = skb_put(skb, 2 + ie_len); 257 *pos++ = WLAN_EID_PEER_MGMT; 258 *pos++ = ie_len; 259 memcpy(pos, &peering_proto, 2); 260 pos += 2; 261 memcpy(pos, &llid, 2); 262 pos += 2; 263 if (include_plid) { 264 memcpy(pos, &plid, 2); 265 pos += 2; 266 } 267 if (action == WLAN_SP_MESH_PEERING_CLOSE) { 268 memcpy(pos, &reason, 2); 269 pos += 2; 270 } 271 272 if (action != WLAN_SP_MESH_PEERING_CLOSE) { 273 if (mesh_add_ht_cap_ie(skb, sdata) || 274 mesh_add_ht_oper_ie(skb, sdata)) 275 goto free; 276 } 277 278 if (mesh_add_vendor_ies(skb, sdata)) 279 goto free; 280 281 ieee80211_tx_skb(sdata, skb); 282 return 0; 283free: 284 kfree_skb(skb); 285 return err; 286} 287 288static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, 289 struct sta_info *sta, 290 struct ieee802_11_elems *elems, bool insert) 291{ 292 struct ieee80211_local *local = sdata->local; 293 enum ieee80211_band band = ieee80211_get_sdata_band(sdata); 294 struct ieee80211_supported_band *sband; 295 u32 rates, basic_rates = 0, changed = 0; 296 297 sband = local->hw.wiphy->bands[band]; 298 rates = ieee80211_sta_get_rates(local, elems, band, &basic_rates); 299 300 spin_lock_bh(&sta->lock); 301 sta->last_rx = jiffies; 302 303 /* rates and capabilities don't change during peering */ 304 if (sta->plink_state == NL80211_PLINK_ESTAB) 305 goto out; 306 307 if (sta->sta.supp_rates[band] != rates) 308 changed |= IEEE80211_RC_SUPP_RATES_CHANGED; 309 sta->sta.supp_rates[band] = rates; 310 if (elems->ht_cap_elem && 311 sdata->vif.bss_conf.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) 312 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, 313 elems->ht_cap_elem, 314 &sta->sta.ht_cap); 315 else 316 memset(&sta->sta.ht_cap, 0, sizeof(sta->sta.ht_cap)); 317 318 if (elems->ht_operation) { 319 struct cfg80211_chan_def chandef; 320 321 if (!(elems->ht_operation->ht_param & 322 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) 323 sta->sta.ht_cap.cap &= 324 ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; 325 ieee80211_ht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan, 326 elems->ht_operation, &chandef); 327 if (sta->ch_width != chandef.width) 328 changed |= IEEE80211_RC_BW_CHANGED; 329 sta->ch_width = chandef.width; 330 } 331 332 if (insert) 333 rate_control_rate_init(sta); 334 else 335 rate_control_rate_update(local, sband, sta, changed); 336out: 337 spin_unlock_bh(&sta->lock); 338} 339 340static struct sta_info * 341__mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *hw_addr) 342{ 343 struct sta_info *sta; 344 345 if (sdata->local->num_sta >= MESH_MAX_PLINKS) 346 return NULL; 347 348 sta = sta_info_alloc(sdata, hw_addr, GFP_KERNEL); 349 if (!sta) 350 return NULL; 351 352 sta->plink_state = NL80211_PLINK_LISTEN; 353 init_timer(&sta->plink_timer); 354 355 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); 356 sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); 357 sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); 358 359 set_sta_flag(sta, WLAN_STA_WME); 360 361 return sta; 362} 363 364static struct sta_info * 365mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr, 366 struct ieee802_11_elems *elems) 367{ 368 struct sta_info *sta = NULL; 369 370 /* Userspace handles peer allocation when security is enabled */ 371 if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) 372 cfg80211_notify_new_peer_candidate(sdata->dev, addr, 373 elems->ie_start, 374 elems->total_len, 375 GFP_KERNEL); 376 else 377 sta = __mesh_sta_info_alloc(sdata, addr); 378 379 return sta; 380} 381 382/* 383 * mesh_sta_info_get - return mesh sta info entry for @addr. 384 * 385 * @sdata: local meshif 386 * @addr: peer's address 387 * @elems: IEs from beacon or mesh peering frame. 388 * 389 * Return existing or newly allocated sta_info under RCU read lock. 390 * (re)initialize with given IEs. 391 */ 392static struct sta_info * 393mesh_sta_info_get(struct ieee80211_sub_if_data *sdata, 394 u8 *addr, struct ieee802_11_elems *elems) __acquires(RCU) 395{ 396 struct sta_info *sta = NULL; 397 398 rcu_read_lock(); 399 sta = sta_info_get(sdata, addr); 400 if (sta) { 401 mesh_sta_info_init(sdata, sta, elems, false); 402 } else { 403 rcu_read_unlock(); 404 /* can't run atomic */ 405 sta = mesh_sta_info_alloc(sdata, addr, elems); 406 if (!sta) { 407 rcu_read_lock(); 408 return NULL; 409 } 410 411 if (sta_info_insert_rcu(sta)) 412 return NULL; 413 } 414 415 return sta; 416} 417 418/* 419 * mesh_neighbour_update - update or initialize new mesh neighbor. 420 * 421 * @sdata: local meshif 422 * @addr: peer's address 423 * @elems: IEs from beacon or mesh peering frame 424 * 425 * Initiates peering if appropriate. 426 */ 427void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, 428 u8 *hw_addr, 429 struct ieee802_11_elems *elems) 430{ 431 struct sta_info *sta; 432 433 sta = mesh_sta_info_get(sdata, hw_addr, elems); 434 if (!sta) 435 goto out; 436 437 if (mesh_peer_accepts_plinks(elems) && 438 sta->plink_state == NL80211_PLINK_LISTEN && 439 sdata->u.mesh.accepting_plinks && 440 sdata->u.mesh.mshcfg.auto_open_plinks && 441 rssi_threshold_check(sta, sdata)) 442 mesh_plink_open(sta); 443 444out: 445 rcu_read_unlock(); 446} 447 448static void mesh_plink_timer(unsigned long data) 449{ 450 struct sta_info *sta; 451 __le16 llid, plid, reason; 452 struct ieee80211_sub_if_data *sdata; 453 struct mesh_config *mshcfg; 454 455 /* 456 * This STA is valid because sta_info_destroy() will 457 * del_timer_sync() this timer after having made sure 458 * it cannot be readded (by deleting the plink.) 459 */ 460 sta = (struct sta_info *) data; 461 462 if (sta->sdata->local->quiescing) { 463 sta->plink_timer_was_running = true; 464 return; 465 } 466 467 spin_lock_bh(&sta->lock); 468 if (sta->ignore_plink_timer) { 469 sta->ignore_plink_timer = false; 470 spin_unlock_bh(&sta->lock); 471 return; 472 } 473 mpl_dbg(sta->sdata, 474 "Mesh plink timer for %pM fired on state %d\n", 475 sta->sta.addr, sta->plink_state); 476 reason = 0; 477 llid = sta->llid; 478 plid = sta->plid; 479 sdata = sta->sdata; 480 mshcfg = &sdata->u.mesh.mshcfg; 481 482 switch (sta->plink_state) { 483 case NL80211_PLINK_OPN_RCVD: 484 case NL80211_PLINK_OPN_SNT: 485 /* retry timer */ 486 if (sta->plink_retries < mshcfg->dot11MeshMaxRetries) { 487 u32 rand; 488 mpl_dbg(sta->sdata, 489 "Mesh plink for %pM (retry, timeout): %d %d\n", 490 sta->sta.addr, sta->plink_retries, 491 sta->plink_timeout); 492 get_random_bytes(&rand, sizeof(u32)); 493 sta->plink_timeout = sta->plink_timeout + 494 rand % sta->plink_timeout; 495 ++sta->plink_retries; 496 mod_plink_timer(sta, sta->plink_timeout); 497 spin_unlock_bh(&sta->lock); 498 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, 499 sta->sta.addr, llid, 0, 0); 500 break; 501 } 502 reason = cpu_to_le16(WLAN_REASON_MESH_MAX_RETRIES); 503 /* fall through on else */ 504 case NL80211_PLINK_CNF_RCVD: 505 /* confirm timer */ 506 if (!reason) 507 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT); 508 sta->plink_state = NL80211_PLINK_HOLDING; 509 mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout); 510 spin_unlock_bh(&sta->lock); 511 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 512 sta->sta.addr, llid, plid, reason); 513 break; 514 case NL80211_PLINK_HOLDING: 515 /* holding timer */ 516 del_timer(&sta->plink_timer); 517 mesh_plink_fsm_restart(sta); 518 spin_unlock_bh(&sta->lock); 519 break; 520 default: 521 spin_unlock_bh(&sta->lock); 522 break; 523 } 524} 525 526#ifdef CONFIG_PM 527void mesh_plink_quiesce(struct sta_info *sta) 528{ 529 if (del_timer_sync(&sta->plink_timer)) 530 sta->plink_timer_was_running = true; 531} 532 533void mesh_plink_restart(struct sta_info *sta) 534{ 535 if (sta->plink_timer_was_running) { 536 add_timer(&sta->plink_timer); 537 sta->plink_timer_was_running = false; 538 } 539} 540#endif 541 542static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout) 543{ 544 sta->plink_timer.expires = jiffies + (HZ * timeout / 1000); 545 sta->plink_timer.data = (unsigned long) sta; 546 sta->plink_timer.function = mesh_plink_timer; 547 sta->plink_timeout = timeout; 548 add_timer(&sta->plink_timer); 549} 550 551int mesh_plink_open(struct sta_info *sta) 552{ 553 __le16 llid; 554 struct ieee80211_sub_if_data *sdata = sta->sdata; 555 556 if (!test_sta_flag(sta, WLAN_STA_AUTH)) 557 return -EPERM; 558 559 spin_lock_bh(&sta->lock); 560 get_random_bytes(&llid, 2); 561 sta->llid = llid; 562 if (sta->plink_state != NL80211_PLINK_LISTEN && 563 sta->plink_state != NL80211_PLINK_BLOCKED) { 564 spin_unlock_bh(&sta->lock); 565 return -EBUSY; 566 } 567 sta->plink_state = NL80211_PLINK_OPN_SNT; 568 mesh_plink_timer_set(sta, sdata->u.mesh.mshcfg.dot11MeshRetryTimeout); 569 spin_unlock_bh(&sta->lock); 570 mpl_dbg(sdata, 571 "Mesh plink: starting establishment with %pM\n", 572 sta->sta.addr); 573 574 return mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, 575 sta->sta.addr, llid, 0, 0); 576} 577 578void mesh_plink_block(struct sta_info *sta) 579{ 580 struct ieee80211_sub_if_data *sdata = sta->sdata; 581 u32 changed; 582 583 spin_lock_bh(&sta->lock); 584 changed = __mesh_plink_deactivate(sta); 585 sta->plink_state = NL80211_PLINK_BLOCKED; 586 spin_unlock_bh(&sta->lock); 587 588 ieee80211_bss_info_change_notify(sdata, changed); 589} 590 591 592void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, 593 size_t len, struct ieee80211_rx_status *rx_status) 594{ 595 struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg; 596 struct ieee802_11_elems elems; 597 struct sta_info *sta; 598 enum plink_event event; 599 enum ieee80211_self_protected_actioncode ftype; 600 size_t baselen; 601 bool matches_local = true; 602 u8 ie_len; 603 u8 *baseaddr; 604 u32 changed = 0; 605 __le16 plid, llid, reason; 606 static const char *mplstates[] = { 607 [NL80211_PLINK_LISTEN] = "LISTEN", 608 [NL80211_PLINK_OPN_SNT] = "OPN-SNT", 609 [NL80211_PLINK_OPN_RCVD] = "OPN-RCVD", 610 [NL80211_PLINK_CNF_RCVD] = "CNF_RCVD", 611 [NL80211_PLINK_ESTAB] = "ESTAB", 612 [NL80211_PLINK_HOLDING] = "HOLDING", 613 [NL80211_PLINK_BLOCKED] = "BLOCKED" 614 }; 615 616 /* need action_code, aux */ 617 if (len < IEEE80211_MIN_ACTION_SIZE + 3) 618 return; 619 620 if (is_multicast_ether_addr(mgmt->da)) { 621 mpl_dbg(sdata, 622 "Mesh plink: ignore frame from multicast address\n"); 623 return; 624 } 625 626 baseaddr = mgmt->u.action.u.self_prot.variable; 627 baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt; 628 if (mgmt->u.action.u.self_prot.action_code == 629 WLAN_SP_MESH_PEERING_CONFIRM) { 630 baseaddr += 4; 631 baselen += 4; 632 } 633 ieee802_11_parse_elems(baseaddr, len - baselen, &elems); 634 if (!elems.peering) { 635 mpl_dbg(sdata, 636 "Mesh plink: missing necessary peer link ie\n"); 637 return; 638 } 639 if (elems.rsn_len && 640 sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) { 641 mpl_dbg(sdata, 642 "Mesh plink: can't establish link with secure peer\n"); 643 return; 644 } 645 646 ftype = mgmt->u.action.u.self_prot.action_code; 647 ie_len = elems.peering_len; 648 if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) || 649 (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) || 650 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6 651 && ie_len != 8)) { 652 mpl_dbg(sdata, 653 "Mesh plink: incorrect plink ie length %d %d\n", 654 ftype, ie_len); 655 return; 656 } 657 658 if (ftype != WLAN_SP_MESH_PEERING_CLOSE && 659 (!elems.mesh_id || !elems.mesh_config)) { 660 mpl_dbg(sdata, "Mesh plink: missing necessary ie\n"); 661 return; 662 } 663 /* Note the lines below are correct, the llid in the frame is the plid 664 * from the point of view of this host. 665 */ 666 memcpy(&plid, PLINK_GET_LLID(elems.peering), 2); 667 if (ftype == WLAN_SP_MESH_PEERING_CONFIRM || 668 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8)) 669 memcpy(&llid, PLINK_GET_PLID(elems.peering), 2); 670 671 /* WARNING: Only for sta pointer, is dropped & re-acquired */ 672 rcu_read_lock(); 673 674 sta = sta_info_get(sdata, mgmt->sa); 675 if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) { 676 mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n"); 677 rcu_read_unlock(); 678 return; 679 } 680 681 if (ftype == WLAN_SP_MESH_PEERING_OPEN && 682 !rssi_threshold_check(sta, sdata)) { 683 mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n", 684 mgmt->sa); 685 rcu_read_unlock(); 686 return; 687 } 688 689 if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) { 690 mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n"); 691 rcu_read_unlock(); 692 return; 693 } 694 695 if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) { 696 rcu_read_unlock(); 697 return; 698 } 699 700 /* Now we will figure out the appropriate event... */ 701 event = PLINK_UNDEFINED; 702 if (ftype != WLAN_SP_MESH_PEERING_CLOSE && 703 !mesh_matches_local(sdata, &elems)) { 704 matches_local = false; 705 switch (ftype) { 706 case WLAN_SP_MESH_PEERING_OPEN: 707 event = OPN_RJCT; 708 break; 709 case WLAN_SP_MESH_PEERING_CONFIRM: 710 event = CNF_RJCT; 711 break; 712 default: 713 break; 714 } 715 } 716 717 if (!sta && !matches_local) { 718 rcu_read_unlock(); 719 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); 720 llid = 0; 721 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 722 mgmt->sa, llid, plid, reason); 723 return; 724 } else if (!sta) { 725 /* ftype == WLAN_SP_MESH_PEERING_OPEN */ 726 if (!mesh_plink_free_count(sdata)) { 727 mpl_dbg(sdata, "Mesh plink error: no more free plinks\n"); 728 rcu_read_unlock(); 729 return; 730 } 731 event = OPN_ACPT; 732 } else if (matches_local) { 733 switch (ftype) { 734 case WLAN_SP_MESH_PEERING_OPEN: 735 if (!mesh_plink_free_count(sdata) || 736 (sta->plid && sta->plid != plid)) 737 event = OPN_IGNR; 738 else 739 event = OPN_ACPT; 740 break; 741 case WLAN_SP_MESH_PEERING_CONFIRM: 742 if (!mesh_plink_free_count(sdata) || 743 (sta->llid != llid || sta->plid != plid)) 744 event = CNF_IGNR; 745 else 746 event = CNF_ACPT; 747 break; 748 case WLAN_SP_MESH_PEERING_CLOSE: 749 if (sta->plink_state == NL80211_PLINK_ESTAB) 750 /* Do not check for llid or plid. This does not 751 * follow the standard but since multiple plinks 752 * per sta are not supported, it is necessary in 753 * order to avoid a livelock when MP A sees an 754 * establish peer link to MP B but MP B does not 755 * see it. This can be caused by a timeout in 756 * B's peer link establishment or B beign 757 * restarted. 758 */ 759 event = CLS_ACPT; 760 else if (sta->plid != plid) 761 event = CLS_IGNR; 762 else if (ie_len == 7 && sta->llid != llid) 763 event = CLS_IGNR; 764 else 765 event = CLS_ACPT; 766 break; 767 default: 768 mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n"); 769 rcu_read_unlock(); 770 return; 771 } 772 } 773 774 if (event == OPN_ACPT) { 775 rcu_read_unlock(); 776 /* allocate sta entry if necessary and update info */ 777 sta = mesh_sta_info_get(sdata, mgmt->sa, &elems); 778 if (!sta) { 779 mpl_dbg(sdata, "Mesh plink: failed to init peer!\n"); 780 rcu_read_unlock(); 781 return; 782 } 783 } 784 785 mpl_dbg(sdata, 786 "Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", 787 mgmt->sa, mplstates[sta->plink_state], 788 le16_to_cpu(sta->llid), le16_to_cpu(sta->plid), 789 event); 790 reason = 0; 791 spin_lock_bh(&sta->lock); 792 switch (sta->plink_state) { 793 /* spin_unlock as soon as state is updated at each case */ 794 case NL80211_PLINK_LISTEN: 795 switch (event) { 796 case CLS_ACPT: 797 mesh_plink_fsm_restart(sta); 798 spin_unlock_bh(&sta->lock); 799 break; 800 case OPN_ACPT: 801 sta->plink_state = NL80211_PLINK_OPN_RCVD; 802 sta->plid = plid; 803 get_random_bytes(&llid, 2); 804 sta->llid = llid; 805 mesh_plink_timer_set(sta, 806 mshcfg->dot11MeshRetryTimeout); 807 spin_unlock_bh(&sta->lock); 808 mesh_plink_frame_tx(sdata, 809 WLAN_SP_MESH_PEERING_OPEN, 810 sta->sta.addr, llid, 0, 0); 811 mesh_plink_frame_tx(sdata, 812 WLAN_SP_MESH_PEERING_CONFIRM, 813 sta->sta.addr, llid, plid, 0); 814 break; 815 default: 816 spin_unlock_bh(&sta->lock); 817 break; 818 } 819 break; 820 821 case NL80211_PLINK_OPN_SNT: 822 switch (event) { 823 case OPN_RJCT: 824 case CNF_RJCT: 825 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); 826 case CLS_ACPT: 827 if (!reason) 828 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 829 sta->reason = reason; 830 sta->plink_state = NL80211_PLINK_HOLDING; 831 if (!mod_plink_timer(sta, 832 mshcfg->dot11MeshHoldingTimeout)) 833 sta->ignore_plink_timer = true; 834 835 llid = sta->llid; 836 spin_unlock_bh(&sta->lock); 837 mesh_plink_frame_tx(sdata, 838 WLAN_SP_MESH_PEERING_CLOSE, 839 sta->sta.addr, llid, plid, reason); 840 break; 841 case OPN_ACPT: 842 /* retry timer is left untouched */ 843 sta->plink_state = NL80211_PLINK_OPN_RCVD; 844 sta->plid = plid; 845 llid = sta->llid; 846 spin_unlock_bh(&sta->lock); 847 mesh_plink_frame_tx(sdata, 848 WLAN_SP_MESH_PEERING_CONFIRM, 849 sta->sta.addr, llid, plid, 0); 850 break; 851 case CNF_ACPT: 852 sta->plink_state = NL80211_PLINK_CNF_RCVD; 853 if (!mod_plink_timer(sta, 854 mshcfg->dot11MeshConfirmTimeout)) 855 sta->ignore_plink_timer = true; 856 857 spin_unlock_bh(&sta->lock); 858 break; 859 default: 860 spin_unlock_bh(&sta->lock); 861 break; 862 } 863 break; 864 865 case NL80211_PLINK_OPN_RCVD: 866 switch (event) { 867 case OPN_RJCT: 868 case CNF_RJCT: 869 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); 870 case CLS_ACPT: 871 if (!reason) 872 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 873 sta->reason = reason; 874 sta->plink_state = NL80211_PLINK_HOLDING; 875 if (!mod_plink_timer(sta, 876 mshcfg->dot11MeshHoldingTimeout)) 877 sta->ignore_plink_timer = true; 878 879 llid = sta->llid; 880 spin_unlock_bh(&sta->lock); 881 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 882 sta->sta.addr, llid, plid, reason); 883 break; 884 case OPN_ACPT: 885 llid = sta->llid; 886 spin_unlock_bh(&sta->lock); 887 mesh_plink_frame_tx(sdata, 888 WLAN_SP_MESH_PEERING_CONFIRM, 889 sta->sta.addr, llid, plid, 0); 890 break; 891 case CNF_ACPT: 892 del_timer(&sta->plink_timer); 893 sta->plink_state = NL80211_PLINK_ESTAB; 894 spin_unlock_bh(&sta->lock); 895 changed |= mesh_plink_inc_estab_count(sdata); 896 changed |= mesh_set_ht_prot_mode(sdata); 897 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", 898 sta->sta.addr); 899 break; 900 default: 901 spin_unlock_bh(&sta->lock); 902 break; 903 } 904 break; 905 906 case NL80211_PLINK_CNF_RCVD: 907 switch (event) { 908 case OPN_RJCT: 909 case CNF_RJCT: 910 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); 911 case CLS_ACPT: 912 if (!reason) 913 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 914 sta->reason = reason; 915 sta->plink_state = NL80211_PLINK_HOLDING; 916 if (!mod_plink_timer(sta, 917 mshcfg->dot11MeshHoldingTimeout)) 918 sta->ignore_plink_timer = true; 919 920 llid = sta->llid; 921 spin_unlock_bh(&sta->lock); 922 mesh_plink_frame_tx(sdata, 923 WLAN_SP_MESH_PEERING_CLOSE, 924 sta->sta.addr, llid, plid, reason); 925 break; 926 case OPN_ACPT: 927 del_timer(&sta->plink_timer); 928 sta->plink_state = NL80211_PLINK_ESTAB; 929 spin_unlock_bh(&sta->lock); 930 changed |= mesh_plink_inc_estab_count(sdata); 931 changed |= mesh_set_ht_prot_mode(sdata); 932 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", 933 sta->sta.addr); 934 mesh_plink_frame_tx(sdata, 935 WLAN_SP_MESH_PEERING_CONFIRM, 936 sta->sta.addr, llid, plid, 0); 937 break; 938 default: 939 spin_unlock_bh(&sta->lock); 940 break; 941 } 942 break; 943 944 case NL80211_PLINK_ESTAB: 945 switch (event) { 946 case CLS_ACPT: 947 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 948 sta->reason = reason; 949 changed |= __mesh_plink_deactivate(sta); 950 sta->plink_state = NL80211_PLINK_HOLDING; 951 llid = sta->llid; 952 mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout); 953 spin_unlock_bh(&sta->lock); 954 changed |= mesh_set_ht_prot_mode(sdata); 955 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 956 sta->sta.addr, llid, plid, reason); 957 break; 958 case OPN_ACPT: 959 llid = sta->llid; 960 spin_unlock_bh(&sta->lock); 961 mesh_plink_frame_tx(sdata, 962 WLAN_SP_MESH_PEERING_CONFIRM, 963 sta->sta.addr, llid, plid, 0); 964 break; 965 default: 966 spin_unlock_bh(&sta->lock); 967 break; 968 } 969 break; 970 case NL80211_PLINK_HOLDING: 971 switch (event) { 972 case CLS_ACPT: 973 if (del_timer(&sta->plink_timer)) 974 sta->ignore_plink_timer = 1; 975 mesh_plink_fsm_restart(sta); 976 spin_unlock_bh(&sta->lock); 977 break; 978 case OPN_ACPT: 979 case CNF_ACPT: 980 case OPN_RJCT: 981 case CNF_RJCT: 982 llid = sta->llid; 983 reason = sta->reason; 984 spin_unlock_bh(&sta->lock); 985 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 986 sta->sta.addr, llid, plid, reason); 987 break; 988 default: 989 spin_unlock_bh(&sta->lock); 990 } 991 break; 992 default: 993 /* should not get here, PLINK_BLOCKED is dealt with at the 994 * beginning of the function 995 */ 996 spin_unlock_bh(&sta->lock); 997 break; 998 } 999 1000 rcu_read_unlock(); 1001 1002 if (changed) 1003 ieee80211_bss_info_change_notify(sdata, changed); 1004} 1005