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