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