mesh_plink.c 25.4 KB
Newer Older
1
/*
R
Rui Paulo 已提交
2
 * Copyright (c) 2008, 2009 open80211s Ltd.
3 4 5 6 7 8
 * Author:     Luis Carlos Cobo <luisca@cozybit.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
9
#include <linux/gfp.h>
J
Johannes Berg 已提交
10 11
#include <linux/kernel.h>
#include <linux/random.h>
12
#include "ieee80211_i.h"
J
Johannes Berg 已提交
13
#include "rate.h"
14 15 16 17 18 19 20 21
#include "mesh.h"

#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
#define mpl_dbg(fmt, args...)	printk(KERN_DEBUG fmt, ##args)
#else
#define mpl_dbg(fmt, args...)	do { (void)(0); } while (0)
#endif

22 23
#define PLINK_GET_LLID(p) (p + 2)
#define PLINK_GET_PLID(p) (p + 4)
24 25 26 27

#define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
				jiffies + HZ * t / 1000))

28 29 30 31 32
#define dot11MeshMaxRetries(s) (s->u.mesh.mshcfg.dot11MeshMaxRetries)
#define dot11MeshRetryTimeout(s) (s->u.mesh.mshcfg.dot11MeshRetryTimeout)
#define dot11MeshConfirmTimeout(s) (s->u.mesh.mshcfg.dot11MeshConfirmTimeout)
#define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout)
#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)
33

34 35
/* We only need a valid sta if user configured a minimum rssi_threshold. */
#define rssi_threshold_check(sta, sdata) \
36
		(sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\
37 38
		(sta && (s8) -ewma_read(&sta->avg_signal) > \
		sdata->u.mesh.mshcfg.rssi_threshold))
39

40 41 42 43 44 45 46 47 48 49 50 51
enum plink_event {
	PLINK_UNDEFINED,
	OPN_ACPT,
	OPN_RJCT,
	OPN_IGNR,
	CNF_ACPT,
	CNF_RJCT,
	CNF_IGNR,
	CLS_ACPT,
	CLS_IGNR
};

52 53 54 55
static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
		enum ieee80211_self_protected_actioncode action,
		u8 *da, __le16 llid, __le16 plid, __le16 reason);

56 57 58
static inline
void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
{
59
	atomic_inc(&sdata->u.mesh.mshstats.estab_plinks);
60
	mesh_accept_plinks_update(sdata);
61 62 63 64 65
}

static inline
void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
{
66
	atomic_dec(&sdata->u.mesh.mshstats.estab_plinks);
67
	mesh_accept_plinks_update(sdata);
68 69 70 71 72
}

/**
 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
 *
R
Rui Paulo 已提交
73
 * @sta: mesh peer link to restart
74
 *
75
 * Locking: this function must be called holding sta->lock
76 77 78
 */
static inline void mesh_plink_fsm_restart(struct sta_info *sta)
{
79
	sta->plink_state = NL80211_PLINK_LISTEN;
80 81
	sta->llid = sta->plid = sta->reason = 0;
	sta->plink_retries = 0;
82 83
}

84
/*
85
 * Allocate mesh sta entry and insert into station table
86
 */
87
static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
88
					 u8 *hw_addr)
89 90 91
{
	struct sta_info *sta;

92
	if (sdata->local->num_sta >= MESH_MAX_PLINKS)
J
Johannes Berg 已提交
93
		return NULL;
94

95
	sta = sta_info_alloc(sdata, hw_addr, GFP_KERNEL);
J
Johannes Berg 已提交
96 97
	if (!sta)
		return NULL;
98

99 100 101
	sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
	sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
	sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
102

J
Johannes Berg 已提交
103
	set_sta_flag(sta, WLAN_STA_WME);
104

105 106 107
	return sta;
}

108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
/** mesh_set_ht_prot_mode - set correct HT protection mode
 *
 * Section 9.23.3.5 of IEEE 80211s standard describes the protection rules for
 * HT mesh STA in a MBSS. Three HT protection modes are supported for now,
 * non-HT mixed mode, 20MHz-protection and no-protection mode. non-HT mixed
 * mode is selected if any non-HT peers are present in our MBSS.
 * 20MHz-protection mode is selected if all peers in our 20/40MHz MBSS support
 * HT and atleast one HT20 peer is present. Otherwise no-protection mode is
 * selected.
 */
