mesh_plink.c 28.8 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
#include "mesh.h"

16 17
#define PLINK_GET_LLID(p) (p + 2)
#define PLINK_GET_PLID(p) (p + 4)
18 19 20 21

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

22 23
/* We only need a valid sta if user configured a minimum rssi_threshold. */
#define rssi_threshold_check(sta, sdata) \
24
		(sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\
25 26
		(sta && (s8) -ewma_read(&sta->avg_signal) > \
		sdata->u.mesh.mshcfg.rssi_threshold))
27

28 29 30 31 32 33 34 35 36 37 38 39
enum plink_event {
	PLINK_UNDEFINED,
	OPN_ACPT,
	OPN_RJCT,
	OPN_IGNR,
	CNF_ACPT,
	CNF_RJCT,
	CNF_IGNR,
	CLS_ACPT,
	CLS_IGNR
};

40 41 42 43
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);

44 45 46
/**
 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
 *
R
Rui Paulo 已提交
47
 * @sta: mesh peer link to restart
48
 *
49
 * Locking: this function must be called holding sta->lock
50 51 52
 */
static inline void mesh_plink_fsm_restart(struct sta_info *sta)
{
53
	sta->plink_state = NL80211_PLINK_LISTEN;
54 55
	sta->llid = sta->plid = sta->reason = 0;
	sta->plink_retries = 0;
56 57
}

58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
/*
 * mesh_set_short_slot_time - enable / disable ERP short slot time.
 *
 * The standard indirectly mandates mesh STAs to turn off short slot time by
 * disallowing advertising this (802.11-2012 8.4.1.4), but that doesn't mean we
 * can't be sneaky about it. Enable short slot time if all mesh STAs in the
 * MBSS support ERP rates.
 *
 * Returns BSS_CHANGED_ERP_SLOT or 0 for no change.
 */
static u32 mesh_set_short_slot_time(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_local *local = sdata->local;
	enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
	struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
	struct sta_info *sta;
	u32 erp_rates = 0, changed = 0;
	int i;
	bool short_slot = false;

	if (band == IEEE80211_BAND_5GHZ) {
		/* (IEEE 802.11-2012 19.4.5) */
		short_slot = true;
		goto out;
	} else if (band != IEEE80211_BAND_2GHZ ||
		   (band == IEEE80211_BAND_2GHZ &&
		    local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
		goto out;

	for (i = 0; i < sband->n_bitrates; i++)
		if (sband->bitrates[i].flags & IEEE80211_RATE_ERP_G)
			erp_rates |= BIT(i);

	if (!erp_rates)
		goto out;

	rcu_read_lock();
	list_for_each_entry_rcu(sta, &local->sta_list, list) {
		if (sdata != sta->sdata ||
		    sta->plink_state != NL80211_PLINK_ESTAB)
			continue;

		short_slot = false;
		if (erp_rates & sta->sta.supp_rates[band])
			short_slot = true;
		 else
			break;
	}
	rcu_read_unlock();

out:
	if (sdata->vif.bss_conf.use_short_slot != short_slot) {
		sdata->vif.bss_conf.use_short_slot = short_slot;
		changed = BSS_CHANGED_ERP_SLOT;
		mpl_dbg(sdata, "mesh_plink %pM: ERP short slot time %d\n",
			sdata->vif.addr, short_slot);
	}
	return changed;
}

118
/**
119
 * mesh_set_ht_prot_mode - set correct HT protection mode
120
 *
121 122 123 124 125 126
 * Section 9.23.3.5 of IEEE 80211-2012 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.
127 128 129 130 131 132 133 134 135
 */
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;

136
	if (sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
137 138 139 140
		return 0;

	rcu_read_lock();
	list_for_each_entry_rcu(sta, &local->sta_list, list) {
141 142 143 144
		if (sdata != sta->sdata ||
		    sta->plink_state != NL80211_PLINK_ESTAB)
			continue;

145 146
		switch (sta->ch_width) {
		case NL80211_CHAN_WIDTH_20_NOHT:
J
Johannes Berg 已提交
147 148
			mpl_dbg(sdata,
				"mesh_plink %pM: nonHT sta (%pM) is present\n",
149 150 151
				sdata->vif.addr, sta->sta.addr);
			non_ht_sta = true;
			goto out;
152
		case NL80211_CHAN_WIDTH_20:
J
Johannes Berg 已提交
153 154
			mpl_dbg(sdata,
				"mesh_plink %pM: HT20 sta (%pM) is present\n",
155 156 157 158
				sdata->vif.addr, sta->sta.addr);
			ht20_sta = true;
		default:
			break;
159 160 161 162 163 164 165
		}
	}
out:
	rcu_read_unlock();

	if (non_ht_sta)
		ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED;
166
	else if (ht20_sta &&
167
		 sdata->vif.bss_conf.chandef.width > NL80211_CHAN_WIDTH_20)
168 169 170 171 172 173
		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;
174
		sdata->u.mesh.mshcfg.ht_opmode = ht_opmode;
175
		changed = BSS_CHANGED_HT;
J
Johannes Berg 已提交
176 177
		mpl_dbg(sdata,
			"mesh_plink %pM: protection mode changed to %d\n",
178 179 180 181 182 183
			sdata->vif.addr, ht_opmode);
	}

	return changed;
}

184
/**
185
 * __mesh_plink_deactivate - deactivate mesh peer link
186 187 188 189
 *
 * @sta: mesh peer link to deactivate
 *
 * All mesh paths with this peer as next hop will be flushed
190
 * Returns beacon changed flag if the beacon content changed.
191
 *
192
 * Locking: the caller must hold sta->lock
193
 */
194
static u32 __mesh_plink_deactivate(struct sta_info *sta)
195
{
196
	struct ieee80211_sub_if_data *sdata = sta->sdata;
197
	u32 changed = 0;
198

199 200
	if (sta->plink_state == NL80211_PLINK_ESTAB)
		changed = mesh_plink_dec_estab_count(sdata);
201
	sta->plink_state = NL80211_PLINK_BLOCKED;
202
	mesh_path_flush_by_nexthop(sta);
203

M
Marco Porsch 已提交
204 205 206
	ieee80211_mps_sta_status_update(sta);
	ieee80211_mps_local_status_update(sdata);

207
	return changed;
208 209
}

J
Johannes Berg 已提交
210
/**
211
 * mesh_plink_deactivate - deactivate mesh peer link
J
Johannes Berg 已提交
212 213 214 215 216
 *
 * @sta: mesh peer link to deactivate
 *
 * All mesh paths with this peer as next hop will be flushed
 */
217
u32 mesh_plink_deactivate(struct sta_info *sta)
J
Johannes Berg 已提交
218
{
219
	struct ieee80211_sub_if_data *sdata = sta->sdata;
220
	u32 changed;
221

222
	spin_lock_bh(&sta->lock);
223
	changed = __mesh_plink_deactivate(sta);
224 225 226 227
	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);
228
	spin_unlock_bh(&sta->lock);
229

230
	return changed;
J
Johannes Berg 已提交
231 232
}

