mesh_plink.c 28.2 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
	if (sta->sdata->local->quiescing)
538 539
		return;

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

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

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

608
u32 mesh_plink_open(struct sta_info *sta)
609 610
{
	__le16 llid;
611
	struct ieee80211_sub_if_data *sdata = sta->sdata;
612
	u32 changed;
613

J
Johannes Berg 已提交
614
	if (!test_sta_flag(sta, WLAN_STA_AUTH))
615
		return 0;
616

617
	spin_lock_bh(&sta->lock);
618 619
	get_random_bytes(&llid, 2);
	sta->llid = llid;
620 621
	if (sta->plink_state != NL80211_PLINK_LISTEN &&
	    sta->plink_state != NL80211_PLINK_BLOCKED) {
622
		spin_unlock_bh(&sta->lock);
623
		return 0;
624
	}
625
	sta->plink_state = NL80211_PLINK_OPN_SNT;
626
	mesh_plink_timer_set(sta, sdata->u.mesh.mshcfg.dot11MeshRetryTimeout);
627
	spin_unlock_bh(&sta->lock);
J
Johannes Berg 已提交
628 629
	mpl_dbg(sdata,
		"Mesh plink: starting establishment with %pM\n",
630
		sta->sta.addr);
631

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

635 636 637
	mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
			    sta->sta.addr, llid, 0, 0);
	return changed;
638 639
}

640
u32 mesh_plink_block(struct sta_info *sta)
641
{
642
	u32 changed;
643

644
	spin_lock_bh(&sta->lock);
645
	changed = __mesh_plink_deactivate(sta);
646
	sta->plink_state = NL80211_PLINK_BLOCKED;
647
	spin_unlock_bh(&sta->lock);
648

649
	return changed;
650 651 652
}


J
Johannes Berg 已提交
653 654 655
void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
			 struct ieee80211_mgmt *mgmt, size_t len,
			 struct ieee80211_rx_status *rx_status)
656
{
657
	struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
658 659 660
	struct ieee802_11_elems elems;
	struct sta_info *sta;
	enum plink_event event;
661
	enum ieee80211_self_protected_actioncode ftype;
662
	size_t baselen;
663
	bool matches_local = true;
664 665
	u8 ie_len;
	u8 *baseaddr;
666
	u32 changed = 0;
667 668
	__le16 plid, llid, reason;

669 670 671 672
	/* need action_code, aux */
	if (len < IEEE80211_MIN_ACTION_SIZE + 3)
		return;

673
	if (is_multicast_ether_addr(mgmt->da)) {
J
Johannes Berg 已提交
674 675
		mpl_dbg(sdata,
			"Mesh plink: ignore frame from multicast address\n");
676 677 678
		return;
	}

679 680 681
	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 ==
682
						WLAN_SP_MESH_PEERING_CONFIRM) {
683
		baseaddr += 4;
684
		baselen += 4;
685 686
	}
	ieee802_11_parse_elems(baseaddr, len - baselen, &elems);
J
Johannes Berg 已提交
687

688
	if (!elems.peering) {
J
Johannes Berg 已提交
689 690
		mpl_dbg(sdata,
			"Mesh plink: missing necessary peer link ie\n");
691 692
		return;
	}
J
Johannes Berg 已提交
693

694
	if (elems.rsn_len &&
J
Johannes Berg 已提交
695
	    sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
J
Johannes Berg 已提交
696 697
		mpl_dbg(sdata,
			"Mesh plink: can't establish link with secure peer\n");
698 699
		return;
	}
700

701 702 703 704 705 706
	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 已提交
707 708 709
		mpl_dbg(sdata,
			"Mesh plink: incorrect plink ie length %d %d\n",
			ftype, ie_len);
710 711 712
		return;
	}

713
	if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
J
Johannes Berg 已提交
714
	    (!elems.mesh_id || !elems.mesh_config)) {
J
Johannes Berg 已提交
715
		mpl_dbg(sdata, "Mesh plink: missing necessary ie\n");
716 717 718 719 720
		return;
	}
	/* Note the lines below are correct, the llid in the frame is the plid
	 * from the point of view of this host.
	 */