static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_local *local = sdata->local;
	struct sta_info *sta;
	u32 changed = 0;
	u16 ht_opmode;
	bool non_ht_sta = false, ht20_sta = false;

	if (local->_oper_channel_type == NL80211_CHAN_NO_HT)
		return 0;

	rcu_read_lock();
	list_for_each_entry_rcu(sta, &local->sta_list, list) {
		if (sdata == sta->sdata &&
		    sta->plink_state == NL80211_PLINK_ESTAB) {
			switch (sta->ch_type) {
			case NL80211_CHAN_NO_HT:
				mpl_dbg("mesh_plink %pM: nonHT sta (%pM) is present",
					sdata->vif.addr, sta->sta.addr);
				non_ht_sta = true;
				goto out;
			case NL80211_CHAN_HT20:
				mpl_dbg("mesh_plink %pM: HT20 sta (%pM) is present",
					sdata->vif.addr, sta->sta.addr);
				ht20_sta = true;
			default:
				break;
			}
		}
	}
out:
	rcu_read_unlock();

	if (non_ht_sta)
		ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED;
	else if (ht20_sta && local->_oper_channel_type > NL80211_CHAN_HT20)
		ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_20MHZ;
	else
		ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONE;

	if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
		sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
160
		sdata->u.mesh.mshcfg.ht_opmode = ht_opmode;
161 162 163 164 165 166 167 168
		changed = BSS_CHANGED_HT;
		mpl_dbg("mesh_plink %pM: protection mode changed to %d",
			sdata->vif.addr, ht_opmode);
	}

	return changed;
}

169
/**
170
 * __mesh_plink_deactivate - deactivate mesh peer link
171 172 173 174 175
 *
 * @sta: mesh peer link to deactivate
 *
 * All mesh paths with this peer as next hop will be flushed
 *
176
 * Locking: the caller must hold sta->lock
177
 */
178
static bool __mesh_plink_deactivate(struct sta_info *sta)
179
{
180
	struct ieee80211_sub_if_data *sdata = sta->sdata;
181
	bool deactivated = false;
182

183
	if (sta->plink_state == NL80211_PLINK_ESTAB) {
184
		mesh_plink_dec_estab_count(sdata);
185 186
		deactivated = true;
	}
187
	sta->plink_state = NL80211_PLINK_BLOCKED;
188
	mesh_path_flush_by_nexthop(sta);
189 190

	return deactivated;
191 192
}

J
Johannes Berg 已提交
193
/**
194
 * mesh_plink_deactivate - deactivate mesh peer link
J
Johannes Berg 已提交
195 196 197 198 199 200 201
 *
 * @sta: mesh peer link to deactivate
 *
 * All mesh paths with this peer as next hop will be flushed
 */
void mesh_plink_deactivate(struct sta_info *sta)
{
202 203 204
	struct ieee80211_sub_if_data *sdata = sta->sdata;
	bool deactivated;

205
	spin_lock_bh(&sta->lock);
206
	deactivated = __mesh_plink_deactivate(sta);
207 208 209 210
	sta->reason = cpu_to_le16(WLAN_REASON_MESH_PEER_CANCELED);
	mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
			    sta->sta.addr, sta->llid, sta->plid,
			    sta->reason);
211
	spin_unlock_bh(&sta->lock);
212 213 214

	if (deactivated)
		ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
J
Johannes Berg 已提交
215 216
}

217
static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
218 219
		enum ieee80211_self_protected_actioncode action,
		u8 *da, __le16 llid, __le16 plid, __le16 reason) {
220
	struct ieee80211_local *local = sdata->local;
221
	struct sk_buff *skb;
222 223
	struct ieee80211_mgmt *mgmt;
	bool include_plid = false;
224
	u16 peering_proto = 0;
225 226 227 228
	u8 *pos, ie_len = 4;
	int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.self_prot) +
		      sizeof(mgmt->u.action.u.self_prot);

229
	skb = dev_alloc_skb(local->tx_headroom +
230 231 232 233 234 235 236
			    hdr_len +
			    2 + /* capability info */
			    2 + /* AID */
			    2 + 8 + /* supported rates */
			    2 + (IEEE80211_MAX_SUPP_RATES - 8) +
			    2 + sdata->u.mesh.mesh_id_len +
			    2 + sizeof(struct ieee80211_meshconf_ie) +
237
			    2 + sizeof(struct ieee80211_ht_cap) +
238
			    2 + sizeof(struct ieee80211_ht_operation) +
239 240
			    2 + 8 + /* peering IE */
			    sdata->u.mesh.ie_len);
