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