233
static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
234 235
		enum ieee80211_self_protected_actioncode action,
		u8 *da, __le16 llid, __le16 plid, __le16 reason) {
236
	struct ieee80211_local *local = sdata->local;
237
	struct sk_buff *skb;
238
	struct ieee80211_tx_info *info;
239 240
	struct ieee80211_mgmt *mgmt;
	bool include_plid = false;
241
	u16 peering_proto = 0;
242 243 244
	u8 *pos, ie_len = 4;
	int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.self_prot) +
		      sizeof(mgmt->u.action.u.self_prot);
245
	int err = -ENOMEM;
246

247
	skb = dev_alloc_skb(local->tx_headroom +
248 249 250 251 252 253 254
			    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) +
255
			    2 + sizeof(struct ieee80211_ht_cap) +
256
			    2 + sizeof(struct ieee80211_ht_operation) +
257 258
			    2 + 8 + /* peering IE */
			    sdata->u.mesh.ie_len);
259 260
	if (!skb)
		return -1;
261
	info = IEEE80211_SKB_CB(skb);
262
	skb_reserve(skb, local->tx_headroom);
263 264
	mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
	memset(mgmt, 0, hdr_len);
265 266
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_ACTION);
267
	memcpy(mgmt->da, da, ETH_ALEN);
268
	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
269
	memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
270 271
	mgmt->u.action.category = WLAN_CATEGORY_SELF_PROTECTED;
	mgmt->u.action.u.self_prot.action_code = action;
272

