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