mesh_plink.c 28.7 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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
static const char * const mplstates[] = {
	[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"
};

static const char * const mplevents[] = {
	[PLINK_UNDEFINED] = "NONE",
	[OPN_ACPT] = "OPN_ACPT",
	[OPN_RJCT] = "OPN_RJCT",
	[OPN_IGNR] = "OPN_IGNR",
	[CNF_ACPT] = "CNF_ACPT",
	[CNF_RJCT] = "CNF_RJCT",
	[CNF_IGNR] = "CNF_IGNR",
	[CLS_ACPT] = "CLS_ACPT",
	[CLS_IGNR] = "CLS_IGNR"
};

62
static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
J
Johannes Berg 已提交
63 64
			       enum ieee80211_self_protected_actioncode action,
			       u8 *da, __le16 llid, __le16 plid, __le16 reason);
65

66 67 68
/**
 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
 *
R
Rui Paulo 已提交
69
 * @sta: mesh peer link to restart
70
 *
71
 * Locking: this function must be called holding sta->lock
72 73 74
 */
static inline void mesh_plink_fsm_restart(struct sta_info *sta)
{
75
	sta->plink_state = NL80211_PLINK_LISTEN;
76 77
	sta->llid = sta->plid = sta->reason = 0;
	sta->plink_retries = 0;
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 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
/*
 * 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;
}

140
/**
141
 * mesh_set_ht_prot_mode - set correct HT protection mode
142
 *
143 144 145 146 147 148
 * 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.
149 150 151 152 153 154 155 156
 */
static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_local *local = sdata->local;
	struct sta_info *sta;
	u16 ht_opmode;
	bool non_ht_sta = false, ht20_sta = false;

157
	if (sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
158 159 160 161
		return 0;

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

166 167 168 169 170 171
		if (sta->sta.bandwidth > IEEE80211_STA_RX_BW_20)
			continue;

		if (!sta->sta.ht_cap.ht_supported) {
			mpl_dbg(sdata, "nonHT sta (%pM) is present\n",
				       sta->sta.addr);
172 173
			non_ht_sta = true;
			break;
174
		}
175 176 177

		mpl_dbg(sdata, "HT20 sta (%pM) is present\n", sta->sta.addr);
		ht20_sta = true;
178 179 180 181 182
	}
	rcu_read_unlock();

	if (non_ht_sta)
		ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED;
183
	else if (ht20_sta &&
184
		 sdata->vif.bss_conf.chandef.width > NL80211_CHAN_WIDTH_20)
185 186 187 188
		ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_20MHZ;
	else
		ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONE;

189 190
	if (sdata->vif.bss_conf.ht_operation_mode == ht_opmode)
		return 0;
191

192 193 194 195
	sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
	sdata->u.mesh.mshcfg.ht_opmode = ht_opmode;
	mpl_dbg(sdata, "selected new HT protection mode %d\n", ht_opmode);
	return BSS_CHANGED_HT;
196 197
}

198
/**
199
 * __mesh_plink_deactivate - deactivate mesh peer link
200 201 202 203
 *
 * @sta: mesh peer link to deactivate
 *
 * All mesh paths with this peer as next hop will be flushed
204
 * Returns beacon changed flag if the beacon content changed.
205
 *
206
 * Locking: the caller must hold sta->lock
207
 */
208
static u32 __mesh_plink_deactivate(struct sta_info *sta)
209
{
210
	struct ieee80211_sub_if_data *sdata = sta->sdata;
211
	u32 changed = 0;
212

213 214
	if (sta->plink_state == NL80211_PLINK_ESTAB)
		changed = mesh_plink_dec_estab_count(sdata);
215
	sta->plink_state = NL80211_PLINK_BLOCKED;
216
	mesh_path_flush_by_nexthop(sta);
217

M
Marco Porsch 已提交
218
	ieee80211_mps_sta_status_update(sta);
219
	changed |= ieee80211_mps_local_status_update(sdata);
M
Marco Porsch 已提交
220

221
	return changed;
222 223
}

J
Johannes Berg 已提交
224
/**
225
 * mesh_plink_deactivate - deactivate mesh peer link
J
Johannes Berg 已提交
226 227 228 229 230
 *
 * @sta: mesh peer link to deactivate
 *
 * All mesh paths with this peer as next hop will be flushed
 */
