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