241 242
	if (!skb)
		return -1;
243
	skb_reserve(skb, local->tx_headroom);
244 245
	mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
	memset(mgmt, 0, hdr_len);
246 247
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  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 252
	mgmt->u.action.category = WLAN_CATEGORY_SELF_PROTECTED;
	mgmt->u.action.u.self_prot.action_code = action;
253

254 255 256 257
	if (action != WLAN_SP_MESH_PEERING_CLOSE) {
		/* capability info */
		pos = skb_put(skb, 2);
		memset(pos, 0, 2);
258
		if (action == WLAN_SP_MESH_PEERING_CONFIRM) {
259 260
			/* AID */
			pos = skb_put(skb, 2);
261
			memcpy(pos + 2, &plid, 2);
262
		}
263 264
		if (ieee80211_add_srates_ie(&sdata->vif, skb, true) ||
		    ieee80211_add_ext_srates_ie(&sdata->vif, skb, true) ||
265 266 267 268
		    mesh_add_rsn_ie(skb, sdata) ||
		    mesh_add_meshid_ie(skb, sdata) ||
		    mesh_add_meshconf_ie(skb, sdata))
			return -1;
269 270 271
	} else {	/* WLAN_SP_MESH_PEERING_CLOSE */
		if (mesh_add_meshid_ie(skb, sdata))
			return -1;
272 273
	}

274
	/* Add Mesh Peering Management element */
275
	switch (action) {
276
	case WLAN_SP_MESH_PEERING_OPEN:
277
		break;
278
	case WLAN_SP_MESH_PEERING_CONFIRM:
279
		ie_len += 2;
280 281
		include_plid = true;
		break;
282
	case WLAN_SP_MESH_PEERING_CLOSE:
283 284
		if (plid) {
			ie_len += 2;
285 286
			include_plid = true;
		}
287
		ie_len += 2;	/* reason code */
288
		break;
289 290
	default:
		return -EINVAL;
291 292
	}

293 294 295
	if (WARN_ON(skb_tailroom(skb) < 2 + ie_len))
		return -ENOMEM;

296
	pos = skb_put(skb, 2 + ie_len);
297
	*pos++ = WLAN_EID_PEER_MGMT;
298
	*pos++ = ie_len;
299 300
	memcpy(pos, &peering_proto, 2);
	pos += 2;
301
	memcpy(pos, &llid, 2);
302
	pos += 2;
303 304
	if (include_plid) {
		memcpy(pos, &plid, 2);
305
		pos += 2;
306
	}
307
	if (action == WLAN_SP_MESH_PEERING_CLOSE) {
308
		memcpy(pos, &reason, 2);
309
		pos += 2;
310
	}
311 312 313

	if (action != WLAN_SP_MESH_PEERING_CLOSE) {
		if (mesh_add_ht_cap_ie(skb, sdata) ||
314
		    mesh_add_ht_oper_ie(skb, sdata))
315 316 317
			return -1;
	}

318 319
	if (mesh_add_vendor_ies(skb, sdata))
		return -1;
320

321
	ieee80211_tx_skb(sdata, skb);
322 323 324
	return 0;
}

325 326 327 328 329 330 331 332 333
/* mesh_peer_init - initialize new mesh peer and return resulting sta_info
 *
 * @sdata: local meshif
 * @addr: peer's address
 * @elems: IEs from beacon or mesh peering frame
 *
 * call under RCU
 */
static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata,
334
				       u8 *addr,
335
				       struct ieee802_11_elems *elems)
336
{
337
	struct ieee80211_local *local = sdata->local;
338
	enum ieee80211_band band = local->oper_channel->band;
339
	struct ieee80211_supported_band *sband;
340
	u32 rates, basic_rates = 0;
341
	struct sta_info *sta;
342
	bool insert = false;
343

344 345
	sband = local->hw.wiphy->bands[band];
	rates = ieee80211_sta_get_rates(local, elems, band, &basic_rates);
346

347
	sta = sta_info_get(sdata, addr);
348
	if (!sta) {
349 350 351 352 353 354 355 356 357
		/* Userspace handles peer allocation when security is enabled */
		if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) {
			cfg80211_notify_new_peer_candidate(sdata->dev, addr,
							   elems->ie_start,
							   elems->total_len,
							   GFP_ATOMIC);
			return NULL;
		}

358
		sta = mesh_plink_alloc(sdata, addr);
359
		if (!sta)
360
			return NULL;
361
		insert = true;
362 363
	}

