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