File Index
Files and directories
Sign in
FILE

mesh_plink.c

File preview with syntax highlighting.

linux-6.19.14/net/mac80211/mesh_plink.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2008, 2009 open80211s Ltd.
   4 * Copyright (C) 2019, 2021-2025 Intel Corporation
   5 * Author:     Luis Carlos Cobo <luisca@cozybit.com>
   6 */
   7#include <linux/gfp.h>
   8#include <linux/kernel.h>
   9#include <linux/random.h>
  10#include <linux/rculist.h>
  11
  12#include "ieee80211_i.h"
  13#include "rate.h"
  14#include "mesh.h"
  15
  16#define PLINK_CNF_AID(mgmt) ((mgmt)->u.action.u.self_prot.variable + 2)
  17#define PLINK_GET_LLID(p) (p + 2)
  18#define PLINK_GET_PLID(p) (p + 4)
  19
  20#define mod_plink_timer(s, t) (mod_timer(&s->mesh->plink_timer, \
  21				jiffies + msecs_to_jiffies(t)))
  22
  23enum plink_event {
  24	PLINK_UNDEFINED,
  25	OPN_ACPT,
  26	OPN_RJCT,
  27	OPN_IGNR,
  28	CNF_ACPT,
  29	CNF_RJCT,
  30	CNF_IGNR,
  31	CLS_ACPT,
  32	CLS_IGNR
  33};
  34
  35static const char * const mplstates[] = {
  36	[NL80211_PLINK_LISTEN] = "LISTEN",
  37	[NL80211_PLINK_OPN_SNT] = "OPN-SNT",
  38	[NL80211_PLINK_OPN_RCVD] = "OPN-RCVD",
  39	[NL80211_PLINK_CNF_RCVD] = "CNF_RCVD",
  40	[NL80211_PLINK_ESTAB] = "ESTAB",
  41	[NL80211_PLINK_HOLDING] = "HOLDING",
  42	[NL80211_PLINK_BLOCKED] = "BLOCKED"
  43};
  44
  45static const char * const mplevents[] = {
  46	[PLINK_UNDEFINED] = "NONE",
  47	[OPN_ACPT] = "OPN_ACPT",
  48	[OPN_RJCT] = "OPN_RJCT",
  49	[OPN_IGNR] = "OPN_IGNR",
  50	[CNF_ACPT] = "CNF_ACPT",
  51	[CNF_RJCT] = "CNF_RJCT",
  52	[CNF_IGNR] = "CNF_IGNR",
  53	[CLS_ACPT] = "CLS_ACPT",
  54	[CLS_IGNR] = "CLS_IGNR"
  55};
  56
  57/* We only need a valid sta if user configured a minimum rssi_threshold. */
  58static bool rssi_threshold_check(struct ieee80211_sub_if_data *sdata,
  59				 struct sta_info *sta)
  60{
  61	s32 rssi_threshold = sdata->u.mesh.mshcfg.rssi_threshold;
  62	return rssi_threshold == 0 ||
  63	       (sta &&
  64		(s8)-ewma_signal_read(&sta->deflink.rx_stats_avg.signal) >
  65		rssi_threshold);
  66}
  67
  68/**
  69 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
  70 *
  71 * @sta: mesh peer link to restart
  72 *
  73 * Locking: this function must be called holding sta->mesh->plink_lock
  74 */
  75static inline void mesh_plink_fsm_restart(struct sta_info *sta)
  76{
  77	lockdep_assert_held(&sta->mesh->plink_lock);
  78	sta->mesh->plink_state = NL80211_PLINK_LISTEN;
  79	sta->mesh->llid = sta->mesh->plid = sta->mesh->reason = 0;
  80	sta->mesh->plink_retries = 0;
  81}
  82
  83/*
  84 * mesh_set_short_slot_time - enable / disable ERP short slot time.
  85 *
  86 * The standard indirectly mandates mesh STAs to turn off short slot time by
  87 * disallowing advertising this (802.11-2012 8.4.1.4), but that doesn't mean we
  88 * can't be sneaky about it. Enable short slot time if all mesh STAs in the
  89 * MBSS support ERP rates.
  90 *
  91 * Returns BSS_CHANGED_ERP_SLOT or 0 for no change.
  92 */
  93static u64 mesh_set_short_slot_time(struct ieee80211_sub_if_data *sdata)
  94{
  95	struct ieee80211_local *local = sdata->local;
  96	struct ieee80211_supported_band *sband;
  97	struct sta_info *sta;
  98	u32 erp_rates = 0;
  99	u64 changed = 0;
 100	int i;
 101	bool short_slot = false;
 102
 103	sband = ieee80211_get_sband(sdata);
 104	if (!sband)
 105		return changed;
 106
 107	if (sband->band == NL80211_BAND_5GHZ) {
 108		/* (IEEE 802.11-2012 19.4.5) */
 109		short_slot = true;
 110		goto out;
 111	} else if (sband->band != NL80211_BAND_2GHZ) {
 112		goto out;
 113	}
 114
 115	for (i = 0; i < sband->n_bitrates; i++)
 116		if (sband->bitrates[i].flags & IEEE80211_RATE_ERP_G)
 117			erp_rates |= BIT(i);
 118
 119	if (!erp_rates)
 120		goto out;
 121
 122	rcu_read_lock();
 123	list_for_each_entry_rcu(sta, &local->sta_list, list) {
 124		if (sdata != sta->sdata ||
 125		    sta->mesh->plink_state != NL80211_PLINK_ESTAB)
 126			continue;
 127
 128		short_slot = false;
 129		if (erp_rates & sta->sta.deflink.supp_rates[sband->band])
 130			short_slot = true;
 131		 else
 132			break;
 133	}
 134	rcu_read_unlock();
 135
 136out:
 137	if (sdata->vif.bss_conf.use_short_slot != short_slot) {
 138		sdata->vif.bss_conf.use_short_slot = short_slot;
 139		changed = BSS_CHANGED_ERP_SLOT;
 140		mpl_dbg(sdata, "mesh_plink %pM: ERP short slot time %d\n",
 141			sdata->vif.addr, short_slot);
 142	}
 143	return changed;
 144}
 145
 146/**
 147 * mesh_set_ht_prot_mode - set correct HT protection mode
 148 * @sdata: the (mesh) interface to handle
 149 *
 150 * Section 9.23.3.5 of IEEE 80211-2012 describes the protection rules for HT
 151 * mesh STA in a MBSS. Three HT protection modes are supported for now, non-HT
 152 * mixed mode, 20MHz-protection and no-protection mode. non-HT mixed mode is
 153 * selected if any non-HT peers are present in our MBSS.  20MHz-protection mode
 154 * is selected if all peers in our 20/40MHz MBSS support HT and at least one
 155 * HT20 peer is present. Otherwise no-protection mode is selected.
 156 *
 157 * Returns: BSS_CHANGED_HT or 0 for no change
 158 */
 159static u64 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
 160{
 161	struct ieee80211_local *local = sdata->local;
 162	struct sta_info *sta;
 163	u16 ht_opmode;
 164	bool non_ht_sta = false, ht20_sta = false;
 165
 166	switch (sdata->vif.bss_conf.chanreq.oper.width) {
 167	case NL80211_CHAN_WIDTH_20_NOHT:
 168	case NL80211_CHAN_WIDTH_5:
 169	case NL80211_CHAN_WIDTH_10:
 170		return 0;
 171	default:
 172		break;
 173	}
 174
 175	rcu_read_lock();
 176	list_for_each_entry_rcu(sta, &local->sta_list, list) {
 177		if (sdata != sta->sdata ||
 178		    sta->mesh->plink_state != NL80211_PLINK_ESTAB)
 179			continue;
 180
 181		if (sta->sta.deflink.bandwidth > IEEE80211_STA_RX_BW_20)
 182			continue;
 183
 184		if (!sta->sta.deflink.ht_cap.ht_supported) {
 185			mpl_dbg(sdata, "nonHT sta (%pM) is present\n",
 186				       sta->sta.addr);
 187			non_ht_sta = true;
 188			break;
 189		}
 190
 191		mpl_dbg(sdata, "HT20 sta (%pM) is present\n", sta->sta.addr);
 192		ht20_sta = true;
 193	}
 194	rcu_read_unlock();
 195
 196	if (non_ht_sta)
 197		ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED;
 198	else if (ht20_sta &&
 199		 sdata->vif.bss_conf.chanreq.oper.width > NL80211_CHAN_WIDTH_20)
 200		ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_20MHZ;
 201	else
 202		ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
 203
 204	if (sdata->vif.bss_conf.ht_operation_mode == ht_opmode)
 205		return 0;
 206
 207	sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
 208	sdata->u.mesh.mshcfg.ht_opmode = ht_opmode;
 209	mpl_dbg(sdata, "selected new HT protection mode %d\n", ht_opmode);
 210	return BSS_CHANGED_HT;
 211}
 212
 213static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
 214			       struct sta_info *sta,
 215			       enum ieee80211_self_protected_actioncode action,
 216			       u8 *da, u16 llid, u16 plid, u16 reason)
 217{
 218	struct ieee80211_local *local = sdata->local;
 219	struct sk_buff *skb;
 220	struct ieee80211_tx_info *info;
 221	struct ieee80211_mgmt *mgmt;
 222	bool include_plid = false;
 223	u16 peering_proto = 0;
 224	u8 *pos, ie_len = 4;
 225	u8 ie_len_he_cap, ie_len_eht_cap;
 226	int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.self_prot);
 227	int err = -ENOMEM;
 228
 229	ie_len_he_cap = ieee80211_ie_len_he_cap(sdata);
 230	ie_len_eht_cap = ieee80211_ie_len_eht_cap(sdata);
 231	skb = dev_alloc_skb(local->tx_headroom +
 232			    hdr_len +
 233			    2 + /* capability info */
 234			    2 + /* AID */
 235			    2 + 8 + /* supported rates */
 236			    2 + (IEEE80211_MAX_SUPP_RATES - 8) +
 237			    2 + sdata->u.mesh.mesh_id_len +
 238			    2 + sizeof(struct ieee80211_meshconf_ie) +
 239			    2 + sizeof(struct ieee80211_ht_cap) +
 240			    2 + sizeof(struct ieee80211_ht_operation) +
 241			    2 + sizeof(struct ieee80211_vht_cap) +
 242			    2 + sizeof(struct ieee80211_vht_operation) +
 243			    ie_len_he_cap +
 244			    2 + 1 + sizeof(struct ieee80211_he_operation) +
 245				    sizeof(struct ieee80211_he_6ghz_oper) +
 246			    2 + 1 + sizeof(struct ieee80211_he_6ghz_capa) +
 247			    ie_len_eht_cap +
 248			    2 + 1 + offsetof(struct ieee80211_eht_operation, optional) +
 249				    offsetof(struct ieee80211_eht_operation_info, optional) +
 250			    2 + 8 + /* peering IE */
 251			    sdata->u.mesh.ie_len);
 252	if (!skb)
 253		return err;
 254	info = IEEE80211_SKB_CB(skb);
 255	skb_reserve(skb, local->tx_headroom);
 256	mgmt = skb_put_zero(skb, hdr_len);
 257	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
 258					  IEEE80211_STYPE_ACTION);
 259	memcpy(mgmt->da, da, ETH_ALEN);
 260	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
 261	memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
 262	mgmt->u.action.category = WLAN_CATEGORY_SELF_PROTECTED;
 263	mgmt->u.action.u.self_prot.action_code = action;
 264
 265	if (action != WLAN_SP_MESH_PEERING_CLOSE) {
 266		struct ieee80211_supported_band *sband;
 267		u32 basic_rates;
 268
 269		sband = ieee80211_get_sband(sdata);
 270		if (!sband) {
 271			err = -EINVAL;
 272			goto free;
 273		}
 274
 275		/* capability info */
 276		pos = skb_put_zero(skb, 2);
 277		if (action == WLAN_SP_MESH_PEERING_CONFIRM) {
 278			/* AID */
 279			pos = skb_put(skb, 2);
 280			put_unaligned_le16(sta->sta.aid, pos);
 281		}
 282
 283		basic_rates = sdata->vif.bss_conf.basic_rates;
 284
 285		if (ieee80211_put_srates_elem(skb, sband, basic_rates,
 286					      0, WLAN_EID_SUPP_RATES) ||
 287		    ieee80211_put_srates_elem(skb, sband, basic_rates,
 288					      0, WLAN_EID_EXT_SUPP_RATES) ||
 289		    mesh_add_rsn_ie(sdata, skb) ||
 290		    mesh_add_meshid_ie(sdata, skb) ||
 291		    mesh_add_meshconf_ie(sdata, skb))
 292			goto free;
 293	} else {	/* WLAN_SP_MESH_PEERING_CLOSE */
 294		info->flags |= IEEE80211_TX_CTL_NO_ACK;
 295		if (mesh_add_meshid_ie(sdata, skb))
 296			goto free;
 297	}
 298
 299	/* Add Mesh Peering Management element */
 300	switch (action) {
 301	case WLAN_SP_MESH_PEERING_OPEN:
 302		break;
 303	case WLAN_SP_MESH_PEERING_CONFIRM:
 304		ie_len += 2;
 305		include_plid = true;
 306		break;
 307	case WLAN_SP_MESH_PEERING_CLOSE:
 308		if (plid) {
 309			ie_len += 2;
 310			include_plid = true;
 311		}
 312		ie_len += 2;	/* reason code */
 313		break;
 314	default:
 315		err = -EINVAL;
 316		goto free;
 317	}
 318
 319	if (WARN_ON(skb_tailroom(skb) < 2 + ie_len))
 320		goto free;
 321
 322	pos = skb_put(skb, 2 + ie_len);
 323	*pos++ = WLAN_EID_PEER_MGMT;
 324	*pos++ = ie_len;
 325	memcpy(pos, &peering_proto, 2);
 326	pos += 2;
 327	put_unaligned_le16(llid, pos);
 328	pos += 2;
 329	if (include_plid) {
 330		put_unaligned_le16(plid, pos);
 331		pos += 2;
 332	}
 333	if (action == WLAN_SP_MESH_PEERING_CLOSE) {
 334		put_unaligned_le16(reason, pos);
 335		pos += 2;
 336	}
 337
 338	if (action != WLAN_SP_MESH_PEERING_CLOSE) {
 339		if (mesh_add_ht_cap_ie(sdata, skb) ||
 340		    mesh_add_ht_oper_ie(sdata, skb) ||
 341		    mesh_add_vht_cap_ie(sdata, skb) ||
 342		    mesh_add_vht_oper_ie(sdata, skb) ||
 343		    mesh_add_he_cap_ie(sdata, skb, ie_len_he_cap) ||
 344		    mesh_add_he_oper_ie(sdata, skb) ||
 345		    mesh_add_he_6ghz_cap_ie(sdata, skb) ||
 346		    mesh_add_eht_cap_ie(sdata, skb, ie_len_eht_cap) ||
 347		    mesh_add_eht_oper_ie(sdata, skb))
 348			goto free;
 349	}
 350
 351	if (mesh_add_vendor_ies(sdata, skb))
 352		goto free;
 353
 354	ieee80211_tx_skb(sdata, skb);
 355	return 0;
 356free:
 357	kfree_skb(skb);
 358	return err;
 359}
 360
 361/**
 362 * __mesh_plink_deactivate - deactivate mesh peer link
 363 *
 364 * @sta: mesh peer link to deactivate
 365 *
 366 * Mesh paths with this peer as next hop should be flushed
 367 * by the caller outside of plink_lock.
 368 *
 369 * Returns: beacon changed flag if the beacon content changed.
 370 *
 371 * Locking: the caller must hold sta->mesh->plink_lock
 372 */
 373static u64 __mesh_plink_deactivate(struct sta_info *sta)
 374{
 375	struct ieee80211_sub_if_data *sdata = sta->sdata;
 376	u64 changed = 0;
 377
 378	lockdep_assert_held(&sta->mesh->plink_lock);
 379
 380	if (sta->mesh->plink_state == NL80211_PLINK_ESTAB)
 381		changed = mesh_plink_dec_estab_count(sdata);
 382	sta->mesh->plink_state = NL80211_PLINK_BLOCKED;
 383
 384	ieee80211_mps_sta_status_update(sta);
 385	changed |= ieee80211_mps_set_sta_local_pm(sta,
 386			NL80211_MESH_POWER_UNKNOWN);
 387
 388	return changed;
 389}
 390
 391/**
 392 * mesh_plink_deactivate - deactivate mesh peer link
 393 *
 394 * @sta: mesh peer link to deactivate
 395 *
 396 * All mesh paths with this peer as next hop will be flushed
 397 *
 398 * Returns: beacon changed flag if the beacon content changed.
 399 */
 400u64 mesh_plink_deactivate(struct sta_info *sta)
 401{
 402	struct ieee80211_sub_if_data *sdata = sta->sdata;
 403	u64 changed;
 404
 405	spin_lock_bh(&sta->mesh->plink_lock);
 406	changed = __mesh_plink_deactivate(sta);
 407
 408	if (!sdata->u.mesh.user_mpm) {
 409		sta->mesh->reason = WLAN_REASON_MESH_PEER_CANCELED;
 410		mesh_plink_frame_tx(sdata, sta, WLAN_SP_MESH_PEERING_CLOSE,
 411				    sta->sta.addr, sta->mesh->llid,
 412				    sta->mesh->plid, sta->mesh->reason);
 413	}
 414	spin_unlock_bh(&sta->mesh->plink_lock);
 415	if (!sdata->u.mesh.user_mpm)
 416		timer_delete_sync(&sta->mesh->plink_timer);
 417	mesh_path_flush_by_nexthop(sta);
 418
 419	/* make sure no readers can access nexthop sta from here on */
 420	synchronize_net();
 421
 422	return changed;
 423}
 424
 425static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
 426			       struct sta_info *sta,
 427			       struct ieee802_11_elems *elems)
 428{
 429	struct ieee80211_local *local = sdata->local;
 430	struct ieee80211_supported_band *sband;
 431	u32 rates, changed = 0;
 432	enum ieee80211_sta_rx_bandwidth bw = sta->sta.deflink.bandwidth;
 433
 434	sband = ieee80211_get_sband(sdata);
 435	if (!sband)
 436		return;
 437
 438	rates = ieee80211_sta_get_rates(sdata, elems, sband->band, NULL);
 439
 440	spin_lock_bh(&sta->mesh->plink_lock);
 441	sta->deflink.rx_stats.last_rx = jiffies;
 442
 443	/* rates and capabilities don't change during peering */
 444	if (sta->mesh->plink_state == NL80211_PLINK_ESTAB &&
 445	    sta->mesh->processed_beacon)
 446		goto out;
 447	sta->mesh->processed_beacon = true;
 448
 449	if (sta->sta.deflink.supp_rates[sband->band] != rates)
 450		changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
 451	sta->sta.deflink.supp_rates[sband->band] = rates;
 452
 453	if (ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
 454					      elems->ht_cap_elem,
 455					      &sta->deflink))
 456		changed |= IEEE80211_RC_BW_CHANGED;
 457
 458	ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
 459					    elems->vht_cap_elem, NULL,
 460					    &sta->deflink);
 461
 462	ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband, elems->he_cap,
 463					  elems->he_cap_len,
 464					  elems->he_6ghz_capa,
 465					  &sta->deflink);
 466
 467	ieee80211_eht_cap_ie_to_sta_eht_cap(sdata, sband, elems->he_cap,
 468					    elems->he_cap_len,
 469					    elems->eht_cap, elems->eht_cap_len,
 470					    &sta->deflink);
 471
 472	if (bw != sta->sta.deflink.bandwidth)
 473		changed |= IEEE80211_RC_BW_CHANGED;
 474
 475	/* HT peer is operating 20MHz-only */
 476	if (elems->ht_operation &&
 477	    !(elems->ht_operation->ht_param &
 478	      IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
 479		if (sta->sta.deflink.bandwidth != IEEE80211_STA_RX_BW_20)
 480			changed |= IEEE80211_RC_BW_CHANGED;
 481		sta->sta.deflink.bandwidth = IEEE80211_STA_RX_BW_20;
 482	}
 483
 484	/* FIXME: this check is wrong without SW rate control */
 485	if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
 486		rate_control_rate_init(&sta->deflink);
 487	else
 488		rate_control_rate_update(local, sband, &sta->deflink, changed);
 489out:
 490	spin_unlock_bh(&sta->mesh->plink_lock);
 491}
 492
 493static int mesh_allocate_aid(struct ieee80211_sub_if_data *sdata)
 494{
 495	struct sta_info *sta;
 496	unsigned long *aid_map;
 497	int aid;
 498
 499	aid_map = bitmap_zalloc(IEEE80211_MAX_AID + 1, GFP_KERNEL);
 500	if (!aid_map)
 501		return -ENOMEM;
 502
 503	/* reserve aid 0 for mcast indication */
 504	__set_bit(0, aid_map);
 505
 506	rcu_read_lock();
 507	list_for_each_entry_rcu(sta, &sdata->local->sta_list, list)
 508		__set_bit(sta->sta.aid, aid_map);
 509	rcu_read_unlock();
 510
 511	aid = find_first_zero_bit(aid_map, IEEE80211_MAX_AID + 1);
 512	bitmap_free(aid_map);
 513
 514	if (aid > IEEE80211_MAX_AID)
 515		return -ENOBUFS;
 516
 517	return aid;
 518}
 519
 520static struct sta_info *
 521__mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *hw_addr)
 522{
 523	struct sta_info *sta;
 524	int aid;
 525
 526	if (sdata->local->num_sta >= MESH_MAX_PLINKS)
 527		return NULL;
 528
 529	aid = mesh_allocate_aid(sdata);
 530	if (aid < 0)
 531		return NULL;
 532
 533	sta = sta_info_alloc(sdata, hw_addr, GFP_KERNEL);
 534	if (!sta)
 535		return NULL;
 536
 537	sta->mesh->plink_state = NL80211_PLINK_LISTEN;
 538	sta->sta.wme = true;
 539	sta->sta.aid = aid;
 540
 541	sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
 542	sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
 543	sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
 544
 545	return sta;
 546}
 547
 548static struct sta_info *
 549mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr,
 550		    struct ieee802_11_elems *elems,
 551		    struct ieee80211_rx_status *rx_status)
 552{
 553	struct sta_info *sta = NULL;
 554
 555	/* Userspace handles station allocation */
 556	if (sdata->u.mesh.user_mpm ||
 557	    sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) {
 558		if (mesh_peer_accepts_plinks(elems) &&
 559		    mesh_plink_availables(sdata)) {
 560			int sig = 0;
 561
 562			if (ieee80211_hw_check(&sdata->local->hw, SIGNAL_DBM))
 563				sig = rx_status->signal;
 564
 565			cfg80211_notify_new_peer_candidate(sdata->dev, addr,
 566							   elems->ie_start,
 567							   elems->total_len,
 568							   sig, GFP_KERNEL);
 569		}
 570	} else
 571		sta = __mesh_sta_info_alloc(sdata, addr);
 572
 573	return sta;
 574}
 575
 576/*
 577 * mesh_sta_info_get - return mesh sta info entry for @addr.
 578 *
 579 * @sdata: local meshif
 580 * @addr: peer's address
 581 * @elems: IEs from beacon or mesh peering frame.
 582 * @rx_status: rx status for the frame for signal reporting
 583 *
 584 * Return existing or newly allocated sta_info under RCU read lock.
 585 * (re)initialize with given IEs.
 586 */
 587static struct sta_info *
 588mesh_sta_info_get(struct ieee80211_sub_if_data *sdata,
 589		  u8 *addr, struct ieee802_11_elems *elems,
 590		  struct ieee80211_rx_status *rx_status) __acquires(RCU)
 591{
 592	struct sta_info *sta = NULL;
 593
 594	rcu_read_lock();
 595	sta = sta_info_get(sdata, addr);
 596	if (sta) {
 597		mesh_sta_info_init(sdata, sta, elems);
 598	} else {
 599		rcu_read_unlock();
 600		/* can't run atomic */
 601		sta = mesh_sta_info_alloc(sdata, addr, elems, rx_status);
 602		if (!sta) {
 603			rcu_read_lock();
 604			return NULL;
 605		}
 606
 607		mesh_sta_info_init(sdata, sta, elems);
 608
 609		if (sta_info_insert_rcu(sta))
 610			return NULL;
 611	}
 612
 613	return sta;
 614}
 615
 616/*
 617 * mesh_neighbour_update - update or initialize new mesh neighbor.
 618 *
 619 * @sdata: local meshif
 620 * @addr: peer's address
 621 * @elems: IEs from beacon or mesh peering frame
 622 * @rx_status: rx status for the frame for signal reporting
 623 *
 624 * Initiates peering if appropriate.
 625 */
 626void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
 627			   u8 *hw_addr,
 628			   struct ieee802_11_elems *elems,
 629			   struct ieee80211_rx_status *rx_status)
 630{
 631	struct sta_info *sta;
 632	u64 changed = 0;
 633
 634	sta = mesh_sta_info_get(sdata, hw_addr, elems, rx_status);
 635	if (!sta)
 636		goto out;
 637
 638	sta->mesh->connected_to_gate = elems->mesh_config->meshconf_form &
 639		IEEE80211_MESHCONF_FORM_CONNECTED_TO_GATE;
 640
 641	if (mesh_peer_accepts_plinks(elems) &&
 642	    sta->mesh->plink_state == NL80211_PLINK_LISTEN &&
 643	    sdata->u.mesh.accepting_plinks &&
 644	    sdata->u.mesh.mshcfg.auto_open_plinks &&
 645	    rssi_threshold_check(sdata, sta))
 646		changed = mesh_plink_open(sta);
 647
 648	ieee80211_mps_frame_release(sta, elems);
 649out:
 650	rcu_read_unlock();
 651	ieee80211_mbss_info_change_notify(sdata, changed);
 652}
 653
 654void mesh_plink_timer(struct timer_list *t)
 655{
 656	struct mesh_sta *mesh = timer_container_of(mesh, t, plink_timer);
 657	struct sta_info *sta;
 658	u16 reason = 0;
 659	struct ieee80211_sub_if_data *sdata;
 660	struct mesh_config *mshcfg;
 661	enum ieee80211_self_protected_actioncode action = 0;
 662
 663	/*
 664	 * This STA is valid because sta_info_destroy() will
 665	 * timer_delete_sync() this timer after having made sure
 666	 * it cannot be re-added (by deleting the plink.)
 667	 */
 668	sta = mesh->plink_sta;
 669
 670	if (sta->sdata->local->quiescing)
 671		return;
 672
 673	spin_lock_bh(&sta->mesh->plink_lock);
 674
 675	/* If a timer fires just before a state transition on another CPU,
 676	 * we may have already extended the timeout and changed state by the
 677	 * time we've acquired the lock and arrived  here.  In that case,
 678	 * skip this timer and wait for the new one.
 679	 */
 680	if (time_before(jiffies, sta->mesh->plink_timer.expires)) {
 681		mpl_dbg(sta->sdata,
 682			"Ignoring timer for %pM in state %s (timer adjusted)",
 683			sta->sta.addr, mplstates[sta->mesh->plink_state]);
 684		spin_unlock_bh(&sta->mesh->plink_lock);
 685		return;
 686	}
 687
 688	/* timer_delete() and handler may race when entering these states */
 689	if (sta->mesh->plink_state == NL80211_PLINK_LISTEN ||
 690	    sta->mesh->plink_state == NL80211_PLINK_ESTAB) {
 691		mpl_dbg(sta->sdata,
 692			"Ignoring timer for %pM in state %s (timer deleted)",
 693			sta->sta.addr, mplstates[sta->mesh->plink_state]);
 694		spin_unlock_bh(&sta->mesh->plink_lock);
 695		return;
 696	}
 697
 698	mpl_dbg(sta->sdata,
 699		"Mesh plink timer for %pM fired on state %s\n",
 700		sta->sta.addr, mplstates[sta->mesh->plink_state]);
 701	sdata = sta->sdata;
 702	mshcfg = &sdata->u.mesh.mshcfg;
 703
 704	switch (sta->mesh->plink_state) {
 705	case NL80211_PLINK_OPN_RCVD:
 706	case NL80211_PLINK_OPN_SNT:
 707		/* retry timer */
 708		if (sta->mesh->plink_retries < mshcfg->dot11MeshMaxRetries) {
 709			u32 rand;
 710			mpl_dbg(sta->sdata,
 711				"Mesh plink for %pM (retry, timeout): %d %d\n",
 712				sta->sta.addr, sta->mesh->plink_retries,
 713				sta->mesh->plink_timeout);
 714			get_random_bytes(&rand, sizeof(u32));
 715			sta->mesh->plink_timeout = sta->mesh->plink_timeout +
 716					     rand % sta->mesh->plink_timeout;
 717			++sta->mesh->plink_retries;
 718			mod_plink_timer(sta, sta->mesh->plink_timeout);
 719			action = WLAN_SP_MESH_PEERING_OPEN;
 720			break;
 721		}
 722		reason = WLAN_REASON_MESH_MAX_RETRIES;
 723		fallthrough;
 724	case NL80211_PLINK_CNF_RCVD:
 725		/* confirm timer */
 726		if (!reason)
 727			reason = WLAN_REASON_MESH_CONFIRM_TIMEOUT;
 728		sta->mesh->plink_state = NL80211_PLINK_HOLDING;
 729		mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
 730		action = WLAN_SP_MESH_PEERING_CLOSE;
 731		break;
 732	case NL80211_PLINK_HOLDING:
 733		/* holding timer */
 734		timer_delete(&sta->mesh->plink_timer);
 735		mesh_plink_fsm_restart(sta);
 736		break;
 737	default:
 738		break;
 739	}
 740	spin_unlock_bh(&sta->mesh->plink_lock);
 741	if (action)
 742		mesh_plink_frame_tx(sdata, sta, action, sta->sta.addr,
 743				    sta->mesh->llid, sta->mesh->plid, reason);
 744}
 745
 746static inline void mesh_plink_timer_set(struct sta_info *sta, u32 timeout)
 747{
 748	sta->mesh->plink_timeout = timeout;
 749	mod_timer(&sta->mesh->plink_timer, jiffies + msecs_to_jiffies(timeout));
 750}
 751
 752static bool llid_in_use(struct ieee80211_sub_if_data *sdata,
 753			u16 llid)
 754{
 755	struct ieee80211_local *local = sdata->local;
 756	bool in_use = false;
 757	struct sta_info *sta;
 758
 759	rcu_read_lock();
 760	list_for_each_entry_rcu(sta, &local->sta_list, list) {
 761		if (sdata != sta->sdata)
 762			continue;
 763
 764		if (!memcmp(&sta->mesh->llid, &llid, sizeof(llid))) {
 765			in_use = true;
 766			break;
 767		}
 768	}
 769	rcu_read_unlock();
 770
 771	return in_use;
 772}
 773
 774static u16 mesh_get_new_llid(struct ieee80211_sub_if_data *sdata)
 775{
 776	u16 llid;
 777
 778	do {
 779		get_random_bytes(&llid, sizeof(llid));
 780	} while (llid_in_use(sdata, llid));
 781
 782	return llid;
 783}
 784
 785u64 mesh_plink_open(struct sta_info *sta)
 786{
 787	struct ieee80211_sub_if_data *sdata = sta->sdata;
 788	u64 changed;
 789
 790	if (!test_sta_flag(sta, WLAN_STA_AUTH))
 791		return 0;
 792
 793	spin_lock_bh(&sta->mesh->plink_lock);
 794	sta->mesh->llid = mesh_get_new_llid(sdata);
 795	if (sta->mesh->plink_state != NL80211_PLINK_LISTEN &&
 796	    sta->mesh->plink_state != NL80211_PLINK_BLOCKED) {
 797		spin_unlock_bh(&sta->mesh->plink_lock);
 798		return 0;
 799	}
 800	sta->mesh->plink_state = NL80211_PLINK_OPN_SNT;
 801	mesh_plink_timer_set(sta, sdata->u.mesh.mshcfg.dot11MeshRetryTimeout);
 802	spin_unlock_bh(&sta->mesh->plink_lock);
 803	mpl_dbg(sdata,
 804		"Mesh plink: starting establishment with %pM\n",
 805		sta->sta.addr);
 806
 807	/* set the non-peer mode to active during peering */
 808	changed = ieee80211_mps_local_status_update(sdata);
 809
 810	mesh_plink_frame_tx(sdata, sta, WLAN_SP_MESH_PEERING_OPEN,
 811			    sta->sta.addr, sta->mesh->llid, 0, 0);
 812	return changed;
 813}
 814
 815u64 mesh_plink_block(struct sta_info *sta)
 816{
 817	u64 changed;
 818
 819	spin_lock_bh(&sta->mesh->plink_lock);
 820	changed = __mesh_plink_deactivate(sta);
 821	sta->mesh->plink_state = NL80211_PLINK_BLOCKED;
 822	spin_unlock_bh(&sta->mesh->plink_lock);
 823	mesh_path_flush_by_nexthop(sta);
 824
 825	return changed;
 826}
 827
 828static void mesh_plink_close(struct ieee80211_sub_if_data *sdata,
 829			     struct sta_info *sta,
 830			     enum plink_event event)
 831{
 832	struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
 833	u16 reason = (event == CLS_ACPT) ?
 834		     WLAN_REASON_MESH_CLOSE : WLAN_REASON_MESH_CONFIG;
 835
 836	sta->mesh->reason = reason;
 837	sta->mesh->plink_state = NL80211_PLINK_HOLDING;
 838	mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
 839}
 840
 841static u64 mesh_plink_establish(struct ieee80211_sub_if_data *sdata,
 842				struct sta_info *sta)
 843{
 844	struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
 845	u64 changed = 0;
 846
 847	timer_delete(&sta->mesh->plink_timer);
 848	sta->mesh->plink_state = NL80211_PLINK_ESTAB;
 849	changed |= mesh_plink_inc_estab_count(sdata);
 850	changed |= mesh_set_ht_prot_mode(sdata);
 851	changed |= mesh_set_short_slot_time(sdata);
 852	mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", sta->sta.addr);
 853	ieee80211_mps_sta_status_update(sta);
 854	changed |= ieee80211_mps_set_sta_local_pm(sta, mshcfg->power_mode);
 855	return changed;
 856}
 857
 858/**
 859 * mesh_plink_fsm - step @sta MPM based on @event
 860 *
 861 * @sdata: interface
 862 * @sta: mesh neighbor
 863 * @event: peering event
 864 *
 865 * Return: changed MBSS flags
 866 */
 867static u64 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata,
 868			  struct sta_info *sta, enum plink_event event)
 869{
 870	struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
 871	enum ieee80211_self_protected_actioncode action = 0;
 872	u64 changed = 0;
 873	bool flush = false;
 874
 875	mpl_dbg(sdata, "peer %pM in state %s got event %s\n", sta->sta.addr,
 876		mplstates[sta->mesh->plink_state], mplevents[event]);
 877
 878	spin_lock_bh(&sta->mesh->plink_lock);
 879	switch (sta->mesh->plink_state) {
 880	case NL80211_PLINK_LISTEN:
 881		switch (event) {
 882		case CLS_ACPT:
 883			mesh_plink_fsm_restart(sta);
 884			break;
 885		case OPN_ACPT:
 886			sta->mesh->plink_state = NL80211_PLINK_OPN_RCVD;
 887			sta->mesh->llid = mesh_get_new_llid(sdata);
 888			mesh_plink_timer_set(sta,
 889					     mshcfg->dot11MeshRetryTimeout);
 890
 891			/* set the non-peer mode to active during peering */
 892			changed |= ieee80211_mps_local_status_update(sdata);
 893			action = WLAN_SP_MESH_PEERING_OPEN;
 894			break;
 895		default:
 896			break;
 897		}
 898		break;
 899	case NL80211_PLINK_OPN_SNT:
 900		switch (event) {
 901		case OPN_RJCT:
 902		case CNF_RJCT:
 903		case CLS_ACPT:
 904			mesh_plink_close(sdata, sta, event);
 905			action = WLAN_SP_MESH_PEERING_CLOSE;
 906			break;
 907		case OPN_ACPT:
 908			/* retry timer is left untouched */
 909			sta->mesh->plink_state = NL80211_PLINK_OPN_RCVD;
 910			action = WLAN_SP_MESH_PEERING_CONFIRM;
 911			break;
 912		case CNF_ACPT:
 913			sta->mesh->plink_state = NL80211_PLINK_CNF_RCVD;
 914			mod_plink_timer(sta, mshcfg->dot11MeshConfirmTimeout);
 915			break;
 916		default:
 917			break;
 918		}
 919		break;
 920	case NL80211_PLINK_OPN_RCVD:
 921		switch (event) {
 922		case OPN_RJCT:
 923		case CNF_RJCT:
 924		case CLS_ACPT:
 925			mesh_plink_close(sdata, sta, event);
 926			action = WLAN_SP_MESH_PEERING_CLOSE;
 927			break;
 928		case OPN_ACPT:
 929			action = WLAN_SP_MESH_PEERING_CONFIRM;
 930			break;
 931		case CNF_ACPT:
 932			changed |= mesh_plink_establish(sdata, sta);
 933			break;
 934		default:
 935			break;
 936		}
 937		break;
 938	case NL80211_PLINK_CNF_RCVD:
 939		switch (event) {
 940		case OPN_RJCT:
 941		case CNF_RJCT:
 942		case CLS_ACPT:
 943			mesh_plink_close(sdata, sta, event);
 944			action = WLAN_SP_MESH_PEERING_CLOSE;
 945			break;
 946		case OPN_ACPT:
 947			changed |= mesh_plink_establish(sdata, sta);
 948			action = WLAN_SP_MESH_PEERING_CONFIRM;
 949			break;
 950		default:
 951			break;
 952		}
 953		break;
 954	case NL80211_PLINK_ESTAB:
 955		switch (event) {
 956		case CLS_ACPT:
 957			changed |= __mesh_plink_deactivate(sta);
 958			changed |= mesh_set_ht_prot_mode(sdata);
 959			changed |= mesh_set_short_slot_time(sdata);
 960			mesh_plink_close(sdata, sta, event);
 961			action = WLAN_SP_MESH_PEERING_CLOSE;
 962			flush = true;
 963			break;
 964		case OPN_ACPT:
 965			action = WLAN_SP_MESH_PEERING_CONFIRM;
 966			break;
 967		default:
 968			break;
 969		}
 970		break;
 971	case NL80211_PLINK_HOLDING:
 972		switch (event) {
 973		case CLS_ACPT:
 974			timer_delete(&sta->mesh->plink_timer);
 975			mesh_plink_fsm_restart(sta);
 976			break;
 977		case OPN_ACPT:
 978		case CNF_ACPT:
 979		case OPN_RJCT:
 980		case CNF_RJCT:
 981			action = WLAN_SP_MESH_PEERING_CLOSE;
 982			break;
 983		default:
 984			break;
 985		}
 986		break;
 987	default:
 988		/* should not get here, PLINK_BLOCKED is dealt with at the
 989		 * beginning of the function
 990		 */
 991		break;
 992	}
 993	spin_unlock_bh(&sta->mesh->plink_lock);
 994	if (flush)
 995		mesh_path_flush_by_nexthop(sta);
 996	if (action) {
 997		mesh_plink_frame_tx(sdata, sta, action, sta->sta.addr,
 998				    sta->mesh->llid, sta->mesh->plid,
 999				    sta->mesh->reason);
1000
1001		/* also send confirm in open case */
1002		if (action == WLAN_SP_MESH_PEERING_OPEN) {
1003			mesh_plink_frame_tx(sdata, sta,
1004					    WLAN_SP_MESH_PEERING_CONFIRM,
1005					    sta->sta.addr, sta->mesh->llid,
1006					    sta->mesh->plid, 0);
1007		}
1008	}
1009
1010	return changed;
1011}
1012
1013/*
1014 * mesh_plink_get_event - get correct MPM event
1015 *
1016 * @sdata: interface
1017 * @sta: peer, leave NULL if processing a frame from a new suitable peer
1018 * @elems: peering management IEs
1019 * @ftype: frame type
1020 * @llid: peer's peer link ID
1021 * @plid: peer's local link ID
1022 *
1023 * Return: new peering event for @sta, but PLINK_UNDEFINED should be treated as
1024 * an error.
1025 */
1026static enum plink_event
1027mesh_plink_get_event(struct ieee80211_sub_if_data *sdata,
1028		     struct sta_info *sta,
1029		     struct ieee802_11_elems *elems,
1030		     enum ieee80211_self_protected_actioncode ftype,
1031		     u16 llid, u16 plid)
1032{
1033	enum plink_event event = PLINK_UNDEFINED;
1034	u8 ie_len = elems->peering_len;
1035	bool matches_local;
1036
1037	matches_local = (ftype == WLAN_SP_MESH_PEERING_CLOSE ||
1038			 mesh_matches_local(sdata, elems));
1039
1040	/* deny open request from non-matching peer */
1041	if (!matches_local && !sta) {
1042		event = OPN_RJCT;
1043		goto out;
1044	}
1045
1046	if (!sta) {
1047		if (ftype != WLAN_SP_MESH_PEERING_OPEN) {
1048			mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n");
1049			goto out;
1050		}
1051		/* ftype == WLAN_SP_MESH_PEERING_OPEN */
1052		if (!mesh_plink_free_count(sdata)) {
1053			mpl_dbg(sdata, "Mesh plink error: no more free plinks\n");
1054			goto out;
1055		}
1056
1057		/* new matching peer */
1058		event = OPN_ACPT;
1059		goto out;
1060	} else {
1061		if (!test_sta_flag(sta, WLAN_STA_AUTH)) {
1062			mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n");
1063			goto out;
1064		}
1065		if (sta->mesh->plink_state == NL80211_PLINK_BLOCKED)
1066			goto out;
1067	}
1068
1069	switch (ftype) {
1070	case WLAN_SP_MESH_PEERING_OPEN:
1071		if (!matches_local)
1072			event = OPN_RJCT;
1073		else if (!mesh_plink_free_count(sdata) ||
1074			 (sta->mesh->plid && sta->mesh->plid != plid))
1075			event = OPN_IGNR;
1076		else
1077			event = OPN_ACPT;
1078		break;
1079	case WLAN_SP_MESH_PEERING_CONFIRM:
1080		if (!matches_local)
1081			event = CNF_RJCT;
1082		else if (!mesh_plink_free_count(sdata) ||
1083			 sta->mesh->llid != llid ||
1084			 (sta->mesh->plid && sta->mesh->plid != plid))
1085			event = CNF_IGNR;
1086		else
1087			event = CNF_ACPT;
1088		break;
1089	case WLAN_SP_MESH_PEERING_CLOSE:
1090		if (sta->mesh->plink_state == NL80211_PLINK_ESTAB)
1091			/* Do not check for llid or plid. This does not
1092			 * follow the standard but since multiple plinks
1093			 * per sta are not supported, it is necessary in
1094			 * order to avoid a livelock when MP A sees an
1095			 * establish peer link to MP B but MP B does not
1096			 * see it. This can be caused by a timeout in
1097			 * B's peer link establishment or B beign
1098			 * restarted.
1099			 */
1100			event = CLS_ACPT;
1101		else if (sta->mesh->plid != plid)
1102			event = CLS_IGNR;
1103		else if (ie_len == 8 && sta->mesh->llid != llid)
1104			event = CLS_IGNR;
1105		else
1106			event = CLS_ACPT;
1107		break;
1108	default:
1109		mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n");
1110		break;
1111	}
1112
1113out:
1114	return event;
1115}
1116
1117static void
1118mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
1119			 struct ieee80211_mgmt *mgmt,
1120			 struct ieee802_11_elems *elems,
1121			 struct ieee80211_rx_status *rx_status)
1122{
1123
1124	struct sta_info *sta;
1125	enum plink_event event;
1126	enum ieee80211_self_protected_actioncode ftype;
1127	u64 changed = 0;
1128	u8 ie_len = elems->peering_len;
1129	u16 plid, llid = 0;
1130
1131	if (!elems->peering) {
1132		mpl_dbg(sdata,
1133			"Mesh plink: missing necessary peer link ie\n");
1134		return;
1135	}
1136
1137	if (elems->rsn_len &&
1138	    sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
1139		mpl_dbg(sdata,
1140			"Mesh plink: can't establish link with secure peer\n");
1141		return;
1142	}
1143
1144	ftype = mgmt->u.action.u.self_prot.action_code;
1145	if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) ||
1146	    (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) ||
1147	    (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6
1148							&& ie_len != 8)) {
1149		mpl_dbg(sdata,
1150			"Mesh plink: incorrect plink ie length %d %d\n",
1151			ftype, ie_len);
1152		return;
1153	}
1154
1155	if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
1156	    (!elems->mesh_id || !elems->mesh_config)) {
1157		mpl_dbg(sdata, "Mesh plink: missing necessary ie\n");
1158		return;
1159	}
1160	/* Note the lines below are correct, the llid in the frame is the plid
1161	 * from the point of view of this host.
1162	 */
1163	plid = get_unaligned_le16(PLINK_GET_LLID(elems->peering));
1164	if (ftype == WLAN_SP_MESH_PEERING_CONFIRM ||
1165	    (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8))
1166		llid = get_unaligned_le16(PLINK_GET_PLID(elems->peering));
1167
1168	/* WARNING: Only for sta pointer, is dropped & re-acquired */
1169	rcu_read_lock();
1170
1171	sta = sta_info_get(sdata, mgmt->sa);
1172
1173	if (ftype == WLAN_SP_MESH_PEERING_OPEN &&
1174	    !rssi_threshold_check(sdata, sta)) {
1175		mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n",
1176			mgmt->sa);
1177		goto unlock_rcu;
1178	}
1179
1180	/* Now we will figure out the appropriate event... */
1181	event = mesh_plink_get_event(sdata, sta, elems, ftype, llid, plid);
1182
1183	if (event == OPN_ACPT) {
1184		rcu_read_unlock();
1185		/* allocate sta entry if necessary and update info */
1186		sta = mesh_sta_info_get(sdata, mgmt->sa, elems, rx_status);
1187		if (!sta) {
1188			mpl_dbg(sdata, "Mesh plink: failed to init peer!\n");
1189			goto unlock_rcu;
1190		}
1191		sta->mesh->plid = plid;
1192	} else if (!sta && event == OPN_RJCT) {
1193		mesh_plink_frame_tx(sdata, NULL, WLAN_SP_MESH_PEERING_CLOSE,
1194				    mgmt->sa, 0, plid,
1195				    WLAN_REASON_MESH_CONFIG);
1196		goto unlock_rcu;
1197	} else if (!sta || event == PLINK_UNDEFINED) {
1198		/* something went wrong */
1199		goto unlock_rcu;
1200	}
1201
1202	if (event == CNF_ACPT) {
1203		/* 802.11-2012 13.3.7.2 - update plid on CNF if not set */
1204		if (!sta->mesh->plid)
1205			sta->mesh->plid = plid;
1206
1207		sta->mesh->aid = get_unaligned_le16(PLINK_CNF_AID(mgmt));
1208	}
1209
1210	changed |= mesh_plink_fsm(sdata, sta, event);
1211
1212unlock_rcu:
1213	rcu_read_unlock();
1214
1215	if (changed)
1216		ieee80211_mbss_info_change_notify(sdata, changed);
1217}
1218
1219void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
1220			 struct ieee80211_mgmt *mgmt, size_t len,
1221			 struct ieee80211_rx_status *rx_status)
1222{
1223	struct ieee802_11_elems *elems;
1224	size_t baselen;
1225	u8 *baseaddr;
1226
1227	/* need action_code, aux */
1228	if (len < IEEE80211_MIN_ACTION_SIZE + 3)
1229		return;
1230
1231	if (sdata->u.mesh.user_mpm)
1232		/* userspace must register for these */
1233		return;
1234
1235	if (is_multicast_ether_addr(mgmt->da)) {
1236		mpl_dbg(sdata,
1237			"Mesh plink: ignore frame from multicast address\n");
1238		return;
1239	}
1240
1241	baseaddr = mgmt->u.action.u.self_prot.variable;
1242	baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt;
1243	if (mgmt->u.action.u.self_prot.action_code ==
1244						WLAN_SP_MESH_PEERING_CONFIRM) {
1245		baseaddr += 4;
1246		baselen += 4;
1247
1248		if (baselen > len)
1249			return;
1250	}
1251	elems = ieee802_11_parse_elems(baseaddr, len - baselen,
1252				       IEEE80211_FTYPE_MGMT |
1253				       IEEE80211_STYPE_ACTION,
1254				       NULL);
1255	if (elems) {
1256		mesh_process_plink_frame(sdata, mgmt, elems, rx_status);
1257		kfree(elems);
1258	}
1259}
~/ Read-only file preview.