364
	spin_lock_bh(&sta->lock);
365
	sta->last_rx = jiffies;
366
	sta->sta.supp_rates[band] = rates;
367 368
	if (elems->ht_cap_elem &&
	    sdata->local->_oper_channel_type != NL80211_CHAN_NO_HT)
369 370 371 372 373 374
		ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
						  elems->ht_cap_elem,
						  &sta->sta.ht_cap);
	else
		memset(&sta->sta.ht_cap, 0, sizeof(sta->sta.ht_cap));

375
	if (elems->ht_operation) {
376 377 378 379
		if (!(elems->ht_operation->ht_param &
		      IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
			sta->sta.ht_cap.cap &=
					    ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
380 381 382
		sta->ch_type =
			ieee80211_ht_oper_to_channel_type(elems->ht_operation);
	}
383

384 385 386
	rate_control_rate_init(sta);
	spin_unlock_bh(&sta->lock);

387 388 389
	if (insert && sta_info_insert(sta))
		return NULL;

390 391 392
	return sta;
}

393 394
void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
			   u8 *hw_addr,
395 396 397 398 399
			   struct ieee802_11_elems *elems)
{
	struct sta_info *sta;

	rcu_read_lock();
400
	sta = mesh_peer_init(sdata, hw_addr, elems);
401 402 403
	if (!sta)
		goto out;

404
	if (mesh_peer_accepts_plinks(elems) &&
405 406 407 408
	    sta->plink_state == NL80211_PLINK_LISTEN &&
	    sdata->u.mesh.accepting_plinks &&
	    sdata->u.mesh.mshcfg.auto_open_plinks &&
	    rssi_threshold_check(sta, sdata))
409 410
		mesh_plink_open(sta);

411
out:
412
	rcu_read_unlock();
413 414 415 416 417 418 419 420
}

static void mesh_plink_timer(unsigned long data)
{
	struct sta_info *sta;
	__le16 llid, plid, reason;
	struct ieee80211_sub_if_data *sdata;

421 422 423 424 425
	/*
	 * This STA is valid because sta_info_destroy() will
	 * del_timer_sync() this timer after having made sure
	 * it cannot be readded (by deleting the plink.)
	 */
426 427
	sta = (struct sta_info *) data;

428 429 430 431 432
	if (sta->sdata->local->quiescing) {
		sta->plink_timer_was_running = true;
		return;
	}

433
	spin_lock_bh(&sta->lock);
434 435
	if (sta->ignore_plink_timer) {
		sta->ignore_plink_timer = false;
436
		spin_unlock_bh(&sta->lock);
437 438
		return;
	}
439 440
	mpl_dbg("Mesh plink timer for %pM fired on state %d\n",
		sta->sta.addr, sta->plink_state);
441 442 443
	reason = 0;
	llid = sta->llid;
	plid = sta->plid;
444
	sdata = sta->sdata;
445 446

	switch (sta->plink_state) {
447 448
	case NL80211_PLINK_OPN_RCVD:
	case NL80211_PLINK_OPN_SNT:
449 450 451
		/* retry timer */
		if (sta->plink_retries < dot11MeshMaxRetries(sdata)) {
			u32 rand;
452 453 454
			mpl_dbg("Mesh plink for %pM (retry, timeout): %d %d\n",
				sta->sta.addr, sta->plink_retries,
				sta->plink_timeout);
455 456 457 458
			get_random_bytes(&rand, sizeof(u32));
			sta->plink_timeout = sta->plink_timeout +
					     rand % sta->plink_timeout;
			++sta->plink_retries;
459
			mod_plink_timer(sta, sta->plink_timeout);
460
			spin_unlock_bh(&sta->lock);
461 462
			mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
					    sta->sta.addr, llid, 0, 0);
463 464
			break;
		}
465
		reason = cpu_to_le16(WLAN_REASON_MESH_MAX_RETRIES);
466
		/* fall through on else */
467
	case NL80211_PLINK_CNF_RCVD:
468 469
		/* confirm timer */
		if (!reason)
470
			reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT);
471
		sta->plink_state = NL80211_PLINK_HOLDING;
472
		mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
473
		spin_unlock_bh(&sta->lock);