273
	if (action != WLAN_SP_MESH_PEERING_CLOSE) {
J
Johannes Berg 已提交
274 275
		enum ieee80211_band band = ieee80211_get_sdata_band(sdata);

276 277 278
		/* capability info */
		pos = skb_put(skb, 2);
		memset(pos, 0, 2);
279
		if (action == WLAN_SP_MESH_PEERING_CONFIRM) {
280 281
			/* AID */
			pos = skb_put(skb, 2);
282
			memcpy(pos + 2, &plid, 2);
283
		}
J
Johannes Berg 已提交
284 285
		if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
		    ieee80211_add_ext_srates_ie(sdata, skb, true, band) ||
286 287 288
		    mesh_add_rsn_ie(skb, sdata) ||
		    mesh_add_meshid_ie(skb, sdata) ||
		    mesh_add_meshconf_ie(skb, sdata))
289
			goto free;
290
	} else {	/* WLAN_SP_MESH_PEERING_CLOSE */
291
		info->flags |= IEEE80211_TX_CTL_NO_ACK;
292
		if (mesh_add_meshid_ie(skb, sdata))
293
			goto free;
294 295
	}

296
	/* Add Mesh Peering Management element */
297
	switch (action) {
298
	case WLAN_SP_MESH_PEERING_OPEN:
299
		break;
300
	case WLAN_SP_MESH_PEERING_CONFIRM:
301
		ie_len += 2;
302 303
		include_plid = true;
		break;
304
	case WLAN_SP_MESH_PEERING_CLOSE:
305 306
		if (plid) {
			ie_len += 2;
307 308
			include_plid = true;
		}
309
		ie_len += 2;	/* reason code */
310
		break;
311
	default:
312 313
		err = -EINVAL;
		goto free;
314 315
	}

316
	if (WARN_ON(skb_tailroom(skb) < 2 + ie_len))
317
		goto free;
318

319
	pos = skb_put(skb, 2 + ie_len);
320
	*pos++ = WLAN_EID_PEER_MGMT;
321
	*pos++ = ie_len;
322 323
	memcpy(pos, &peering_proto, 2);
	pos += 2;
324
	memcpy(pos, &llid, 2);
325
	pos += 2;
326 327
	if (include_plid) {
		memcpy(pos, &plid, 2);
328
		pos += 2;
329
	}
330
	if (action == WLAN_SP_MESH_PEERING_CLOSE) {
331
		memcpy(pos, &reason, 2);
332
		pos += 2;
333
	}
334 335 336

	if (action != WLAN_SP_MESH_PEERING_CLOSE) {
		if (mesh_add_ht_cap_ie(skb, sdata) ||
337
		    mesh_add_ht_oper_ie(skb, sdata))
338
			goto free;
339 340
	}

341
	if (mesh_add_vendor_ies(skb, sdata))
342
		goto free;
343

344
	ieee80211_tx_skb(sdata, skb);
345
	return 0;
346 347 348
free:
	kfree_skb(skb);
	return err;
349 350
}

351 352 353
static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
			       struct sta_info *sta,
			       struct ieee802_11_elems *elems, bool insert)
354
{
355
	struct ieee80211_local *local = sdata->local;
J
Johannes Berg 已提交
356
	enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
357
	struct ieee80211_supported_band *sband;
358
	u32 rates, basic_rates = 0, changed = 0;
359

360 361
	sband = local->hw.wiphy->bands[band];
	rates = ieee80211_sta_get_rates(local, elems, band, &basic_rates);
362

363
	spin_lock_bh(&sta->lock);
364
	sta->last_rx = jiffies;
365 366 367 368

	/* rates and capabilities don't change during peering */
	if (sta->plink_state == NL80211_PLINK_ESTAB)
		goto out;
369

370 371
	if (sta->sta.supp_rates[band] != rates)
		changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
372
	sta->sta.supp_rates[band] = rates;
373
	if (elems->ht_cap_elem &&
374
	    sdata->vif.bss_conf.chandef.width != NL80211_CHAN_WIDTH_20_NOHT)
375 376 377 378 379 380
		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));

381
	if (elems->ht_operation) {
382 383
		struct cfg80211_chan_def chandef;

384 385 386 387
		if (!(elems->ht_operation->ht_param &
		      IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
			sta->sta.ht_cap.cap &=
					    ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
388 389
		ieee80211_ht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan,
					     elems->ht_operation, &chandef);
390 391
		if (sta->ch_width != chandef.width)
			changed |= IEEE80211_RC_BW_CHANGED;
392
		sta->ch_width = chandef.width;
393
	}
394

395 396
	if (insert)
		rate_control_rate_init(sta);
397 398
	else
		rate_control_rate_update(local, sband, sta, changed);
399
out:
400
	spin_unlock_bh(&sta->lock);
401 402 403 404 405 406
}

