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