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
	sta = sta_info_alloc(sdata, hw_addr, GFP_KERNEL);
	if (!sta)
		return NULL;

	sta->plink_state = NL80211_PLINK_LISTEN;

	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;

439 440 441
	/* Userspace handles station allocation */
	if (sdata->u.mesh.user_mpm ||
	    sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED)
442 443 444 445 446 447 448
		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 674 675 676
	if (sdata->u.mesh.user_mpm)
		/* userspace must register for these */
		return;

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

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

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

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

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

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

730
	/* WARNING: Only for sta pointer, is dropped & re-acquired */
731 732
	rcu_read_lock();

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

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

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

754
	if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) {
755
		rcu_read_unlock();
756 757 758 759 760
		return;
	}

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

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

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

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

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

867
			spin_unlock_bh(&sta->lock);
868 869 870 871 872 873
			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);
874 875
			break;
		default:
876
			spin_unlock_bh(&sta->lock);
877 878 879 880
			break;
		}
		break;

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

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

917
			spin_unlock_bh(&sta->lock);
918 919
			break;
		default:
920
			spin_unlock_bh(&sta->lock);
921 922 923 924
			break;
		}
		break;

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

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

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

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

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

	rcu_read_unlock();
1070 1071

	if (changed)
T
Thomas Pedersen 已提交
1072
		ieee80211_mbss_info_change_notify(sdata, changed);
1073
}