static struct sta_info *
__mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *hw_addr)
{
	struct sta_info *sta;
407

408
	if (sdata->local->num_sta >= MESH_MAX_PLINKS)
409 410
		return NULL;

411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441
	sta = sta_info_alloc(sdata, hw_addr, GFP_KERNEL);
	if (!sta)
		return NULL;

	sta->plink_state = NL80211_PLINK_LISTEN;
	init_timer(&sta->plink_timer);

	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);

	set_sta_flag(sta, WLAN_STA_WME);

	return sta;
}

static struct sta_info *
mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr,
		    struct ieee802_11_elems *elems)
{
	struct sta_info *sta = NULL;

	/* 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_KERNEL);
	else
		sta = __mesh_sta_info_alloc(sdata, addr);

442 443 444
	return sta;
}

445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
/*
 * mesh_sta_info_get - return mesh sta info entry for @addr.
 *
 * @sdata: local meshif
 * @addr: peer's address
 * @elems: IEs from beacon or mesh peering frame.
 *
 * Return existing or newly allocated sta_info under RCU read lock.
 * (re)initialize with given IEs.
 */
static struct sta_info *
mesh_sta_info_get(struct ieee80211_sub_if_data *sdata,
		  u8 *addr, struct ieee802_11_elems *elems) __acquires(RCU)
{
	struct sta_info *sta = NULL;

	rcu_read_lock();
	sta = sta_info_get(sdata, addr);
	if (sta) {
		mesh_sta_info_init(sdata, sta, elems, false);
	} else {
		rcu_read_unlock();
		/* can't run atomic */
		sta = mesh_sta_info_alloc(sdata, addr, elems);
		if (!sta) {
			rcu_read_lock();
			return NULL;
		}

474 475
		mesh_sta_info_init(sdata, sta, elems, true);

476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
		if (sta_info_insert_rcu(sta))
			return NULL;
	}

	return sta;
}

/*
 * mesh_neighbour_update - update or initialize new mesh neighbor.
 *
 * @sdata: local meshif
 * @addr: peer's address
 * @elems: IEs from beacon or mesh peering frame
 *
 * Initiates peering if appropriate.
 */
492 493
void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
			   u8 *hw_addr,
494 495 496 497
			   struct ieee802_11_elems *elems)
{
	struct sta_info *sta;

498
	sta = mesh_sta_info_get(sdata, hw_addr, elems);
499 500 501
	if (!sta)
		goto out;

502
	if (mesh_peer_accepts_plinks(elems) &&
503 504 505 506
	    sta->plink_state == NL80211_PLINK_LISTEN &&
	    sdata->u.mesh.accepting_plinks &&
	    sdata->u.mesh.mshcfg.auto_open_plinks &&
	    rssi_threshold_check(sta, sdata))
507 508
		mesh_plink_open(sta);

M
Marco Porsch 已提交
509
	ieee80211_mps_frame_release(sta, elems);
510
out:
511
	rcu_read_unlock();
512 513 514 515 516 517 518
}

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

521 522 523 524 525
	/*
	 * 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.)
	 */
526 527
	sta = (struct sta_info *) data;

528 529 530 531 532
	if (sta->sdata->local->quiescing) {
		sta->plink_timer_was_running = true;
		return;
	}

533
	spin_lock_bh(&sta->lock);
534 535
	if (sta->ignore_plink_timer) {
		sta->ignore_plink_timer = false;
536
		spin_unlock_bh(&sta->lock);
537 538
		return;
	}
J
Johannes Berg 已提交
539 540
	mpl_dbg(sta->sdata,
		"Mesh plink timer for %pM fired on state %d\n",
541
		sta->sta.addr, sta->plink_state);
542 543 544
	reason = 0;
	llid = sta->llid;
	plid = sta->plid;
545
	sdata = sta->sdata;
546
	mshcfg = &sdata->u.mesh.mshcfg;
547 548

	switch (sta->plink_state) {
549 550
	case NL80211_PLINK_OPN_RCVD:
	case NL80211_PLINK_OPN_SNT:
551
		/* retry timer */
552
		if (sta->plink_retries < mshcfg->dot11MeshMaxRetries) {
553
			u32 rand;
J
Johannes Berg 已提交
554 555
			mpl_dbg(sta->sdata,
				"Mesh plink for %pM (retry, timeout): %d %d\n",
556 557
				sta->sta.addr, sta->plink_retries,
				sta->plink_timeout);
558 559 560 561
			get_random_bytes(&rand, sizeof(u32));
			sta->plink_timeout = sta->plink_timeout +
					     rand % sta->plink_timeout;
			++sta->plink_retries;
562
			mod_plink_timer(sta, sta->plink_timeout);
563
			spin_unlock_bh(&sta->lock);
564 565
			mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
					    sta->sta.addr, llid, 0, 0);
566 567
			break;
		}
