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