474 475
		mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
				    sta->sta.addr, llid, plid, reason);
476
		break;
477
	case NL80211_PLINK_HOLDING:
478
		/* holding timer */
479
		del_timer(&sta->plink_timer);
480
		mesh_plink_fsm_restart(sta);
481
		spin_unlock_bh(&sta->lock);
482 483
		break;
	default:
484
		spin_unlock_bh(&sta->lock);
485 486 487 488
		break;
	}
}

489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504
#ifdef CONFIG_PM
void mesh_plink_quiesce(struct sta_info *sta)
{
	if (del_timer_sync(&sta->plink_timer))
		sta->plink_timer_was_running = true;
}

void mesh_plink_restart(struct sta_info *sta)
{
	if (sta->plink_timer_was_running) {
		add_timer(&sta->plink_timer);
		sta->plink_timer_was_running = false;
	}
}
#endif

505 506 507 508 509 510 511 512 513 514 515 516
static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout)
{
	sta->plink_timer.expires = jiffies + (HZ * timeout / 1000);
	sta->plink_timer.data = (unsigned long) sta;
	sta->plink_timer.function = mesh_plink_timer;
	sta->plink_timeout = timeout;
	add_timer(&sta->plink_timer);
}

int mesh_plink_open(struct sta_info *sta)
{
	__le16 llid;
517
	struct ieee80211_sub_if_data *sdata = sta->sdata;
518

J
Johannes Berg 已提交
519
	if (!test_sta_flag(sta, WLAN_STA_AUTH))
520 521
		return -EPERM;

522
	spin_lock_bh(&sta->lock);
523 524
	get_random_bytes(&llid, 2);
	sta->llid = llid;
525
	if (sta->plink_state != NL80211_PLINK_LISTEN) {
526
		spin_unlock_bh(&sta->lock);
527 528
		return -EBUSY;
	}
529
	sta->plink_state = NL80211_PLINK_OPN_SNT;
530
	mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
531
	spin_unlock_bh(&sta->lock);
532 533
	mpl_dbg("Mesh plink: starting establishment with %pM\n",
		sta->sta.addr);
534

535
	return mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
536
				   sta->sta.addr, llid, 0, 0);
537 538 539 540
}

void mesh_plink_block(struct sta_info *sta)
{
541 542 543
	struct ieee80211_sub_if_data *sdata = sta->sdata;
	bool deactivated;

544
	spin_lock_bh(&sta->lock);
545
	deactivated = __mesh_plink_deactivate(sta);
546
	sta->plink_state = NL80211_PLINK_BLOCKED;
547
	spin_unlock_bh(&sta->lock);
548 549 550

	if (deactivated)
		ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
551 552 553
}


554
void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt,
555 556 557 558 559
			 size_t len, struct ieee80211_rx_status *rx_status)
{
	struct ieee802_11_elems elems;
	struct sta_info *sta;
	enum plink_event event;
560
	enum ieee80211_self_protected_actioncode ftype;
561
	size_t baselen;
562
	bool matches_local = true;
563 564
	u8 ie_len;
	u8 *baseaddr;
565
	u32 changed = 0;
566
	__le16 plid, llid, reason;
567 568
#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
	static const char *mplstates[] = {
569 570 571 572 573 574 575
		[NL80211_PLINK_LISTEN] = "LISTEN",
		[NL80211_PLINK_OPN_SNT] = "OPN-SNT",
		[NL80211_PLINK_OPN_RCVD] = "OPN-RCVD",
		[NL80211_PLINK_CNF_RCVD] = "CNF_RCVD",
		[NL80211_PLINK_ESTAB] = "ESTAB",
		[NL80211_PLINK_HOLDING] = "HOLDING",
		[NL80211_PLINK_BLOCKED] = "BLOCKED"
576 577
	};
#endif
578

579 580 581 582
	/* need action_code, aux */
	if (len < IEEE80211_MIN_ACTION_SIZE + 3)
		return;

583 584 585 586 587
	if (is_multicast_ether_addr(mgmt->da)) {
		mpl_dbg("Mesh plink: ignore frame from multicast address");
		return;
	}

588 589 590
	baseaddr = mgmt->u.action.u.self_prot.variable;
	baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt;
	if (mgmt->u.action.u.self_prot.action_code ==
591
						WLAN_SP_MESH_PEERING_CONFIRM) {
592
		baseaddr += 4;
593
		baselen += 4;
594 595
	}
	ieee802_11_parse_elems(baseaddr, len - baselen, &elems);
596
	if (!elems.peering) {
597 598 599
		mpl_dbg("Mesh plink: missing necessary peer link ie\n");
		return;
	}
600 601
	if (elems.rsn_len &&
			sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
602 603 604
		mpl_dbg("Mesh plink: can't establish link with secure peer\n");
		return;
	}
605

606 607 608 609 610 611
	ftype = mgmt->u.action.u.self_prot.action_code;
	ie_len = elems.peering_len;
	if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) ||
	    (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) ||
	    (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6
							&& ie_len != 8)) {
612 613
		mpl_dbg("Mesh plink: incorrect plink ie length %d %d\n",
		    ftype, ie_len);
614 615 616
		return;
	}

