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