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