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