568
		reason = cpu_to_le16(WLAN_REASON_MESH_MAX_RETRIES);
569
		/* fall through on else */
570
	case NL80211_PLINK_CNF_RCVD:
571 572
		/* confirm timer */
		if (!reason)
573
			reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT);
574
		sta->plink_state = NL80211_PLINK_HOLDING;
575
		mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
576
		spin_unlock_bh(&sta->lock);
577 578
		mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
				    sta->sta.addr, llid, plid, reason);
579
		break;
580
	case NL80211_PLINK_HOLDING:
581
		/* holding timer */
582
		del_timer(&sta->plink_timer);
583
		mesh_plink_fsm_restart(sta);
584
		spin_unlock_bh(&sta->lock);
585 586
		break;
	default:
587
		spin_unlock_bh(&sta->lock);
588 589 590 591
		break;
	}
}

592 593 594
#ifdef CONFIG_PM
void mesh_plink_quiesce(struct sta_info *sta)
{
595 596 597
	if (!ieee80211_vif_is_mesh(&sta->sdata->vif))
		return;

598 599 600 601
	/* no kernel mesh sta timers have been initialized */
	if (sta->sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)
		return;

602 603 604 605 606 607 608 609 610 611 612 613 614
	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

615 616 617 618 619 620 621 622 623 624 625 626
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;
627
	struct ieee80211_sub_if_data *sdata = sta->sdata;
628

J
Johannes Berg 已提交
629
	if (!test_sta_flag(sta, WLAN_STA_AUTH))
630 631
		return -EPERM;

632
	spin_lock_bh(&sta->lock);
633 634
	get_random_bytes(&llid, 2);
	sta->llid = llid;
635 636
	if (sta->plink_state != NL80211_PLINK_LISTEN &&
	    sta->plink_state != NL80211_PLINK_BLOCKED) {
637
		spin_unlock_bh(&sta->lock);
638 639
		return -EBUSY;
	}
640
	sta->plink_state = NL80211_PLINK_OPN_SNT;
641
	mesh_plink_timer_set(sta, sdata->u.mesh.mshcfg.dot11MeshRetryTimeout);
642
	spin_unlock_bh(&sta->lock);
J
Johannes Berg 已提交
643 644
	mpl_dbg(sdata,
		"Mesh plink: starting establishment with %pM\n",
645
		sta->sta.addr);
646

M
Marco Porsch 已提交
647 648 649
	/* set the non-peer mode to active during peering */
	ieee80211_mps_local_status_update(sdata);

650
	return mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
651
				   sta->sta.addr, llid, 0, 0);
652 653 654 655
}

void mesh_plink_block(struct sta_info *sta)
{
656
	struct ieee80211_sub_if_data *sdata = sta->sdata;
657
	u32 changed;
658

659
	spin_lock_bh(&sta->lock);
660
	changed = __mesh_plink_deactivate(sta);
661
	sta->plink_state = NL80211_PLINK_BLOCKED;
662
	spin_unlock_bh(&sta->lock);
663

664
	ieee80211_bss_info_change_notify(sdata, changed);
665 666 667
}


668
void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt,
669 670
			 size_t len, struct ieee80211_rx_status *rx_status)
{
671
	struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
672 673 674
	struct ieee802_11_elems elems;
	struct sta_info *sta;
	enum plink_event event;
675
	enum ieee80211_self_protected_actioncode ftype;
676
	size_t baselen;
677
	bool matches_local = true;
678 679
	u8 ie_len;
	u8 *baseaddr;
680
	u32 changed = 0;
681
	__le16 plid, llid, reason;
682
	static const char *mplstates[] = {
683 684 685 686 687 688 689
		[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"
690
	};
691

692 693 694 695
	/* need action_code, aux */
	if (len < IEEE80211_MIN_ACTION_SIZE + 3)
		return;

696
	if (is_multicast_ether_addr(mgmt->da)) {
J
Johannes Berg 已提交
697 698
		mpl_dbg(sdata,
			"Mesh plink: ignore frame from multicast address\n");
699 700 701
		return;
	}

702 703 704
	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 ==
705
						WLAN_SP_MESH_PEERING_CONFIRM) {
706
		baseaddr += 4;
707
		baselen += 4;
708 709
	}
	ieee802_11_parse_elems(baseaddr, len - baselen, &elems);
710
	if (!elems.peering) {
J
Johannes Berg 已提交
711 712
		mpl_dbg(sdata,
			"Mesh plink: missing necessary peer link ie\n");
713 714
		return;
	}
715 716
	if (elems.rsn_len &&
			sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
J
Johannes Berg 已提交
717 718
		mpl_dbg(sdata,
			"Mesh plink: can't establish link with secure peer\n");
719 720
		return;
	}
721

722 723 724 725 726 727
	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)) {
J
Johannes Berg 已提交
728 729 730
		mpl_dbg(sdata,
			"Mesh plink: incorrect plink ie length %d %d\n",
			ftype, ie_len);
731 732 733
		return;
	}