617 618
	if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
				(!elems.mesh_id || !elems.mesh_config)) {
619 620 621 622 623 624
		mpl_dbg("Mesh plink: missing necessary ie\n");
		return;
	}
	/* Note the lines below are correct, the llid in the frame is the plid
	 * from the point of view of this host.
	 */
625
	memcpy(&plid, PLINK_GET_LLID(elems.peering), 2);
626
	if (ftype == WLAN_SP_MESH_PEERING_CONFIRM ||
627 628
	    (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8))
		memcpy(&llid, PLINK_GET_PLID(elems.peering), 2);
629

630 631
	rcu_read_lock();

632
	sta = sta_info_get(sdata, mgmt->sa);
633
	if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) {
634
		mpl_dbg("Mesh plink: cls or cnf from unknown peer\n");
635
		rcu_read_unlock();
636 637 638
		return;
	}

639
	if (ftype == WLAN_SP_MESH_PEERING_OPEN &&
640
	    !rssi_threshold_check(sta, sdata)) {
641
		mpl_dbg("Mesh plink: %pM does not meet rssi threshold\n",
642
			mgmt->sa);
643 644 645 646
		rcu_read_unlock();
		return;
	}

J
Johannes Berg 已提交
647
	if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) {
648 649 650 651 652
		mpl_dbg("Mesh plink: Action frame from non-authed peer\n");
		rcu_read_unlock();
		return;
	}

653
	if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) {
654
		rcu_read_unlock();
655 656 657 658 659
		return;
	}

	/* Now we will figure out the appropriate event... */
	event = PLINK_UNDEFINED;
660
	if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
661
	    !mesh_matches_local(sdata, &elems)) {
662
		matches_local = false;
663
		switch (ftype) {
664
		case WLAN_SP_MESH_PEERING_OPEN:
665 666
			event = OPN_RJCT;
			break;
667
		case WLAN_SP_MESH_PEERING_CONFIRM:
668 669
			event = CNF_RJCT;
			break;
670
		default:
671 672
			break;
		}
673 674 675 676
	}

	if (!sta && !matches_local) {
		rcu_read_unlock();
677
		reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
678
		llid = 0;
679 680
		mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
				    mgmt->sa, llid, plid, reason);
681
		return;
682
	} else if (!sta) {
683
		/* ftype == WLAN_SP_MESH_PEERING_OPEN */
684 685
		if (!mesh_plink_free_count(sdata)) {
			mpl_dbg("Mesh plink error: no more free plinks\n");
J
Johannes Berg 已提交
686 687 688
			rcu_read_unlock();
			return;
		}
689
		event = OPN_ACPT;
690
	} else if (matches_local) {
691
		switch (ftype) {
692
		case WLAN_SP_MESH_PEERING_OPEN:
693
			if (!mesh_plink_free_count(sdata) ||
694
			    (sta->plid && sta->plid != plid))
695 696 697 698
				event = OPN_IGNR;
			else
				event = OPN_ACPT;
			break;
699
		case WLAN_SP_MESH_PEERING_CONFIRM:
700
			if (!mesh_plink_free_count(sdata) ||
701
			    (sta->llid != llid || sta->plid != plid))
702 703 704 705
				event = CNF_IGNR;
			else
				event = CNF_ACPT;
			break;
706
		case WLAN_SP_MESH_PEERING_CLOSE:
707
			if (sta->plink_state == NL80211_PLINK_ESTAB)
708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726
				/* Do not check for llid or plid. This does not
				 * follow the standard but since multiple plinks
				 * per sta are not supported, it is necessary in
				 * order to avoid a livelock when MP A sees an
				 * establish peer link to MP B but MP B does not
				 * see it. This can be caused by a timeout in
				 * B's peer link establishment or B beign
				 * restarted.
				 */
				event = CLS_ACPT;
			else if (sta->plid != plid)
				event = CLS_IGNR;
			else if (ie_len == 7 && sta->llid != llid)
				event = CLS_IGNR;
			else
				event = CLS_ACPT;
			break;
		default:
			mpl_dbg("Mesh plink: unknown frame subtype\n");
727
			rcu_read_unlock();
728 729
			return;
		}
730 731 732 733
	}

	if (event == OPN_ACPT) {
		/* allocate sta entry if necessary and update info */
734
		sta = mesh_peer_init(sdata, mgmt->sa, &elems);
735 736 737 738 739
		if (!sta) {
			mpl_dbg("Mesh plink: failed to init peer!\n");
			rcu_read_unlock();
			return;
		}
740 741
	}

