xref: /openbmc/linux/net/mac80211/mesh_plink.c (revision d0709a65181beb787ef3f58cfe45536a2bb254c8)
1 /*
2  * Copyright (c) 2008 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/kernel.h>
10 #include <linux/random.h>
11 #include "ieee80211_i.h"
12 #include "ieee80211_rate.h"
13 #include "mesh.h"
14 
15 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
16 #define mpl_dbg(fmt, args...)	printk(KERN_DEBUG fmt, ##args)
17 #else
18 #define mpl_dbg(fmt, args...)	do { (void)(0); } while (0)
19 #endif
20 
21 #define IEEE80211_FC(type, stype) cpu_to_le16(type | stype)
22 #define PLINK_GET_FRAME_SUBTYPE(p) (p)
23 #define PLINK_GET_LLID(p) (p + 1)
24 #define PLINK_GET_PLID(p) (p + 3)
25 
26 #define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
27 				jiffies + HZ * t / 1000))
28 
29 /* Peer link cancel reasons, all subject to ANA approval */
30 #define MESH_LINK_CANCELLED			2
31 #define MESH_MAX_NEIGHBORS			3
32 #define MESH_CAPABILITY_POLICY_VIOLATION	4
33 #define MESH_CLOSE_RCVD				5
34 #define MESH_MAX_RETRIES			6
35 #define MESH_CONFIRM_TIMEOUT			7
36 #define MESH_SECURITY_ROLE_NEGOTIATION_DIFFERS	8
37 #define MESH_SECURITY_AUTHENTICATION_IMPOSSIBLE	9
38 #define MESH_SECURITY_FAILED_VERIFICATION	10
39 
40 #define dot11MeshMaxRetries(s) (s->u.sta.mshcfg.dot11MeshMaxRetries)
41 #define dot11MeshRetryTimeout(s) (s->u.sta.mshcfg.dot11MeshRetryTimeout)
42 #define dot11MeshConfirmTimeout(s) (s->u.sta.mshcfg.dot11MeshConfirmTimeout)
43 #define dot11MeshHoldingTimeout(s) (s->u.sta.mshcfg.dot11MeshHoldingTimeout)
44 #define dot11MeshMaxPeerLinks(s) (s->u.sta.mshcfg.dot11MeshMaxPeerLinks)
45 
46 enum plink_frame_type {
47 	PLINK_OPEN = 0,
48 	PLINK_CONFIRM,
49 	PLINK_CLOSE
50 };
51 
52 enum plink_event {
53 	PLINK_UNDEFINED,
54 	OPN_ACPT,
55 	OPN_RJCT,
56 	OPN_IGNR,
57 	CNF_ACPT,
58 	CNF_RJCT,
59 	CNF_IGNR,
60 	CLS_ACPT,
61 	CLS_IGNR
62 };
63 
64 static inline
65 void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
66 {
67 	atomic_inc(&sdata->u.sta.mshstats.estab_plinks);
68 	mesh_accept_plinks_update(sdata);
69 }
70 
71 static inline
72 void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
73 {
74 	atomic_dec(&sdata->u.sta.mshstats.estab_plinks);
75 	mesh_accept_plinks_update(sdata);
76 }
77 
78 /**
79  * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
80  *
81  * @sta: mes peer link to restart
82  *
83  * Locking: this function must be called holding sta->plink_lock
84  */
85 static inline void mesh_plink_fsm_restart(struct sta_info *sta)
86 {
87 	sta->plink_state = LISTEN;
88 	sta->llid = sta->plid = sta->reason = sta->plink_retries = 0;
89 }
90 
91 /**
92  * mesh_plink_add - allocate and add a new mesh peer link
93  *
94  * @hw_addr: hardware address (ETH_ALEN length)
95  * @rates: rates the mesh peer supports
96  * @dev: local mesh interface
97  *
98  * The initial state of the new plink is set to LISTEN
99  *
100  * Returns: non-NULL on success, ERR_PTR() on error.
101  */
102 struct sta_info *mesh_plink_add(u8 *hw_addr, u64 rates,
103 				struct ieee80211_sub_if_data *sdata)
104 {
105 	struct ieee80211_local *local = sdata->local;
106 	struct sta_info *sta;
107 
108 	if (compare_ether_addr(hw_addr, sdata->dev->dev_addr) == 0)
109 		/* never add ourselves as neighbours */
110 		return ERR_PTR(-EINVAL);
111 
112 	if (is_multicast_ether_addr(hw_addr))
113 		return ERR_PTR(-EINVAL);
114 
115 	if (local->num_sta >= MESH_MAX_PLINKS)
116 		return ERR_PTR(-ENOSPC);
117 
118 	sta = sta_info_add(sdata, hw_addr);
119 	if (IS_ERR(sta))
120 		return sta;
121 
122 	sta->plink_state = LISTEN;
123 	spin_lock_init(&sta->plink_lock);
124 	init_timer(&sta->plink_timer);
125 	sta->flags |= WLAN_STA_AUTHORIZED;
126 	sta->supp_rates[local->hw.conf.channel->band] = rates;
127 	rate_control_rate_init(sta, local);
128 
129 	mesh_accept_plinks_update(sdata);
130 
131 	return sta;
132 }
133 
134 /**
135  * mesh_plink_deactivate - deactivate mesh peer link
136  *
137  * @sta: mesh peer link to deactivate
138  *
139  * All mesh paths with this peer as next hop will be flushed
140  *
141  * Locking: the caller must hold sta->plink_lock
142  */
143 static void __mesh_plink_deactivate(struct sta_info *sta)
144 {
145 	struct ieee80211_sub_if_data *sdata = sta->sdata;
146 
147 	if (sta->plink_state == ESTAB)
148 		mesh_plink_dec_estab_count(sdata);
149 	sta->plink_state = BLOCKED;
150 	mesh_path_flush_by_nexthop(sta);
151 }
152 
153 /**
154  * __mesh_plink_deactivate - deactivate mesh peer link
155  *
156  * @sta: mesh peer link to deactivate
157  *
158  * All mesh paths with this peer as next hop will be flushed
159  */
160 void mesh_plink_deactivate(struct sta_info *sta)
161 {
162 	spin_lock_bh(&sta->plink_lock);
163 	__mesh_plink_deactivate(sta);
164 	spin_unlock_bh(&sta->plink_lock);
165 }
166 
167 static int mesh_plink_frame_tx(struct net_device *dev,
168 		enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid,
169 		__le16 reason) {
170 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
171 	struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
172 	struct ieee80211_mgmt *mgmt;
173 	bool include_plid = false;
174 	u8 *pos;
175 	int ie_len;
176 
177 	if (!skb)
178 		return -1;
179 	skb_reserve(skb, local->hw.extra_tx_headroom);
180 	/* 25 is the size of the common mgmt part (24) plus the size of the
181 	 * common action part (1)
182 	 */
183 	mgmt = (struct ieee80211_mgmt *)
184 		skb_put(skb, 25 + sizeof(mgmt->u.action.u.plink_action));
185 	memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.plink_action));
186 	mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
187 					   IEEE80211_STYPE_ACTION);
188 	memcpy(mgmt->da, da, ETH_ALEN);
189 	memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
190 	/* BSSID is left zeroed, wildcard value */
191 	mgmt->u.action.category = PLINK_CATEGORY;
192 	mgmt->u.action.u.plink_action.action_code = action;
193 
194 	if (action == PLINK_CLOSE)
195 		mgmt->u.action.u.plink_action.aux = reason;
196 	else {
197 		mgmt->u.action.u.plink_action.aux = cpu_to_le16(0x0);
198 		if (action == PLINK_CONFIRM) {
199 			pos = skb_put(skb, 4);
200 			/* two-byte status code followed by two-byte AID */
201 			memset(pos, 0, 4);
202 		}
203 		mesh_mgmt_ies_add(skb, dev);
204 	}
205 
206 	/* Add Peer Link Management element */
207 	switch (action) {
208 	case PLINK_OPEN:
209 		ie_len = 3;
210 		break;
211 	case PLINK_CONFIRM:
212 		ie_len = 5;
213 		include_plid = true;
214 		break;
215 	case PLINK_CLOSE:
216 	default:
217 		if (!plid)
218 			ie_len = 5;
219 		else {
220 			ie_len = 7;
221 			include_plid = true;
222 		}
223 		break;
224 	}
225 
226 	pos = skb_put(skb, 2 + ie_len);
227 	*pos++ = WLAN_EID_PEER_LINK;
228 	*pos++ = ie_len;
229 	*pos++ = action;
230 	memcpy(pos, &llid, 2);
231 	if (include_plid) {
232 		pos += 2;
233 		memcpy(pos, &plid, 2);
234 	}
235 	if (action == PLINK_CLOSE) {
236 		pos += 2;
237 		memcpy(pos, &reason, 2);
238 	}
239 
240 	ieee80211_sta_tx(dev, skb, 0);
241 	return 0;
242 }
243 
244 void mesh_neighbour_update(u8 *hw_addr, u64 rates, struct net_device *dev,
245 			   bool peer_accepting_plinks)
246 {
247 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
248 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
249 	struct sta_info *sta;
250 
251 	rcu_read_lock();
252 
253 	sta = sta_info_get(local, hw_addr);
254 	if (!sta) {
255 		sta = mesh_plink_add(hw_addr, rates, sdata);
256 		if (IS_ERR(sta)) {
257 			rcu_read_unlock();
258 			return;
259 		}
260 	}
261 
262 	sta->last_rx = jiffies;
263 	sta->supp_rates[local->hw.conf.channel->band] = rates;
264 	if (peer_accepting_plinks && sta->plink_state == LISTEN &&
265 			sdata->u.sta.accepting_plinks &&
266 			sdata->u.sta.mshcfg.auto_open_plinks)
267 		mesh_plink_open(sta);
268 
269 	rcu_read_unlock();
270 }
271 
272 static void mesh_plink_timer(unsigned long data)
273 {
274 	struct sta_info *sta;
275 	__le16 llid, plid, reason;
276 	struct net_device *dev = NULL;
277 	struct ieee80211_sub_if_data *sdata;
278 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
279 	DECLARE_MAC_BUF(mac);
280 #endif
281 
282 	/*
283 	 * This STA is valid because sta_info_destroy() will
284 	 * del_timer_sync() this timer after having made sure
285 	 * it cannot be readded (by deleting the plink.)
286 	 */
287 	sta = (struct sta_info *) data;
288 
289 	spin_lock_bh(&sta->plink_lock);
290 	if (sta->ignore_plink_timer) {
291 		sta->ignore_plink_timer = false;
292 		spin_unlock_bh(&sta->plink_lock);
293 		return;
294 	}
295 	mpl_dbg("Mesh plink timer for %s fired on state %d\n",
296 			print_mac(mac, sta->addr), sta->plink_state);
297 	reason = 0;
298 	llid = sta->llid;
299 	plid = sta->plid;
300 	sdata = sta->sdata;
301 	dev = sdata->dev;
302 
303 	switch (sta->plink_state) {
304 	case OPN_RCVD:
305 	case OPN_SNT:
306 		/* retry timer */
307 		if (sta->plink_retries < dot11MeshMaxRetries(sdata)) {
308 			u32 rand;
309 			mpl_dbg("Mesh plink for %s (retry, timeout): %d %d\n",
310 					print_mac(mac, sta->addr),
311 					sta->plink_retries, sta->plink_timeout);
312 			get_random_bytes(&rand, sizeof(u32));
313 			sta->plink_timeout = sta->plink_timeout +
314 					     rand % sta->plink_timeout;
315 			++sta->plink_retries;
316 			mod_plink_timer(sta, sta->plink_timeout);
317 			spin_unlock_bh(&sta->plink_lock);
318 			mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid,
319 					    0, 0);
320 			break;
321 		}
322 		reason = cpu_to_le16(MESH_MAX_RETRIES);
323 		/* fall through on else */
324 	case CNF_RCVD:
325 		/* confirm timer */
326 		if (!reason)
327 			reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT);
328 		sta->plink_state = HOLDING;
329 		mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
330 		spin_unlock_bh(&sta->plink_lock);
331 		mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid,
332 				    reason);
333 		break;
334 	case HOLDING:
335 		/* holding timer */
336 		del_timer(&sta->plink_timer);
337 		mesh_plink_fsm_restart(sta);
338 		spin_unlock_bh(&sta->plink_lock);
339 		break;
340 	default:
341 		spin_unlock_bh(&sta->plink_lock);
342 		break;
343 	}
344 }
345 
346 static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout)
347 {
348 	sta->plink_timer.expires = jiffies + (HZ * timeout / 1000);
349 	sta->plink_timer.data = (unsigned long) sta;
350 	sta->plink_timer.function = mesh_plink_timer;
351 	sta->plink_timeout = timeout;
352 	add_timer(&sta->plink_timer);
353 }
354 
355 int mesh_plink_open(struct sta_info *sta)
356 {
357 	__le16 llid;
358 	struct ieee80211_sub_if_data *sdata = sta->sdata;
359 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
360 	DECLARE_MAC_BUF(mac);
361 #endif
362 
363 	spin_lock_bh(&sta->plink_lock);
364 	get_random_bytes(&llid, 2);
365 	sta->llid = llid;
366 	if (sta->plink_state != LISTEN) {
367 		spin_unlock_bh(&sta->plink_lock);
368 		return -EBUSY;
369 	}
370 	sta->plink_state = OPN_SNT;
371 	mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
372 	spin_unlock_bh(&sta->plink_lock);
373 	mpl_dbg("Mesh plink: starting establishment with %s\n",
374 		print_mac(mac, sta->addr));
375 
376 	return mesh_plink_frame_tx(sdata->dev, PLINK_OPEN,
377 				   sta->addr, llid, 0, 0);
378 }
379 
380 void mesh_plink_block(struct sta_info *sta)
381 {
382 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
383 	DECLARE_MAC_BUF(mac);
384 #endif
385 
386 	spin_lock_bh(&sta->plink_lock);
387 	__mesh_plink_deactivate(sta);
388 	sta->plink_state = BLOCKED;
389 	spin_unlock_bh(&sta->plink_lock);
390 }
391 
392 int mesh_plink_close(struct sta_info *sta)
393 {
394 	struct ieee80211_sub_if_data *sdata = sta->sdata;
395 	int llid, plid, reason;
396 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
397 	DECLARE_MAC_BUF(mac);
398 #endif
399 
400 	mpl_dbg("Mesh plink: closing link with %s\n",
401 			print_mac(mac, sta->addr));
402 	spin_lock_bh(&sta->plink_lock);
403 	sta->reason = cpu_to_le16(MESH_LINK_CANCELLED);
404 	reason = sta->reason;
405 
406 	if (sta->plink_state == LISTEN || sta->plink_state == BLOCKED) {
407 		mesh_plink_fsm_restart(sta);
408 		spin_unlock_bh(&sta->plink_lock);
409 		return 0;
410 	} else if (sta->plink_state == ESTAB) {
411 		__mesh_plink_deactivate(sta);
412 		/* The timer should not be running */
413 		mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
414 	} else if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)))
415 		sta->ignore_plink_timer = true;
416 
417 	sta->plink_state = HOLDING;
418 	llid = sta->llid;
419 	plid = sta->plid;
420 	spin_unlock_bh(&sta->plink_lock);
421 	mesh_plink_frame_tx(sta->sdata->dev, PLINK_CLOSE, sta->addr, llid,
422 			    plid, reason);
423 	return 0;
424 }
425 
426 void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
427 			 size_t len, struct ieee80211_rx_status *rx_status)
428 {
429 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
430 	struct ieee80211_local *local = sdata->local;
431 	struct ieee802_11_elems elems;
432 	struct sta_info *sta;
433 	enum plink_event event;
434 	enum plink_frame_type ftype;
435 	size_t baselen;
436 	u8 ie_len;
437 	u8 *baseaddr;
438 	__le16 plid, llid, reason;
439 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
440 	DECLARE_MAC_BUF(mac);
441 #endif
442 
443 	if (is_multicast_ether_addr(mgmt->da)) {
444 		mpl_dbg("Mesh plink: ignore frame from multicast address");
445 		return;
446 	}
447 
448 	baseaddr = mgmt->u.action.u.plink_action.variable;
449 	baselen = (u8 *) mgmt->u.action.u.plink_action.variable - (u8 *) mgmt;
450 	if (mgmt->u.action.u.plink_action.action_code == PLINK_CONFIRM) {
451 		baseaddr += 4;
452 		baselen -= 4;
453 	}
454 	ieee802_11_parse_elems(baseaddr, len - baselen, &elems);
455 	if (!elems.peer_link) {
456 		mpl_dbg("Mesh plink: missing necessary peer link ie\n");
457 		return;
458 	}
459 
460 	ftype = *((u8 *)PLINK_GET_FRAME_SUBTYPE(elems.peer_link));
461 	ie_len = elems.peer_link_len;
462 	if ((ftype == PLINK_OPEN && ie_len != 3) ||
463 	    (ftype == PLINK_CONFIRM && ie_len != 5) ||
464 	    (ftype == PLINK_CLOSE && ie_len != 5 && ie_len != 7)) {
465 		mpl_dbg("Mesh plink: incorrect plink ie length\n");
466 		return;
467 	}
468 
469 	if (ftype != PLINK_CLOSE && (!elems.mesh_id || !elems.mesh_config)) {
470 		mpl_dbg("Mesh plink: missing necessary ie\n");
471 		return;
472 	}
473 	/* Note the lines below are correct, the llid in the frame is the plid
474 	 * from the point of view of this host.
475 	 */
476 	memcpy(&plid, PLINK_GET_LLID(elems.peer_link), 2);
477 	if (ftype == PLINK_CONFIRM || (ftype == PLINK_CLOSE && ie_len == 7))
478 		memcpy(&llid, PLINK_GET_PLID(elems.peer_link), 2);
479 
480 	rcu_read_lock();
481 
482 	sta = sta_info_get(local, mgmt->sa);
483 	if (!sta && ftype != PLINK_OPEN) {
484 		mpl_dbg("Mesh plink: cls or cnf from unknown peer\n");
485 		rcu_read_unlock();
486 		return;
487 	}
488 
489 	if (sta && sta->plink_state == BLOCKED) {
490 		rcu_read_unlock();
491 		return;
492 	}
493 
494 	/* Now we will figure out the appropriate event... */
495 	event = PLINK_UNDEFINED;
496 	if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, dev))) {
497 		switch (ftype) {
498 		case PLINK_OPEN:
499 			event = OPN_RJCT;
500 			break;
501 		case PLINK_CONFIRM:
502 			event = CNF_RJCT;
503 			break;
504 		case PLINK_CLOSE:
505 			/* avoid warning */
506 			break;
507 		}
508 		spin_lock_bh(&sta->plink_lock);
509 	} else if (!sta) {
510 		/* ftype == PLINK_OPEN */
511 		u64 rates;
512 		if (!mesh_plink_free_count(sdata)) {
513 			mpl_dbg("Mesh plink error: no more free plinks\n");
514 			rcu_read_unlock();
515 			return;
516 		}
517 
518 		rates = ieee80211_sta_get_rates(local, &elems, rx_status->band);
519 		sta = mesh_plink_add(mgmt->sa, rates, sdata);
520 		if (IS_ERR(sta)) {
521 			mpl_dbg("Mesh plink error: plink table full\n");
522 			rcu_read_unlock();
523 			return;
524 		}
525 		event = OPN_ACPT;
526 		spin_lock_bh(&sta->plink_lock);
527 	} else {
528 		spin_lock_bh(&sta->plink_lock);
529 		switch (ftype) {
530 		case PLINK_OPEN:
531 			if (!mesh_plink_free_count(sdata) ||
532 			    (sta->plid && sta->plid != plid))
533 				event = OPN_IGNR;
534 			else
535 				event = OPN_ACPT;
536 			break;
537 		case PLINK_CONFIRM:
538 			if (!mesh_plink_free_count(sdata) ||
539 			    (sta->llid != llid || sta->plid != plid))
540 				event = CNF_IGNR;
541 			else
542 				event = CNF_ACPT;
543 			break;
544 		case PLINK_CLOSE:
545 			if (sta->plink_state == ESTAB)
546 				/* Do not check for llid or plid. This does not
547 				 * follow the standard but since multiple plinks
548 				 * per sta are not supported, it is necessary in
549 				 * order to avoid a livelock when MP A sees an
550 				 * establish peer link to MP B but MP B does not
551 				 * see it. This can be caused by a timeout in
552 				 * B's peer link establishment or B beign
553 				 * restarted.
554 				 */
555 				event = CLS_ACPT;
556 			else if (sta->plid != plid)
557 				event = CLS_IGNR;
558 			else if (ie_len == 7 && sta->llid != llid)
559 				event = CLS_IGNR;
560 			else
561 				event = CLS_ACPT;
562 			break;
563 		default:
564 			mpl_dbg("Mesh plink: unknown frame subtype\n");
565 			spin_unlock_bh(&sta->plink_lock);
566 			rcu_read_unlock();
567 			return;
568 		}
569 	}
570 
571 	mpl_dbg("Mesh plink (peer, state, llid, plid, event): %s %d %d %d %d\n",
572 			print_mac(mac, mgmt->sa), sta->plink_state,
573 			__le16_to_cpu(sta->llid), __le16_to_cpu(sta->plid),
574 			event);
575 	reason = 0;
576 	switch (sta->plink_state) {
577 		/* spin_unlock as soon as state is updated at each case */
578 	case LISTEN:
579 		switch (event) {
580 		case CLS_ACPT:
581 			mesh_plink_fsm_restart(sta);
582 			spin_unlock_bh(&sta->plink_lock);
583 			break;
584 		case OPN_ACPT:
585 			sta->plink_state = OPN_RCVD;
586 			sta->plid = plid;
587 			get_random_bytes(&llid, 2);
588 			sta->llid = llid;
589 			mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
590 			spin_unlock_bh(&sta->plink_lock);
591 			mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid,
592 					    0, 0);
593 			mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr,
594 					    llid, plid, 0);
595 			break;
596 		default:
597 			spin_unlock_bh(&sta->plink_lock);
598 			break;
599 		}
600 		break;
601 
602 	case OPN_SNT:
603 		switch (event) {
604 		case OPN_RJCT:
605 		case CNF_RJCT:
606 			reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
607 		case CLS_ACPT:
608 			if (!reason)
609 				reason = cpu_to_le16(MESH_CLOSE_RCVD);
610 			sta->reason = reason;
611 			sta->plink_state = HOLDING;
612 			if (!mod_plink_timer(sta,
613 					     dot11MeshHoldingTimeout(sdata)))
614 				sta->ignore_plink_timer = true;
615 
616 			llid = sta->llid;
617 			spin_unlock_bh(&sta->plink_lock);
618 			mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
619 					    plid, reason);
620 			break;
621 		case OPN_ACPT:
622 			/* retry timer is left untouched */
623 			sta->plink_state = OPN_RCVD;
624 			sta->plid = plid;
625 			llid = sta->llid;
626 			spin_unlock_bh(&sta->plink_lock);
627 			mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
628 					    plid, 0);
629 			break;
630 		case CNF_ACPT:
631 			sta->plink_state = CNF_RCVD;
632 			if (!mod_plink_timer(sta,
633 					     dot11MeshConfirmTimeout(sdata)))
634 				sta->ignore_plink_timer = true;
635 
636 			spin_unlock_bh(&sta->plink_lock);
637 			break;
638 		default:
639 			spin_unlock_bh(&sta->plink_lock);
640 			break;
641 		}
642 		break;
643 
644 	case OPN_RCVD:
645 		switch (event) {
646 		case OPN_RJCT:
647 		case CNF_RJCT:
648 			reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
649 		case CLS_ACPT:
650 			if (!reason)
651 				reason = cpu_to_le16(MESH_CLOSE_RCVD);
652 			sta->reason = reason;
653 			sta->plink_state = HOLDING;
654 			if (!mod_plink_timer(sta,
655 					     dot11MeshHoldingTimeout(sdata)))
656 				sta->ignore_plink_timer = true;
657 
658 			llid = sta->llid;
659 			spin_unlock_bh(&sta->plink_lock);
660 			mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
661 					    plid, reason);
662 			break;
663 		case OPN_ACPT:
664 			llid = sta->llid;
665 			spin_unlock_bh(&sta->plink_lock);
666 			mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
667 					    plid, 0);
668 			break;
669 		case CNF_ACPT:
670 			del_timer(&sta->plink_timer);
671 			sta->plink_state = ESTAB;
672 			mesh_plink_inc_estab_count(sdata);
673 			spin_unlock_bh(&sta->plink_lock);
674 			mpl_dbg("Mesh plink with %s ESTABLISHED\n",
675 					print_mac(mac, sta->addr));
676 			break;
677 		default:
678 			spin_unlock_bh(&sta->plink_lock);
679 			break;
680 		}
681 		break;
682 
683 	case CNF_RCVD:
684 		switch (event) {
685 		case OPN_RJCT:
686 		case CNF_RJCT:
687 			reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
688 		case CLS_ACPT:
689 			if (!reason)
690 				reason = cpu_to_le16(MESH_CLOSE_RCVD);
691 			sta->reason = reason;
692 			sta->plink_state = HOLDING;
693 			if (!mod_plink_timer(sta,
694 					     dot11MeshHoldingTimeout(sdata)))
695 				sta->ignore_plink_timer = true;
696 
697 			llid = sta->llid;
698 			spin_unlock_bh(&sta->plink_lock);
699 			mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
700 					    plid, reason);
701 			break;
702 		case OPN_ACPT:
703 			del_timer(&sta->plink_timer);
704 			sta->plink_state = ESTAB;
705 			mesh_plink_inc_estab_count(sdata);
706 			spin_unlock_bh(&sta->plink_lock);
707 			mpl_dbg("Mesh plink with %s ESTABLISHED\n",
708 					print_mac(mac, sta->addr));
709 			mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
710 					    plid, 0);
711 			break;
712 		default:
713 			spin_unlock_bh(&sta->plink_lock);
714 			break;
715 		}
716 		break;
717 
718 	case ESTAB:
719 		switch (event) {
720 		case CLS_ACPT:
721 			reason = cpu_to_le16(MESH_CLOSE_RCVD);
722 			sta->reason = reason;
723 			__mesh_plink_deactivate(sta);
724 			sta->plink_state = HOLDING;
725 			llid = sta->llid;
726 			mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
727 			spin_unlock_bh(&sta->plink_lock);
728 			mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
729 					    plid, reason);
730 			break;
731 		case OPN_ACPT:
732 			llid = sta->llid;
733 			spin_unlock_bh(&sta->plink_lock);
734 			mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
735 					    plid, 0);
736 			break;
737 		default:
738 			spin_unlock_bh(&sta->plink_lock);
739 			break;
740 		}
741 		break;
742 	case HOLDING:
743 		switch (event) {
744 		case CLS_ACPT:
745 			if (del_timer(&sta->plink_timer))
746 				sta->ignore_plink_timer = 1;
747 			mesh_plink_fsm_restart(sta);
748 			spin_unlock_bh(&sta->plink_lock);
749 			break;
750 		case OPN_ACPT:
751 		case CNF_ACPT:
752 		case OPN_RJCT:
753 		case CNF_RJCT:
754 			llid = sta->llid;
755 			reason = sta->reason;
756 			spin_unlock_bh(&sta->plink_lock);
757 			mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
758 					    plid, reason);
759 			break;
760 		default:
761 			spin_unlock_bh(&sta->plink_lock);
762 		}
763 		break;
764 	default:
765 		/* should not get here, BLOCKED is dealt with at the beggining
766 		 * of the function
767 		 */
768 		spin_unlock_bh(&sta->plink_lock);
769 		break;
770 	}
771 
772 	rcu_read_unlock();
773 }
774