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