231
u32 mesh_plink_deactivate(struct sta_info *sta)
J
Johannes Berg 已提交
232
{
233
	struct ieee80211_sub_if_data *sdata = sta->sdata;
234
	u32 changed;
235

236
	spin_lock_bh(&sta->lock);
237
	changed = __mesh_plink_deactivate(sta);
238 239 240 241
	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);
242
	spin_unlock_bh(&sta->lock);
243

244
	return changed;
J
Johannes Berg 已提交
245 246
}

247
static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
J
Johannes Berg 已提交
248 249 250
			       enum ieee80211_self_protected_actioncode action,
			       u8 *da, __le16 llid, __le16 plid, __le16 reason)
{
251
	struct ieee80211_local *local = sdata->local;
252
	struct sk_buff *skb;
253
	struct ieee80211_tx_info *info;
254 255
	struct ieee80211_mgmt *mgmt;
	bool include_plid = false;
256
	u16 peering_proto = 0;
257 258 259
	u8 *pos, ie_len = 4;
	int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.self_prot) +
		      sizeof(mgmt->u.action.u.self_prot);
260
	int err = -ENOMEM;
261

262
	skb = dev_alloc_skb(local->tx_headroom +
263 264 265 266 267 268 269
			    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) +
270
			    2 + sizeof(struct ieee80211_ht_cap) +
271
			    2 + sizeof(struct ieee80211_ht_operation) +
272 273
			    2 + 8 + /* peering IE */
			    sdata->u.mesh.ie_len);
274 275
	if (!skb)
		return -1;
276
	info = IEEE80211_SKB_CB(skb);
277
	skb_reserve(skb, local->tx_headroom);
278 279
	mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
	memset(mgmt, 0, hdr_len);
280 281
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_ACTION);
282
	memcpy(mgmt->da, da, ETH_ALEN);
283
	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
284
	memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
285 286
	mgmt->u.action.category = WLAN_CATEGORY_SELF_PROTECTED;
	mgmt->u.action.u.self_prot.action_code = action;
287

288
	if (action != WLAN_SP_MESH_PEERING_CLOSE) {
J
Johannes Berg 已提交
289 290
		enum ieee80211_band band = ieee80211_get_sdata_band(sdata);

291 292 293
		/* capability info */
		pos = skb_put(skb, 2);
		memset(pos, 0, 2);
294
		if (action == WLAN_SP_MESH_PEERING_CONFIRM) {
295 296
			/* AID */
			pos = skb_put(skb, 2);
297
			memcpy(pos + 2, &plid, 2);
298
		}
J
Johannes Berg 已提交
299 300
		if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
		    ieee80211_add_ext_srates_ie(sdata, skb, true, band) ||
J
Johannes Berg 已提交
301 302 303
		    mesh_add_rsn_ie(sdata, skb) ||
		    mesh_add_meshid_ie(sdata, skb) ||
		    mesh_add_meshconf_ie(sdata, skb))
304
			goto free;
305
	} else {	/* WLAN_SP_MESH_PEERING_CLOSE */
306
		info->flags |= IEEE80211_TX_CTL_NO_ACK;
J
Johannes Berg 已提交
307
		if (mesh_add_meshid_ie(sdata, skb))
308
			goto free;
309 310
	}

311
	/* Add Mesh Peering Management element */
312
	switch (action) {
313
	case WLAN_SP_MESH_PEERING_OPEN:
314
		break;
315
	case WLAN_SP_MESH_PEERING_CONFIRM:
316
		ie_len += 2;
317 318
		include_plid = true;
		break;
319
	case WLAN_SP_MESH_PEERING_CLOSE:
320 321
		if (plid) {
			ie_len += 2;
322 323
			include_plid = true;
		}
324
		ie_len += 2;	/* reason code */
325
		break;
326
	default:
327 328
		err = -EINVAL;
		goto free;
329 330
	}

331
	if (WARN_ON(skb_tailroom(skb) < 2 + ie_len))
332
		goto free;
333

334
	pos = skb_put(skb, 2 + ie_len);
335
	*pos++ = WLAN_EID_PEER_MGMT;
336
	*pos++ = ie_len;
337 338
	memcpy(pos, &peering_proto, 2);
	pos += 2;
339
	memcpy(pos, &llid, 2);
340
	pos += 2;
341 342
	if (include_plid) {
		memcpy(pos, &plid, 2);
343
		pos += 2;
344
	}
345
	if (action == WLAN_SP_MESH_PEERING_CLOSE) {
346
		memcpy(pos, &reason, 2);
347
		pos += 2;
348
	}