721
	memcpy(&plid, PLINK_GET_LLID(elems.peering), 2);
722
	if (ftype == WLAN_SP_MESH_PEERING_CONFIRM ||
723 724
	    (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8))
		memcpy(&llid, PLINK_GET_PLID(elems.peering), 2);
725

726
	/* WARNING: Only for sta pointer, is dropped & re-acquired */
727 728
	rcu_read_lock();

729
	sta = sta_info_get(sdata, mgmt->sa);
730
	if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) {
J
Johannes Berg 已提交
731
		mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n");
732
		rcu_read_unlock();
733 734 735
		return;
	}

736
	if (ftype == WLAN_SP_MESH_PEERING_OPEN &&
737
	    !rssi_threshold_check(sta, sdata)) {
J
Johannes Berg 已提交
738
		mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n",
739
			mgmt->sa);
740 741 742 743
		rcu_read_unlock();
		return;
	}

J
Johannes Berg 已提交
744
	if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) {
J
Johannes Berg 已提交
745
		mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n");
746 747 748 749
		rcu_read_unlock();
		return;
	}

750
	if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) {
751
		rcu_read_unlock();
752 753 754 755 756
		return;
	}

	/* Now we will figure out the appropriate event... */
	event = PLINK_UNDEFINED;
757
	if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
758
	    !mesh_matches_local(sdata, &elems)) {
759
		matches_local = false;
760
		switch (ftype) {
761
		case WLAN_SP_MESH_PEERING_OPEN:
762 763
			event = OPN_RJCT;
			break;
764
		case WLAN_SP_MESH_PEERING_CONFIRM:
765 766
			event = CNF_RJCT;
			break;
767
		default:
768 769
			break;
		}
770 771 772 773
	}

	if (!sta && !matches_local) {
		rcu_read_unlock();
774
		reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
775
		llid = 0;
776 777
		mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
				    mgmt->sa, llid, plid, reason);
778
		return;
779
	} else if (!sta) {
780
		/* ftype == WLAN_SP_MESH_PEERING_OPEN */
781
		if (!mesh_plink_free_count(sdata)) {
J
Johannes Berg 已提交
782
			mpl_dbg(sdata, "Mesh plink error: no more free plinks\n");
J
Johannes Berg 已提交
783 784 785
			rcu_read_unlock();
			return;
		}
786
		event = OPN_ACPT;
787
	} else if (matches_local) {
788
		switch (ftype) {
789
		case WLAN_SP_MESH_PEERING_OPEN:
790
			if (!mesh_plink_free_count(sdata) ||
791
			    (sta->plid && sta->plid != plid))
792 793 794 795
				event = OPN_IGNR;
			else
				event = OPN_ACPT;
			break;
796
		case WLAN_SP_MESH_PEERING_CONFIRM:
797
			if (!mesh_plink_free_count(sdata) ||
798
			    (sta->llid != llid || sta->plid != plid))
799 800 801 802
				event = CNF_IGNR;
			else
				event = CNF_ACPT;
			break;
803
		case WLAN_SP_MESH_PEERING_CLOSE:
804
			if (sta->plink_state == NL80211_PLINK_ESTAB)
805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822
				/* 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 已提交
823
			mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n");
824
			rcu_read_unlock();
825 826
			return;
		}
827 828 829
	}

	if (event == OPN_ACPT) {
830
		rcu_read_unlock();
831
		/* allocate sta entry if necessary and update info */
832
		sta = mesh_sta_info_get(sdata, mgmt->sa, &elems);
833
		if (!sta) {
J
Johannes Berg 已提交
834
			mpl_dbg(sdata, "Mesh plink: failed to init peer!\n");
835 836 837
			rcu_read_unlock();
			return;
		}
838 839
	}

840 841
	mpl_dbg(sdata, "peer %pM in state %s got event %s\n", mgmt->sa,
		       mplstates[sta->plink_state], mplevents[event]);
842
	reason = 0;
843
	spin_lock_bh(&sta->lock);
844 845
	switch (sta->plink_state) {
		/* spin_unlock as soon as state is updated at each case */
846
	case NL80211_PLINK_LISTEN:
847 848 849
		switch (event) {
		case CLS_ACPT:
			mesh_plink_fsm_restart(sta);
850
			spin_unlock_bh(&sta->lock);
851 852
			break;
		case OPN_ACPT:
853
			sta->plink_state = NL80211_PLINK_OPN_RCVD;
854 855 856
			sta->plid = plid;
			get_random_bytes(&llid, 2);
			sta->llid = llid;
857 858
			mesh_plink_timer_set(sta,
					     mshcfg->dot11MeshRetryTimeout);
M
Marco Porsch 已提交
859 860

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

863
			spin_unlock_bh(&sta->lock);
864 865 866 867 868 869
			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);
870 871
			break;
		default:
872
			spin_unlock_bh(&sta->lock);
873 874 875 876
			break;
		}
		break;

877
	case NL80211_PLINK_OPN_SNT:
878 879 880
		switch (event) {
		case OPN_RJCT:
		case CNF_RJCT:
881
			reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
882 883
		case CLS_ACPT:
			if (!reason)
884
				reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
885
			sta->reason = reason;
886
			sta->plink_state = NL80211_PLINK_HOLDING;
887
			if (!mod_plink_timer(sta,
888
					     mshcfg->dot11MeshHoldingTimeout))
889 890 891
				sta->ignore_plink_timer = true;

			llid = sta->llid;
892
			spin_unlock_bh(&sta->lock);
893 894 895
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CLOSE,
					    sta->sta.addr, llid, plid, reason);
896 897 898
			break;
		case OPN_ACPT:
			/* retry timer is left untouched */
899
			sta->plink_state = NL80211_PLINK_OPN_RCVD;
900 901
			sta->plid = plid;
			llid = sta->llid;
902
			spin_unlock_bh(&sta->lock);
903 904 905
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CONFIRM,
					    sta->sta.addr, llid, plid, 0);