734 735
	if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
				(!elems.mesh_id || !elems.mesh_config)) {
J
Johannes Berg 已提交
736
		mpl_dbg(sdata, "Mesh plink: missing necessary ie\n");
737 738 739 740 741
		return;
	}
	/* Note the lines below are correct, the llid in the frame is the plid
	 * from the point of view of this host.
	 */
742
	memcpy(&plid, PLINK_GET_LLID(elems.peering), 2);
743
	if (ftype == WLAN_SP_MESH_PEERING_CONFIRM ||
744 745
	    (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8))
		memcpy(&llid, PLINK_GET_PLID(elems.peering), 2);
746

747
	/* WARNING: Only for sta pointer, is dropped & re-acquired */
748 749
	rcu_read_lock();

750
	sta = sta_info_get(sdata, mgmt->sa);
751
	if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) {
J
Johannes Berg 已提交
752
		mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n");
753
		rcu_read_unlock();
754 755 756
		return;
	}

757
	if (ftype == WLAN_SP_MESH_PEERING_OPEN &&
758
	    !rssi_threshold_check(sta, sdata)) {
J
Johannes Berg 已提交
759
		mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n",
760
			mgmt->sa);
761 762 763 764
		rcu_read_unlock();
		return;
	}

J
Johannes Berg 已提交
765
	if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) {
J
Johannes Berg 已提交
766
		mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n");
767 768 769 770
		rcu_read_unlock();
		return;
	}

771
	if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) {
772
		rcu_read_unlock();
773 774 775 776 777
		return;
	}

	/* Now we will figure out the appropriate event... */
	event = PLINK_UNDEFINED;
778
	if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
779
	    !mesh_matches_local(sdata, &elems)) {
780
		matches_local = false;
781
		switch (ftype) {
782
		case WLAN_SP_MESH_PEERING_OPEN:
783 784
			event = OPN_RJCT;
			break;
785
		case WLAN_SP_MESH_PEERING_CONFIRM:
786 787
			event = CNF_RJCT;
			break;
788
		default:
789 790
			break;
		}
791 792 793 794
	}

	if (!sta && !matches_local) {
		rcu_read_unlock();
795
		reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
796
		llid = 0;
797 798
		mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
				    mgmt->sa, llid, plid, reason);
799
		return;