742 743
	mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n",
		mgmt->sa, mplstates[sta->plink_state],
744 745
		le16_to_cpu(sta->llid), le16_to_cpu(sta->plid),
		event);
746
	reason = 0;
747
	spin_lock_bh(&sta->lock);
748 749
	switch (sta->plink_state) {
		/* spin_unlock as soon as state is updated at each case */
750
	case NL80211_PLINK_LISTEN:
751 752 753
		switch (event) {
		case CLS_ACPT:
			mesh_plink_fsm_restart(sta);
754
			spin_unlock_bh(&sta->lock);
755 756
			break;
		case OPN_ACPT:
757
			sta->plink_state = NL80211_PLINK_OPN_RCVD;
758 759 760 761
			sta->plid = plid;
			get_random_bytes(&llid, 2);
			sta->llid = llid;
			mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
762
			spin_unlock_bh(&sta->lock);
763 764 765 766 767 768
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_OPEN,
					    sta->sta.addr, llid, 0, 0);
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CONFIRM,
					    sta->sta.addr, llid, plid, 0);
769 770
			break;
		default:
771
			spin_unlock_bh(&sta->lock);
772 773 774 775
			break;
		}
		break;

776
	case NL80211_PLINK_OPN_SNT:
777 778 779
		switch (event) {
		case OPN_RJCT:
		case CNF_RJCT:
780
			reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
781 782
		case CLS_ACPT:
			if (!reason)
783
				reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
784
			sta->reason = reason;
785
			sta->plink_state = NL80211_PLINK_HOLDING;
786 787 788 789 790
			if (!mod_plink_timer(sta,
					     dot11MeshHoldingTimeout(sdata)))
				sta->ignore_plink_timer = true;

			llid = sta->llid;
791
			spin_unlock_bh(&sta->lock);
792 793 794
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CLOSE,
					    sta->sta.addr, llid, plid, reason);
795 796 797
			break;
		case OPN_ACPT:
			/* retry timer is left untouched */
798
			sta->plink_state = NL80211_PLINK_OPN_RCVD;
799 800
			sta->plid = plid;
			llid = sta->llid;
801
			spin_unlock_bh(&sta->lock);
802 803 804
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CONFIRM,
					    sta->sta.addr, llid, plid, 0);
805 806
			break;
		case CNF_ACPT:
807
			sta->plink_state = NL80211_PLINK_CNF_RCVD;
808 809 810 811
			if (!mod_plink_timer(sta,
					     dot11MeshConfirmTimeout(sdata)))
				sta->ignore_plink_timer = true;

812
			spin_unlock_bh(&sta->lock);
813 814
			break;
		default:
815
			spin_unlock_bh(&sta->lock);
816 817 818 819
			break;
		}
		break;

820
	case NL80211_PLINK_OPN_RCVD:
821 822 823
		switch (event) {
		case OPN_RJCT:
		case CNF_RJCT:
824
			reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
825 826
		case CLS_ACPT:
			if (!reason)
827
				reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
828
			sta->reason = reason;
829
			sta->plink_state = NL80211_PLINK_HOLDING;
830 831 832 833 834
			if (!mod_plink_timer(sta,
					     dot11MeshHoldingTimeout(sdata)))
				sta->ignore_plink_timer = true;

			llid = sta->llid;
835
			spin_unlock_bh(&sta->lock);
836 837
			mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
					    sta->sta.addr, llid, plid, reason);