349 350

	if (action != WLAN_SP_MESH_PEERING_CLOSE) {
J
Johannes Berg 已提交
351 352
		if (mesh_add_ht_cap_ie(sdata, skb) ||
		    mesh_add_ht_oper_ie(sdata, skb))
353
			goto free;
354 355
	}

J
Johannes Berg 已提交
356
	if (mesh_add_vendor_ies(sdata, skb))
357
		goto free;
358

359
	ieee80211_tx_skb(sdata, skb);
360
	return 0;
361 362 363
free:
	kfree_skb(skb);
	return err;
364 365
}

366 367 368
static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
			       struct sta_info *sta,
			       struct ieee802_11_elems *elems, bool insert)
369
{
370
	struct ieee80211_local *local = sdata->local;
J
Johannes Berg 已提交
371
	enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
372
	struct ieee80211_supported_band *sband;
373
	u32 rates, basic_rates = 0, changed = 0;
374

375 376
	sband = local->hw.wiphy->bands[band];
	rates = ieee80211_sta_get_rates(local, elems, band, &basic_rates);
377

378
	spin_lock_bh(&sta->lock);
379
	sta->last_rx = jiffies;
380 381 382 383

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

385 386
	if (sta->sta.supp_rates[band] != rates)
		changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
387
	sta->sta.supp_rates[band] = rates;
388

389 390 391
	if (ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
					      elems->ht_cap_elem, sta))
		changed |= IEEE80211_RC_BW_CHANGED;
392

393 394 395 396 397
	/* HT peer is operating 20MHz-only */
	if (elems->ht_operation &&
	    !(elems->ht_operation->ht_param &
	      IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
		if (sta->sta.bandwidth != IEEE80211_STA_RX_BW_20)
398
			changed |= IEEE80211_RC_BW_CHANGED;
399
		sta->sta.bandwidth = IEEE80211_STA_RX_BW_20;
400
	}
401

402 403
	if (insert)
		rate_control_rate_init(sta);
404 405
	else
		rate_control_rate_update(local, sband, sta, changed);
406
out:
407
	spin_unlock_bh(&sta->lock);
408 409 410 411 412 413
}

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

415
	if (sdata->local->num_sta >= MESH_MAX_PLINKS)
416 417
		return NULL;

418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
	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);

449 450 451
	return sta;
}

452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480
/*
 * 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;
		}

481 482
		mesh_sta_info_init(sdata, sta, elems, true);

483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498
		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.
 */
499 500
void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
			   u8 *hw_addr,
501 502 503
			   struct ieee802_11_elems *elems)
{
	struct sta_info *sta;
504
	u32 changed = 0;
505

506
	sta = mesh_sta_info_get(sdata, hw_addr, elems);
507 508 509
	if (!sta)
		goto out;

510
	if (mesh_peer_accepts_plinks(elems) &&
511 512 513 514
	    sta->plink_state == NL80211_PLINK_LISTEN &&
	    sdata->u.mesh.accepting_plinks &&
	    sdata->u.mesh.mshcfg.auto_open_plinks &&
	    rssi_threshold_check(sta, sdata))
515
		changed = mesh_plink_open(sta);
516

M
Marco Porsch 已提交
517
	ieee80211_mps_frame_release(sta, elems);
518
out:
519
	rcu_read_unlock();
T
Thomas Pedersen 已提交
520
	ieee80211_mbss_info_change_notify(sdata, changed);
521 522 523 524 525 526 527
}

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

530 531 532 533 534
	/*
	 * 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.)
	 */
535 536
	sta = (struct sta_info *) data;

537 538 539 540 541
	if (sta->sdata->local->quiescing) {
		sta->plink_timer_was_running = true;
		return;
	}

542
	spin_lock_bh(&sta->lock);
543 544
	if (sta->ignore_plink_timer) {
		sta->ignore_plink_timer = false;
545
		spin_unlock_bh(&sta->lock);
546 547
		return;
	}
J
Johannes Berg 已提交
548 549
	mpl_dbg(sta->sdata,
		"Mesh plink timer for %pM fired on state %d\n",
550
		sta->sta.addr, sta->plink_state);
551 552 553
	reason = 0;
	llid = sta->llid;
	plid = sta->plid;
554
	sdata = sta->sdata;
555
	mshcfg = &sdata->u.mesh.mshcfg;
556 557

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