800
	} else if (!sta) {
801
		/* ftype == WLAN_SP_MESH_PEERING_OPEN */
802
		if (!mesh_plink_free_count(sdata)) {
J
Johannes Berg 已提交
803
			mpl_dbg(sdata, "Mesh plink error: no more free plinks\n");
J
Johannes Berg 已提交
804 805 806
			rcu_read_unlock();
			return;
		}
807
		event = OPN_ACPT;
808
	} else if (matches_local) {
809
		switch (ftype) {
810
		case WLAN_SP_MESH_PEERING_OPEN:
811
			if (!mesh_plink_free_count(sdata) ||
812
			    (sta->plid && sta->plid != plid))
813 814 815 816
				event = OPN_IGNR;
			else
				event = OPN_ACPT;
			break;
817
		case WLAN_SP_MESH_PEERING_CONFIRM:
818
			if (!mesh_plink_free_count(sdata) ||
819
			    (sta->llid != llid || sta->plid != plid))
820 821 822 823
				event = CNF_IGNR;
			else
				event = CNF_ACPT;
			break;
824
		case WLAN_SP_MESH_PEERING_CLOSE:
825
			if (sta->plink_state == NL80211_PLINK_ESTAB)
826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843
				/* 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:
J
Johannes Berg 已提交
844
			mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n");
845
			rcu_read_unlock();
846 847
			return;
		}
848 849 850
	}

	if (event == OPN_ACPT) {
851
		rcu_read_unlock();
852
		/* allocate sta entry if necessary and update info */
853
		sta = mesh_sta_info_get(sdata, mgmt->sa, &elems);
854
		if (!sta) {
J
Johannes Berg 已提交
855
			mpl_dbg(sdata, "Mesh plink: failed to init peer!\n");
856 857 858
			rcu_read_unlock();
			return;
		}
859 860
	}

J
Johannes Berg 已提交
861 862
	mpl_dbg(sdata,
		"Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n",
863
		mgmt->sa, mplstates[sta->plink_state],
864 865
		le16_to_cpu(sta->llid), le16_to_cpu(sta->plid),
		event);
866
	reason = 0;
867
	spin_lock_bh(&sta->lock);
868 869
	switch (sta->plink_state) {
		/* spin_unlock as soon as state is updated at each case */
870
	case NL80211_PLINK_LISTEN:
871 872 873
		switch (event) {
		case CLS_ACPT:
			mesh_plink_fsm_restart(sta);
874
			spin_unlock_bh(&sta->lock);
875 876
			break;
		case OPN_ACPT:
877
			sta->plink_state = NL80211_PLINK_OPN_RCVD;
878 879 880
			sta->plid = plid;
			get_random_bytes(&llid, 2);
			sta->llid = llid;
881 882
			mesh_plink_timer_set(sta,
					     mshcfg->dot11MeshRetryTimeout);
M
Marco Porsch 已提交
883 884 885 886

			/* set the non-peer mode to active during peering */
			ieee80211_mps_local_status_update(sdata);

887
			spin_unlock_bh(&sta->lock);
888 889 890 891 892 893
			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);
894 895
			break;
		default:
896
			spin_unlock_bh(&sta->lock);
897 898 899 900
			break;
		}
		break;

901
	case NL80211_PLINK_OPN_SNT:
902 903 904
		switch (event) {
		case OPN_RJCT:
		case CNF_RJCT:
905
			reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
906 907
		case CLS_ACPT:
			if (!reason)
908
				reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
909
			sta->reason = reason;
910
			sta->plink_state = NL80211_PLINK_HOLDING;
911
			if (!mod_plink_timer(sta,
912
					     mshcfg->dot11MeshHoldingTimeout))
913 914 915
				sta->ignore_plink_timer = true;

			llid = sta->llid;
916
			spin_unlock_bh(&sta->lock);
917 918 919
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CLOSE,
					    sta->sta.addr, llid, plid, reason);
920 921 922
			break;
		case OPN_ACPT:
			/* retry timer is left untouched */
923
			sta->plink_state = NL80211_PLINK_OPN_RCVD;
924 925
			sta->plid = plid;
			llid = sta->llid;
926
			spin_unlock_bh(&sta->lock);
927 928 929
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CONFIRM,
					    sta->sta.addr, llid, plid, 0);
930 931
			break;
		case CNF_ACPT:
932
			sta->plink_state = NL80211_PLINK_CNF_RCVD;
933
			if (!mod_plink_timer(sta,
934
					     mshcfg->dot11MeshConfirmTimeout))
935 936
				sta->ignore_plink_timer = true;

937
			spin_unlock_bh(&sta->lock);
938 939
			break;
		default:
940
			spin_unlock_bh(&sta->lock);
941 942 943 944
			break;
		}
		break;

945
	case NL80211_PLINK_OPN_RCVD:
946 947 948
		switch (event) {
		case OPN_RJCT:
		case CNF_RJCT:
949
			reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
950 951
		case CLS_ACPT:
			if (!reason)
952
				reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
953
			sta->reason = reason;
954
			sta->plink_state = NL80211_PLINK_HOLDING;
955
			if (!mod_plink_timer(sta,
956
					     mshcfg->dot11MeshHoldingTimeout))
957 958 959
				sta->ignore_plink_timer = true;

			llid = sta->llid;
960
			spin_unlock_bh(&sta->lock);
961 962
			mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
					    sta->sta.addr, llid, plid, reason);
963 964 965
			break;
		case OPN_ACPT:
			llid = sta->llid;
966
			spin_unlock_bh(&sta->lock);
967 968 969
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CONFIRM,
					    sta->sta.addr, llid, plid, 0);
970 971
			break;
		case CNF_ACPT:
972
			del_timer(&sta->plink_timer);
973
			sta->plink_state = NL80211_PLINK_ESTAB;
974
			spin_unlock_bh(&sta->lock);
