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