601 602 603
#ifdef CONFIG_PM
void mesh_plink_quiesce(struct sta_info *sta)
{
604 605 606
	if (!ieee80211_vif_is_mesh(&sta->sdata->vif))
		return;

607 608 609 610
	/* no kernel mesh sta timers have been initialized */
	if (sta->sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)
		return;

611 612 613 614 615 616 617 618 619 620 621 622 623
	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

624 625 626 627 628 629 630 631 632
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);
}

633
u32 mesh_plink_open(struct sta_info *sta)
634 635
{
	__le16 llid;
636
	struct ieee80211_sub_if_data *sdata = sta->sdata;
637
	u32 changed;
638

J
Johannes Berg 已提交
639
	if (!test_sta_flag(sta, WLAN_STA_AUTH))
640
		return 0;
641

642
	spin_lock_bh(&sta->lock);
643 644
	get_random_bytes(&llid, 2);
	sta->llid = llid;
645 646
	if (sta->plink_state != NL80211_PLINK_LISTEN &&
	    sta->plink_state != NL80211_PLINK_BLOCKED) {
647
		spin_unlock_bh(&sta->lock);
648
		return 0;
649
	}
650
	sta->plink_state = NL80211_PLINK_OPN_SNT;
651
	mesh_plink_timer_set(sta, sdata->u.mesh.mshcfg.dot11MeshRetryTimeout);
652
	spin_unlock_bh(&sta->lock);
J
Johannes Berg 已提交
653 654
	mpl_dbg(sdata,
		"Mesh plink: starting establishment with %pM\n",
655
		sta->sta.addr);
656

M
Marco Porsch 已提交
657
	/* set the non-peer mode to active during peering */
658
	changed = ieee80211_mps_local_status_update(sdata);
M
Marco Porsch 已提交
659

660 661 662
	mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
			    sta->sta.addr, llid, 0, 0);
	return changed;
663 664
}

665
u32 mesh_plink_block(struct sta_info *sta)
666
{
667
	u32 changed;
668

669
	spin_lock_bh(&sta->lock);
670
	changed = __mesh_plink_deactivate(sta);
671
	sta->plink_state = NL80211_PLINK_BLOCKED;
672
	spin_unlock_bh(&sta->lock);
673

674
	return changed;
675 676 677
}


J
Johannes Berg 已提交
678 679 680
void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
			 struct ieee80211_mgmt *mgmt, size_t len,
			 struct ieee80211_rx_status *rx_status)
681
{
682
	struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
683 684 685
	struct ieee802_11_elems elems;
	struct sta_info *sta;
	enum plink_event event;
686
	enum ieee80211_self_protected_actioncode ftype;
687
	size_t baselen;
688
	bool matches_local = true;
689 690
	u8 ie_len;
	u8 *baseaddr;
691
	u32 changed = 0;
692 693
	__le16 plid, llid, reason;

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

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

704 705 706
	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 ==
707
						WLAN_SP_MESH_PEERING_CONFIRM) {
708
		baseaddr += 4;
709
		baselen += 4;
710 711
	}
	ieee802_11_parse_elems(baseaddr, len - baselen, &elems);
J
Johannes Berg 已提交
712

713
	if (!elems.peering) {
J
Johannes Berg 已提交
714 715
		mpl_dbg(sdata,
			"Mesh plink: missing necessary peer link ie\n");
716 717
		return;
	}
J
Johannes Berg 已提交
718

719
	if (elems.rsn_len &&
J
Johannes Berg 已提交
720
	    sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
J
Johannes Berg 已提交
721 722
		mpl_dbg(sdata,
			"Mesh plink: can't establish link with secure peer\n");
723 724
		return;
	}
725

726 727 728 729 730 731
	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 已提交
732 733 734
		mpl_dbg(sdata,
			"Mesh plink: incorrect plink ie length %d %d\n",
			ftype, ie_len);
735 736 737
		return;
	}

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

751
	/* WARNING: Only for sta pointer, is dropped & re-acquired */
752 753
	rcu_read_lock();

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

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

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

775
	if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) {
776
		rcu_read_unlock();
777 778 779 780 781
		return;
	}

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

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

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

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

			/* set the non-peer mode to active during peering */
886
			changed |= ieee80211_mps_local_status_update(sdata);
M
Marco Porsch 已提交
887

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

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

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

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

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

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

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

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

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

	rcu_read_unlock();
1091 1092

	if (changed)
T
Thomas Pedersen 已提交
1093
		ieee80211_mbss_info_change_notify(sdata, changed);
1094
}