975
			changed |= mesh_plink_inc_estab_count(sdata);
976
			changed |= mesh_set_ht_prot_mode(sdata);
977
			changed |= mesh_set_short_slot_time(sdata);
J
Johannes Berg 已提交
978
			mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
979
				sta->sta.addr);
M
Marco Porsch 已提交
980 981 982
			ieee80211_mps_sta_status_update(sta);
			ieee80211_mps_set_sta_local_pm(sta,
						       mshcfg->power_mode);
983 984
			break;
		default:
985
			spin_unlock_bh(&sta->lock);
986 987 988 989
			break;
		}
		break;

990
	case NL80211_PLINK_CNF_RCVD:
991 992 993
		switch (event) {
		case OPN_RJCT:
		case CNF_RJCT:
994
			reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
995 996
		case CLS_ACPT:
			if (!reason)
997
				reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
998
			sta->reason = reason;
999
			sta->plink_state = NL80211_PLINK_HOLDING;
1000
			if (!mod_plink_timer(sta,
1001
					     mshcfg->dot11MeshHoldingTimeout))
1002 1003 1004
				sta->ignore_plink_timer = true;

			llid = sta->llid;
1005
			spin_unlock_bh(&sta->lock);
1006 1007 1008
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CLOSE,
					    sta->sta.addr, llid, plid, reason);
1009
			break;
1010
		case OPN_ACPT:
1011
			del_timer(&sta->plink_timer);
1012
			sta->plink_state = NL80211_PLINK_ESTAB;
1013
			spin_unlock_bh(&sta->lock);
1014
			changed |= mesh_plink_inc_estab_count(sdata);
1015
			changed |= mesh_set_ht_prot_mode(sdata);
1016
			changed |= mesh_set_short_slot_time(sdata);
J
Johannes Berg 已提交
1017
			mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
1018
				sta->sta.addr);
1019 1020 1021
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CONFIRM,
					    sta->sta.addr, llid, plid, 0);
M
Marco Porsch 已提交
1022 1023 1024
			ieee80211_mps_sta_status_update(sta);
			ieee80211_mps_set_sta_local_pm(sta,
						       mshcfg->power_mode);
1025 1026
			break;
		default:
1027
			spin_unlock_bh(&sta->lock);
1028 1029 1030 1031
			break;
		}
		break;

1032
	case NL80211_PLINK_ESTAB:
1033 1034
		switch (event) {
		case CLS_ACPT:
1035
			reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
1036
			sta->reason = reason;
1037
			changed |= __mesh_plink_deactivate(sta);
1038
			sta->plink_state = NL80211_PLINK_HOLDING;
1039
			llid = sta->llid;
1040
			mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
1041
			spin_unlock_bh(&sta->lock);
1042
			changed |= mesh_set_ht_prot_mode(sdata);
1043
			changed |= mesh_set_short_slot_time(sdata);
1044 1045
			mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
					    sta->sta.addr, llid, plid, reason);
1046 1047 1048
			break;
		case OPN_ACPT:
			llid = sta->llid;
1049
			spin_unlock_bh(&sta->lock);
1050 1051 1052
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CONFIRM,
					    sta->sta.addr, llid, plid, 0);
1053 1054
			break;
		default:
1055
			spin_unlock_bh(&sta->lock);
1056 1057 1058
			break;
		}
		break;
1059
	case NL80211_PLINK_HOLDING:
1060 1061
		switch (event) {
		case CLS_ACPT:
1062
			if (del_timer(&sta->plink_timer))
1063 1064
				sta->ignore_plink_timer = 1;
			mesh_plink_fsm_restart(sta);
1065
			spin_unlock_bh(&sta->lock);
1066 1067 1068 1069 1070 1071 1072
			break;
		case OPN_ACPT:
		case CNF_ACPT:
		case OPN_RJCT:
		case CNF_RJCT:
			llid = sta->llid;
			reason = sta->reason;
1073
			spin_unlock_bh(&sta->lock);
1074 1075
			mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
					    sta->sta.addr, llid, plid, reason);
1076 1077
			break;
		default:
1078
			spin_unlock_bh(&sta->lock);
1079 1080 1081
		}
		break;
	default:
1082
		/* should not get here, PLINK_BLOCKED is dealt with at the
D
Daniel Mack 已提交
1083
		 * beginning of the function
1084
		 */
1085
		spin_unlock_bh(&sta->lock);
1086 1087
		break;
	}
1088 1089

	rcu_read_unlock();
1090 1091 1092

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