xref: /freebsd/contrib/wpa/wpa_supplicant/mesh_mpm.c (revision a90b9d0159070121c221b966469c3e36d912bf82)
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 
mesh_mpm_parse_peer_mgmt(struct wpa_supplicant * wpa_s,u8 action_field,const u8 * ie,size_t len,struct mesh_peer_mgmt_ie * mpm_ie)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 
plink_free_count(struct hostapd_data * hapd)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 
copy_supp_rates(struct wpa_supplicant * wpa_s,struct sta_info * sta,struct ieee802_11_elems * elems)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 */
matches_local(struct wpa_supplicant * wpa_s,struct ieee802_11_elems * elems)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 */
llid_in_use(struct wpa_supplicant * wpa_s,u16 llid)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 */
mesh_mpm_init_link(struct wpa_supplicant * wpa_s,struct sta_info * sta)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 
mesh_mpm_send_plink_action(struct wpa_supplicant * wpa_s,struct sta_info * sta,enum plink_action_field type,u16 close_reason)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 */
wpa_mesh_set_plink_state(struct wpa_supplicant * wpa_s,struct sta_info * sta,enum mesh_plink_state state)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 
mesh_mpm_fsm_restart(struct wpa_supplicant * wpa_s,struct sta_info * sta)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 
plink_timer(void * eloop_ctx,void * user_data)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
mesh_mpm_plink_open(struct wpa_supplicant * wpa_s,struct sta_info * sta,enum mesh_plink_state next_state)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 
mesh_mpm_plink_close(struct hostapd_data * hapd,struct sta_info * sta,void * ctx)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 
mesh_mpm_close_peer(struct wpa_supplicant * wpa_s,const u8 * addr)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 
peer_add_timer(void * eloop_ctx,void * user_data)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 
mesh_mpm_connect_peer(struct wpa_supplicant * wpa_s,const u8 * addr,int duration)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 
mesh_mpm_deinit(struct wpa_supplicant * wpa_s,struct hostapd_iface * ifmsh)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 */
mesh_mpm_auth_peer(struct wpa_supplicant * wpa_s,const u8 * addr)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  */
mesh_mpm_add_peer(struct wpa_supplicant * wpa_s,const u8 * addr,struct ieee802_11_elems * elems)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 
wpa_mesh_new_mesh_peer(struct wpa_supplicant * wpa_s,const u8 * addr,struct ieee802_11_elems * elems)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 
mesh_mpm_mgmt_rx(struct wpa_supplicant * wpa_s,struct rx_mgmt * rx_mgmt)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 
mesh_mpm_plink_estab(struct wpa_supplicant * wpa_s,struct sta_info * sta)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 
mesh_mpm_fsm(struct wpa_supplicant * wpa_s,struct sta_info * sta,enum plink_event event,u16 reason)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 
mesh_mpm_action_rx(struct wpa_supplicant * wpa_s,const struct ieee80211_mgmt * mgmt,size_t len)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 */
mesh_mpm_free_sta(struct hostapd_data * hapd,struct sta_info * 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