906 907
			break;
		case CNF_ACPT:
908
			sta->plink_state = NL80211_PLINK_CNF_RCVD;
909
			if (!mod_plink_timer(sta,
910
					     mshcfg->dot11MeshConfirmTimeout))
911 912
				sta->ignore_plink_timer = true;

913
			spin_unlock_bh(&sta->lock);
914 915
			break;
		default:
916
			spin_unlock_bh(&sta->lock);
917 918 919 920
			break;
		}
		break;

921
	case NL80211_PLINK_OPN_RCVD:
922 923 924
		switch (event) {
		case OPN_RJCT:
		case CNF_RJCT:
925
			reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
926 927
		case CLS_ACPT:
			if (!reason)
928
				reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
929
			sta->reason = reason;
930
			sta->plink_state = NL80211_PLINK_HOLDING;
931
			if (!mod_plink_timer(sta,
932
					     mshcfg->dot11MeshHoldingTimeout))
933 934 935
				sta->ignore_plink_timer = true;

			llid = sta->llid;
936
			spin_unlock_bh(&sta->lock);
937 938
			mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
					    sta->sta.addr, llid, plid, reason);
939 940 941
			break;
		case OPN_ACPT:
			llid = sta->llid;
942
			spin_unlock_bh(&sta->lock);
943 944 945
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CONFIRM,
					    sta->sta.addr, llid, plid, 0);
946 947
			break;
		case CNF_ACPT:
948
			del_timer(&sta->plink_timer);
949
			sta->plink_state = NL80211_PLINK_ESTAB;
950
			spin_unlock_bh(&sta->lock);
951
			changed |= mesh_plink_inc_estab_count(sdata);
952
			changed |= mesh_set_ht_prot_mode(sdata);
953
			changed |= mesh_set_short_slot_time(sdata);
J
Johannes Berg 已提交
954
			mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
955
				sta->sta.addr);
M
Marco Porsch 已提交
956
			ieee80211_mps_sta_status_update(sta);
957
			changed |= ieee80211_mps_set_sta_local_pm(sta,
M
Marco Porsch 已提交
958
						       mshcfg->power_mode);
959 960
			break;
		default:
961
			spin_unlock_bh(&sta->lock);
