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