]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/wpa/wpa_supplicant/mesh_mpm.c
bhnd(9): Fix a few mandoc related issues
[FreeBSD/FreeBSD.git] / contrib / wpa / 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 }