]> git.ipfire.org Git - thirdparty/hostap.git/blob - wpa_supplicant/mesh_mpm.c
EAP: Increase the maximum number of message exchanges
[thirdparty/hostap.git] / wpa_supplicant / mesh_mpm.c
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/wpa_auth.h"
20 #include "wpa_supplicant_i.h"
21 #include "driver_i.h"
22 #include "mesh_mpm.h"
23 #include "mesh_rsn.h"
24 #include "notify.h"
25
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) */
32 };
33
34 static void plink_timer(void *eloop_ctx, void *user_data);
35
36
37 enum plink_event {
38 PLINK_UNDEFINED,
39 OPN_ACPT,
40 OPN_RJCT,
41 CNF_ACPT,
42 CNF_RJCT,
43 CLS_ACPT,
44 REQ_RJCT
45 };
46
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"
56 };
57
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",
66 };
67
68
69 static int mesh_mpm_parse_peer_mgmt(struct wpa_supplicant *wpa_s,
70 u8 action_field,
71 const u8 *ie, size_t len,
72 struct mesh_peer_mgmt_ie *mpm_ie)
73 {
74 os_memset(mpm_ie, 0, sizeof(*mpm_ie));
75
76 /* Remove optional Chosen PMK field at end */
77 if (len >= SAE_PMKID_LEN) {
78 mpm_ie->chosen_pmk = ie + len - SAE_PMKID_LEN;
79 len -= SAE_PMKID_LEN;
80 }
81
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");
86 return -1;
87 }
88
89 /* required fields */
90 if (len < 4)
91 return -1;
92 mpm_ie->proto_id = ie;
93 mpm_ie->llid = ie + 2;
94 ie += 4;
95 len -= 4;
96
97 /* close reason is always present at end for close */
98 if (action_field == PLINK_CLOSE) {
99 if (len < 2)
100 return -1;
101 mpm_ie->reason = ie + len - 2;
102 len -= 2;
103 }
104
105 /* Peer Link ID, present for confirm, and possibly close */
106 if (len >= 2)
107 mpm_ie->plid = ie;
108
109 return 0;
110 }
111
112
113 static int plink_free_count(struct hostapd_data *hapd)
114 {
115 if (hapd->max_plinks > hapd->num_plinks)
116 return hapd->max_plinks - hapd->num_plinks;
117 return 0;
118 }
119
120
121 static u16 copy_supp_rates(struct wpa_supplicant *wpa_s,
122 struct sta_info *sta,
123 struct ieee802_11_elems *elems)
124 {
125 if (!elems->supp_rates) {
126 wpa_msg(wpa_s, MSG_ERROR, "no supported rates from " MACSTR,
127 MAC2STR(sta->addr));
128 return WLAN_STATUS_UNSPECIFIED_FAILURE;
129 }
130
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;
138 }
139
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);
144
145 return WLAN_STATUS_SUCCESS;
146 }
147
148
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)
152 {
153 struct mesh_conf *mconf = wpa_s->ifmsh->mconf;
154
155 if (elems->mesh_config_len < 5)
156 return FALSE;
157
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]);
166 }
167
168
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)
171 {
172 struct sta_info *sta;
173 struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
174
175 for (sta = hapd->sta_list; sta; sta = sta->next) {
176 if (sta->my_lid == llid)
177 return TRUE;
178 }
179
180 return FALSE;
181 }
182
183
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)
187 {
188 u16 llid;
189
190 do {
191 if (os_get_random((u8 *) &llid, sizeof(llid)) < 0)
192 llid = 0; /* continue */
193 } while (!llid || llid_in_use(wpa_s, llid));
194
195 sta->my_lid = llid;
196 sta->peer_lid = 0;
197 sta->peer_aid = 0;
198
199 /*
200 * We do not use wpa_mesh_set_plink_state() here because there is no
201 * entry in kernel yet.
202 */
203 sta->plink_state = PLINK_IDLE;
204 }
205
206
207 static void mesh_mpm_send_plink_action(struct wpa_supplicant *wpa_s,
208 struct sta_info *sta,
209 enum plink_action_field type,
210 u16 close_reason)
211 {
212 struct wpabuf *buf;
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];
217 u8 *pos, *cat;
218 u8 ie_len, add_plid = 0;
219 int ret;
220 int ampe = conf->security & MESH_CONF_SEC_AMPE;
221 size_t buf_len;
222
223 if (!sta)
224 return;
225
226 buf_len = 2 + /* Category and Action */
227 2 + /* capability info */
228 2 + /* AID */
229 2 + 8 + /* supported rates */
230 2 + (32 - 8) +
231 2 + 32 + /* mesh ID */
232 2 + 7 + /* mesh config */
233 2 + 24 + /* peering management */
234 2 + 96 + /* AMPE */
235 2 + 16; /* MIC */
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 */
240 }
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 */
246 }
247 #endif /* CONFIG_IEEE80211AC */
248 #ifdef CONFIG_IEEE80211AX
249 if (type != PLINK_CLOSE && wpa_s->mesh_he_enabled) {
250 buf_len += 3 +
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);
256 }
257 #endif /* CONFIG_IEEE80211AX */
258 if (type != PLINK_CLOSE)
259 buf_len += conf->rsn_ie_len; /* RSN IE */
260 #ifdef CONFIG_OCV
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 */
265
266 buf = wpabuf_alloc(buf_len);
267 if (!buf)
268 return;
269
270 cat = wpabuf_mhead_u8(buf);
271 wpabuf_put_u8(buf, WLAN_ACTION_SELF_PROTECTED);
272 wpabuf_put_u8(buf, type);
273
274 if (type != PLINK_CLOSE) {
275 u8 info;
276
277 /* capability info */
278 wpabuf_put_le16(buf, ampe ? IEEE80211_CAP_PRIVACY : 0);
279
280 /* aid */
281 if (type == PLINK_CONFIRM)
282 wpabuf_put_le16(buf, sta->aid);
283
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);
288
289 /* IE: RSN IE */
290 wpabuf_put_data(buf, conf->rsn_ie, conf->rsn_ie_len);
291
292 /* IE: Mesh ID */
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);
296
297 /* IE: mesh conf */
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 */
312 /* IE: Mesh ID */
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);
316 }
317
318 /* IE: Mesh Peering Management element */
319 ie_len = 4;
320 if (ampe)
321 ie_len += PMKID_LEN;
322 switch (type) {
323 case PLINK_OPEN:
324 break;
325 case PLINK_CONFIRM:
326 ie_len += 2;
327 add_plid = 1;
328 break;
329 case PLINK_CLOSE:
330 ie_len += 2;
331 add_plid = 1;
332 ie_len += 2; /* reason code */
333 break;
334 }
335
336 wpabuf_put_u8(buf, WLAN_EID_PEER_MGMT);
337 wpabuf_put_u8(buf, ie_len);
338 /* peering protocol */
339 if (ampe)
340 wpabuf_put_le16(buf, 1);
341 else
342 wpabuf_put_le16(buf, 0);
343 wpabuf_put_le16(buf, sta->my_lid);
344 if (add_plid)
345 wpabuf_put_le16(buf, sta->peer_lid);
346 if (type == PLINK_CLOSE)
347 wpabuf_put_le16(buf, close_reason);
348 if (ampe) {
349 if (sta->sae == NULL) {
350 wpa_msg(wpa_s, MSG_INFO, "Mesh MPM: no SAE session");
351 goto fail;
352 }
353 mesh_rsn_get_pmkid(wpa_s->mesh_rsn, sta,
354 wpabuf_put(buf, PMKID_LEN));
355 }
356
357 #ifdef CONFIG_IEEE80211N
358 if (type != PLINK_CLOSE && wpa_s->mesh_ht_enabled) {
359 u8 ht_capa_oper[2 + 26 + 2 + 22];
360
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);
364 }
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];
369
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);
373 }
374 #endif /* CONFIG_IEEE80211AC */
375 #ifdef CONFIG_IEEE80211AX
376 if (type != PLINK_CLOSE && wpa_s->mesh_he_enabled) {
377 u8 he_capa_oper[3 +
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)];
383
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);
388 }
389 #endif /* CONFIG_IEEE80211AX */
390
391 #ifdef CONFIG_OCV
392 if (type != PLINK_CLOSE && conf->ocv) {
393 struct wpa_channel_info ci;
394
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");
398 goto fail;
399 }
400
401 pos = wpabuf_put(buf, OCV_OCI_EXTENDED_LEN);
402 if (ocv_insert_extended_oci(&ci, pos) < 0)
403 goto fail;
404 }
405 #endif /* CONFIG_OCV */
406
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");
410 goto fail;
411 }
412
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);
419 if (ret < 0)
420 wpa_msg(wpa_s, MSG_INFO,
421 "Mesh MPM: failed to send peering frame");
422
423 fail:
424 wpabuf_free(buf);
425 }
426
427
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)
432 {
433 struct hostapd_sta_add_params params;
434 int ret;
435
436 wpa_msg(wpa_s, MSG_DEBUG, "MPM set " MACSTR " from %s into %s",
437 MAC2STR(sta->addr), mplstate[sta->plink_state],
438 mplstate[state]);
439 sta->plink_state = state;
440
441 os_memset(&params, 0, sizeof(params));
442 params.addr = sta->addr;
443 params.plink_state = state;
444 params.peer_aid = sta->peer_aid;
445 params.set = 1;
446
447 ret = wpa_drv_sta_add(wpa_s, &params);
448 if (ret) {
449 wpa_msg(wpa_s, MSG_ERROR, "Driver failed to set " MACSTR
450 ": %d", MAC2STR(sta->addr), ret);
451 }
452 }
453
454
455 static void mesh_mpm_fsm_restart(struct wpa_supplicant *wpa_s,
456 struct sta_info *sta)
457 {
458 struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
459
460 eloop_cancel_timeout(plink_timer, wpa_s, sta);
461
462 ap_free_sta(hapd, sta);
463 }
464
465
466 static void plink_timer(void *eloop_ctx, void *user_data)
467 {
468 struct wpa_supplicant *wpa_s = eloop_ctx;
469 struct sta_info *sta = user_data;
470 u16 reason = 0;
471 struct mesh_conf *conf = wpa_s->ifmsh->mconf;
472 struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
473
474 switch (sta->plink_state) {
475 case PLINK_OPN_RCVD:
476 case PLINK_OPN_SNT:
477 /* retry timer */
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);
484 sta->mpm_retries++;
485 break;
486 }
487 reason = WLAN_REASON_MESH_MAX_RETRIES;
488 /* fall through */
489
490 case PLINK_CNF_RCVD:
491 /* confirm timer */
492 if (!reason)
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);
499 break;
500 case PLINK_HOLDING:
501 /* holding timer */
502
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",
506 MAC2STR(sta->addr));
507 wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
508 }
509 mesh_mpm_fsm_restart(wpa_s, sta);
510 break;
511 default:
512 break;
513 }
514 }
515
516
517 /* initiate peering with station */
518 static void
519 mesh_mpm_plink_open(struct wpa_supplicant *wpa_s, struct sta_info *sta,
520 enum mesh_plink_state next_state)
521 {
522 struct mesh_conf *conf = wpa_s->ifmsh->mconf;
523
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);
530 }
531
532
533 static int mesh_mpm_plink_close(struct hostapd_data *hapd, struct sta_info *sta,
534 void *ctx)
535 {
536 struct wpa_supplicant *wpa_s = ctx;
537 int reason = WLAN_REASON_MESH_PEERING_CANCELLED;
538
539 if (sta) {
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,
543 MAC2STR(sta->addr));
544 eloop_cancel_timeout(plink_timer, wpa_s, sta);
545 return 0;
546 }
547
548 return 1;
549 }
550
551
552 int mesh_mpm_close_peer(struct wpa_supplicant *wpa_s, const u8 *addr)
553 {
554 struct hostapd_data *hapd;
555 struct sta_info *sta;
556
557 if (!wpa_s->ifmsh) {
558 wpa_msg(wpa_s, MSG_INFO, "Mesh is not prepared yet");
559 return -1;
560 }
561
562 hapd = wpa_s->ifmsh->bss[0];
563 sta = ap_get_sta(hapd, addr);
564 if (!sta) {
565 wpa_msg(wpa_s, MSG_INFO, "No such mesh peer");
566 return -1;
567 }
568
569 return mesh_mpm_plink_close(hapd, sta, wpa_s) == 0 ? 0 : -1;
570 }
571
572
573 static void peer_add_timer(void *eloop_ctx, void *user_data)
574 {
575 struct wpa_supplicant *wpa_s = eloop_ctx;
576 struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
577
578 os_memset(hapd->mesh_required_peer, 0, ETH_ALEN);
579 }
580
581
582 int mesh_mpm_connect_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
583 int duration)
584 {
585 struct wpa_ssid *ssid = wpa_s->current_ssid;
586 struct hostapd_data *hapd;
587 struct sta_info *sta;
588 struct mesh_conf *conf;
589
590 if (!wpa_s->ifmsh) {
591 wpa_msg(wpa_s, MSG_INFO, "Mesh is not prepared yet");
592 return -1;
593 }
594
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");
598 return -1;
599 }
600
601 hapd = wpa_s->ifmsh->bss[0];
602 conf = wpa_s->ifmsh->mconf;
603
604 sta = ap_get_sta(hapd, addr);
605 if (!sta) {
606 wpa_msg(wpa_s, MSG_INFO, "No such mesh peer");
607 return -1;
608 }
609
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");
615 return -1;
616 }
617
618 if (conf->security == MESH_CONF_SEC_NONE) {
619 mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_SNT);
620 } else {
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);
625 }
626
627 return 0;
628 }
629
630
631 void mesh_mpm_deinit(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh)
632 {
633 struct hostapd_data *hapd = ifmsh->bss[0];
634
635 /* notify peers we're leaving */
636 ap_for_each_sta(hapd, mesh_mpm_plink_close, wpa_s);
637
638 hapd->num_plinks = 0;
639 hostapd_free_stas(hapd);
640 eloop_cancel_timeout(peer_add_timer, wpa_s, NULL);
641 }
642
643
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)
647 {
648 struct hostapd_data *data = wpa_s->ifmsh->bss[0];
649 struct hostapd_sta_add_params params;
650 struct sta_info *sta;
651 int ret;
652
653 sta = ap_get_sta(data, addr);
654 if (!sta) {
655 wpa_msg(wpa_s, MSG_DEBUG, "no such mesh peer");
656 return;
657 }
658
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;
662
663 mesh_rsn_init_ampe_sta(wpa_s, sta);
664
665 os_memset(&params, 0, sizeof(params));
666 params.addr = sta->addr;
667 params.flags = WPA_STA_AUTHENTICATED | WPA_STA_AUTHORIZED;
668 params.set = 1;
669
670 wpa_msg(wpa_s, MSG_DEBUG, "MPM authenticating " MACSTR,
671 MAC2STR(sta->addr));
672 ret = wpa_drv_sta_add(wpa_s, &params);
673 if (ret) {
674 wpa_msg(wpa_s, MSG_ERROR,
675 "Driver failed to set " MACSTR ": %d",
676 MAC2STR(sta->addr), ret);
677 }
678
679 if (!sta->my_lid)
680 mesh_mpm_init_link(wpa_s, sta);
681
682 mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_SNT);
683 }
684
685 /*
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.
690 */
691 static struct sta_info * mesh_mpm_add_peer(struct wpa_supplicant *wpa_s,
692 const u8 *addr,
693 struct ieee802_11_elems *elems)
694 {
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 */
702 int ret;
703
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,
708 MAC2STR(addr));
709 return NULL;
710 }
711
712 sta = ap_get_sta(data, addr);
713 if (!sta) {
714 sta = ap_sta_add(data, addr);
715 if (!sta)
716 return NULL;
717 }
718
719 /* Set WMM by default since Mesh STAs are QoS STAs */
720 sta->flags |= WLAN_STA_WMM;
721
722 /* initialize sta */
723 if (copy_supp_rates(wpa_s, sta, elems)) {
724 ap_free_sta(data, sta);
725 return NULL;
726 }
727
728 if (!sta->my_lid)
729 mesh_mpm_init_link(wpa_s, sta);
730
731 #ifdef CONFIG_IEEE80211N
732 copy_sta_ht_capab(data, sta, elems->ht_capabilities);
733
734 oper = (struct ieee80211_ht_operation *) elems->ht_operation;
735 if (oper &&
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",
740 MAC2STR(sta->addr));
741 set_disable_ht40(sta->ht_capabilities, 1);
742 }
743
744 update_ht_state(data, sta);
745 #endif /* CONFIG_IEEE80211N */
746
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 */
752
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 */
757
758 if (hostapd_get_aid(data, sta) < 0) {
759 wpa_msg(wpa_s, MSG_ERROR, "No AIDs available");
760 ap_free_sta(data, sta);
761 return NULL;
762 }
763
764 /* insert into driver */
765 os_memset(&params, 0, sizeof(params));
766 params.supp_rates = sta->supported_rates;
767 params.supp_rates_len = sta->supported_rates_len;
768 params.addr = addr;
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;
782 } else {
783 sta->flags |= WLAN_STA_MFP;
784 params.flags |= WPA_STA_MFP;
785 }
786
787 ret = wpa_drv_sta_add(wpa_s, &params);
788 if (ret) {
789 wpa_msg(wpa_s, MSG_ERROR,
790 "Driver failed to insert " MACSTR ": %d",
791 MAC2STR(addr), ret);
792 ap_free_sta(data, sta);
793 return NULL;
794 }
795
796 return sta;
797 }
798
799
800 void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
801 struct ieee802_11_elems *elems)
802 {
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;
807
808 sta = mesh_mpm_add_peer(wpa_s, addr, elems);
809 if (!sta)
810 return;
811
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;
821
822 mgmt = wpabuf_head(data->mesh_pending_auth);
823 os_reltime_age(&data->mesh_pending_auth_time, &age);
824 if (age.sec < 2 &&
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));
831 ieee802_11_mgmt(
832 data,
833 wpabuf_head(data->mesh_pending_auth),
834 wpabuf_len(data->mesh_pending_auth),
835 &fi);
836 }
837 wpabuf_free(data->mesh_pending_auth);
838 data->mesh_pending_auth = NULL;
839 }
840 return;
841 }
842
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);
847 } else {
848 mesh_rsn_auth_sae_sta(wpa_s, sta);
849 }
850 }
851
852
853 void mesh_mpm_mgmt_rx(struct wpa_supplicant *wpa_s, struct rx_mgmt *rx_mgmt)
854 {
855 struct hostapd_frame_info fi;
856
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);
862 }
863
864
865 static void mesh_mpm_plink_estab(struct wpa_supplicant *wpa_s,
866 struct sta_info *sta)
867 {
868 struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
869 struct mesh_conf *conf = wpa_s->ifmsh->mconf;
870 u8 seq[6] = {};
871
872 wpa_msg(wpa_s, MSG_INFO, "mesh plink with " MACSTR " established",
873 MAC2STR(sta->addr));
874
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);
880
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);
889
890 if (sta->igtk_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);
895 wpa_drv_set_key(
896 wpa_s,
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);
901 }
902 }
903
904 wpa_mesh_set_plink_state(wpa_s, sta, PLINK_ESTAB);
905 hapd->num_plinks++;
906
907 sta->flags |= WLAN_STA_ASSOC;
908 sta->mesh_sae_pmksa_caching = 0;
909
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);
913
914 /* Send ctrl event */
915 wpa_msg(wpa_s, MSG_INFO, MESH_PEER_CONNECTED MACSTR,
916 MAC2STR(sta->addr));
917
918 /* Send D-Bus event */
919 wpas_notify_mesh_peer_connected(wpa_s, sta->addr);
920 }
921
922
923 static void mesh_mpm_fsm(struct wpa_supplicant *wpa_s, struct sta_info *sta,
924 enum plink_event event, u16 reason)
925 {
926 struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
927 struct mesh_conf *conf = wpa_s->ifmsh->mconf;
928
929 wpa_msg(wpa_s, MSG_DEBUG, "MPM " MACSTR " state %s event %s",
930 MAC2STR(sta->addr), mplstate[sta->plink_state],
931 mplevent[event]);
932
933 switch (sta->plink_state) {
934 case PLINK_IDLE:
935 switch (event) {
936 case CLS_ACPT:
937 mesh_mpm_fsm_restart(wpa_s, sta);
938 break;
939 case OPN_ACPT:
940 mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_RCVD);
941 mesh_mpm_send_plink_action(wpa_s, sta, PLINK_CONFIRM,
942 0);
943 break;
944 case REQ_RJCT:
945 mesh_mpm_send_plink_action(wpa_s, sta,
946 PLINK_CLOSE, reason);
947 break;
948 default:
949 break;
950 }
951 break;
952 case PLINK_OPN_SNT:
953 switch (event) {
954 case OPN_RJCT:
955 case CNF_RJCT:
956 if (!reason)
957 reason = WLAN_REASON_MESH_CONFIG_POLICY_VIOLATION;
958 /* fall-through */
959 case CLS_ACPT:
960 wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
961 if (!reason)
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);
969 break;
970 case OPN_ACPT:
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,
974 PLINK_CONFIRM, 0);
975 break;
976 case CNF_ACPT:
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);
983 break;
984 default:
985 break;
986 }
987 break;
988 case PLINK_OPN_RCVD:
989 switch (event) {
990 case OPN_RJCT:
991 case CNF_RJCT:
992 if (!reason)
993 reason = WLAN_REASON_MESH_CONFIG_POLICY_VIOLATION;
994 /* fall-through */
995 case CLS_ACPT:
996 wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
997 if (!reason)
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);
1006 break;
1007 case OPN_ACPT:
1008 mesh_mpm_send_plink_action(wpa_s, sta,
1009 PLINK_CONFIRM, 0);
1010 break;
1011 case CNF_ACPT:
1012 if (conf->security & MESH_CONF_SEC_AMPE)
1013 mesh_rsn_derive_mtk(wpa_s, sta);
1014 mesh_mpm_plink_estab(wpa_s, sta);
1015 break;
1016 default:
1017 break;
1018 }
1019 break;
1020 case PLINK_CNF_RCVD:
1021 switch (event) {
1022 case OPN_RJCT:
1023 case CNF_RJCT:
1024 if (!reason)
1025 reason = WLAN_REASON_MESH_CONFIG_POLICY_VIOLATION;
1026 /* fall-through */
1027 case CLS_ACPT:
1028 wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
1029 if (!reason)
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);
1038 break;
1039 case OPN_ACPT:
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,
1044 PLINK_CONFIRM, 0);
1045 break;
1046 default:
1047 break;
1048 }
1049 break;
1050 case PLINK_ESTAB:
1051 switch (event) {
1052 case OPN_RJCT:
1053 case CNF_RJCT:
1054 case CLS_ACPT:
1055 wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
1056 if (!reason)
1057 reason = WLAN_REASON_MESH_CLOSE_RCVD;
1058
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;
1064
1065 wpa_msg(wpa_s, MSG_INFO, "mesh plink with " MACSTR
1066 " closed with reason %d",
1067 MAC2STR(sta->addr), reason);
1068
1069 wpa_msg(wpa_s, MSG_INFO, MESH_PEER_DISCONNECTED MACSTR,
1070 MAC2STR(sta->addr));
1071
1072 /* Send D-Bus event */
1073 wpas_notify_mesh_peer_disconnected(wpa_s, sta->addr,
1074 reason);
1075
1076 hapd->num_plinks--;
1077
1078 mesh_mpm_send_plink_action(wpa_s, sta,
1079 PLINK_CLOSE, reason);
1080 break;
1081 case OPN_ACPT:
1082 mesh_mpm_send_plink_action(wpa_s, sta,
1083 PLINK_CONFIRM, 0);
1084 break;
1085 default:
1086 break;
1087 }
1088 break;
1089 case PLINK_HOLDING:
1090 switch (event) {
1091 case CLS_ACPT:
1092 mesh_mpm_fsm_restart(wpa_s, sta);
1093 break;
1094 case OPN_ACPT:
1095 case CNF_ACPT:
1096 case OPN_RJCT:
1097 case CNF_RJCT:
1098 reason = sta->mpm_close_reason;
1099 mesh_mpm_send_plink_action(wpa_s, sta,
1100 PLINK_CLOSE, reason);
1101 break;
1102 default:
1103 break;
1104 }
1105 break;
1106 default:
1107 wpa_msg(wpa_s, MSG_DEBUG,
1108 "Unsupported MPM event %s for state %s",
1109 mplevent[event], mplstate[sta->plink_state]);
1110 break;
1111 }
1112 }
1113
1114
1115 void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
1116 const struct ieee80211_mgmt *mgmt, size_t len)
1117 {
1118 u8 action_field;
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;
1126 const u8 *ies;
1127 size_t ie_len;
1128 int ret;
1129 u16 reason = 0;
1130
1131 if (mgmt->u.action.category != WLAN_ACTION_SELF_PROTECTED)
1132 return;
1133
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)
1138 return;
1139
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;
1143
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);
1149 return;
1150 }
1151 wpa_printf(MSG_DEBUG, "MPM: Received PLINK action %u", action_field);
1152
1153 if (action_field == PLINK_OPEN || action_field == PLINK_CONFIRM) {
1154 wpa_printf(MSG_DEBUG, "MPM: Capability 0x%x",
1155 WPA_GET_LE16(ies));
1156 ies += 2; /* capability */
1157 ie_len -= 2;
1158 }
1159 if (action_field == PLINK_CONFIRM) {
1160 aid = WPA_GET_LE16(ies);
1161 wpa_printf(MSG_DEBUG, "MPM: AID 0x%x", aid);
1162 ies += 2; /* aid */
1163 ie_len -= 2;
1164 }
1165
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");
1169 return;
1170 }
1171 if (!elems.peer_mgmt) {
1172 wpa_printf(MSG_DEBUG,
1173 "MPM: No Mesh Peering Management element");
1174 return;
1175 }
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");
1180 return;
1181 }
1182
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");
1186 return;
1187 }
1188 }
1189
1190 ret = mesh_mpm_parse_peer_mgmt(wpa_s, action_field,
1191 elems.peer_mgmt,
1192 elems.peer_mgmt_len,
1193 &peer_mgmt_ie);
1194 if (ret) {
1195 wpa_printf(MSG_DEBUG, "MPM: Mesh parsing rejected frame");
1196 return;
1197 }
1198
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);
1204
1205 if (action_field == PLINK_CLOSE)
1206 wpa_printf(MSG_DEBUG, "MPM: close reason=%u",
1207 WPA_GET_LE16(peer_mgmt_ie.reason));
1208
1209 sta = ap_get_sta(hapd, mgmt->sa);
1210
1211 /*
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.
1214 */
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);
1219
1220 if (!sta) {
1221 wpa_printf(MSG_DEBUG, "MPM: No STA entry for peer");
1222 return;
1223 }
1224
1225 #ifdef CONFIG_SAE
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");
1229 return;
1230 }
1231 #endif /* CONFIG_SAE */
1232
1233 if (!sta->my_lid)
1234 mesh_mpm_init_link(wpa_s, sta);
1235
1236 if (mconf->security & MESH_CONF_SEC_AMPE) {
1237 int res;
1238
1239 res = mesh_rsn_process_ampe(wpa_s, sta, &elems,
1240 &mgmt->u.action.category,
1241 peer_mgmt_ie.chosen_pmk,
1242 ies, ie_len);
1243 if (res) {
1244 wpa_printf(MSG_DEBUG,
1245 "MPM: RSN process rejected frame (res=%d)",
1246 res);
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);
1251 }
1252 return;
1253 }
1254
1255 #ifdef CONFIG_OCV
1256 if (action_field == PLINK_OPEN && elems.rsn_ie) {
1257 struct wpa_state_machine *sm = sta->wpa_sm;
1258 struct wpa_ie_data data;
1259
1260 res = wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2,
1261 elems.rsn_ie_len + 2,
1262 &data);
1263 if (res) {
1264 wpa_printf(MSG_DEBUG,
1265 "Failed to parse RSN IE (res=%d)",
1266 res);
1267 wpa_hexdump(MSG_DEBUG, "RSN IE", elems.rsn_ie,
1268 elems.rsn_ie_len);
1269 return;
1270 }
1271
1272 wpa_auth_set_ocv(sm, mconf->ocv &&
1273 (data.capabilities &
1274 WPA_CAPABILITY_OCVC));
1275 }
1276
1277 if (action_field != PLINK_CLOSE &&
1278 wpa_auth_uses_ocv(sta->wpa_sm)) {
1279 struct wpa_channel_info ci;
1280 int tx_chanwidth;
1281 int tx_seg1_idx;
1282
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");
1286 return;
1287 }
1288
1289 if (get_tx_parameters(
1290 sta, channel_width_to_int(ci.chanwidth),
1291 ci.seg1_idx, &tx_chanwidth,
1292 &tx_seg1_idx) < 0)
1293 return;
1294
1295 if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci,
1296 tx_chanwidth, tx_seg1_idx) !=
1297 0) {
1298 wpa_printf(MSG_WARNING, "MPM: %s",
1299 ocv_errorstr);
1300 return;
1301 }
1302 }
1303 #endif /* CONFIG_OCV */
1304 }
1305
1306 if (sta->plink_state == PLINK_BLOCKED) {
1307 wpa_printf(MSG_DEBUG, "MPM: PLINK_BLOCKED");
1308 return;
1309 }
1310
1311 /* Now we will figure out the appropriate event... */
1312 switch (action_field) {
1313 case PLINK_OPEN:
1314 if (plink_free_count(hapd) == 0) {
1315 event = REQ_RJCT;
1316 reason = WLAN_REASON_MESH_MAX_PEERS;
1317 wpa_printf(MSG_INFO,
1318 "MPM: Peer link num over quota(%d)",
1319 hapd->max_plinks);
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 */
1325 } else {
1326 sta->peer_lid = plid;
1327 event = OPN_ACPT;
1328 }
1329 break;
1330 case PLINK_CONFIRM:
1331 if (plink_free_count(hapd) == 0) {
1332 event = REQ_RJCT;
1333 reason = WLAN_REASON_MESH_MAX_PEERS;
1334 wpa_printf(MSG_INFO,
1335 "MPM: Peer link num over quota(%d)",
1336 hapd->max_plinks);
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 */
1343 } else {
1344 if (!sta->peer_lid)
1345 sta->peer_lid = plid;
1346 sta->peer_aid = aid;
1347 event = CNF_ACPT;
1348 }
1349 break;
1350 case PLINK_CLOSE:
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
1359 * restarted.
1360 */
1361 event = CLS_ACPT;
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",
1370 sta->my_lid, llid);
1371 return; /* no FSM event */
1372 } else {
1373 event = CLS_ACPT;
1374 }
1375 break;
1376 default:
1377 /*
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.
1381 */
1382 return;
1383 }
1384 mesh_mpm_fsm(wpa_s, sta, event, reason);
1385 }
1386
1387
1388 /* called by ap_free_sta */
1389 void mesh_mpm_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
1390 {
1391 if (sta->plink_state == PLINK_ESTAB)
1392 hapd->num_plinks--;
1393 eloop_cancel_timeout(plink_timer, ELOOP_ALL_CTX, sta);
1394 eloop_cancel_timeout(mesh_auth_timer, ELOOP_ALL_CTX, sta);
1395 }