2 * WPA Supplicant - Basic mesh peer management
3 * Copyright (c) 2013-2014, cozybit, Inc. All rights reserved.
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
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/wpa_auth.h"
20 #include "wpa_supplicant_i.h"
26 struct mesh_peer_mgmt_ie {
27 const u8 *proto_id; /* Mesh Peering Protocol Identifier (2 octets) */
28 const u8 *llid; /* Local Link ID (2 octets) */
29 const u8 *plid; /* Peer Link ID (conditional, 2 octets) */
30 const u8 *reason; /* Reason Code (conditional, 2 octets) */
31 const u8 *chosen_pmk; /* Chosen PMK (optional, 16 octets) */
34 static void plink_timer(void *eloop_ctx, void *user_data);
47 static const char * const mplstate[] = {
48 [0] = "UNINITIALIZED",
49 [PLINK_IDLE] = "IDLE",
50 [PLINK_OPN_SNT] = "OPN_SNT",
51 [PLINK_OPN_RCVD] = "OPN_RCVD",
52 [PLINK_CNF_RCVD] = "CNF_RCVD",
53 [PLINK_ESTAB] = "ESTAB",
54 [PLINK_HOLDING] = "HOLDING",
55 [PLINK_BLOCKED] = "BLOCKED"
58 static const char * const mplevent[] = {
59 [PLINK_UNDEFINED] = "UNDEFINED",
60 [OPN_ACPT] = "OPN_ACPT",
61 [OPN_RJCT] = "OPN_RJCT",
62 [CNF_ACPT] = "CNF_ACPT",
63 [CNF_RJCT] = "CNF_RJCT",
64 [CLS_ACPT] = "CLS_ACPT",
65 [REQ_RJCT] = "REQ_RJCT",
69 static int mesh_mpm_parse_peer_mgmt(struct wpa_supplicant *wpa_s,
71 const u8 *ie, size_t len,
72 struct mesh_peer_mgmt_ie *mpm_ie)
74 os_memset(mpm_ie, 0, sizeof(*mpm_ie));
76 /* Remove optional Chosen PMK field at end */
77 if (len >= SAE_PMKID_LEN) {
78 mpm_ie->chosen_pmk = ie + len - SAE_PMKID_LEN;
82 if ((action_field == PLINK_OPEN && len != 4) ||
83 (action_field == PLINK_CONFIRM && len != 6) ||
84 (action_field == PLINK_CLOSE && len != 6 && len != 8)) {
85 wpa_msg(wpa_s, MSG_DEBUG, "MPM: Invalid peer mgmt ie");
92 mpm_ie->proto_id = ie;
93 mpm_ie->llid = ie + 2;
97 /* close reason is always present at end for close */
98 if (action_field == PLINK_CLOSE) {
101 mpm_ie->reason = ie + len - 2;
105 /* Peer Link ID, present for confirm, and possibly close */
113 static int plink_free_count(struct hostapd_data *hapd)
115 if (hapd->max_plinks > hapd->num_plinks)
116 return hapd->max_plinks - hapd->num_plinks;
121 static u16 copy_supp_rates(struct wpa_supplicant *wpa_s,
122 struct sta_info *sta,
123 struct ieee802_11_elems *elems)
125 if (!elems->supp_rates) {
126 wpa_msg(wpa_s, MSG_ERROR, "no supported rates from " MACSTR,
128 return WLAN_STATUS_UNSPECIFIED_FAILURE;
131 if (elems->supp_rates_len + elems->ext_supp_rates_len >
132 sizeof(sta->supported_rates)) {
133 wpa_msg(wpa_s, MSG_ERROR,
134 "Invalid supported rates element length " MACSTR
135 " %d+%d", MAC2STR(sta->addr), elems->supp_rates_len,
136 elems->ext_supp_rates_len);
137 return WLAN_STATUS_UNSPECIFIED_FAILURE;
140 sta->supported_rates_len = merge_byte_arrays(
141 sta->supported_rates, sizeof(sta->supported_rates),
142 elems->supp_rates, elems->supp_rates_len,
143 elems->ext_supp_rates, elems->ext_supp_rates_len);
145 return WLAN_STATUS_SUCCESS;
149 /* return true if elems from a neighbor match this MBSS */
150 static Boolean matches_local(struct wpa_supplicant *wpa_s,
151 struct ieee802_11_elems *elems)
153 struct mesh_conf *mconf = wpa_s->ifmsh->mconf;
155 if (elems->mesh_config_len < 5)
158 return (mconf->meshid_len == elems->mesh_id_len &&
159 os_memcmp(mconf->meshid, elems->mesh_id,
160 elems->mesh_id_len) == 0 &&
161 mconf->mesh_pp_id == elems->mesh_config[0] &&
162 mconf->mesh_pm_id == elems->mesh_config[1] &&
163 mconf->mesh_cc_id == elems->mesh_config[2] &&
164 mconf->mesh_sp_id == elems->mesh_config[3] &&
165 mconf->mesh_auth_id == elems->mesh_config[4]);
169 /* check if local link id is already used with another peer */
170 static Boolean llid_in_use(struct wpa_supplicant *wpa_s, u16 llid)
172 struct sta_info *sta;
173 struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
175 for (sta = hapd->sta_list; sta; sta = sta->next) {
176 if (sta->my_lid == llid)
184 /* generate an llid for a link and set to initial state */
185 static void mesh_mpm_init_link(struct wpa_supplicant *wpa_s,
186 struct sta_info *sta)
191 if (os_get_random((u8 *) &llid, sizeof(llid)) < 0)
192 llid = 0; /* continue */
193 } while (!llid || llid_in_use(wpa_s, llid));
200 * We do not use wpa_mesh_set_plink_state() here because there is no
201 * entry in kernel yet.
203 sta->plink_state = PLINK_IDLE;
207 static void mesh_mpm_send_plink_action(struct wpa_supplicant *wpa_s,
208 struct sta_info *sta,
209 enum plink_action_field type,
213 struct hostapd_iface *ifmsh = wpa_s->ifmsh;
214 struct hostapd_data *bss = ifmsh->bss[0];
215 struct mesh_conf *conf = ifmsh->mconf;
216 u8 supp_rates[2 + 2 + 32];
218 u8 ie_len, add_plid = 0;
220 int ampe = conf->security & MESH_CONF_SEC_AMPE;
226 buf_len = 2 + /* Category and Action */
227 2 + /* capability info */
229 2 + 8 + /* supported rates */
231 2 + 32 + /* mesh ID */
232 2 + 7 + /* mesh config */
233 2 + 24 + /* peering management */
236 #ifdef CONFIG_IEEE80211N
237 if (type != PLINK_CLOSE && wpa_s->mesh_ht_enabled) {
238 buf_len += 2 + 26 + /* HT capabilities */
239 2 + 22; /* HT operation */
241 #endif /* CONFIG_IEEE80211N */
242 #ifdef CONFIG_IEEE80211AC
243 if (type != PLINK_CLOSE && wpa_s->mesh_vht_enabled) {
244 buf_len += 2 + 12 + /* VHT Capabilities */
245 2 + 5; /* VHT Operation */
247 #endif /* CONFIG_IEEE80211AC */
248 #ifdef CONFIG_IEEE80211AX
249 if (type != PLINK_CLOSE && wpa_s->mesh_he_enabled) {
251 HE_MAX_MAC_CAPAB_SIZE +
252 HE_MAX_PHY_CAPAB_SIZE +
253 HE_MAX_MCS_CAPAB_SIZE +
254 HE_MAX_PPET_CAPAB_SIZE;
255 buf_len += 3 + sizeof(struct ieee80211_he_operation);
257 #endif /* CONFIG_IEEE80211AX */
258 if (type != PLINK_CLOSE)
259 buf_len += conf->rsn_ie_len; /* RSN IE */
261 /* OCI is included even when the other STA doesn't support OCV */
262 if (type != PLINK_CLOSE && conf->ocv)
263 buf_len += OCV_OCI_EXTENDED_LEN;
264 #endif /* CONFIG_OCV */
266 buf = wpabuf_alloc(buf_len);
270 cat = wpabuf_mhead_u8(buf);
271 wpabuf_put_u8(buf, WLAN_ACTION_SELF_PROTECTED);
272 wpabuf_put_u8(buf, type);
274 if (type != PLINK_CLOSE) {
277 /* capability info */
278 wpabuf_put_le16(buf, ampe ? IEEE80211_CAP_PRIVACY : 0);
281 if (type == PLINK_CONFIRM)
282 wpabuf_put_le16(buf, sta->aid);
284 /* IE: supp + ext. supp rates */
285 pos = hostapd_eid_supp_rates(bss, supp_rates);
286 pos = hostapd_eid_ext_supp_rates(bss, pos);
287 wpabuf_put_data(buf, supp_rates, pos - supp_rates);
290 wpabuf_put_data(buf, conf->rsn_ie, conf->rsn_ie_len);
293 wpabuf_put_u8(buf, WLAN_EID_MESH_ID);
294 wpabuf_put_u8(buf, conf->meshid_len);
295 wpabuf_put_data(buf, conf->meshid, conf->meshid_len);
298 wpabuf_put_u8(buf, WLAN_EID_MESH_CONFIG);
299 wpabuf_put_u8(buf, 7);
300 wpabuf_put_u8(buf, conf->mesh_pp_id);
301 wpabuf_put_u8(buf, conf->mesh_pm_id);
302 wpabuf_put_u8(buf, conf->mesh_cc_id);
303 wpabuf_put_u8(buf, conf->mesh_sp_id);
304 wpabuf_put_u8(buf, conf->mesh_auth_id);
305 info = (bss->num_plinks > 63 ? 63 : bss->num_plinks) << 1;
306 /* TODO: Add Connected to Mesh Gate/AS subfields */
307 wpabuf_put_u8(buf, info);
308 /* always forwarding & accepting plinks for now */
309 wpabuf_put_u8(buf, MESH_CAP_ACCEPT_ADDITIONAL_PEER |
310 MESH_CAP_FORWARDING);
311 } else { /* Peer closing frame */
313 wpabuf_put_u8(buf, WLAN_EID_MESH_ID);
314 wpabuf_put_u8(buf, conf->meshid_len);
315 wpabuf_put_data(buf, conf->meshid, conf->meshid_len);
318 /* IE: Mesh Peering Management element */
332 ie_len += 2; /* reason code */
336 wpabuf_put_u8(buf, WLAN_EID_PEER_MGMT);
337 wpabuf_put_u8(buf, ie_len);
338 /* peering protocol */
340 wpabuf_put_le16(buf, 1);
342 wpabuf_put_le16(buf, 0);
343 wpabuf_put_le16(buf, sta->my_lid);
345 wpabuf_put_le16(buf, sta->peer_lid);
346 if (type == PLINK_CLOSE)
347 wpabuf_put_le16(buf, close_reason);
349 if (sta->sae == NULL) {
350 wpa_msg(wpa_s, MSG_INFO, "Mesh MPM: no SAE session");
353 mesh_rsn_get_pmkid(wpa_s->mesh_rsn, sta,
354 wpabuf_put(buf, PMKID_LEN));
357 #ifdef CONFIG_IEEE80211N
358 if (type != PLINK_CLOSE && wpa_s->mesh_ht_enabled) {
359 u8 ht_capa_oper[2 + 26 + 2 + 22];
361 pos = hostapd_eid_ht_capabilities(bss, ht_capa_oper);
362 pos = hostapd_eid_ht_operation(bss, pos);
363 wpabuf_put_data(buf, ht_capa_oper, pos - ht_capa_oper);
365 #endif /* CONFIG_IEEE80211N */
366 #ifdef CONFIG_IEEE80211AC
367 if (type != PLINK_CLOSE && wpa_s->mesh_vht_enabled) {
368 u8 vht_capa_oper[2 + 12 + 2 + 5];
370 pos = hostapd_eid_vht_capabilities(bss, vht_capa_oper, 0);
371 pos = hostapd_eid_vht_operation(bss, pos);
372 wpabuf_put_data(buf, vht_capa_oper, pos - vht_capa_oper);
374 #endif /* CONFIG_IEEE80211AC */
375 #ifdef CONFIG_IEEE80211AX
376 if (type != PLINK_CLOSE && wpa_s->mesh_he_enabled) {
378 HE_MAX_MAC_CAPAB_SIZE +
379 HE_MAX_PHY_CAPAB_SIZE +
380 HE_MAX_MCS_CAPAB_SIZE +
381 HE_MAX_PPET_CAPAB_SIZE +
382 3 + sizeof(struct ieee80211_he_operation)];
384 pos = hostapd_eid_he_capab(bss, he_capa_oper,
385 IEEE80211_MODE_MESH);
386 pos = hostapd_eid_he_operation(bss, pos);
387 wpabuf_put_data(buf, he_capa_oper, pos - he_capa_oper);
389 #endif /* CONFIG_IEEE80211AX */
392 if (type != PLINK_CLOSE && conf->ocv) {
393 struct wpa_channel_info ci;
395 if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
396 wpa_printf(MSG_WARNING,
397 "Mesh MPM: Failed to get channel info for OCI element");
401 pos = wpabuf_put(buf, OCV_OCI_EXTENDED_LEN);
402 if (ocv_insert_extended_oci(&ci, pos) < 0)
405 #endif /* CONFIG_OCV */
407 if (ampe && mesh_rsn_protect_frame(wpa_s->mesh_rsn, sta, cat, buf)) {
408 wpa_msg(wpa_s, MSG_INFO,
409 "Mesh MPM: failed to add AMPE and MIC IE");
413 wpa_msg(wpa_s, MSG_DEBUG, "Mesh MPM: Sending peering frame type %d to "
414 MACSTR " (my_lid=0x%x peer_lid=0x%x)",
415 type, MAC2STR(sta->addr), sta->my_lid, sta->peer_lid);
416 ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0,
417 sta->addr, wpa_s->own_addr, wpa_s->own_addr,
418 wpabuf_head(buf), wpabuf_len(buf), 0);
420 wpa_msg(wpa_s, MSG_INFO,
421 "Mesh MPM: failed to send peering frame");
428 /* configure peering state in ours and driver's station entry */
429 void wpa_mesh_set_plink_state(struct wpa_supplicant *wpa_s,
430 struct sta_info *sta,
431 enum mesh_plink_state state)
433 struct hostapd_sta_add_params params;
436 wpa_msg(wpa_s, MSG_DEBUG, "MPM set " MACSTR " from %s into %s",
437 MAC2STR(sta->addr), mplstate[sta->plink_state],
439 sta->plink_state = state;
441 os_memset(¶ms, 0, sizeof(params));
442 params.addr = sta->addr;
443 params.plink_state = state;
444 params.peer_aid = sta->peer_aid;
447 ret = wpa_drv_sta_add(wpa_s, ¶ms);
449 wpa_msg(wpa_s, MSG_ERROR, "Driver failed to set " MACSTR
450 ": %d", MAC2STR(sta->addr), ret);
455 static void mesh_mpm_fsm_restart(struct wpa_supplicant *wpa_s,
456 struct sta_info *sta)
458 struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
460 eloop_cancel_timeout(plink_timer, wpa_s, sta);
462 ap_free_sta(hapd, sta);
466 static void plink_timer(void *eloop_ctx, void *user_data)
468 struct wpa_supplicant *wpa_s = eloop_ctx;
469 struct sta_info *sta = user_data;
471 struct mesh_conf *conf = wpa_s->ifmsh->mconf;
472 struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
474 switch (sta->plink_state) {
478 if (sta->mpm_retries < conf->dot11MeshMaxRetries) {
479 eloop_register_timeout(
480 conf->dot11MeshRetryTimeout / 1000,
481 (conf->dot11MeshRetryTimeout % 1000) * 1000,
482 plink_timer, wpa_s, sta);
483 mesh_mpm_send_plink_action(wpa_s, sta, PLINK_OPEN, 0);
487 reason = WLAN_REASON_MESH_MAX_RETRIES;
493 reason = WLAN_REASON_MESH_CONFIRM_TIMEOUT;
494 wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
495 eloop_register_timeout(conf->dot11MeshHoldingTimeout / 1000,
496 (conf->dot11MeshHoldingTimeout % 1000) * 1000,
497 plink_timer, wpa_s, sta);
498 mesh_mpm_send_plink_action(wpa_s, sta, PLINK_CLOSE, reason);
503 if (sta->mesh_sae_pmksa_caching) {
504 wpa_printf(MSG_DEBUG, "MPM: Peer " MACSTR
505 " looks like it does not support mesh SAE PMKSA caching, so remove the cached entry for it",
507 wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
509 mesh_mpm_fsm_restart(wpa_s, sta);
517 /* initiate peering with station */
519 mesh_mpm_plink_open(struct wpa_supplicant *wpa_s, struct sta_info *sta,
520 enum mesh_plink_state next_state)
522 struct mesh_conf *conf = wpa_s->ifmsh->mconf;
524 eloop_cancel_timeout(plink_timer, wpa_s, sta);
525 eloop_register_timeout(conf->dot11MeshRetryTimeout / 1000,
526 (conf->dot11MeshRetryTimeout % 1000) * 1000,
527 plink_timer, wpa_s, sta);
528 mesh_mpm_send_plink_action(wpa_s, sta, PLINK_OPEN, 0);
529 wpa_mesh_set_plink_state(wpa_s, sta, next_state);
533 static int mesh_mpm_plink_close(struct hostapd_data *hapd, struct sta_info *sta,
536 struct wpa_supplicant *wpa_s = ctx;
537 int reason = WLAN_REASON_MESH_PEERING_CANCELLED;
540 wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
541 mesh_mpm_send_plink_action(wpa_s, sta, PLINK_CLOSE, reason);
542 wpa_printf(MSG_DEBUG, "MPM closing plink sta=" MACSTR,
544 eloop_cancel_timeout(plink_timer, wpa_s, sta);
552 int mesh_mpm_close_peer(struct wpa_supplicant *wpa_s, const u8 *addr)
554 struct hostapd_data *hapd;
555 struct sta_info *sta;
558 wpa_msg(wpa_s, MSG_INFO, "Mesh is not prepared yet");
562 hapd = wpa_s->ifmsh->bss[0];
563 sta = ap_get_sta(hapd, addr);
565 wpa_msg(wpa_s, MSG_INFO, "No such mesh peer");
569 return mesh_mpm_plink_close(hapd, sta, wpa_s) == 0 ? 0 : -1;
573 static void peer_add_timer(void *eloop_ctx, void *user_data)
575 struct wpa_supplicant *wpa_s = eloop_ctx;
576 struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
578 os_memset(hapd->mesh_required_peer, 0, ETH_ALEN);
582 int mesh_mpm_connect_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
585 struct wpa_ssid *ssid = wpa_s->current_ssid;
586 struct hostapd_data *hapd;
587 struct sta_info *sta;
588 struct mesh_conf *conf;
591 wpa_msg(wpa_s, MSG_INFO, "Mesh is not prepared yet");
595 if (!ssid || !ssid->no_auto_peer) {
596 wpa_msg(wpa_s, MSG_INFO,
597 "This command is available only with no_auto_peer mesh network");
601 hapd = wpa_s->ifmsh->bss[0];
602 conf = wpa_s->ifmsh->mconf;
604 sta = ap_get_sta(hapd, addr);
606 wpa_msg(wpa_s, MSG_INFO, "No such mesh peer");
610 if ((PLINK_OPN_SNT <= sta->plink_state &&
611 sta->plink_state <= PLINK_ESTAB) ||
612 (sta->sae && sta->sae->state > SAE_NOTHING)) {
613 wpa_msg(wpa_s, MSG_INFO,
614 "Specified peer is connecting/connected");
618 if (conf->security == MESH_CONF_SEC_NONE) {
619 mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_SNT);
621 mesh_rsn_auth_sae_sta(wpa_s, sta);
622 os_memcpy(hapd->mesh_required_peer, addr, ETH_ALEN);
623 eloop_register_timeout(duration == -1 ? 10 : duration, 0,
624 peer_add_timer, wpa_s, NULL);
631 void mesh_mpm_deinit(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh)
633 struct hostapd_data *hapd = ifmsh->bss[0];
635 /* notify peers we're leaving */
636 ap_for_each_sta(hapd, mesh_mpm_plink_close, wpa_s);
638 hapd->num_plinks = 0;
639 hostapd_free_stas(hapd);
640 eloop_cancel_timeout(peer_add_timer, wpa_s, NULL);
644 /* for mesh_rsn to indicate this peer has completed authentication, and we're
645 * ready to start AMPE */
646 void mesh_mpm_auth_peer(struct wpa_supplicant *wpa_s, const u8 *addr)
648 struct hostapd_data *data = wpa_s->ifmsh->bss[0];
649 struct hostapd_sta_add_params params;
650 struct sta_info *sta;
653 sta = ap_get_sta(data, addr);
655 wpa_msg(wpa_s, MSG_DEBUG, "no such mesh peer");
659 /* TODO: Should do nothing if this STA is already authenticated, but
660 * the AP code already sets this flag. */
661 sta->flags |= WLAN_STA_AUTH;
663 mesh_rsn_init_ampe_sta(wpa_s, sta);
665 os_memset(¶ms, 0, sizeof(params));
666 params.addr = sta->addr;
667 params.flags = WPA_STA_AUTHENTICATED | WPA_STA_AUTHORIZED;
670 wpa_msg(wpa_s, MSG_DEBUG, "MPM authenticating " MACSTR,
672 ret = wpa_drv_sta_add(wpa_s, ¶ms);
674 wpa_msg(wpa_s, MSG_ERROR,
675 "Driver failed to set " MACSTR ": %d",
676 MAC2STR(sta->addr), ret);
680 mesh_mpm_init_link(wpa_s, sta);
682 mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_SNT);
686 * Initialize a sta_info structure for a peer and upload it into the driver
687 * in preparation for beginning authentication or peering. This is done when a
688 * Beacon (secure or open mesh) or a peering open frame (for open mesh) is
689 * received from the peer for the first time.
691 static struct sta_info * mesh_mpm_add_peer(struct wpa_supplicant *wpa_s,
693 struct ieee802_11_elems *elems)
695 struct hostapd_sta_add_params params;
696 struct mesh_conf *conf = wpa_s->ifmsh->mconf;
697 struct hostapd_data *data = wpa_s->ifmsh->bss[0];
698 struct sta_info *sta;
699 #ifdef CONFIG_IEEE80211N
700 struct ieee80211_ht_operation *oper;
701 #endif /* CONFIG_IEEE80211N */
704 if (elems->mesh_config_len >= 7 &&
705 !(elems->mesh_config[6] & MESH_CAP_ACCEPT_ADDITIONAL_PEER)) {
706 wpa_msg(wpa_s, MSG_DEBUG,
707 "mesh: Ignore a crowded peer " MACSTR,
712 sta = ap_get_sta(data, addr);
714 sta = ap_sta_add(data, addr);
719 /* Set WMM by default since Mesh STAs are QoS STAs */
720 sta->flags |= WLAN_STA_WMM;
723 if (copy_supp_rates(wpa_s, sta, elems)) {
724 ap_free_sta(data, sta);
729 mesh_mpm_init_link(wpa_s, sta);
731 #ifdef CONFIG_IEEE80211N
732 copy_sta_ht_capab(data, sta, elems->ht_capabilities);
734 oper = (struct ieee80211_ht_operation *) elems->ht_operation;
736 !(oper->ht_param & HT_INFO_HT_PARAM_STA_CHNL_WIDTH) &&
737 sta->ht_capabilities) {
738 wpa_msg(wpa_s, MSG_DEBUG, MACSTR
739 " does not support 40 MHz bandwidth",
741 set_disable_ht40(sta->ht_capabilities, 1);
744 update_ht_state(data, sta);
745 #endif /* CONFIG_IEEE80211N */
747 #ifdef CONFIG_IEEE80211AC
748 copy_sta_vht_capab(data, sta, elems->vht_capabilities);
749 copy_sta_vht_oper(data, sta, elems->vht_operation);
750 set_sta_vht_opmode(data, sta, elems->vht_opmode_notif);
751 #endif /* CONFIG_IEEE80211AC */
753 #ifdef CONFIG_IEEE80211AX
754 copy_sta_he_capab(data, sta, IEEE80211_MODE_MESH,
755 elems->he_capabilities, elems->he_capabilities_len);
756 #endif /* CONFIG_IEEE80211AX */
758 if (hostapd_get_aid(data, sta) < 0) {
759 wpa_msg(wpa_s, MSG_ERROR, "No AIDs available");
760 ap_free_sta(data, sta);
764 /* insert into driver */
765 os_memset(¶ms, 0, sizeof(params));
766 params.supp_rates = sta->supported_rates;
767 params.supp_rates_len = sta->supported_rates_len;
769 params.plink_state = sta->plink_state;
770 params.aid = sta->aid;
771 params.peer_aid = sta->peer_aid;
772 params.listen_interval = 100;
773 params.ht_capabilities = sta->ht_capabilities;
774 params.vht_capabilities = sta->vht_capabilities;
775 params.he_capab = sta->he_capab;
776 params.he_capab_len = sta->he_capab_len;
777 params.flags |= WPA_STA_WMM;
778 params.flags_mask |= WPA_STA_AUTHENTICATED;
779 if (conf->security == MESH_CONF_SEC_NONE) {
780 params.flags |= WPA_STA_AUTHORIZED;
781 params.flags |= WPA_STA_AUTHENTICATED;
783 sta->flags |= WLAN_STA_MFP;
784 params.flags |= WPA_STA_MFP;
787 ret = wpa_drv_sta_add(wpa_s, ¶ms);
789 wpa_msg(wpa_s, MSG_ERROR,
790 "Driver failed to insert " MACSTR ": %d",
792 ap_free_sta(data, sta);
800 void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
801 struct ieee802_11_elems *elems)
803 struct mesh_conf *conf = wpa_s->ifmsh->mconf;
804 struct hostapd_data *data = wpa_s->ifmsh->bss[0];
805 struct sta_info *sta;
806 struct wpa_ssid *ssid = wpa_s->current_ssid;
808 sta = mesh_mpm_add_peer(wpa_s, addr, elems);
812 if (ssid && ssid->no_auto_peer &&
813 (is_zero_ether_addr(data->mesh_required_peer) ||
814 os_memcmp(data->mesh_required_peer, addr, ETH_ALEN) != 0)) {
815 wpa_msg(wpa_s, MSG_INFO, "will not initiate new peer link with "
816 MACSTR " because of no_auto_peer", MAC2STR(addr));
817 if (data->mesh_pending_auth) {
818 struct os_reltime age;
819 const struct ieee80211_mgmt *mgmt;
820 struct hostapd_frame_info fi;
822 mgmt = wpabuf_head(data->mesh_pending_auth);
823 os_reltime_age(&data->mesh_pending_auth_time, &age);
825 os_memcmp(mgmt->sa, addr, ETH_ALEN) == 0) {
826 wpa_printf(MSG_DEBUG,
827 "mesh: Process pending Authentication frame from %u.%06u seconds ago",
828 (unsigned int) age.sec,
829 (unsigned int) age.usec);
830 os_memset(&fi, 0, sizeof(fi));
833 wpabuf_head(data->mesh_pending_auth),
834 wpabuf_len(data->mesh_pending_auth),
837 wpabuf_free(data->mesh_pending_auth);
838 data->mesh_pending_auth = NULL;
843 if (conf->security == MESH_CONF_SEC_NONE) {
844 if (sta->plink_state < PLINK_OPN_SNT ||
845 sta->plink_state > PLINK_ESTAB)
846 mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_SNT);
848 mesh_rsn_auth_sae_sta(wpa_s, sta);
853 void mesh_mpm_mgmt_rx(struct wpa_supplicant *wpa_s, struct rx_mgmt *rx_mgmt)
855 struct hostapd_frame_info fi;
857 os_memset(&fi, 0, sizeof(fi));
858 fi.datarate = rx_mgmt->datarate;
859 fi.ssi_signal = rx_mgmt->ssi_signal;
860 ieee802_11_mgmt(wpa_s->ifmsh->bss[0], rx_mgmt->frame,
861 rx_mgmt->frame_len, &fi);
865 static void mesh_mpm_plink_estab(struct wpa_supplicant *wpa_s,
866 struct sta_info *sta)
868 struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
869 struct mesh_conf *conf = wpa_s->ifmsh->mconf;
872 wpa_msg(wpa_s, MSG_INFO, "mesh plink with " MACSTR " established",
875 if (conf->security & MESH_CONF_SEC_AMPE) {
876 wpa_hexdump_key(MSG_DEBUG, "mesh: MTK", sta->mtk, sta->mtk_len);
877 wpa_drv_set_key(wpa_s, wpa_cipher_to_alg(conf->pairwise_cipher),
878 sta->addr, 0, 0, seq, sizeof(seq),
879 sta->mtk, sta->mtk_len);
881 wpa_hexdump_key(MSG_DEBUG, "mesh: RX MGTK Key RSC",
882 sta->mgtk_rsc, sizeof(sta->mgtk_rsc));
883 wpa_hexdump_key(MSG_DEBUG, "mesh: RX MGTK",
884 sta->mgtk, sta->mgtk_len);
885 wpa_drv_set_key(wpa_s, wpa_cipher_to_alg(conf->group_cipher),
886 sta->addr, sta->mgtk_key_id, 0,
887 sta->mgtk_rsc, sizeof(sta->mgtk_rsc),
888 sta->mgtk, sta->mgtk_len);
891 wpa_hexdump_key(MSG_DEBUG, "mesh: RX IGTK Key RSC",
892 sta->igtk_rsc, sizeof(sta->igtk_rsc));
893 wpa_hexdump_key(MSG_DEBUG, "mesh: RX IGTK",
894 sta->igtk, sta->igtk_len);
897 wpa_cipher_to_alg(conf->mgmt_group_cipher),
898 sta->addr, sta->igtk_key_id, 0,
899 sta->igtk_rsc, sizeof(sta->igtk_rsc),
900 sta->igtk, sta->igtk_len);
904 wpa_mesh_set_plink_state(wpa_s, sta, PLINK_ESTAB);
907 sta->flags |= WLAN_STA_ASSOC;
908 sta->mesh_sae_pmksa_caching = 0;
910 eloop_cancel_timeout(peer_add_timer, wpa_s, NULL);
911 peer_add_timer(wpa_s, NULL);
912 eloop_cancel_timeout(plink_timer, wpa_s, sta);
914 /* Send ctrl event */
915 wpa_msg(wpa_s, MSG_INFO, MESH_PEER_CONNECTED MACSTR,
918 /* Send D-Bus event */
919 wpas_notify_mesh_peer_connected(wpa_s, sta->addr);
923 static void mesh_mpm_fsm(struct wpa_supplicant *wpa_s, struct sta_info *sta,
924 enum plink_event event, u16 reason)
926 struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
927 struct mesh_conf *conf = wpa_s->ifmsh->mconf;
929 wpa_msg(wpa_s, MSG_DEBUG, "MPM " MACSTR " state %s event %s",
930 MAC2STR(sta->addr), mplstate[sta->plink_state],
933 switch (sta->plink_state) {
937 mesh_mpm_fsm_restart(wpa_s, sta);
940 mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_RCVD);
941 mesh_mpm_send_plink_action(wpa_s, sta, PLINK_CONFIRM,
945 mesh_mpm_send_plink_action(wpa_s, sta,
946 PLINK_CLOSE, reason);
957 reason = WLAN_REASON_MESH_CONFIG_POLICY_VIOLATION;
960 wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
962 reason = WLAN_REASON_MESH_CLOSE_RCVD;
963 eloop_register_timeout(
964 conf->dot11MeshHoldingTimeout / 1000,
965 (conf->dot11MeshHoldingTimeout % 1000) * 1000,
966 plink_timer, wpa_s, sta);
967 mesh_mpm_send_plink_action(wpa_s, sta,
968 PLINK_CLOSE, reason);
971 /* retry timer is left untouched */
972 wpa_mesh_set_plink_state(wpa_s, sta, PLINK_OPN_RCVD);
973 mesh_mpm_send_plink_action(wpa_s, sta,
977 wpa_mesh_set_plink_state(wpa_s, sta, PLINK_CNF_RCVD);
978 eloop_cancel_timeout(plink_timer, wpa_s, sta);
979 eloop_register_timeout(
980 conf->dot11MeshConfirmTimeout / 1000,
981 (conf->dot11MeshConfirmTimeout % 1000) * 1000,
982 plink_timer, wpa_s, sta);
993 reason = WLAN_REASON_MESH_CONFIG_POLICY_VIOLATION;
996 wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
998 reason = WLAN_REASON_MESH_CLOSE_RCVD;
999 eloop_register_timeout(
1000 conf->dot11MeshHoldingTimeout / 1000,
1001 (conf->dot11MeshHoldingTimeout % 1000) * 1000,
1002 plink_timer, wpa_s, sta);
1003 sta->mpm_close_reason = reason;
1004 mesh_mpm_send_plink_action(wpa_s, sta,
1005 PLINK_CLOSE, reason);
1008 mesh_mpm_send_plink_action(wpa_s, sta,
1012 if (conf->security & MESH_CONF_SEC_AMPE)
1013 mesh_rsn_derive_mtk(wpa_s, sta);
1014 mesh_mpm_plink_estab(wpa_s, sta);
1020 case PLINK_CNF_RCVD:
1025 reason = WLAN_REASON_MESH_CONFIG_POLICY_VIOLATION;
1028 wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
1030 reason = WLAN_REASON_MESH_CLOSE_RCVD;
1031 eloop_register_timeout(
1032 conf->dot11MeshHoldingTimeout / 1000,
1033 (conf->dot11MeshHoldingTimeout % 1000) * 1000,
1034 plink_timer, wpa_s, sta);
1035 sta->mpm_close_reason = reason;
1036 mesh_mpm_send_plink_action(wpa_s, sta,
1037 PLINK_CLOSE, reason);
1040 if (conf->security & MESH_CONF_SEC_AMPE)
1041 mesh_rsn_derive_mtk(wpa_s, sta);
1042 mesh_mpm_plink_estab(wpa_s, sta);
1043 mesh_mpm_send_plink_action(wpa_s, sta,
1055 wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
1057 reason = WLAN_REASON_MESH_CLOSE_RCVD;
1059 eloop_register_timeout(
1060 conf->dot11MeshHoldingTimeout / 1000,
1061 (conf->dot11MeshHoldingTimeout % 1000) * 1000,
1062 plink_timer, wpa_s, sta);
1063 sta->mpm_close_reason = reason;
1065 wpa_msg(wpa_s, MSG_INFO, "mesh plink with " MACSTR
1066 " closed with reason %d",
1067 MAC2STR(sta->addr), reason);
1069 wpa_msg(wpa_s, MSG_INFO, MESH_PEER_DISCONNECTED MACSTR,
1070 MAC2STR(sta->addr));
1072 /* Send D-Bus event */
1073 wpas_notify_mesh_peer_disconnected(wpa_s, sta->addr,
1078 mesh_mpm_send_plink_action(wpa_s, sta,
1079 PLINK_CLOSE, reason);
1082 mesh_mpm_send_plink_action(wpa_s, sta,
1092 mesh_mpm_fsm_restart(wpa_s, sta);
1098 reason = sta->mpm_close_reason;
1099 mesh_mpm_send_plink_action(wpa_s, sta,
1100 PLINK_CLOSE, reason);
1107 wpa_msg(wpa_s, MSG_DEBUG,
1108 "Unsupported MPM event %s for state %s",
1109 mplevent[event], mplstate[sta->plink_state]);
1115 void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
1116 const struct ieee80211_mgmt *mgmt, size_t len)
1119 struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
1120 struct mesh_conf *mconf = wpa_s->ifmsh->mconf;
1121 struct sta_info *sta;
1122 u16 plid = 0, llid = 0, aid = 0;
1123 enum plink_event event;
1124 struct ieee802_11_elems elems;
1125 struct mesh_peer_mgmt_ie peer_mgmt_ie;
1131 if (mgmt->u.action.category != WLAN_ACTION_SELF_PROTECTED)
1134 action_field = mgmt->u.action.u.slf_prot_action.action;
1135 if (action_field != PLINK_OPEN &&
1136 action_field != PLINK_CONFIRM &&
1137 action_field != PLINK_CLOSE)
1140 ies = mgmt->u.action.u.slf_prot_action.variable;
1141 ie_len = (const u8 *) mgmt + len -
1142 mgmt->u.action.u.slf_prot_action.variable;
1144 /* at least expect mesh id and peering mgmt */
1145 if (ie_len < 2 + 2) {
1146 wpa_printf(MSG_DEBUG,
1147 "MPM: Ignore too short action frame %u ie_len %u",
1148 action_field, (unsigned int) ie_len);
1151 wpa_printf(MSG_DEBUG, "MPM: Received PLINK action %u", action_field);
1153 if (action_field == PLINK_OPEN || action_field == PLINK_CONFIRM) {
1154 wpa_printf(MSG_DEBUG, "MPM: Capability 0x%x",
1156 ies += 2; /* capability */
1159 if (action_field == PLINK_CONFIRM) {
1160 aid = WPA_GET_LE16(ies);
1161 wpa_printf(MSG_DEBUG, "MPM: AID 0x%x", aid);
1166 /* check for mesh peering, mesh id and mesh config IEs */
1167 if (ieee802_11_parse_elems(ies, ie_len, &elems, 0) == ParseFailed) {
1168 wpa_printf(MSG_DEBUG, "MPM: Failed to parse PLINK IEs");
1171 if (!elems.peer_mgmt) {
1172 wpa_printf(MSG_DEBUG,
1173 "MPM: No Mesh Peering Management element");
1176 if (action_field != PLINK_CLOSE) {
1177 if (!elems.mesh_id || !elems.mesh_config) {
1178 wpa_printf(MSG_DEBUG,
1179 "MPM: No Mesh ID or Mesh Configuration element");
1183 if (!matches_local(wpa_s, &elems)) {
1184 wpa_printf(MSG_DEBUG,
1185 "MPM: Mesh ID or Mesh Configuration element do not match local MBSS");
1190 ret = mesh_mpm_parse_peer_mgmt(wpa_s, action_field,
1192 elems.peer_mgmt_len,
1195 wpa_printf(MSG_DEBUG, "MPM: Mesh parsing rejected frame");
1199 /* the sender's llid is our plid and vice-versa */
1200 plid = WPA_GET_LE16(peer_mgmt_ie.llid);
1201 if (peer_mgmt_ie.plid)
1202 llid = WPA_GET_LE16(peer_mgmt_ie.plid);
1203 wpa_printf(MSG_DEBUG, "MPM: plid=0x%x llid=0x%x", plid, llid);
1205 if (action_field == PLINK_CLOSE)
1206 wpa_printf(MSG_DEBUG, "MPM: close reason=%u",
1207 WPA_GET_LE16(peer_mgmt_ie.reason));
1209 sta = ap_get_sta(hapd, mgmt->sa);
1212 * If this is an open frame from an unknown STA, and this is an
1213 * open mesh, then go ahead and add the peer before proceeding.
1215 if (!sta && action_field == PLINK_OPEN &&
1216 (!(mconf->security & MESH_CONF_SEC_AMPE) ||
1217 wpa_auth_pmksa_get(hapd->wpa_auth, mgmt->sa, NULL)))
1218 sta = mesh_mpm_add_peer(wpa_s, mgmt->sa, &elems);
1221 wpa_printf(MSG_DEBUG, "MPM: No STA entry for peer");
1226 /* peer is in sae_accepted? */
1227 if (sta->sae && sta->sae->state != SAE_ACCEPTED) {
1228 wpa_printf(MSG_DEBUG, "MPM: SAE not yet accepted for peer");
1231 #endif /* CONFIG_SAE */
1234 mesh_mpm_init_link(wpa_s, sta);
1236 if (mconf->security & MESH_CONF_SEC_AMPE) {
1239 res = mesh_rsn_process_ampe(wpa_s, sta, &elems,
1240 &mgmt->u.action.category,
1241 peer_mgmt_ie.chosen_pmk,
1244 wpa_printf(MSG_DEBUG,
1245 "MPM: RSN process rejected frame (res=%d)",
1247 if (action_field == PLINK_OPEN && res == -2) {
1248 /* AES-SIV decryption failed */
1249 mesh_mpm_fsm(wpa_s, sta, OPN_RJCT,
1250 WLAN_REASON_MESH_INVALID_GTK);
1256 if (action_field == PLINK_OPEN && elems.rsn_ie) {
1257 struct wpa_state_machine *sm = sta->wpa_sm;
1258 struct wpa_ie_data data;
1260 res = wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2,
1261 elems.rsn_ie_len + 2,
1264 wpa_printf(MSG_DEBUG,
1265 "Failed to parse RSN IE (res=%d)",
1267 wpa_hexdump(MSG_DEBUG, "RSN IE", elems.rsn_ie,
1272 wpa_auth_set_ocv(sm, mconf->ocv &&
1273 (data.capabilities &
1274 WPA_CAPABILITY_OCVC));
1277 if (action_field != PLINK_CLOSE &&
1278 wpa_auth_uses_ocv(sta->wpa_sm)) {
1279 struct wpa_channel_info ci;
1283 if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
1284 wpa_printf(MSG_WARNING,
1285 "MPM: Failed to get channel info to validate received OCI in MPM Confirm");
1289 if (get_tx_parameters(
1290 sta, channel_width_to_int(ci.chanwidth),
1291 ci.seg1_idx, &tx_chanwidth,
1295 if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci,
1296 tx_chanwidth, tx_seg1_idx) !=
1298 wpa_printf(MSG_WARNING, "MPM: %s",
1303 #endif /* CONFIG_OCV */
1306 if (sta->plink_state == PLINK_BLOCKED) {
1307 wpa_printf(MSG_DEBUG, "MPM: PLINK_BLOCKED");
1311 /* Now we will figure out the appropriate event... */
1312 switch (action_field) {
1314 if (plink_free_count(hapd) == 0) {
1316 reason = WLAN_REASON_MESH_MAX_PEERS;
1317 wpa_printf(MSG_INFO,
1318 "MPM: Peer link num over quota(%d)",
1320 } else if (sta->peer_lid && sta->peer_lid != plid) {
1321 wpa_printf(MSG_DEBUG,
1322 "MPM: peer_lid mismatch: 0x%x != 0x%x",
1323 sta->peer_lid, plid);
1324 return; /* no FSM event */
1326 sta->peer_lid = plid;
1331 if (plink_free_count(hapd) == 0) {
1333 reason = WLAN_REASON_MESH_MAX_PEERS;
1334 wpa_printf(MSG_INFO,
1335 "MPM: Peer link num over quota(%d)",
1337 } else if (sta->my_lid != llid ||
1338 (sta->peer_lid && sta->peer_lid != plid)) {
1339 wpa_printf(MSG_DEBUG,
1340 "MPM: lid mismatch: my_lid: 0x%x != 0x%x or peer_lid: 0x%x != 0x%x",
1341 sta->my_lid, llid, sta->peer_lid, plid);
1342 return; /* no FSM event */
1345 sta->peer_lid = plid;
1346 sta->peer_aid = aid;
1351 if (sta->plink_state == PLINK_ESTAB)
1352 /* Do not check for llid or plid. This does not
1353 * follow the standard but since multiple plinks
1354 * per cand are not supported, it is necessary in
1355 * order to avoid a livelock when MP A sees an
1356 * establish peer link to MP B but MP B does not
1357 * see it. This can be caused by a timeout in
1358 * B's peer link establishment or B being
1362 else if (sta->peer_lid != plid) {
1363 wpa_printf(MSG_DEBUG,
1364 "MPM: peer_lid mismatch: 0x%x != 0x%x",
1365 sta->peer_lid, plid);
1366 return; /* no FSM event */
1367 } else if (peer_mgmt_ie.plid && sta->my_lid != llid) {
1368 wpa_printf(MSG_DEBUG,
1369 "MPM: my_lid mismatch: 0x%x != 0x%x",
1371 return; /* no FSM event */
1378 * This cannot be hit due to the action_field check above, but
1379 * compilers may not be able to figure that out and can warn
1380 * about uninitialized event below.
1384 mesh_mpm_fsm(wpa_s, sta, event, reason);
1388 /* called by ap_free_sta */
1389 void mesh_mpm_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
1391 if (sta->plink_state == PLINK_ESTAB)
1393 eloop_cancel_timeout(plink_timer, ELOOP_ALL_CTX, sta);
1394 eloop_cancel_timeout(mesh_auth_timer, ELOOP_ALL_CTX, sta);