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