838 839 840
			break;
		case OPN_ACPT:
			llid = sta->llid;
841
			spin_unlock_bh(&sta->lock);
842 843 844
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CONFIRM,
					    sta->sta.addr, llid, plid, 0);
845 846
			break;
		case CNF_ACPT:
847
			del_timer(&sta->plink_timer);
848
			sta->plink_state = NL80211_PLINK_ESTAB;
849
			spin_unlock_bh(&sta->lock);
850
			mesh_plink_inc_estab_count(sdata);
851 852
			changed |= mesh_set_ht_prot_mode(sdata);
			changed |= BSS_CHANGED_BEACON;
853 854
			mpl_dbg("Mesh plink with %pM ESTABLISHED\n",
				sta->sta.addr);
855 856
			break;
		default:
857
			spin_unlock_bh(&sta->lock);
858 859 860 861
			break;
		}
		break;

862
	case NL80211_PLINK_CNF_RCVD:
863 864 865
		switch (event) {
		case OPN_RJCT:
		case CNF_RJCT:
866
			reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
867 868
		case CLS_ACPT:
			if (!reason)
869
				reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
870
			sta->reason = reason;
871
			sta->plink_state = NL80211_PLINK_HOLDING;
872 873 874 875 876
			if (!mod_plink_timer(sta,
					     dot11MeshHoldingTimeout(sdata)))
				sta->ignore_plink_timer = true;

			llid = sta->llid;
877
			spin_unlock_bh(&sta->lock);
878 879 880
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CLOSE,
					    sta->sta.addr, llid, plid, reason);
881
			break;
882
		case OPN_ACPT:
883
			del_timer(&sta->plink_timer);
884
			sta->plink_state = NL80211_PLINK_ESTAB;
885
			spin_unlock_bh(&sta->lock);
886
			mesh_plink_inc_estab_count(sdata);
887 888
			changed |= mesh_set_ht_prot_mode(sdata);
			changed |= BSS_CHANGED_BEACON;
889 890
			mpl_dbg("Mesh plink with %pM ESTABLISHED\n",
				sta->sta.addr);
891 892 893
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CONFIRM,
					    sta->sta.addr, llid, plid, 0);
894 895
			break;
		default:
896
			spin_unlock_bh(&sta->lock);
897 898 899 900
			break;
		}
		break;

901
	case NL80211_PLINK_ESTAB:
902 903
		switch (event) {
		case CLS_ACPT:
904
			reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
905
			sta->reason = reason;
906
			__mesh_plink_deactivate(sta);
907
			sta->plink_state = NL80211_PLINK_HOLDING;
908
			llid = sta->llid;
909
			mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
910
			spin_unlock_bh(&sta->lock);
911 912
			changed |= mesh_set_ht_prot_mode(sdata);
			changed |= BSS_CHANGED_BEACON;
913 914
			mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
					    sta->sta.addr, llid, plid, reason);
915 916 917
			break;
		case OPN_ACPT:
			llid = sta->llid;
918
			spin_unlock_bh(&sta->lock);
919 920 921
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CONFIRM,
					    sta->sta.addr, llid, plid, 0);
922 923
			break;
		default:
924
			spin_unlock_bh(&sta->lock);
925 926 927
			break;
		}
		break;
928
	case NL80211_PLINK_HOLDING:
929 930
		switch (event) {
		case CLS_ACPT:
931
			if (del_timer(&sta->plink_timer))
932 933
				sta->ignore_plink_timer = 1;
			mesh_plink_fsm_restart(sta);
934
			spin_unlock_bh(&sta->lock);
935 936 937 938 939 940 941
			break;
		case OPN_ACPT:
		case CNF_ACPT:
		case OPN_RJCT:
		case CNF_RJCT:
			llid = sta->llid;
			reason = sta->reason;
942
			spin_unlock_bh(&sta->lock);
943 944
			mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
					    sta->sta.addr, llid, plid, reason);
945 946
			break;
		default:
947
			spin_unlock_bh(&sta->lock);
948 949 950
		}
		break;
	default:
951
		/* should not get here, PLINK_BLOCKED is dealt with at the
D
Daniel Mack 已提交
952
		 * beginning of the function
953
		 */
954
		spin_unlock_bh(&sta->lock);
955 956
		break;
	}
957 958

	rcu_read_unlock();
959 960 961

	if (changed)
		ieee80211_bss_info_change_notify(sdata, changed);
962
}