962 963 964 965
			break;
		}
		break;

966
	case NL80211_PLINK_CNF_RCVD:
967 968 969
		switch (event) {
		case OPN_RJCT:
		case CNF_RJCT:
970
			reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
971 972
		case CLS_ACPT:
			if (!reason)
973
				reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
974
			sta->reason = reason;
975
			sta->plink_state = NL80211_PLINK_HOLDING;
976
			if (!mod_plink_timer(sta,
977
					     mshcfg->dot11MeshHoldingTimeout))
978 979 980
				sta->ignore_plink_timer = true;

			llid = sta->llid;
981
			spin_unlock_bh(&sta->lock);
982 983 984
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CLOSE,
					    sta->sta.addr, llid, plid, reason);
985
			break;
986
		case OPN_ACPT:
987
			del_timer(&sta->plink_timer);
988
			sta->plink_state = NL80211_PLINK_ESTAB;
989
			spin_unlock_bh(&sta->lock);
990
			changed |= mesh_plink_inc_estab_count(sdata);
991
			changed |= mesh_set_ht_prot_mode(sdata);
992
			changed |= mesh_set_short_slot_time(sdata);
J
Johannes Berg 已提交
993
			mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
994
				sta->sta.addr);
995 996 997
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CONFIRM,
					    sta->sta.addr, llid, plid, 0);
M
Marco Porsch 已提交
998
			ieee80211_mps_sta_status_update(sta);
999 1000
			changed |= ieee80211_mps_set_sta_local_pm(sta,
							mshcfg->power_mode);
1001 1002
			break;
		default:
1003
			spin_unlock_bh(&sta->lock);
1004 1005 1006 1007
			break;
		}
		break;

1008
	case NL80211_PLINK_ESTAB:
1009 1010
		switch (event) {
		case CLS_ACPT:
1011
			reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
1012
			sta->reason = reason;
1013
			changed |= __mesh_plink_deactivate(sta);
1014
			sta->plink_state = NL80211_PLINK_HOLDING;
1015
			llid = sta->llid;
1016
			mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
1017
			spin_unlock_bh(&sta->lock);
1018
			changed |= mesh_set_ht_prot_mode(sdata);
1019
			changed |= mesh_set_short_slot_time(sdata);
1020 1021
			mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
					    sta->sta.addr, llid, plid, reason);
1022 1023 1024
			break;
		case OPN_ACPT:
			llid = sta->llid;
1025
			spin_unlock_bh(&sta->lock);
1026 1027 1028
			mesh_plink_frame_tx(sdata,
					    WLAN_SP_MESH_PEERING_CONFIRM,
					    sta->sta.addr, llid, plid, 0);
1029 1030
			break;
		default:
1031
			spin_unlock_bh(&sta->lock);
1032 1033 1034
			break;
		}
		break;
1035
	case NL80211_PLINK_HOLDING:
1036 1037
		switch (event) {
		case CLS_ACPT:
1038
			if (del_timer(&sta->plink_timer))
1039 1040
				sta->ignore_plink_timer = 1;
			mesh_plink_fsm_restart(sta);
1041
			spin_unlock_bh(&sta->lock);
1042 1043 1044 1045 1046 1047 1048
			break;
		case OPN_ACPT:
		case CNF_ACPT:
		case OPN_RJCT:
		case CNF_RJCT:
			llid = sta->llid;
			reason = sta->reason;
1049
			spin_unlock_bh(&sta->lock);
1050 1051
			mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
					    sta->sta.addr, llid, plid, reason);
1052 1053
			break;
		default:
1054
			spin_unlock_bh(&sta->lock);
1055 1056 1057
		}
		break;
	default:
1058
		/* should not get here, PLINK_BLOCKED is dealt with at the
D
Daniel Mack 已提交
1059
		 * beginning of the function
1060
		 */
1061
		spin_unlock_bh(&sta->lock);
1062 1063
		break;
	}
1064 1065

	rcu_read_unlock();
1066 1067

	if (changed)
T
Thomas Pedersen 已提交
1068
		ieee80211_mbss_info_change_notify(sdata, changed);
1069
}