Home | History | Annotate | Line # | Download | only in wpa_supplicant
      1 /*
      2  * WPA Supplicant - Basic mesh peer management
      3  * Copyright (c) 2013-2014, cozybit, Inc.  All rights reserved.
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "utils/includes.h"
     10 
     11 #include "utils/common.h"
     12 #include "utils/eloop.h"
     13 #include "common/ieee802_11_defs.h"
     14 #include "common/hw_features_common.h"
     15 #include "common/ocv.h"
     16 #include "ap/hostapd.h"
     17 #include "ap/sta_info.h"
     18 #include "ap/ieee802_11.h"
     19 #include "ap/beacon.h"
     20 #include "ap/wpa_auth.h"
     21 #include "wpa_supplicant_i.h"
     22 #include "driver_i.h"
     23 #include "mesh_mpm.h"
     24 #include "mesh_rsn.h"
     25 #include "notify.h"
     26 
     27 struct mesh_peer_mgmt_ie {
     28 	const u8 *proto_id; /* Mesh Peering Protocol Identifier (2 octets) */
     29 	const u8 *llid; /* Local Link ID (2 octets) */
     30 	const u8 *plid; /* Peer Link ID (conditional, 2 octets) */
     31 	const u8 *reason; /* Reason Code (conditional, 2 octets) */
     32 	const u8 *chosen_pmk; /* Chosen PMK (optional, 16 octets) */
     33 };
     34 
     35 static void plink_timer(void *eloop_ctx, void *user_data);
     36 
     37 
     38 enum plink_event {
     39 	PLINK_UNDEFINED,
     40 	OPN_ACPT,
     41 	OPN_RJCT,
     42 	CNF_ACPT,
     43 	CNF_RJCT,
     44 	CLS_ACPT,
     45 	REQ_RJCT
     46 };
     47 
     48 static const char * const mplstate[] = {
     49 	[0] = "UNINITIALIZED",
     50 	[PLINK_IDLE] = "IDLE",
     51 	[PLINK_OPN_SNT] = "OPN_SNT",
     52 	[PLINK_OPN_RCVD] = "OPN_RCVD",
     53 	[PLINK_CNF_RCVD] = "CNF_RCVD",
     54 	[PLINK_ESTAB] = "ESTAB",
     55 	[PLINK_HOLDING] = "HOLDING",
     56 	[PLINK_BLOCKED] = "BLOCKED"
     57 };
     58 
     59 static const char * const mplevent[] = {
     60 	[PLINK_UNDEFINED] = "UNDEFINED",
     61 	[OPN_ACPT] = "OPN_ACPT",
     62 	[OPN_RJCT] = "OPN_RJCT",
     63 	[CNF_ACPT] = "CNF_ACPT",
     64 	[CNF_RJCT] = "CNF_RJCT",
     65 	[CLS_ACPT] = "CLS_ACPT",
     66 	[REQ_RJCT] = "REQ_RJCT",
     67 };
     68 
     69 
     70 static int mesh_mpm_parse_peer_mgmt(struct wpa_supplicant *wpa_s,
     71 				    u8 action_field,
     72 				    const u8 *ie, size_t len,
     73 				    struct mesh_peer_mgmt_ie *mpm_ie)
     74 {
     75 	os_memset(mpm_ie, 0, sizeof(*mpm_ie));
     76 
     77 	/* Remove optional Chosen PMK field at end */
     78 	if (len >= SAE_PMKID_LEN) {
     79 		mpm_ie->chosen_pmk = ie + len - SAE_PMKID_LEN;
     80 		len -= SAE_PMKID_LEN;
     81 	}
     82 
     83 	if ((action_field == PLINK_OPEN && len != 4) ||
     84 	    (action_field == PLINK_CONFIRM && len != 6) ||
     85 	    (action_field == PLINK_CLOSE && len != 6 && len != 8)) {
     86 		wpa_msg(wpa_s, MSG_DEBUG, "MPM: Invalid peer mgmt ie");
     87 		return -1;
     88 	}
     89 
     90 	/* required fields */
     91 	if (len < 4)
     92 		return -1;
     93 	mpm_ie->proto_id = ie;
     94 	mpm_ie->llid = ie + 2;
     95 	ie += 4;
     96 	len -= 4;
     97 
     98 	/* close reason is always present at end for close */
     99 	if (action_field == PLINK_CLOSE) {
    100 		if (len < 2)
    101 			return -1;
    102 		mpm_ie->reason = ie + len - 2;
    103 		len -= 2;
    104 	}
    105 
    106 	/* Peer Link ID, present for confirm, and possibly close */
    107 	if (len >= 2)
    108 		mpm_ie->plid = ie;
    109 
    110 	return 0;
    111 }
    112 
    113 
    114 static int plink_free_count(struct hostapd_data *hapd)
    115 {
    116 	if (hapd->max_plinks > hapd->num_plinks)
    117 		return hapd->max_plinks - hapd->num_plinks;
    118 	return 0;
    119 }
    120 
    121 
    122 static u16 copy_supp_rates(struct wpa_supplicant *wpa_s,
    123 			   struct sta_info *sta,
    124 			   struct ieee802_11_elems *elems)
    125 {
    126 	if (!elems->supp_rates) {
    127 		wpa_msg(wpa_s, MSG_ERROR, "no supported rates from " MACSTR,
    128 			MAC2STR(sta->addr));
    129 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
    130 	}
    131 
    132 	if (elems->supp_rates_len + elems->ext_supp_rates_len >
    133 	    sizeof(sta->supported_rates)) {
    134 		wpa_msg(wpa_s, MSG_ERROR,
    135 			"Invalid supported rates element length " MACSTR
    136 			" %d+%d", MAC2STR(sta->addr), elems->supp_rates_len,
    137 			elems->ext_supp_rates_len);
    138 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
    139 	}
    140 
    141 	sta->supported_rates_len = merge_byte_arrays(
    142 		sta->supported_rates, sizeof(sta->supported_rates),
    143 		elems->supp_rates, elems->supp_rates_len,
    144 		elems->ext_supp_rates, elems->ext_supp_rates_len);
    145 
    146 	return WLAN_STATUS_SUCCESS;
    147 }
    148 
    149 
    150 /* return true if elems from a neighbor match this MBSS */
    151 static bool matches_local(struct wpa_supplicant *wpa_s,
    152 			  struct ieee802_11_elems *elems)
    153 {
    154 	struct mesh_conf *mconf = wpa_s->ifmsh->mconf;
    155 
    156 	if (elems->mesh_config_len < 5)
    157 		return false;
    158 
    159 	return (mconf->meshid_len == elems->mesh_id_len &&
    160 		os_memcmp(mconf->meshid, elems->mesh_id,
    161 			  elems->mesh_id_len) == 0 &&
    162 		mconf->mesh_pp_id == elems->mesh_config[0] &&
    163 		mconf->mesh_pm_id == elems->mesh_config[1] &&
    164 		mconf->mesh_cc_id == elems->mesh_config[2] &&
    165 		mconf->mesh_sp_id == elems->mesh_config[3] &&
    166 		mconf->mesh_auth_id == elems->mesh_config[4]);
    167 }
    168 
    169 
    170 /* check if local link id is already used with another peer */
    171 static bool llid_in_use(struct wpa_supplicant *wpa_s, u16 llid)
    172 {
    173 	struct sta_info *sta;
    174 	struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
    175 
    176 	for (sta = hapd->sta_list; sta; sta = sta->next) {
    177 		if (sta->my_lid == llid)
    178 			return true;
    179 	}
    180 
    181 	return false;
    182 }
    183 
    184 
    185 /* generate an llid for a link and set to initial state */
    186 static void mesh_mpm_init_link(struct wpa_supplicant *wpa_s,
    187 			       struct sta_info *sta)
    188 {
    189 	u16 llid;
    190 
    191 	do {
    192 		if (os_get_random((u8 *) &llid, sizeof(llid)) < 0)
    193 			llid = 0; /* continue */
    194 	} while (!llid || llid_in_use(wpa_s, llid));
    195 
    196 	sta->my_lid = llid;
    197 	sta->peer_lid = 0;
    198 	sta->peer_aid = 0;
    199 
    200 	/*
    201 	 * We do not use wpa_mesh_set_plink_state() here because there is no
    202 	 * entry in kernel yet.
    203 	 */
    204 	sta->plink_state = PLINK_IDLE;
    205 }
    206 
    207 
    208 static void mesh_mpm_send_plink_action(struct wpa_supplicant *wpa_s,
    209 				       struct sta_info *sta,
    210 				       enum plink_action_field type,
    211 				       u16 close_reason)
    212 {
    213 	struct wpabuf *buf;
    214 	struct hostapd_iface *ifmsh = wpa_s->ifmsh;
    215 	struct hostapd_data *bss = ifmsh->bss[0];
    216 	struct mesh_conf *conf = ifmsh->mconf;
    217 	u8 supp_rates[2 + 2 + 32];
    218 	u8 *pos, *cat;
    219 	u8 ie_len, add_plid = 0;
    220 	int ret;
    221 	int ampe = conf->security & MESH_CONF_SEC_AMPE;
    222 	size_t buf_len;
    223 
    224 	if (!sta)
    225 		return;
    226 
    227 	buf_len = 2 +      /* Category and Action */
    228 		  2 +      /* capability info */
    229 		  2 +      /* AID */
    230 		  2 + 8 +  /* supported rates */
    231 		  2 + (32 - 8) +
    232 		  2 + 32 + /* mesh ID */
    233 		  2 + 7 +  /* mesh config */
    234 		  2 + 24 + /* peering management */
    235 		  2 + 96 + 32 + 32 + /* AMPE (96 + max GTKlen + max IGTKlen) */
    236 		  2 + 16;  /* MIC */
    237 	if (type != PLINK_CLOSE && wpa_s->mesh_ht_enabled) {
    238 		buf_len += 2 + 26 + /* HT capabilities */
    239 			   2 + 22;  /* HT operation */
    240 	}
    241 #ifdef CONFIG_IEEE80211AC
    242 	if (type != PLINK_CLOSE && wpa_s->mesh_vht_enabled) {
    243 		buf_len += 2 + 12 + /* VHT Capabilities */
    244 			   2 + 5;  /* VHT Operation */
    245 	}
    246 #endif /* CONFIG_IEEE80211AC */
    247 #ifdef CONFIG_IEEE80211AX
    248 	if (type != PLINK_CLOSE && wpa_s->mesh_he_enabled) {
    249 		buf_len += 3 +
    250 			   HE_MAX_MAC_CAPAB_SIZE +
    251 			   HE_MAX_PHY_CAPAB_SIZE +
    252 			   HE_MAX_MCS_CAPAB_SIZE +
    253 			   HE_MAX_PPET_CAPAB_SIZE;
    254 		buf_len += 3 + sizeof(struct ieee80211_he_operation);
    255 		if (is_6ghz_op_class(bss->iconf->op_class))
    256 			buf_len += sizeof(struct ieee80211_he_6ghz_oper_info) +
    257 				3 + sizeof(struct ieee80211_he_6ghz_band_cap);
    258 	}
    259 #endif /* CONFIG_IEEE80211AX */
    260 	if (type != PLINK_CLOSE)
    261 		buf_len += conf->rsn_ie_len; /* RSN IE */
    262 #ifdef CONFIG_OCV
    263 	/* OCI is included even when the other STA doesn't support OCV */
    264 	if (type != PLINK_CLOSE && conf->ocv)
    265 		buf_len += OCV_OCI_EXTENDED_LEN;
    266 #endif /* CONFIG_OCV */
    267 #ifdef CONFIG_IEEE80211BE
    268 	if (type != PLINK_CLOSE && wpa_s->mesh_eht_enabled) {
    269 		buf_len += 3 + 2 + EHT_PHY_CAPAB_LEN + EHT_MCS_NSS_CAPAB_LEN +
    270 			EHT_PPE_THRESH_CAPAB_LEN;
    271 		buf_len += 3 + sizeof(struct ieee80211_eht_operation);
    272 }
    273 #endif /* CONFIG_IEEE80211BE */
    274 
    275 	buf = wpabuf_alloc(buf_len);
    276 	if (!buf)
    277 		return;
    278 
    279 	cat = wpabuf_mhead_u8(buf);
    280 	wpabuf_put_u8(buf, WLAN_ACTION_SELF_PROTECTED);
    281 	wpabuf_put_u8(buf, type);
    282 
    283 	if (type != PLINK_CLOSE) {
    284 		u8 info;
    285 
    286 		/* capability info */
    287 		wpabuf_put_le16(buf, ampe ? IEEE80211_CAP_PRIVACY : 0);
    288 
    289 		/* aid */
    290 		if (type == PLINK_CONFIRM)
    291 			wpabuf_put_le16(buf, sta->aid);
    292 
    293 		/* IE: supp + ext. supp rates */
    294 		pos = hostapd_eid_supp_rates(bss, supp_rates);
    295 		pos = hostapd_eid_ext_supp_rates(bss, pos);
    296 		wpabuf_put_data(buf, supp_rates, pos - supp_rates);
    297 
    298 		/* IE: RSN IE */
    299 		wpabuf_put_data(buf, conf->rsn_ie, conf->rsn_ie_len);
    300 
    301 		/* IE: Mesh ID */
    302 		wpabuf_put_u8(buf, WLAN_EID_MESH_ID);
    303 		wpabuf_put_u8(buf, conf->meshid_len);
    304 		wpabuf_put_data(buf, conf->meshid, conf->meshid_len);
    305 
    306 		/* IE: mesh conf */
    307 		wpabuf_put_u8(buf, WLAN_EID_MESH_CONFIG);
    308 		wpabuf_put_u8(buf, 7);
    309 		wpabuf_put_u8(buf, conf->mesh_pp_id);
    310 		wpabuf_put_u8(buf, conf->mesh_pm_id);
    311 		wpabuf_put_u8(buf, conf->mesh_cc_id);
    312 		wpabuf_put_u8(buf, conf->mesh_sp_id);
    313 		wpabuf_put_u8(buf, conf->mesh_auth_id);
    314 		info = (bss->num_plinks > 63 ? 63 : bss->num_plinks) << 1;
    315 		/* TODO: Add Connected to Mesh Gate/AS subfields */
    316 		wpabuf_put_u8(buf, info);
    317 		/* Set forwarding based on configuration and always accept
    318 		 * plinks for now */
    319 		wpabuf_put_u8(buf, MESH_CAP_ACCEPT_ADDITIONAL_PEER |
    320 			      (conf->mesh_fwding ? MESH_CAP_FORWARDING : 0));
    321 	} else {	/* Peer closing frame */
    322 		/* IE: Mesh ID */
    323 		wpabuf_put_u8(buf, WLAN_EID_MESH_ID);
    324 		wpabuf_put_u8(buf, conf->meshid_len);
    325 		wpabuf_put_data(buf, conf->meshid, conf->meshid_len);
    326 	}
    327 
    328 	/* IE: Mesh Peering Management element */
    329 	ie_len = 4;
    330 	if (ampe)
    331 		ie_len += PMKID_LEN;
    332 	switch (type) {
    333 	case PLINK_OPEN:
    334 		break;
    335 	case PLINK_CONFIRM:
    336 		ie_len += 2;
    337 		add_plid = 1;
    338 		break;
    339 	case PLINK_CLOSE:
    340 		ie_len += 2;
    341 		add_plid = 1;
    342 		ie_len += 2; /* reason code */
    343 		break;
    344 	}
    345 
    346 	wpabuf_put_u8(buf, WLAN_EID_PEER_MGMT);
    347 	wpabuf_put_u8(buf, ie_len);
    348 	/* peering protocol */
    349 	if (ampe)
    350 		wpabuf_put_le16(buf, 1);
    351 	else
    352 		wpabuf_put_le16(buf, 0);
    353 	wpabuf_put_le16(buf, sta->my_lid);
    354 	if (add_plid)
    355 		wpabuf_put_le16(buf, sta->peer_lid);
    356 	if (type == PLINK_CLOSE)
    357 		wpabuf_put_le16(buf, close_reason);
    358 	if (ampe) {
    359 		if (sta->sae == NULL) {
    360 			wpa_msg(wpa_s, MSG_INFO, "Mesh MPM: no SAE session");
    361 			goto fail;
    362 		}
    363 		mesh_rsn_get_pmkid(wpa_s->mesh_rsn, sta,
    364 				   wpabuf_put(buf, PMKID_LEN));
    365 	}
    366 
    367 	if (type != PLINK_CLOSE && wpa_s->mesh_ht_enabled) {
    368 		u8 ht_capa_oper[2 + 26 + 2 + 22];
    369 
    370 		pos = hostapd_eid_ht_capabilities(bss, ht_capa_oper);
    371 		pos = hostapd_eid_ht_operation(bss, pos);
    372 		wpabuf_put_data(buf, ht_capa_oper, pos - ht_capa_oper);
    373 	}
    374 #ifdef CONFIG_IEEE80211AC
    375 	if (type != PLINK_CLOSE && wpa_s->mesh_vht_enabled) {
    376 		u8 vht_capa_oper[2 + 12 + 2 + 5];
    377 
    378 		pos = hostapd_eid_vht_capabilities(bss, vht_capa_oper, 0);
    379 		pos = hostapd_eid_vht_operation(bss, pos);
    380 		wpabuf_put_data(buf, vht_capa_oper, pos - vht_capa_oper);
    381 	}
    382 #endif /* CONFIG_IEEE80211AC */
    383 #ifdef CONFIG_IEEE80211AX
    384 	if (type != PLINK_CLOSE && wpa_s->mesh_he_enabled) {
    385 		u8 he_capa_oper[3 +
    386 				HE_MAX_MAC_CAPAB_SIZE +
    387 				HE_MAX_PHY_CAPAB_SIZE +
    388 				HE_MAX_MCS_CAPAB_SIZE +
    389 				HE_MAX_PPET_CAPAB_SIZE +
    390 				3 + sizeof(struct ieee80211_he_operation) +
    391 				sizeof(struct ieee80211_he_6ghz_oper_info) +
    392 				3 + sizeof(struct ieee80211_he_6ghz_band_cap)];
    393 
    394 		pos = hostapd_eid_he_capab(bss, he_capa_oper,
    395 					   IEEE80211_MODE_MESH);
    396 		pos = hostapd_eid_he_operation(bss, pos);
    397 		pos = hostapd_eid_he_6ghz_band_cap(bss, pos);
    398 		wpabuf_put_data(buf, he_capa_oper, pos - he_capa_oper);
    399 	}
    400 #endif /* CONFIG_IEEE80211AX */
    401 #ifdef CONFIG_OCV
    402 	if (type != PLINK_CLOSE && conf->ocv) {
    403 		struct wpa_channel_info ci;
    404 
    405 		if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
    406 			wpa_printf(MSG_WARNING,
    407 				   "Mesh MPM: Failed to get channel info for OCI element");
    408 			goto fail;
    409 		}
    410 
    411 		pos = wpabuf_put(buf, OCV_OCI_EXTENDED_LEN);
    412 		if (ocv_insert_extended_oci(&ci, pos) < 0)
    413 			goto fail;
    414 	}
    415 #endif /* CONFIG_OCV */
    416 
    417 #ifdef CONFIG_IEEE80211BE
    418 	if (type != PLINK_CLOSE && wpa_s->mesh_eht_enabled) {
    419 		u8 eht_capa_oper[3 +
    420 				 2 +
    421 				 EHT_PHY_CAPAB_LEN +
    422 				 EHT_MCS_NSS_CAPAB_LEN +
    423 				 EHT_PPE_THRESH_CAPAB_LEN +
    424 				 3 + sizeof(struct ieee80211_eht_operation)];
    425 		pos = hostapd_eid_eht_capab(bss, eht_capa_oper,
    426 					    IEEE80211_MODE_MESH);
    427 		pos = hostapd_eid_eht_operation(bss, pos);
    428 		wpabuf_put_data(buf, eht_capa_oper, pos - eht_capa_oper);
    429 	}
    430 #endif /* CONFIG_IEEE80211BE */
    431 
    432 	if (ampe && mesh_rsn_protect_frame(wpa_s->mesh_rsn, sta, cat, buf)) {
    433 		wpa_msg(wpa_s, MSG_INFO,
    434 			"Mesh MPM: failed to add AMPE and MIC IE");
    435 		goto fail;
    436 	}
    437 
    438 	wpa_msg(wpa_s, MSG_DEBUG, "Mesh MPM: Sending peering frame type %d to "
    439 		MACSTR " (my_lid=0x%x peer_lid=0x%x)",
    440 		type, MAC2STR(sta->addr), sta->my_lid, sta->peer_lid);
    441 	ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0,
    442 				  sta->addr, wpa_s->own_addr, wpa_s->own_addr,
    443 				  wpabuf_head(buf), wpabuf_len(buf), 0);
    444 	if (ret < 0)
    445 		wpa_msg(wpa_s, MSG_INFO,
    446 			"Mesh MPM: failed to send peering frame");
    447 
    448 fail:
    449 	wpabuf_free(buf);
    450 }
    451 
    452 
    453 /* configure peering state in ours and driver's station entry */
    454 void wpa_mesh_set_plink_state(struct wpa_supplicant *wpa_s,
    455 			      struct sta_info *sta,
    456 			      enum mesh_plink_state state)
    457 {
    458 	struct hostapd_sta_add_params params;
    459 	int ret;
    460 
    461 	wpa_msg(wpa_s, MSG_DEBUG, "MPM set " MACSTR " from %s into %s",
    462 		MAC2STR(sta->addr), mplstate[sta->plink_state],
    463 		mplstate[state]);
    464 	sta->plink_state = state;
    465 
    466 	os_memset(&params, 0, sizeof(params));
    467 	params.addr = sta->addr;
    468 	params.plink_state = state;
    469 	params.peer_aid = sta->peer_aid;
    470 	params.set = 1;
    471 	params.mld_link_id = -1;
    472 
    473 	ret = wpa_drv_sta_add(wpa_s, &params);
    474 	if (ret) {
    475 		wpa_msg(wpa_s, MSG_ERROR, "Driver failed to set " MACSTR
    476 			": %d", MAC2STR(sta->addr), ret);
    477 	}
    478 }
    479 
    480 
    481 static void mesh_mpm_fsm_restart(struct wpa_supplicant *wpa_s,
    482 				 struct sta_info *sta)
    483 {
    484 	struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
    485 
    486 	eloop_cancel_timeout(plink_timer, wpa_s, sta);
    487 
    488 	ap_free_sta(hapd, sta);
    489 }
    490 
    491 
    492 static void plink_timer(void *eloop_ctx, void *user_data)
    493 {
    494 	struct wpa_supplicant *wpa_s = eloop_ctx;
    495 	struct sta_info *sta = user_data;
    496 	u16 reason = 0;
    497 	struct mesh_conf *conf = wpa_s->ifmsh->mconf;
    498 	struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
    499 
    500 	switch (sta->plink_state) {
    501 	case PLINK_OPN_RCVD:
    502 	case PLINK_OPN_SNT:
    503 		/* retry timer */
    504 		if (sta->mpm_retries < conf->dot11MeshMaxRetries) {
    505 			eloop_register_timeout(
    506 				conf->dot11MeshRetryTimeout / 1000,
    507 				(conf->dot11MeshRetryTimeout % 1000) * 1000,
    508 				plink_timer, wpa_s, sta);
    509 			mesh_mpm_send_plink_action(wpa_s, sta, PLINK_OPEN, 0);
    510 			sta->mpm_retries++;
    511 			break;
    512 		}
    513 		reason = WLAN_REASON_MESH_MAX_RETRIES;
    514 		/* fall through */
    515 
    516 	case PLINK_CNF_RCVD:
    517 		/* confirm timer */
    518 		if (!reason)
    519 			reason = WLAN_REASON_MESH_CONFIRM_TIMEOUT;
    520 		wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
    521 		eloop_register_timeout(conf->dot11MeshHoldingTimeout / 1000,
    522 			(conf->dot11MeshHoldingTimeout % 1000) * 1000,
    523 			plink_timer, wpa_s, sta);
    524 		mesh_mpm_send_plink_action(wpa_s, sta, PLINK_CLOSE, reason);
    525 		break;
    526 	case PLINK_HOLDING:
    527 		/* holding timer */
    528 
    529 		if (sta->mesh_sae_pmksa_caching) {
    530 			wpa_printf(MSG_DEBUG, "MPM: Peer " MACSTR
    531 				   " looks like it does not support mesh SAE PMKSA caching, so remove the cached entry for it",
    532 				   MAC2STR(sta->addr));
    533 			wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
    534 		}
    535 		mesh_mpm_fsm_restart(wpa_s, sta);
    536 		break;
    537 	default:
    538 		break;
    539 	}
    540 }
    541 
    542 
    543 /* initiate peering with station */
    544 static void
    545 mesh_mpm_plink_open(struct wpa_supplicant *wpa_s, struct sta_info *sta,
    546 		    enum mesh_plink_state next_state)
    547 {
    548 	struct mesh_conf *conf = wpa_s->ifmsh->mconf;
    549 
    550 	eloop_cancel_timeout(plink_timer, wpa_s, sta);
    551 	eloop_register_timeout(conf->dot11MeshRetryTimeout / 1000,
    552 			       (conf->dot11MeshRetryTimeout % 1000) * 1000,
    553 			       plink_timer, wpa_s, sta);
    554 	mesh_mpm_send_plink_action(wpa_s, sta, PLINK_OPEN, 0);
    555 	wpa_mesh_set_plink_state(wpa_s, sta, next_state);
    556 }
    557 
    558 
    559 static int mesh_mpm_plink_close(struct hostapd_data *hapd, struct sta_info *sta,
    560 				void *ctx)
    561 {
    562 	struct wpa_supplicant *wpa_s = ctx;
    563 	int reason = WLAN_REASON_MESH_PEERING_CANCELLED;
    564 
    565 	if (sta) {
    566 		if (sta->plink_state == PLINK_ESTAB) {
    567 			hapd->num_plinks--;
    568 			wpas_notify_mesh_peer_disconnected(
    569 				wpa_s, sta->addr, WLAN_REASON_UNSPECIFIED);
    570 		}
    571 		wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
    572 		mesh_mpm_send_plink_action(wpa_s, sta, PLINK_CLOSE, reason);
    573 		wpa_printf(MSG_DEBUG, "MPM closing plink sta=" MACSTR,
    574 			   MAC2STR(sta->addr));
    575 		eloop_cancel_timeout(plink_timer, wpa_s, sta);
    576 		eloop_cancel_timeout(mesh_auth_timer, wpa_s, sta);
    577 		return 0;
    578 	}
    579 
    580 	return 1;
    581 }
    582 
    583 
    584 int mesh_mpm_close_peer(struct wpa_supplicant *wpa_s, const u8 *addr)
    585 {
    586 	struct hostapd_data *hapd;
    587 	struct sta_info *sta;
    588 
    589 	if (!wpa_s->ifmsh) {
    590 		wpa_msg(wpa_s, MSG_INFO, "Mesh is not prepared yet");
    591 		return -1;
    592 	}
    593 
    594 	hapd = wpa_s->ifmsh->bss[0];
    595 	sta = ap_get_sta(hapd, addr);
    596 	if (!sta) {
    597 		wpa_msg(wpa_s, MSG_INFO, "No such mesh peer");
    598 		return -1;
    599 	}
    600 
    601 	return mesh_mpm_plink_close(hapd, sta, wpa_s) == 0 ? 0 : -1;
    602 }
    603 
    604 
    605 static void peer_add_timer(void *eloop_ctx, void *user_data)
    606 {
    607 	struct wpa_supplicant *wpa_s = eloop_ctx;
    608 	struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
    609 
    610 	os_memset(hapd->mesh_required_peer, 0, ETH_ALEN);
    611 }
    612 
    613 
    614 int mesh_mpm_connect_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
    615 			  int duration)
    616 {
    617 	struct wpa_ssid *ssid = wpa_s->current_ssid;
    618 	struct hostapd_data *hapd;
    619 	struct sta_info *sta;
    620 	struct mesh_conf *conf;
    621 
    622 	if (!wpa_s->ifmsh) {
    623 		wpa_msg(wpa_s, MSG_INFO, "Mesh is not prepared yet");
    624 		return -1;
    625 	}
    626 
    627 	if (!ssid || !ssid->no_auto_peer) {
    628 		wpa_msg(wpa_s, MSG_INFO,
    629 			"This command is available only with no_auto_peer mesh network");
    630 		return -1;
    631 	}
    632 
    633 	hapd = wpa_s->ifmsh->bss[0];
    634 	conf = wpa_s->ifmsh->mconf;
    635 
    636 	sta = ap_get_sta(hapd, addr);
    637 	if (!sta) {
    638 		wpa_msg(wpa_s, MSG_INFO, "No such mesh peer");
    639 		return -1;
    640 	}
    641 
    642 	if ((PLINK_OPN_SNT <= sta->plink_state &&
    643 	    sta->plink_state <= PLINK_ESTAB) ||
    644 	    (sta->sae && sta->sae->state > SAE_NOTHING)) {
    645 		wpa_msg(wpa_s, MSG_INFO,
    646 			"Specified peer is connecting/connected");
    647 		return -1;
    648 	}
    649 
    650 	if (conf->security == MESH_CONF_SEC_NONE) {
    651 		mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_SNT);
    652 	} else {
    653 		mesh_rsn_auth_sae_sta(wpa_s, sta);
    654 		os_memcpy(hapd->mesh_required_peer, addr, ETH_ALEN);
    655 		eloop_register_timeout(duration == -1 ? 10 : duration, 0,
    656 				       peer_add_timer, wpa_s, NULL);
    657 	}
    658 
    659 	return 0;
    660 }
    661 
    662 
    663 void mesh_mpm_deinit(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh)
    664 {
    665 	struct hostapd_data *hapd = ifmsh->bss[0];
    666 
    667 	/* notify peers we're leaving */
    668 	ap_for_each_sta(hapd, mesh_mpm_plink_close, wpa_s);
    669 
    670 	hapd->num_plinks = 0;
    671 	hostapd_free_stas(hapd);
    672 	eloop_cancel_timeout(peer_add_timer, wpa_s, NULL);
    673 }
    674 
    675 
    676 /* for mesh_rsn to indicate this peer has completed authentication, and we're
    677  * ready to start AMPE */
    678 void mesh_mpm_auth_peer(struct wpa_supplicant *wpa_s, const u8 *addr)
    679 {
    680 	struct hostapd_data *data = wpa_s->ifmsh->bss[0];
    681 	struct hostapd_sta_add_params params;
    682 	struct sta_info *sta;
    683 	int ret;
    684 
    685 	sta = ap_get_sta(data, addr);
    686 	if (!sta) {
    687 		wpa_msg(wpa_s, MSG_DEBUG, "no such mesh peer");
    688 		return;
    689 	}
    690 
    691 	/* TODO: Should do nothing if this STA is already authenticated, but
    692 	 * the AP code already sets this flag. */
    693 	sta->flags |= WLAN_STA_AUTH;
    694 
    695 	mesh_rsn_init_ampe_sta(wpa_s, sta);
    696 
    697 	os_memset(&params, 0, sizeof(params));
    698 	params.addr = sta->addr;
    699 	params.flags = WPA_STA_AUTHENTICATED | WPA_STA_AUTHORIZED;
    700 	params.set = 1;
    701 	params.mld_link_id = -1;
    702 
    703 	wpa_msg(wpa_s, MSG_DEBUG, "MPM authenticating " MACSTR,
    704 		MAC2STR(sta->addr));
    705 	ret = wpa_drv_sta_add(wpa_s, &params);
    706 	if (ret) {
    707 		wpa_msg(wpa_s, MSG_ERROR,
    708 			"Driver failed to set " MACSTR ": %d",
    709 			MAC2STR(sta->addr), ret);
    710 	}
    711 
    712 	if (!sta->my_lid)
    713 		mesh_mpm_init_link(wpa_s, sta);
    714 
    715 	mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_SNT);
    716 }
    717 
    718 /*
    719  * Initialize a sta_info structure for a peer and upload it into the driver
    720  * in preparation for beginning authentication or peering. This is done when a
    721  * Beacon (secure or open mesh) or a peering open frame (for open mesh) is
    722  * received from the peer for the first time.
    723  */
    724 static struct sta_info * mesh_mpm_add_peer(struct wpa_supplicant *wpa_s,
    725 					   const u8 *addr,
    726 					   struct ieee802_11_elems *elems)
    727 {
    728 	struct hostapd_sta_add_params params;
    729 	struct mesh_conf *conf = wpa_s->ifmsh->mconf;
    730 	struct hostapd_data *data = wpa_s->ifmsh->bss[0];
    731 	struct sta_info *sta;
    732 	struct ieee80211_ht_operation *oper;
    733 	int ret;
    734 
    735 	if (elems->mesh_config_len >= 7 &&
    736 	    !(elems->mesh_config[6] & MESH_CAP_ACCEPT_ADDITIONAL_PEER)) {
    737 		wpa_msg(wpa_s, MSG_DEBUG,
    738 			"mesh: Ignore a crowded peer " MACSTR,
    739 			MAC2STR(addr));
    740 		return NULL;
    741 	}
    742 
    743 	sta = ap_get_sta(data, addr);
    744 	if (sta)
    745 		return NULL;
    746 
    747 	sta = ap_sta_add(data, addr);
    748 	if (!sta)
    749 		return NULL;
    750 
    751 	/* Set WMM by default since Mesh STAs are QoS STAs */
    752 	sta->flags |= WLAN_STA_WMM;
    753 
    754 	/* initialize sta */
    755 	if (copy_supp_rates(wpa_s, sta, elems)) {
    756 		ap_free_sta(data, sta);
    757 		return NULL;
    758 	}
    759 
    760 	if (!sta->my_lid)
    761 		mesh_mpm_init_link(wpa_s, sta);
    762 
    763 	copy_sta_ht_capab(data, sta, elems->ht_capabilities);
    764 
    765 	oper = (struct ieee80211_ht_operation *) elems->ht_operation;
    766 	if (oper &&
    767 	    !(oper->ht_param & HT_INFO_HT_PARAM_STA_CHNL_WIDTH) &&
    768 	    sta->ht_capabilities) {
    769 		wpa_msg(wpa_s, MSG_DEBUG, MACSTR
    770 			" does not support 40 MHz bandwidth",
    771 			MAC2STR(sta->addr));
    772 		set_disable_ht40(sta->ht_capabilities, 1);
    773 	}
    774 
    775 	if (update_ht_state(data, sta) > 0)
    776 		ieee802_11_update_beacons(data->iface);
    777 
    778 #ifdef CONFIG_IEEE80211AC
    779 	copy_sta_vht_capab(data, sta, elems->vht_capabilities);
    780 	copy_sta_vht_oper(data, sta, elems->vht_operation);
    781 	set_sta_vht_opmode(data, sta, elems->opmode_notif);
    782 #endif /* CONFIG_IEEE80211AC */
    783 
    784 #ifdef CONFIG_IEEE80211AX
    785 	copy_sta_he_capab(data, sta, IEEE80211_MODE_MESH,
    786 			  elems->he_capabilities, elems->he_capabilities_len);
    787 	copy_sta_he_6ghz_capab(data, sta, elems->he_6ghz_band_cap);
    788 #endif /* CONFIG_IEEE80211AX */
    789 #ifdef CONFIG_IEEE80211BE
    790 	copy_sta_eht_capab(data, sta, IEEE80211_MODE_MESH,
    791 			   elems->he_capabilities,
    792 			   elems->he_capabilities_len,
    793 			   elems->eht_capabilities,
    794 			   elems->eht_capabilities_len);
    795 #endif /*CONFIG_IEEE80211BE */
    796 
    797 	if (hostapd_get_aid(data, sta) < 0) {
    798 		wpa_msg(wpa_s, MSG_ERROR, "No AIDs available");
    799 		ap_free_sta(data, sta);
    800 		return NULL;
    801 	}
    802 
    803 	/* insert into driver */
    804 	os_memset(&params, 0, sizeof(params));
    805 	params.supp_rates = sta->supported_rates;
    806 	params.supp_rates_len = sta->supported_rates_len;
    807 	params.addr = addr;
    808 	params.plink_state = sta->plink_state;
    809 	params.aid = sta->aid;
    810 	params.peer_aid = sta->peer_aid;
    811 	params.listen_interval = 100;
    812 	params.ht_capabilities = sta->ht_capabilities;
    813 	params.vht_capabilities = sta->vht_capabilities;
    814 	params.he_capab = sta->he_capab;
    815 	params.he_capab_len = sta->he_capab_len;
    816 	params.he_6ghz_capab = sta->he_6ghz_capab;
    817 	params.eht_capab = sta->eht_capab;
    818 	params.eht_capab_len = sta->eht_capab_len;
    819 	params.flags |= WPA_STA_WMM;
    820 	params.flags_mask |= WPA_STA_AUTHENTICATED;
    821 	params.mld_link_id = -1;
    822 	if (conf->security == MESH_CONF_SEC_NONE) {
    823 		params.flags |= WPA_STA_AUTHORIZED;
    824 		params.flags |= WPA_STA_AUTHENTICATED;
    825 	} else {
    826 		sta->flags |= WLAN_STA_MFP;
    827 		params.flags |= WPA_STA_MFP;
    828 	}
    829 
    830 	ret = wpa_drv_sta_add(wpa_s, &params);
    831 	if (ret) {
    832 		wpa_msg(wpa_s, MSG_ERROR,
    833 			"Driver failed to insert " MACSTR ": %d",
    834 			MAC2STR(addr), ret);
    835 		ap_free_sta(data, sta);
    836 		return NULL;
    837 	}
    838 
    839 	return sta;
    840 }
    841 
    842 
    843 void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
    844 			    struct ieee802_11_elems *elems)
    845 {
    846 	struct mesh_conf *conf = wpa_s->ifmsh->mconf;
    847 	struct hostapd_data *data = wpa_s->ifmsh->bss[0];
    848 	struct sta_info *sta;
    849 	struct wpa_ssid *ssid = wpa_s->current_ssid;
    850 
    851 	sta = mesh_mpm_add_peer(wpa_s, addr, elems);
    852 	if (!sta)
    853 		return;
    854 
    855 	if (ssid && ssid->no_auto_peer &&
    856 	    (is_zero_ether_addr(data->mesh_required_peer) ||
    857 	     !ether_addr_equal(data->mesh_required_peer, addr))) {
    858 		wpa_msg(wpa_s, MSG_INFO, "will not initiate new peer link with "
    859 			MACSTR " because of no_auto_peer", MAC2STR(addr));
    860 		if (data->mesh_pending_auth) {
    861 			struct os_reltime age;
    862 			const struct ieee80211_mgmt *mgmt;
    863 			struct hostapd_frame_info fi;
    864 
    865 			mgmt = wpabuf_head(data->mesh_pending_auth);
    866 			os_reltime_age(&data->mesh_pending_auth_time, &age);
    867 			if (age.sec < 2 &&
    868 			    ether_addr_equal(mgmt->sa, addr)) {
    869 				wpa_printf(MSG_DEBUG,
    870 					   "mesh: Process pending Authentication frame from %u.%06u seconds ago",
    871 					   (unsigned int) age.sec,
    872 					   (unsigned int) age.usec);
    873 				os_memset(&fi, 0, sizeof(fi));
    874 				ieee802_11_mgmt(
    875 					data,
    876 					wpabuf_head(data->mesh_pending_auth),
    877 					wpabuf_len(data->mesh_pending_auth),
    878 					&fi);
    879 			}
    880 			wpabuf_free(data->mesh_pending_auth);
    881 			data->mesh_pending_auth = NULL;
    882 		}
    883 		return;
    884 	}
    885 
    886 	if (conf->security == MESH_CONF_SEC_NONE) {
    887 		if (sta->plink_state < PLINK_OPN_SNT ||
    888 		    sta->plink_state > PLINK_ESTAB)
    889 			mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_SNT);
    890 	} else {
    891 		mesh_rsn_auth_sae_sta(wpa_s, sta);
    892 	}
    893 }
    894 
    895 
    896 void mesh_mpm_mgmt_rx(struct wpa_supplicant *wpa_s, struct rx_mgmt *rx_mgmt)
    897 {
    898 	struct hostapd_frame_info fi;
    899 
    900 	os_memset(&fi, 0, sizeof(fi));
    901 	fi.datarate = rx_mgmt->datarate;
    902 	fi.ssi_signal = rx_mgmt->ssi_signal;
    903 	ieee802_11_mgmt(wpa_s->ifmsh->bss[0], rx_mgmt->frame,
    904 			rx_mgmt->frame_len, &fi);
    905 }
    906 
    907 
    908 static void mesh_mpm_plink_estab(struct wpa_supplicant *wpa_s,
    909 				 struct sta_info *sta)
    910 {
    911 	struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
    912 	struct mesh_conf *conf = wpa_s->ifmsh->mconf;
    913 	u8 seq[6] = {};
    914 
    915 	wpa_msg(wpa_s, MSG_INFO, "mesh plink with " MACSTR " established",
    916 		MAC2STR(sta->addr));
    917 
    918 	if (conf->security & MESH_CONF_SEC_AMPE) {
    919 		wpa_hexdump_key(MSG_DEBUG, "mesh: MTK", sta->mtk, sta->mtk_len);
    920 		wpa_drv_set_key(wpa_s, -1,
    921 				wpa_cipher_to_alg(conf->pairwise_cipher),
    922 				sta->addr, 0, 0, seq, sizeof(seq),
    923 				sta->mtk, sta->mtk_len,
    924 				KEY_FLAG_PAIRWISE_RX_TX);
    925 
    926 		wpa_hexdump_key(MSG_DEBUG, "mesh: RX MGTK Key RSC",
    927 				sta->mgtk_rsc, sizeof(sta->mgtk_rsc));
    928 		wpa_hexdump_key(MSG_DEBUG, "mesh: RX MGTK",
    929 				sta->mgtk, sta->mgtk_len);
    930 		wpa_drv_set_key(wpa_s, -1,
    931 				wpa_cipher_to_alg(conf->group_cipher),
    932 				sta->addr, sta->mgtk_key_id, 0,
    933 				sta->mgtk_rsc, sizeof(sta->mgtk_rsc),
    934 				sta->mgtk, sta->mgtk_len,
    935 				KEY_FLAG_GROUP_RX);
    936 
    937 		if (sta->igtk_len) {
    938 			wpa_hexdump_key(MSG_DEBUG, "mesh: RX IGTK Key RSC",
    939 					sta->igtk_rsc, sizeof(sta->igtk_rsc));
    940 			wpa_hexdump_key(MSG_DEBUG, "mesh: RX IGTK",
    941 					sta->igtk, sta->igtk_len);
    942 			wpa_drv_set_key(
    943 				wpa_s, -1,
    944 				wpa_cipher_to_alg(conf->mgmt_group_cipher),
    945 				sta->addr, sta->igtk_key_id, 0,
    946 				sta->igtk_rsc, sizeof(sta->igtk_rsc),
    947 				sta->igtk, sta->igtk_len,
    948 				KEY_FLAG_GROUP_RX);
    949 		}
    950 	}
    951 
    952 	wpa_mesh_set_plink_state(wpa_s, sta, PLINK_ESTAB);
    953 	hapd->num_plinks++;
    954 
    955 	sta->flags |= WLAN_STA_ASSOC;
    956 	sta->mesh_sae_pmksa_caching = 0;
    957 
    958 	eloop_cancel_timeout(peer_add_timer, wpa_s, NULL);
    959 	peer_add_timer(wpa_s, NULL);
    960 	eloop_cancel_timeout(plink_timer, wpa_s, sta);
    961 
    962 	wpas_notify_mesh_peer_connected(wpa_s, sta->addr);
    963 }
    964 
    965 
    966 static void mesh_mpm_fsm(struct wpa_supplicant *wpa_s, struct sta_info *sta,
    967 			 enum plink_event event, u16 reason)
    968 {
    969 	struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
    970 	struct mesh_conf *conf = wpa_s->ifmsh->mconf;
    971 
    972 	wpa_msg(wpa_s, MSG_DEBUG, "MPM " MACSTR " state %s event %s",
    973 		MAC2STR(sta->addr), mplstate[sta->plink_state],
    974 		mplevent[event]);
    975 
    976 	switch (sta->plink_state) {
    977 	case PLINK_IDLE:
    978 		switch (event) {
    979 		case CLS_ACPT:
    980 			mesh_mpm_fsm_restart(wpa_s, sta);
    981 			break;
    982 		case OPN_ACPT:
    983 			mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_RCVD);
    984 			mesh_mpm_send_plink_action(wpa_s, sta, PLINK_CONFIRM,
    985 						   0);
    986 			break;
    987 		case REQ_RJCT:
    988 			mesh_mpm_send_plink_action(wpa_s, sta,
    989 						   PLINK_CLOSE, reason);
    990 			break;
    991 		default:
    992 			break;
    993 		}
    994 		break;
    995 	case PLINK_OPN_SNT:
    996 		switch (event) {
    997 		case OPN_RJCT:
    998 		case CNF_RJCT:
    999 			if (!reason)
   1000 				reason = WLAN_REASON_MESH_CONFIG_POLICY_VIOLATION;
   1001 			/* fall-through */
   1002 		case CLS_ACPT:
   1003 			wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
   1004 			if (!reason)
   1005 				reason = WLAN_REASON_MESH_CLOSE_RCVD;
   1006 			eloop_register_timeout(
   1007 				conf->dot11MeshHoldingTimeout / 1000,
   1008 				(conf->dot11MeshHoldingTimeout % 1000) * 1000,
   1009 				plink_timer, wpa_s, sta);
   1010 			mesh_mpm_send_plink_action(wpa_s, sta,
   1011 						   PLINK_CLOSE, reason);
   1012 			break;
   1013 		case OPN_ACPT:
   1014 			/* retry timer is left untouched */
   1015 			wpa_mesh_set_plink_state(wpa_s, sta, PLINK_OPN_RCVD);
   1016 			mesh_mpm_send_plink_action(wpa_s, sta,
   1017 						   PLINK_CONFIRM, 0);
   1018 			break;
   1019 		case CNF_ACPT:
   1020 			wpa_mesh_set_plink_state(wpa_s, sta, PLINK_CNF_RCVD);
   1021 			eloop_cancel_timeout(plink_timer, wpa_s, sta);
   1022 			eloop_register_timeout(
   1023 				conf->dot11MeshConfirmTimeout / 1000,
   1024 				(conf->dot11MeshConfirmTimeout % 1000) * 1000,
   1025 				plink_timer, wpa_s, sta);
   1026 			break;
   1027 		default:
   1028 			break;
   1029 		}
   1030 		break;
   1031 	case PLINK_OPN_RCVD:
   1032 		switch (event) {
   1033 		case OPN_RJCT:
   1034 		case CNF_RJCT:
   1035 			if (!reason)
   1036 				reason = WLAN_REASON_MESH_CONFIG_POLICY_VIOLATION;
   1037 			/* fall-through */
   1038 		case CLS_ACPT:
   1039 			wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
   1040 			if (!reason)
   1041 				reason = WLAN_REASON_MESH_CLOSE_RCVD;
   1042 			eloop_register_timeout(
   1043 				conf->dot11MeshHoldingTimeout / 1000,
   1044 				(conf->dot11MeshHoldingTimeout % 1000) * 1000,
   1045 				plink_timer, wpa_s, sta);
   1046 			sta->mpm_close_reason = reason;
   1047 			mesh_mpm_send_plink_action(wpa_s, sta,
   1048 						   PLINK_CLOSE, reason);
   1049 			break;
   1050 		case OPN_ACPT:
   1051 			mesh_mpm_send_plink_action(wpa_s, sta,
   1052 						   PLINK_CONFIRM, 0);
   1053 			break;
   1054 		case CNF_ACPT:
   1055 			if (conf->security & MESH_CONF_SEC_AMPE)
   1056 				mesh_rsn_derive_mtk(wpa_s, sta);
   1057 			mesh_mpm_plink_estab(wpa_s, sta);
   1058 			break;
   1059 		default:
   1060 			break;
   1061 		}
   1062 		break;
   1063 	case PLINK_CNF_RCVD:
   1064 		switch (event) {
   1065 		case OPN_RJCT:
   1066 		case CNF_RJCT:
   1067 			if (!reason)
   1068 				reason = WLAN_REASON_MESH_CONFIG_POLICY_VIOLATION;
   1069 			/* fall-through */
   1070 		case CLS_ACPT:
   1071 			wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
   1072 			if (!reason)
   1073 				reason = WLAN_REASON_MESH_CLOSE_RCVD;
   1074 			eloop_register_timeout(
   1075 				conf->dot11MeshHoldingTimeout / 1000,
   1076 				(conf->dot11MeshHoldingTimeout % 1000) * 1000,
   1077 				plink_timer, wpa_s, sta);
   1078 			sta->mpm_close_reason = reason;
   1079 			mesh_mpm_send_plink_action(wpa_s, sta,
   1080 						   PLINK_CLOSE, reason);
   1081 			break;
   1082 		case OPN_ACPT:
   1083 			if (conf->security & MESH_CONF_SEC_AMPE)
   1084 				mesh_rsn_derive_mtk(wpa_s, sta);
   1085 			mesh_mpm_plink_estab(wpa_s, sta);
   1086 			mesh_mpm_send_plink_action(wpa_s, sta,
   1087 						   PLINK_CONFIRM, 0);
   1088 			break;
   1089 		default:
   1090 			break;
   1091 		}
   1092 		break;
   1093 	case PLINK_ESTAB:
   1094 		switch (event) {
   1095 		case OPN_RJCT:
   1096 		case CNF_RJCT:
   1097 		case CLS_ACPT:
   1098 			wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
   1099 			if (!reason)
   1100 				reason = WLAN_REASON_MESH_CLOSE_RCVD;
   1101 
   1102 			eloop_register_timeout(
   1103 				conf->dot11MeshHoldingTimeout / 1000,
   1104 				(conf->dot11MeshHoldingTimeout % 1000) * 1000,
   1105 				plink_timer, wpa_s, sta);
   1106 			sta->mpm_close_reason = reason;
   1107 
   1108 			wpa_msg(wpa_s, MSG_INFO, "mesh plink with " MACSTR
   1109 				" closed with reason %d",
   1110 				MAC2STR(sta->addr), reason);
   1111 
   1112 			wpas_notify_mesh_peer_disconnected(wpa_s, sta->addr,
   1113 							   reason);
   1114 
   1115 			hapd->num_plinks--;
   1116 
   1117 			mesh_mpm_send_plink_action(wpa_s, sta,
   1118 						   PLINK_CLOSE, reason);
   1119 			break;
   1120 		case OPN_ACPT:
   1121 			mesh_mpm_send_plink_action(wpa_s, sta,
   1122 						   PLINK_CONFIRM, 0);
   1123 			break;
   1124 		default:
   1125 			break;
   1126 		}
   1127 		break;
   1128 	case PLINK_HOLDING:
   1129 		switch (event) {
   1130 		case CLS_ACPT:
   1131 			mesh_mpm_fsm_restart(wpa_s, sta);
   1132 			break;
   1133 		case OPN_ACPT:
   1134 		case CNF_ACPT:
   1135 		case OPN_RJCT:
   1136 		case CNF_RJCT:
   1137 			reason = sta->mpm_close_reason;
   1138 			mesh_mpm_send_plink_action(wpa_s, sta,
   1139 						   PLINK_CLOSE, reason);
   1140 			break;
   1141 		default:
   1142 			break;
   1143 		}
   1144 		break;
   1145 	default:
   1146 		wpa_msg(wpa_s, MSG_DEBUG,
   1147 			"Unsupported MPM event %s for state %s",
   1148 			mplevent[event], mplstate[sta->plink_state]);
   1149 		break;
   1150 	}
   1151 }
   1152 
   1153 
   1154 void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
   1155 			const struct ieee80211_mgmt *mgmt, size_t len)
   1156 {
   1157 	u8 action_field;
   1158 	struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
   1159 	struct mesh_conf *mconf = wpa_s->ifmsh->mconf;
   1160 	struct sta_info *sta;
   1161 	u16 plid = 0, llid = 0, aid = 0;
   1162 	enum plink_event event;
   1163 	struct ieee802_11_elems elems;
   1164 	struct mesh_peer_mgmt_ie peer_mgmt_ie;
   1165 	const u8 *ies;
   1166 	size_t ie_len;
   1167 	int ret;
   1168 	u16 reason = 0;
   1169 
   1170 	if (mgmt->u.action.category != WLAN_ACTION_SELF_PROTECTED)
   1171 		return;
   1172 
   1173 	action_field = mgmt->u.action.u.slf_prot_action.action;
   1174 	if (action_field != PLINK_OPEN &&
   1175 	    action_field != PLINK_CONFIRM &&
   1176 	    action_field != PLINK_CLOSE)
   1177 		return;
   1178 
   1179 	ies = mgmt->u.action.u.slf_prot_action.variable;
   1180 	ie_len = (const u8 *) mgmt + len -
   1181 		mgmt->u.action.u.slf_prot_action.variable;
   1182 
   1183 	/* at least expect mesh id and peering mgmt */
   1184 	if (ie_len < 2 + 2) {
   1185 		wpa_printf(MSG_DEBUG,
   1186 			   "MPM: Ignore too short action frame %u ie_len %u",
   1187 			   action_field, (unsigned int) ie_len);
   1188 		return;
   1189 	}
   1190 	wpa_printf(MSG_DEBUG, "MPM: Received PLINK action %u", action_field);
   1191 
   1192 	if (action_field == PLINK_OPEN || action_field == PLINK_CONFIRM) {
   1193 		wpa_printf(MSG_DEBUG, "MPM: Capability 0x%x",
   1194 			   WPA_GET_LE16(ies));
   1195 		ies += 2;	/* capability */
   1196 		ie_len -= 2;
   1197 	}
   1198 	if (action_field == PLINK_CONFIRM) {
   1199 		aid = WPA_GET_LE16(ies);
   1200 		wpa_printf(MSG_DEBUG, "MPM: AID 0x%x", aid);
   1201 		ies += 2;	/* aid */
   1202 		ie_len -= 2;
   1203 	}
   1204 
   1205 	/* check for mesh peering, mesh id and mesh config IEs */
   1206 	if (ieee802_11_parse_elems(ies, ie_len, &elems, 0) == ParseFailed) {
   1207 		wpa_printf(MSG_DEBUG, "MPM: Failed to parse PLINK IEs");
   1208 		return;
   1209 	}
   1210 	if (!elems.peer_mgmt) {
   1211 		wpa_printf(MSG_DEBUG,
   1212 			   "MPM: No Mesh Peering Management element");
   1213 		return;
   1214 	}
   1215 	if (action_field != PLINK_CLOSE) {
   1216 		if (!elems.mesh_id || !elems.mesh_config) {
   1217 			wpa_printf(MSG_DEBUG,
   1218 				   "MPM: No Mesh ID or Mesh Configuration element");
   1219 			return;
   1220 		}
   1221 
   1222 		if (!matches_local(wpa_s, &elems)) {
   1223 			wpa_printf(MSG_DEBUG,
   1224 				   "MPM: Mesh ID or Mesh Configuration element do not match local MBSS");
   1225 			return;
   1226 		}
   1227 	}
   1228 
   1229 	ret = mesh_mpm_parse_peer_mgmt(wpa_s, action_field,
   1230 				       elems.peer_mgmt,
   1231 				       elems.peer_mgmt_len,
   1232 				       &peer_mgmt_ie);
   1233 	if (ret) {
   1234 		wpa_printf(MSG_DEBUG, "MPM: Mesh parsing rejected frame");
   1235 		return;
   1236 	}
   1237 
   1238 	/* the sender's llid is our plid and vice-versa */
   1239 	plid = WPA_GET_LE16(peer_mgmt_ie.llid);
   1240 	if (peer_mgmt_ie.plid)
   1241 		llid = WPA_GET_LE16(peer_mgmt_ie.plid);
   1242 	wpa_printf(MSG_DEBUG, "MPM: plid=0x%x llid=0x%x", plid, llid);
   1243 
   1244 	if (action_field == PLINK_CLOSE)
   1245 		wpa_printf(MSG_DEBUG, "MPM: close reason=%u",
   1246 			   WPA_GET_LE16(peer_mgmt_ie.reason));
   1247 
   1248 	sta = ap_get_sta(hapd, mgmt->sa);
   1249 
   1250 	/*
   1251 	 * If this is an open frame from an unknown STA, and this is an
   1252 	 * open mesh, then go ahead and add the peer before proceeding.
   1253 	 */
   1254 	if (!sta && action_field == PLINK_OPEN &&
   1255 	    (!(mconf->security & MESH_CONF_SEC_AMPE) ||
   1256 	     wpa_auth_pmksa_get(hapd->wpa_auth, mgmt->sa, NULL)))
   1257 		sta = mesh_mpm_add_peer(wpa_s, mgmt->sa, &elems);
   1258 
   1259 	if (!sta) {
   1260 		wpa_printf(MSG_DEBUG, "MPM: No STA entry for peer");
   1261 		return;
   1262 	}
   1263 
   1264 #ifdef CONFIG_SAE
   1265 	/* peer is in sae_accepted? */
   1266 	if (sta->sae && sta->sae->state != SAE_ACCEPTED) {
   1267 		wpa_printf(MSG_DEBUG, "MPM: SAE not yet accepted for peer");
   1268 		return;
   1269 	}
   1270 #endif /* CONFIG_SAE */
   1271 
   1272 	if (!sta->my_lid)
   1273 		mesh_mpm_init_link(wpa_s, sta);
   1274 
   1275 	if (mconf->security & MESH_CONF_SEC_AMPE) {
   1276 		int res;
   1277 
   1278 		res = mesh_rsn_process_ampe(wpa_s, sta, &elems,
   1279 					    &mgmt->u.action.category,
   1280 					    peer_mgmt_ie.chosen_pmk,
   1281 					    ies, ie_len);
   1282 		if (res) {
   1283 			wpa_printf(MSG_DEBUG,
   1284 				   "MPM: RSN process rejected frame (res=%d)",
   1285 				   res);
   1286 			if (action_field == PLINK_OPEN && res == -2) {
   1287 				/* AES-SIV decryption failed */
   1288 				mesh_mpm_fsm(wpa_s, sta, OPN_RJCT,
   1289 					     WLAN_REASON_MESH_INVALID_GTK);
   1290 			}
   1291 			return;
   1292 		}
   1293 
   1294 #ifdef CONFIG_OCV
   1295 		if (action_field == PLINK_OPEN && elems.rsn_ie) {
   1296 			struct wpa_state_machine *sm = sta->wpa_sm;
   1297 			struct wpa_ie_data data;
   1298 
   1299 			res = wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2,
   1300 						   elems.rsn_ie_len + 2,
   1301 						   &data);
   1302 			if (res) {
   1303 				wpa_printf(MSG_DEBUG,
   1304 					   "Failed to parse RSN IE (res=%d)",
   1305 					   res);
   1306 				wpa_hexdump(MSG_DEBUG, "RSN IE", elems.rsn_ie,
   1307 					    elems.rsn_ie_len);
   1308 				return;
   1309 			}
   1310 
   1311 			wpa_auth_set_ocv(sm, mconf->ocv &&
   1312 					 (data.capabilities &
   1313 					  WPA_CAPABILITY_OCVC));
   1314 		}
   1315 
   1316 		if (action_field != PLINK_CLOSE &&
   1317 		    wpa_auth_uses_ocv(sta->wpa_sm)) {
   1318 			struct wpa_channel_info ci;
   1319 			int tx_chanwidth;
   1320 			int tx_seg1_idx;
   1321 
   1322 			if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
   1323 				wpa_printf(MSG_WARNING,
   1324 					   "MPM: Failed to get channel info to validate received OCI in MPM Confirm");
   1325 				return;
   1326 			}
   1327 
   1328 			if (get_tx_parameters(
   1329 				    sta, channel_width_to_int(ci.chanwidth),
   1330 				    ci.seg1_idx, &tx_chanwidth,
   1331 				    &tx_seg1_idx) < 0)
   1332 				return;
   1333 
   1334 			if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci,
   1335 						 tx_chanwidth, tx_seg1_idx) !=
   1336 			    OCI_SUCCESS) {
   1337 				wpa_printf(MSG_WARNING, "MPM: OCV failed: %s",
   1338 					   ocv_errorstr);
   1339 				return;
   1340 			}
   1341 		}
   1342 #endif /* CONFIG_OCV */
   1343 	}
   1344 
   1345 	if (sta->plink_state == PLINK_BLOCKED) {
   1346 		wpa_printf(MSG_DEBUG, "MPM: PLINK_BLOCKED");
   1347 		return;
   1348 	}
   1349 
   1350 	/* Now we will figure out the appropriate event... */
   1351 	switch (action_field) {
   1352 	case PLINK_OPEN:
   1353 		if (plink_free_count(hapd) == 0) {
   1354 			event = REQ_RJCT;
   1355 			reason = WLAN_REASON_MESH_MAX_PEERS;
   1356 			wpa_printf(MSG_INFO,
   1357 				   "MPM: Peer link num over quota(%d)",
   1358 				   hapd->max_plinks);
   1359 		} else if (sta->peer_lid && sta->peer_lid != plid) {
   1360 			wpa_printf(MSG_DEBUG,
   1361 				   "MPM: peer_lid mismatch: 0x%x != 0x%x",
   1362 				   sta->peer_lid, plid);
   1363 			return; /* no FSM event */
   1364 		} else {
   1365 			sta->peer_lid = plid;
   1366 			event = OPN_ACPT;
   1367 		}
   1368 		break;
   1369 	case PLINK_CONFIRM:
   1370 		if (plink_free_count(hapd) == 0) {
   1371 			event = REQ_RJCT;
   1372 			reason = WLAN_REASON_MESH_MAX_PEERS;
   1373 			wpa_printf(MSG_INFO,
   1374 				   "MPM: Peer link num over quota(%d)",
   1375 				   hapd->max_plinks);
   1376 		} else if (sta->my_lid != llid ||
   1377 			   (sta->peer_lid && sta->peer_lid != plid)) {
   1378 			wpa_printf(MSG_DEBUG,
   1379 				   "MPM: lid mismatch: my_lid: 0x%x != 0x%x or peer_lid: 0x%x != 0x%x",
   1380 				   sta->my_lid, llid, sta->peer_lid, plid);
   1381 			return; /* no FSM event */
   1382 		} else {
   1383 			if (!sta->peer_lid)
   1384 				sta->peer_lid = plid;
   1385 			sta->peer_aid = aid;
   1386 			event = CNF_ACPT;
   1387 		}
   1388 		break;
   1389 	case PLINK_CLOSE:
   1390 		if (sta->plink_state == PLINK_ESTAB)
   1391 			/* Do not check for llid or plid. This does not
   1392 			 * follow the standard but since multiple plinks
   1393 			 * per cand are not supported, it is necessary in
   1394 			 * order to avoid a livelock when MP A sees an
   1395 			 * establish peer link to MP B but MP B does not
   1396 			 * see it. This can be caused by a timeout in
   1397 			 * B's peer link establishment or B being
   1398 			 * restarted.
   1399 			 */
   1400 			event = CLS_ACPT;
   1401 		else if (sta->peer_lid != plid) {
   1402 			wpa_printf(MSG_DEBUG,
   1403 				   "MPM: peer_lid mismatch: 0x%x != 0x%x",
   1404 				   sta->peer_lid, plid);
   1405 			return; /* no FSM event */
   1406 		} else if (peer_mgmt_ie.plid && sta->my_lid != llid) {
   1407 			wpa_printf(MSG_DEBUG,
   1408 				   "MPM: my_lid mismatch: 0x%x != 0x%x",
   1409 				   sta->my_lid, llid);
   1410 			return; /* no FSM event */
   1411 		} else {
   1412 			event = CLS_ACPT;
   1413 		}
   1414 		break;
   1415 	default:
   1416 		/*
   1417 		 * This cannot be hit due to the action_field check above, but
   1418 		 * compilers may not be able to figure that out and can warn
   1419 		 * about uninitialized event below.
   1420 		 */
   1421 		return;
   1422 	}
   1423 	mesh_mpm_fsm(wpa_s, sta, event, reason);
   1424 }
   1425 
   1426 
   1427 /* called by ap_free_sta */
   1428 void mesh_mpm_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
   1429 {
   1430 	struct wpa_supplicant *wpa_s = hapd->iface->owner;
   1431 
   1432 	if (sta->plink_state == PLINK_ESTAB) {
   1433 		hapd->num_plinks--;
   1434 		wpas_notify_mesh_peer_disconnected(
   1435 			wpa_s, sta->addr, WLAN_REASON_UNSPECIFIED);
   1436 	}
   1437 	eloop_cancel_timeout(plink_timer, ELOOP_ALL_CTX, sta);
   1438 	eloop_cancel_timeout(mesh_auth_timer, ELOOP_ALL_CTX, sta);
   1439 }
   1440