/*
 * WPA Supplicant - Basic mesh peer management
 * Copyright (c) 2013-2014, cozybit, Inc.  All rights reserved.
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "utils/includes.h"

#include "utils/common.h"
#include "utils/eloop.h"
#include "common/ieee802_11_defs.h"
#include "common/hw_features_common.h"
#include "common/ocv.h"
#include "ap/hostapd.h"
#include "ap/sta_info.h"
#include "ap/ieee802_11.h"
#include "ap/wpa_auth.h"
#include "wpa_supplicant_i.h"
#include "driver_i.h"
#include "mesh_mpm.h"
#include "mesh_rsn.h"
#include "notify.h"

struct mesh_peer_mgmt_ie {
	const u8 *proto_id; /* Mesh Peering Protocol Identifier (2 octets) */
	const u8 *llid; /* Local Link ID (2 octets) */
	const u8 *plid; /* Peer Link ID (conditional, 2 octets) */
	const u8 *reason; /* Reason Code (conditional, 2 octets) */
	const u8 *chosen_pmk; /* Chosen PMK (optional, 16 octets) */
};

static void plink_timer(void *eloop_ctx, void *user_data);


enum plink_event {
	PLINK_UNDEFINED,
	OPN_ACPT,
	OPN_RJCT,
	CNF_ACPT,
	CNF_RJCT,
	CLS_ACPT,
	REQ_RJCT
};

static const char * const mplstate[] = {
	[0] = "UNINITIALIZED",
	[PLINK_IDLE] = "IDLE",
	[PLINK_OPN_SNT] = "OPN_SNT",
	[PLINK_OPN_RCVD] = "OPN_RCVD",
	[PLINK_CNF_RCVD] = "CNF_RCVD",
	[PLINK_ESTAB] = "ESTAB",
	[PLINK_HOLDING] = "HOLDING",
	[PLINK_BLOCKED] = "BLOCKED"
};

static const char * const mplevent[] = {
	[PLINK_UNDEFINED] = "UNDEFINED",
	[OPN_ACPT] = "OPN_ACPT",
	[OPN_RJCT] = "OPN_RJCT",
	[CNF_ACPT] = "CNF_ACPT",
	[CNF_RJCT] = "CNF_RJCT",
	[CLS_ACPT] = "CLS_ACPT",
	[REQ_RJCT] = "REQ_RJCT",
};


static int mesh_mpm_parse_peer_mgmt(struct wpa_supplicant *wpa_s,
				    u8 action_field,
				    const u8 *ie, size_t len,
				    struct mesh_peer_mgmt_ie *mpm_ie)
{
	os_memset(mpm_ie, 0, sizeof(*mpm_ie));

	/* Remove optional Chosen PMK field at end */
	if (len >= SAE_PMKID_LEN) {
		mpm_ie->chosen_pmk = ie + len - SAE_PMKID_LEN;
		len -= SAE_PMKID_LEN;
	}

	if ((action_field == PLINK_OPEN && len != 4) ||
	    (action_field == PLINK_CONFIRM && len != 6) ||
	    (action_field == PLINK_CLOSE && len != 6 && len != 8)) {
		wpa_msg(wpa_s, MSG_DEBUG, "MPM: Invalid peer mgmt ie");
		return -1;
	}

	/* required fields */
	if (len < 4)
		return -1;
	mpm_ie->proto_id = ie;
	mpm_ie->llid = ie + 2;
	ie += 4;
	len -= 4;

	/* close reason is always present at end for close */
	if (action_field == PLINK_CLOSE) {
		if (len < 2)
			return -1;
		mpm_ie->reason = ie + len - 2;
		len -= 2;
	}

	/* Peer Link ID, present for confirm, and possibly close */
	if (len >= 2)
		mpm_ie->plid = ie;

	return 0;
}


static int plink_free_count(struct hostapd_data *hapd)
{
	if (hapd->max_plinks > hapd->num_plinks)
		return hapd->max_plinks - hapd->num_plinks;
	return 0;
}


static u16 copy_supp_rates(struct wpa_supplicant *wpa_s,
			   struct sta_info *sta,
			   struct ieee802_11_elems *elems)
{
	if (!elems->supp_rates) {
		wpa_msg(wpa_s, MSG_ERROR, "no supported rates from " MACSTR,
			MAC2STR(sta->addr));
		return WLAN_STATUS_UNSPECIFIED_FAILURE;
	}

	if (elems->supp_rates_len + elems->ext_supp_rates_len >
	    sizeof(sta->supported_rates)) {
		wpa_msg(wpa_s, MSG_ERROR,
			"Invalid supported rates element length " MACSTR
			" %d+%d", MAC2STR(sta->addr), elems->supp_rates_len,
			elems->ext_supp_rates_len);
		return WLAN_STATUS_UNSPECIFIED_FAILURE;
	}

	sta->supported_rates_len = merge_byte_arrays(
		sta->supported_rates, sizeof(sta->supported_rates),
		elems->supp_rates, elems->supp_rates_len,
		elems->ext_supp_rates, elems->ext_supp_rates_len);

	return WLAN_STATUS_SUCCESS;
}


/* return true if elems from a neighbor match this MBSS */
static bool matches_local(struct wpa_supplicant *wpa_s,
			  struct ieee802_11_elems *elems)
{
	struct mesh_conf *mconf = wpa_s->ifmsh->mconf;

	if (elems->mesh_config_len < 5)
		return false;

	return (mconf->meshid_len == elems->mesh_id_len &&
		os_memcmp(mconf->meshid, elems->mesh_id,
			  elems->mesh_id_len) == 0 &&
		mconf->mesh_pp_id == elems->mesh_config[0] &&
		mconf->mesh_pm_id == elems->mesh_config[1] &&
		mconf->mesh_cc_id == elems->mesh_config[2] &&
		mconf->mesh_sp_id == elems->mesh_config[3] &&
		mconf->mesh_auth_id == elems->mesh_config[4]);
}


/* check if local link id is already used with another peer */
static bool llid_in_use(struct wpa_supplicant *wpa_s, u16 llid)
{
	struct sta_info *sta;
	struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];

	for (sta = hapd->sta_list; sta; sta = sta->next) {
		if (sta->my_lid == llid)
			return true;
	}

	return false;
}


/* generate an llid for a link and set to initial state */
static void mesh_mpm_init_link(struct wpa_supplicant *wpa_s,
			       struct sta_info *sta)
{
	u16 llid;

	do {
		if (os_get_random((u8 *) &llid, sizeof(llid)) < 0)
			llid = 0; /* continue */
	} while (!llid || llid_in_use(wpa_s, llid));

	sta->my_lid = llid;
	sta->peer_lid = 0;
	sta->peer_aid = 0;

	/*
	 * We do not use wpa_mesh_set_plink_state() here because there is no
	 * entry in kernel yet.
	 */
	sta->plink_state = PLINK_IDLE;
}


static void mesh_mpm_send_plink_action(struct wpa_supplicant *wpa_s,
				       struct sta_info *sta,
				       enum plink_action_field type,
				       u16 close_reason)
{
	struct wpabuf *buf;
	struct hostapd_iface *ifmsh = wpa_s->ifmsh;
	struct hostapd_data *bss = ifmsh->bss[0];
	struct mesh_conf *conf = ifmsh->mconf;
	u8 supp_rates[2 + 2 + 32];
	u8 *pos, *cat;
	u8 ie_len, add_plid = 0;
	int ret;
	int ampe = conf->security & MESH_CONF_SEC_AMPE;
	size_t buf_len;

	if (!sta)
		return;

	buf_len = 2 +      /* Category and Action */
		  2 +      /* capability info */
		  2 +      /* AID */
		  2 + 8 +  /* supported rates */
		  2 + (32 - 8) +
		  2 + 32 + /* mesh ID */
		  2 + 7 +  /* mesh config */
		  2 + 24 + /* peering management */
		  2 + 96 + 32 + 32 + /* AMPE (96 + max GTKlen + max IGTKlen) */
		  2 + 16;  /* MIC */
	if (type != PLINK_CLOSE && wpa_s->mesh_ht_enabled) {
		buf_len += 2 + 26 + /* HT capabilities */
			   2 + 22;  /* HT operation */
	}
#ifdef CONFIG_IEEE80211AC
	if (type != PLINK_CLOSE && wpa_s->mesh_vht_enabled) {
		buf_len += 2 + 12 + /* VHT Capabilities */
			   2 + 5;  /* VHT Operation */
	}
#endif /* CONFIG_IEEE80211AC */
#ifdef CONFIG_IEEE80211AX
	if (type != PLINK_CLOSE && wpa_s->mesh_he_enabled) {
		buf_len += 3 +
			   HE_MAX_MAC_CAPAB_SIZE +
			   HE_MAX_PHY_CAPAB_SIZE +
			   HE_MAX_MCS_CAPAB_SIZE +
			   HE_MAX_PPET_CAPAB_SIZE;
		buf_len += 3 + sizeof(struct ieee80211_he_operation);
	}
#endif /* CONFIG_IEEE80211AX */
	if (type != PLINK_CLOSE)
		buf_len += conf->rsn_ie_len; /* RSN IE */
#ifdef CONFIG_OCV
	/* OCI is included even when the other STA doesn't support OCV */
	if (type != PLINK_CLOSE && conf->ocv)
		buf_len += OCV_OCI_EXTENDED_LEN;
#endif /* CONFIG_OCV */

	buf = wpabuf_alloc(buf_len);
	if (!buf)
		return;

	cat = wpabuf_mhead_u8(buf);
	wpabuf_put_u8(buf, WLAN_ACTION_SELF_PROTECTED);
	wpabuf_put_u8(buf, type);

	if (type != PLINK_CLOSE) {
		u8 info;

		/* capability info */
		wpabuf_put_le16(buf, ampe ? IEEE80211_CAP_PRIVACY : 0);

		/* aid */
		if (type == PLINK_CONFIRM)
			wpabuf_put_le16(buf, sta->aid);

		/* IE: supp + ext. supp rates */
		pos = hostapd_eid_supp_rates(bss, supp_rates);
		pos = hostapd_eid_ext_supp_rates(bss, pos);
		wpabuf_put_data(buf, supp_rates, pos - supp_rates);

		/* IE: RSN IE */
		wpabuf_put_data(buf, conf->rsn_ie, conf->rsn_ie_len);

		/* IE: Mesh ID */
		wpabuf_put_u8(buf, WLAN_EID_MESH_ID);
		wpabuf_put_u8(buf, conf->meshid_len);
		wpabuf_put_data(buf, conf->meshid, conf->meshid_len);

		/* IE: mesh conf */
		wpabuf_put_u8(buf, WLAN_EID_MESH_CONFIG);
		wpabuf_put_u8(buf, 7);
		wpabuf_put_u8(buf, conf->mesh_pp_id);
		wpabuf_put_u8(buf, conf->mesh_pm_id);
		wpabuf_put_u8(buf, conf->mesh_cc_id);
		wpabuf_put_u8(buf, conf->mesh_sp_id);
		wpabuf_put_u8(buf, conf->mesh_auth_id);
		info = (bss->num_plinks > 63 ? 63 : bss->num_plinks) << 1;
		/* TODO: Add Connected to Mesh Gate/AS subfields */
		wpabuf_put_u8(buf, info);
		/* always forwarding & accepting plinks for now */
		wpabuf_put_u8(buf, MESH_CAP_ACCEPT_ADDITIONAL_PEER |
			      MESH_CAP_FORWARDING);
	} else {	/* Peer closing frame */
		/* IE: Mesh ID */
		wpabuf_put_u8(buf, WLAN_EID_MESH_ID);
		wpabuf_put_u8(buf, conf->meshid_len);
		wpabuf_put_data(buf, conf->meshid, conf->meshid_len);
	}

	/* IE: Mesh Peering Management element */
	ie_len = 4;
	if (ampe)
		ie_len += PMKID_LEN;
	switch (type) {
	case PLINK_OPEN:
		break;
	case PLINK_CONFIRM:
		ie_len += 2;
		add_plid = 1;
		break;
	case PLINK_CLOSE:
		ie_len += 2;
		add_plid = 1;
		ie_len += 2; /* reason code */
		break;
	}

	wpabuf_put_u8(buf, WLAN_EID_PEER_MGMT);
	wpabuf_put_u8(buf, ie_len);
	/* peering protocol */
	if (ampe)
		wpabuf_put_le16(buf, 1);
	else
		wpabuf_put_le16(buf, 0);
	wpabuf_put_le16(buf, sta->my_lid);
	if (add_plid)
		wpabuf_put_le16(buf, sta->peer_lid);
	if (type == PLINK_CLOSE)
		wpabuf_put_le16(buf, close_reason);
	if (ampe) {
		if (sta->sae == NULL) {
			wpa_msg(wpa_s, MSG_INFO, "Mesh MPM: no SAE session");
			goto fail;
		}
		mesh_rsn_get_pmkid(wpa_s->mesh_rsn, sta,
				   wpabuf_put(buf, PMKID_LEN));
	}

	if (type != PLINK_CLOSE && wpa_s->mesh_ht_enabled) {
		u8 ht_capa_oper[2 + 26 + 2 + 22];

		pos = hostapd_eid_ht_capabilities(bss, ht_capa_oper);
		pos = hostapd_eid_ht_operation(bss, pos);
		wpabuf_put_data(buf, ht_capa_oper, pos - ht_capa_oper);
	}
#ifdef CONFIG_IEEE80211AC
	if (type != PLINK_CLOSE && wpa_s->mesh_vht_enabled) {
		u8 vht_capa_oper[2 + 12 + 2 + 5];

		pos = hostapd_eid_vht_capabilities(bss, vht_capa_oper, 0);
		pos = hostapd_eid_vht_operation(bss, pos);
		wpabuf_put_data(buf, vht_capa_oper, pos - vht_capa_oper);
	}
#endif /* CONFIG_IEEE80211AC */
#ifdef CONFIG_IEEE80211AX
	if (type != PLINK_CLOSE && wpa_s->mesh_he_enabled) {
		u8 he_capa_oper[3 +
				HE_MAX_MAC_CAPAB_SIZE +
				HE_MAX_PHY_CAPAB_SIZE +
				HE_MAX_MCS_CAPAB_SIZE +
				HE_MAX_PPET_CAPAB_SIZE +
				3 + sizeof(struct ieee80211_he_operation)];

		pos = hostapd_eid_he_capab(bss, he_capa_oper,
					   IEEE80211_MODE_MESH);
		pos = hostapd_eid_he_operation(bss, pos);
		wpabuf_put_data(buf, he_capa_oper, pos - he_capa_oper);
	}
#endif /* CONFIG_IEEE80211AX */

#ifdef CONFIG_OCV
	if (type != PLINK_CLOSE && conf->ocv) {
		struct wpa_channel_info ci;

		if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
			wpa_printf(MSG_WARNING,
				   "Mesh MPM: Failed to get channel info for OCI element");
			goto fail;
		}

		pos = wpabuf_put(buf, OCV_OCI_EXTENDED_LEN);
		if (ocv_insert_extended_oci(&ci, pos) < 0)
			goto fail;
	}
#endif /* CONFIG_OCV */

	if (ampe && mesh_rsn_protect_frame(wpa_s->mesh_rsn, sta, cat, buf)) {
		wpa_msg(wpa_s, MSG_INFO,
			"Mesh MPM: failed to add AMPE and MIC IE");
		goto fail;
	}

	wpa_msg(wpa_s, MSG_DEBUG, "Mesh MPM: Sending peering frame type %d to "
		MACSTR " (my_lid=0x%x peer_lid=0x%x)",
		type, MAC2STR(sta->addr), sta->my_lid, sta->peer_lid);
	ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0,
				  sta->addr, wpa_s->own_addr, wpa_s->own_addr,
				  wpabuf_head(buf), wpabuf_len(buf), 0);
	if (ret < 0)
		wpa_msg(wpa_s, MSG_INFO,
			"Mesh MPM: failed to send peering frame");

fail:
	wpabuf_free(buf);
}


/* configure peering state in ours and driver's station entry */
void wpa_mesh_set_plink_state(struct wpa_supplicant *wpa_s,
			      struct sta_info *sta,
			      enum mesh_plink_state state)
{
	struct hostapd_sta_add_params params;
	int ret;

	wpa_msg(wpa_s, MSG_DEBUG, "MPM set " MACSTR " from %s into %s",
		MAC2STR(sta->addr), mplstate[sta->plink_state],
		mplstate[state]);
	sta->plink_state = state;

	os_memset(&params, 0, sizeof(params));
	params.addr = sta->addr;
	params.plink_state = state;
	params.peer_aid = sta->peer_aid;
	params.set = 1;

	ret = wpa_drv_sta_add(wpa_s, &params);
	if (ret) {
		wpa_msg(wpa_s, MSG_ERROR, "Driver failed to set " MACSTR
			": %d", MAC2STR(sta->addr), ret);
	}
}


static void mesh_mpm_fsm_restart(struct wpa_supplicant *wpa_s,
				 struct sta_info *sta)
{
	struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];

	eloop_cancel_timeout(plink_timer, wpa_s, sta);

	ap_free_sta(hapd, sta);
}


static void plink_timer(void *eloop_ctx, void *user_data)
{
	struct wpa_supplicant *wpa_s = eloop_ctx;
	struct sta_info *sta = user_data;
	u16 reason = 0;
	struct mesh_conf *conf = wpa_s->ifmsh->mconf;
	struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];

	switch (sta->plink_state) {
	case PLINK_OPN_RCVD:
	case PLINK_OPN_SNT:
		/* retry timer */
		if (sta->mpm_retries < conf->dot11MeshMaxRetries) {
			eloop_register_timeout(
				conf->dot11MeshRetryTimeout / 1000,
				(conf->dot11MeshRetryTimeout % 1000) * 1000,
				plink_timer, wpa_s, sta);
			mesh_mpm_send_plink_action(wpa_s, sta, PLINK_OPEN, 0);
			sta->mpm_retries++;
			break;
		}
		reason = WLAN_REASON_MESH_MAX_RETRIES;
		/* fall through */

	case PLINK_CNF_RCVD:
		/* confirm timer */
		if (!reason)
			reason = WLAN_REASON_MESH_CONFIRM_TIMEOUT;
		wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
		eloop_register_timeout(conf->dot11MeshHoldingTimeout / 1000,
			(conf->dot11MeshHoldingTimeout % 1000) * 1000,
			plink_timer, wpa_s, sta);
		mesh_mpm_send_plink_action(wpa_s, sta, PLINK_CLOSE, reason);
		break;
	case PLINK_HOLDING:
		/* holding timer */

		if (sta->mesh_sae_pmksa_caching) {
			wpa_printf(MSG_DEBUG, "MPM: Peer " MACSTR
				   " looks like it does not support mesh SAE PMKSA caching, so remove the cached entry for it",
				   MAC2STR(sta->addr));
			wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
		}
		mesh_mpm_fsm_restart(wpa_s, sta);
		break;
	default:
		break;
	}
}


/* initiate peering with station */
static void
mesh_mpm_plink_open(struct wpa_supplicant *wpa_s, struct sta_info *sta,
		    enum mesh_plink_state next_state)
{
	struct mesh_conf *conf = wpa_s->ifmsh->mconf;

	eloop_cancel_timeout(plink_timer, wpa_s, sta);
	eloop_register_timeout(conf->dot11MeshRetryTimeout / 1000,
			       (conf->dot11MeshRetryTimeout % 1000) * 1000,
			       plink_timer, wpa_s, sta);
	mesh_mpm_send_plink_action(wpa_s, sta, PLINK_OPEN, 0);
	wpa_mesh_set_plink_state(wpa_s, sta, next_state);
}


static int mesh_mpm_plink_close(struct hostapd_data *hapd, struct sta_info *sta,
				void *ctx)
{
	struct wpa_supplicant *wpa_s = ctx;
	int reason = WLAN_REASON_MESH_PEERING_CANCELLED;

	if (sta) {
		if (sta->plink_state == PLINK_ESTAB)
			hapd->num_plinks--;
		wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
		mesh_mpm_send_plink_action(wpa_s, sta, PLINK_CLOSE, reason);
		wpa_printf(MSG_DEBUG, "MPM closing plink sta=" MACSTR,
			   MAC2STR(sta->addr));
		eloop_cancel_timeout(plink_timer, wpa_s, sta);
		eloop_cancel_timeout(mesh_auth_timer, wpa_s, sta);
		return 0;
	}

	return 1;
}


int mesh_mpm_close_peer(struct wpa_supplicant *wpa_s, const u8 *addr)
{
	struct hostapd_data *hapd;
	struct sta_info *sta;

	if (!wpa_s->ifmsh) {
		wpa_msg(wpa_s, MSG_INFO, "Mesh is not prepared yet");
		return -1;
	}

	hapd = wpa_s->ifmsh->bss[0];
	sta = ap_get_sta(hapd, addr);
	if (!sta) {
		wpa_msg(wpa_s, MSG_INFO, "No such mesh peer");
		return -1;
	}

	return mesh_mpm_plink_close(hapd, sta, wpa_s) == 0 ? 0 : -1;
}


static void peer_add_timer(void *eloop_ctx, void *user_data)
{
	struct wpa_supplicant *wpa_s = eloop_ctx;
	struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];

	os_memset(hapd->mesh_required_peer, 0, ETH_ALEN);
}


int mesh_mpm_connect_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
			  int duration)
{
	struct wpa_ssid *ssid = wpa_s->current_ssid;
	struct hostapd_data *hapd;
	struct sta_info *sta;
	struct mesh_conf *conf;

	if (!wpa_s->ifmsh) {
		wpa_msg(wpa_s, MSG_INFO, "Mesh is not prepared yet");
		return -1;
	}

	if (!ssid || !ssid->no_auto_peer) {
		wpa_msg(wpa_s, MSG_INFO,
			"This command is available only with no_auto_peer mesh network");
		return -1;
	}

	hapd = wpa_s->ifmsh->bss[0];
	conf = wpa_s->ifmsh->mconf;

	sta = ap_get_sta(hapd, addr);
	if (!sta) {
		wpa_msg(wpa_s, MSG_INFO, "No such mesh peer");
		return -1;
	}

	if ((PLINK_OPN_SNT <= sta->plink_state &&
	    sta->plink_state <= PLINK_ESTAB) ||
	    (sta->sae && sta->sae->state > SAE_NOTHING)) {
		wpa_msg(wpa_s, MSG_INFO,
			"Specified peer is connecting/connected");
		return -1;
	}

	if (conf->security == MESH_CONF_SEC_NONE) {
		mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_SNT);
	} else {
		mesh_rsn_auth_sae_sta(wpa_s, sta);
		os_memcpy(hapd->mesh_required_peer, addr, ETH_ALEN);
		eloop_register_timeout(duration == -1 ? 10 : duration, 0,
				       peer_add_timer, wpa_s, NULL);
	}

	return 0;
}


void mesh_mpm_deinit(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh)
{
	struct hostapd_data *hapd = ifmsh->bss[0];

	/* notify peers we're leaving */
	ap_for_each_sta(hapd, mesh_mpm_plink_close, wpa_s);

	hapd->num_plinks = 0;
	hostapd_free_stas(hapd);
	eloop_cancel_timeout(peer_add_timer, wpa_s, NULL);
}


/* for mesh_rsn to indicate this peer has completed authentication, and we're
 * ready to start AMPE */
void mesh_mpm_auth_peer(struct wpa_supplicant *wpa_s, const u8 *addr)
{
	struct hostapd_data *data = wpa_s->ifmsh->bss[0];
	struct hostapd_sta_add_params params;
	struct sta_info *sta;
	int ret;

	sta = ap_get_sta(data, addr);
	if (!sta) {
		wpa_msg(wpa_s, MSG_DEBUG, "no such mesh peer");
		return;
	}

	/* TODO: Should do nothing if this STA is already authenticated, but
	 * the AP code already sets this flag. */
	sta->flags |= WLAN_STA_AUTH;

	mesh_rsn_init_ampe_sta(wpa_s, sta);

	os_memset(&params, 0, sizeof(params));
	params.addr = sta->addr;
	params.flags = WPA_STA_AUTHENTICATED | WPA_STA_AUTHORIZED;
	params.set = 1;

	wpa_msg(wpa_s, MSG_DEBUG, "MPM authenticating " MACSTR,
		MAC2STR(sta->addr));
	ret = wpa_drv_sta_add(wpa_s, &params);
	if (ret) {
		wpa_msg(wpa_s, MSG_ERROR,
			"Driver failed to set " MACSTR ": %d",
			MAC2STR(sta->addr), ret);
	}

	if (!sta->my_lid)
		mesh_mpm_init_link(wpa_s, sta);

	mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_SNT);
}

/*
 * Initialize a sta_info structure for a peer and upload it into the driver
 * in preparation for beginning authentication or peering. This is done when a
 * Beacon (secure or open mesh) or a peering open frame (for open mesh) is
 * received from the peer for the first time.
 */
static struct sta_info * mesh_mpm_add_peer(struct wpa_supplicant *wpa_s,
					   const u8 *addr,
					   struct ieee802_11_elems *elems)
{
	struct hostapd_sta_add_params params;
	struct mesh_conf *conf = wpa_s->ifmsh->mconf;
	struct hostapd_data *data = wpa_s->ifmsh->bss[0];
	struct sta_info *sta;
	struct ieee80211_ht_operation *oper;
	int ret;

	if (elems->mesh_config_len >= 7 &&
	    !(elems->mesh_config[6] & MESH_CAP_ACCEPT_ADDITIONAL_PEER)) {
		wpa_msg(wpa_s, MSG_DEBUG,
			"mesh: Ignore a crowded peer " MACSTR,
			MAC2STR(addr));
		return NULL;
	}

	sta = ap_get_sta(data, addr);
	if (sta)
		return NULL;

	sta = ap_sta_add(data, addr);
	if (!sta)
		return NULL;

	/* Set WMM by default since Mesh STAs are QoS STAs */
	sta->flags |= WLAN_STA_WMM;

	/* initialize sta */
	if (copy_supp_rates(wpa_s, sta, elems)) {
		ap_free_sta(data, sta);
		return NULL;
	}

	if (!sta->my_lid)
		mesh_mpm_init_link(wpa_s, sta);

	copy_sta_ht_capab(data, sta, elems->ht_capabilities);

	oper = (struct ieee80211_ht_operation *) elems->ht_operation;
	if (oper &&
	    !(oper->ht_param & HT_INFO_HT_PARAM_STA_CHNL_WIDTH) &&
	    sta->ht_capabilities) {
		wpa_msg(wpa_s, MSG_DEBUG, MACSTR
			" does not support 40 MHz bandwidth",
			MAC2STR(sta->addr));
		set_disable_ht40(sta->ht_capabilities, 1);
	}

	update_ht_state(data, sta);

#ifdef CONFIG_IEEE80211AC
	copy_sta_vht_capab(data, sta, elems->vht_capabilities);
	copy_sta_vht_oper(data, sta, elems->vht_operation);
	set_sta_vht_opmode(data, sta, elems->vht_opmode_notif);
#endif /* CONFIG_IEEE80211AC */

#ifdef CONFIG_IEEE80211AX
	copy_sta_he_capab(data, sta, IEEE80211_MODE_MESH,
			  elems->he_capabilities, elems->he_capabilities_len);
#endif /* CONFIG_IEEE80211AX */

	if (hostapd_get_aid(data, sta) < 0) {
		wpa_msg(wpa_s, MSG_ERROR, "No AIDs available");
		ap_free_sta(data, sta);
		return NULL;
	}

	/* insert into driver */
	os_memset(&params, 0, sizeof(params));
	params.supp_rates = sta->supported_rates;
	params.supp_rates_len = sta->supported_rates_len;
	params.addr = addr;
	params.plink_state = sta->plink_state;
	params.aid = sta->aid;
	params.peer_aid = sta->peer_aid;
	params.listen_interval = 100;
	params.ht_capabilities = sta->ht_capabilities;
	params.vht_capabilities = sta->vht_capabilities;
	params.he_capab = sta->he_capab;
	params.he_capab_len = sta->he_capab_len;
	params.flags |= WPA_STA_WMM;
	params.flags_mask |= WPA_STA_AUTHENTICATED;
	if (conf->security == MESH_CONF_SEC_NONE) {
		params.flags |= WPA_STA_AUTHORIZED;
		params.flags |= WPA_STA_AUTHENTICATED;
	} else {
		sta->flags |= WLAN_STA_MFP;
		params.flags |= WPA_STA_MFP;
	}

	ret = wpa_drv_sta_add(wpa_s, &params);
	if (ret) {
		wpa_msg(wpa_s, MSG_ERROR,
			"Driver failed to insert " MACSTR ": %d",
			MAC2STR(addr), ret);
		ap_free_sta(data, sta);
		return NULL;
	}

	return sta;
}


void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
			    struct ieee802_11_elems *elems)
{
	struct mesh_conf *conf = wpa_s->ifmsh->mconf;
	struct hostapd_data *data = wpa_s->ifmsh->bss[0];
	struct sta_info *sta;
	struct wpa_ssid *ssid = wpa_s->current_ssid;

	sta = mesh_mpm_add_peer(wpa_s, addr, elems);
	if (!sta)
		return;

	if (ssid && ssid->no_auto_peer &&
	    (is_zero_ether_addr(data->mesh_required_peer) ||
	     os_memcmp(data->mesh_required_peer, addr, ETH_ALEN) != 0)) {
		wpa_msg(wpa_s, MSG_INFO, "will not initiate new peer link with "
			MACSTR " because of no_auto_peer", MAC2STR(addr));
		if (data->mesh_pending_auth) {
			struct os_reltime age;
			const struct ieee80211_mgmt *mgmt;
			struct hostapd_frame_info fi;

			mgmt = wpabuf_head(data->mesh_pending_auth);
			os_reltime_age(&data->mesh_pending_auth_time, &age);
			if (age.sec < 2 &&
			    os_memcmp(mgmt->sa, addr, ETH_ALEN) == 0) {
				wpa_printf(MSG_DEBUG,
					   "mesh: Process pending Authentication frame from %u.%06u seconds ago",
					   (unsigned int) age.sec,
					   (unsigned int) age.usec);
				os_memset(&fi, 0, sizeof(fi));
				ieee802_11_mgmt(
					data,
					wpabuf_head(data->mesh_pending_auth),
					wpabuf_len(data->mesh_pending_auth),
					&fi);
			}
			wpabuf_free(data->mesh_pending_auth);
			data->mesh_pending_auth = NULL;
		}
		return;
	}

	if (conf->security == MESH_CONF_SEC_NONE) {
		if (sta->plink_state < PLINK_OPN_SNT ||
		    sta->plink_state > PLINK_ESTAB)
			mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_SNT);
	} else {
		mesh_rsn_auth_sae_sta(wpa_s, sta);
	}
}


void mesh_mpm_mgmt_rx(struct wpa_supplicant *wpa_s, struct rx_mgmt *rx_mgmt)
{
	struct hostapd_frame_info fi;

	os_memset(&fi, 0, sizeof(fi));
	fi.datarate = rx_mgmt->datarate;
	fi.ssi_signal = rx_mgmt->ssi_signal;
	ieee802_11_mgmt(wpa_s->ifmsh->bss[0], rx_mgmt->frame,
			rx_mgmt->frame_len, &fi);
}


static void mesh_mpm_plink_estab(struct wpa_supplicant *wpa_s,
				 struct sta_info *sta)
{
	struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
	struct mesh_conf *conf = wpa_s->ifmsh->mconf;
	u8 seq[6] = {};

	wpa_msg(wpa_s, MSG_INFO, "mesh plink with " MACSTR " established",
		MAC2STR(sta->addr));

	if (conf->security & MESH_CONF_SEC_AMPE) {
		wpa_hexdump_key(MSG_DEBUG, "mesh: MTK", sta->mtk, sta->mtk_len);
		wpa_drv_set_key(wpa_s, wpa_cipher_to_alg(conf->pairwise_cipher),
				sta->addr, 0, 0, seq, sizeof(seq),
				sta->mtk, sta->mtk_len,
				KEY_FLAG_PAIRWISE_RX_TX);

		wpa_hexdump_key(MSG_DEBUG, "mesh: RX MGTK Key RSC",
				sta->mgtk_rsc, sizeof(sta->mgtk_rsc));
		wpa_hexdump_key(MSG_DEBUG, "mesh: RX MGTK",
				sta->mgtk, sta->mgtk_len);
		wpa_drv_set_key(wpa_s, wpa_cipher_to_alg(conf->group_cipher),
				sta->addr, sta->mgtk_key_id, 0,
				sta->mgtk_rsc, sizeof(sta->mgtk_rsc),
				sta->mgtk, sta->mgtk_len,
				KEY_FLAG_GROUP_RX);

		if (sta->igtk_len) {
			wpa_hexdump_key(MSG_DEBUG, "mesh: RX IGTK Key RSC",
					sta->igtk_rsc, sizeof(sta->igtk_rsc));
			wpa_hexdump_key(MSG_DEBUG, "mesh: RX IGTK",
					sta->igtk, sta->igtk_len);
			wpa_drv_set_key(
				wpa_s,
				wpa_cipher_to_alg(conf->mgmt_group_cipher),
				sta->addr, sta->igtk_key_id, 0,
				sta->igtk_rsc, sizeof(sta->igtk_rsc),
				sta->igtk, sta->igtk_len,
				KEY_FLAG_GROUP_RX);
		}
	}

	wpa_mesh_set_plink_state(wpa_s, sta, PLINK_ESTAB);
	hapd->num_plinks++;

	sta->flags |= WLAN_STA_ASSOC;
	sta->mesh_sae_pmksa_caching = 0;

	eloop_cancel_timeout(peer_add_timer, wpa_s, NULL);
	peer_add_timer(wpa_s, NULL);
	eloop_cancel_timeout(plink_timer, wpa_s, sta);

	/* Send ctrl event */
	wpa_msg(wpa_s, MSG_INFO, MESH_PEER_CONNECTED MACSTR,
		MAC2STR(sta->addr));

	/* Send D-Bus event */
	wpas_notify_mesh_peer_connected(wpa_s, sta->addr);
}


static void mesh_mpm_fsm(struct wpa_supplicant *wpa_s, struct sta_info *sta,
			 enum plink_event event, u16 reason)
{
	struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
	struct mesh_conf *conf = wpa_s->ifmsh->mconf;

	wpa_msg(wpa_s, MSG_DEBUG, "MPM " MACSTR " state %s event %s",
		MAC2STR(sta->addr), mplstate[sta->plink_state],
		mplevent[event]);

	switch (sta->plink_state) {
	case PLINK_IDLE:
		switch (event) {
		case CLS_ACPT:
			mesh_mpm_fsm_restart(wpa_s, sta);
			break;
		case OPN_ACPT:
			mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_RCVD);
			mesh_mpm_send_plink_action(wpa_s, sta, PLINK_CONFIRM,
						   0);
			break;
		case REQ_RJCT:
			mesh_mpm_send_plink_action(wpa_s, sta,
						   PLINK_CLOSE, reason);
			break;
		default:
			break;
		}
		break;
	case PLINK_OPN_SNT:
		switch (event) {
		case OPN_RJCT:
		case CNF_RJCT:
			if (!reason)
				reason = WLAN_REASON_MESH_CONFIG_POLICY_VIOLATION;
			/* fall-through */
		case CLS_ACPT:
			wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
			if (!reason)
				reason = WLAN_REASON_MESH_CLOSE_RCVD;
			eloop_register_timeout(
				conf->dot11MeshHoldingTimeout / 1000,
				(conf->dot11MeshHoldingTimeout % 1000) * 1000,
				plink_timer, wpa_s, sta);
			mesh_mpm_send_plink_action(wpa_s, sta,
						   PLINK_CLOSE, reason);
			break;
		case OPN_ACPT:
			/* retry timer is left untouched */
			wpa_mesh_set_plink_state(wpa_s, sta, PLINK_OPN_RCVD);
			mesh_mpm_send_plink_action(wpa_s, sta,
						   PLINK_CONFIRM, 0);
			break;
		case CNF_ACPT:
			wpa_mesh_set_plink_state(wpa_s, sta, PLINK_CNF_RCVD);
			eloop_cancel_timeout(plink_timer, wpa_s, sta);
			eloop_register_timeout(
				conf->dot11MeshConfirmTimeout / 1000,
				(conf->dot11MeshConfirmTimeout % 1000) * 1000,
				plink_timer, wpa_s, sta);
			break;
		default:
			break;
		}
		break;
	case PLINK_OPN_RCVD:
		switch (event) {
		case OPN_RJCT:
		case CNF_RJCT:
			if (!reason)
				reason = WLAN_REASON_MESH_CONFIG_POLICY_VIOLATION;
			/* fall-through */
		case CLS_ACPT:
			wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
			if (!reason)
				reason = WLAN_REASON_MESH_CLOSE_RCVD;
			eloop_register_timeout(
				conf->dot11MeshHoldingTimeout / 1000,
				(conf->dot11MeshHoldingTimeout % 1000) * 1000,
				plink_timer, wpa_s, sta);
			sta->mpm_close_reason = reason;
			mesh_mpm_send_plink_action(wpa_s, sta,
						   PLINK_CLOSE, reason);
			break;
		case OPN_ACPT:
			mesh_mpm_send_plink_action(wpa_s, sta,
						   PLINK_CONFIRM, 0);
			break;
		case CNF_ACPT:
			if (conf->security & MESH_CONF_SEC_AMPE)
				mesh_rsn_derive_mtk(wpa_s, sta);
			mesh_mpm_plink_estab(wpa_s, sta);
			break;
		default:
			break;
		}
		break;
	case PLINK_CNF_RCVD:
		switch (event) {
		case OPN_RJCT:
		case CNF_RJCT:
			if (!reason)
				reason = WLAN_REASON_MESH_CONFIG_POLICY_VIOLATION;
			/* fall-through */
		case CLS_ACPT:
			wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
			if (!reason)
				reason = WLAN_REASON_MESH_CLOSE_RCVD;
			eloop_register_timeout(
				conf->dot11MeshHoldingTimeout / 1000,
				(conf->dot11MeshHoldingTimeout % 1000) * 1000,
				plink_timer, wpa_s, sta);
			sta->mpm_close_reason = reason;
			mesh_mpm_send_plink_action(wpa_s, sta,
						   PLINK_CLOSE, reason);
			break;
		case OPN_ACPT:
			if (conf->security & MESH_CONF_SEC_AMPE)
				mesh_rsn_derive_mtk(wpa_s, sta);
			mesh_mpm_plink_estab(wpa_s, sta);
			mesh_mpm_send_plink_action(wpa_s, sta,
						   PLINK_CONFIRM, 0);
			break;
		default:
			break;
		}
		break;
	case PLINK_ESTAB:
		switch (event) {
		case OPN_RJCT:
		case CNF_RJCT:
		case CLS_ACPT:
			wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
			if (!reason)
				reason = WLAN_REASON_MESH_CLOSE_RCVD;

			eloop_register_timeout(
				conf->dot11MeshHoldingTimeout / 1000,
				(conf->dot11MeshHoldingTimeout % 1000) * 1000,
				plink_timer, wpa_s, sta);
			sta->mpm_close_reason = reason;

			wpa_msg(wpa_s, MSG_INFO, "mesh plink with " MACSTR
				" closed with reason %d",
				MAC2STR(sta->addr), reason);

			wpa_msg(wpa_s, MSG_INFO, MESH_PEER_DISCONNECTED MACSTR,
				MAC2STR(sta->addr));

			/* Send D-Bus event */
			wpas_notify_mesh_peer_disconnected(wpa_s, sta->addr,
							   reason);

			hapd->num_plinks--;

			mesh_mpm_send_plink_action(wpa_s, sta,
						   PLINK_CLOSE, reason);
			break;
		case OPN_ACPT:
			mesh_mpm_send_plink_action(wpa_s, sta,
						   PLINK_CONFIRM, 0);
			break;
		default:
			break;
		}
		break;
	case PLINK_HOLDING:
		switch (event) {
		case CLS_ACPT:
			mesh_mpm_fsm_restart(wpa_s, sta);
			break;
		case OPN_ACPT:
		case CNF_ACPT:
		case OPN_RJCT:
		case CNF_RJCT:
			reason = sta->mpm_close_reason;
			mesh_mpm_send_plink_action(wpa_s, sta,
						   PLINK_CLOSE, reason);
			break;
		default:
			break;
		}
		break;
	default:
		wpa_msg(wpa_s, MSG_DEBUG,
			"Unsupported MPM event %s for state %s",
			mplevent[event], mplstate[sta->plink_state]);
		break;
	}
}


void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
			const struct ieee80211_mgmt *mgmt, size_t len)
{
	u8 action_field;
	struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
	struct mesh_conf *mconf = wpa_s->ifmsh->mconf;
	struct sta_info *sta;
	u16 plid = 0, llid = 0, aid = 0;
	enum plink_event event;
	struct ieee802_11_elems elems;
	struct mesh_peer_mgmt_ie peer_mgmt_ie;
	const u8 *ies;
	size_t ie_len;
	int ret;
	u16 reason = 0;

	if (mgmt->u.action.category != WLAN_ACTION_SELF_PROTECTED)
		return;

	action_field = mgmt->u.action.u.slf_prot_action.action;
	if (action_field != PLINK_OPEN &&
	    action_field != PLINK_CONFIRM &&
	    action_field != PLINK_CLOSE)
		return;

	ies = mgmt->u.action.u.slf_prot_action.variable;
	ie_len = (const u8 *) mgmt + len -
		mgmt->u.action.u.slf_prot_action.variable;

	/* at least expect mesh id and peering mgmt */
	if (ie_len < 2 + 2) {
		wpa_printf(MSG_DEBUG,
			   "MPM: Ignore too short action frame %u ie_len %u",
			   action_field, (unsigned int) ie_len);
		return;
	}
	wpa_printf(MSG_DEBUG, "MPM: Received PLINK action %u", action_field);

	if (action_field == PLINK_OPEN || action_field == PLINK_CONFIRM) {
		wpa_printf(MSG_DEBUG, "MPM: Capability 0x%x",
			   WPA_GET_LE16(ies));
		ies += 2;	/* capability */
		ie_len -= 2;
	}
	if (action_field == PLINK_CONFIRM) {
		aid = WPA_GET_LE16(ies);
		wpa_printf(MSG_DEBUG, "MPM: AID 0x%x", aid);
		ies += 2;	/* aid */
		ie_len -= 2;
	}

	/* check for mesh peering, mesh id and mesh config IEs */
	if (ieee802_11_parse_elems(ies, ie_len, &elems, 0) == ParseFailed) {
		wpa_printf(MSG_DEBUG, "MPM: Failed to parse PLINK IEs");
		return;
	}
	if (!elems.peer_mgmt) {
		wpa_printf(MSG_DEBUG,
			   "MPM: No Mesh Peering Management element");
		return;
	}
	if (action_field != PLINK_CLOSE) {
		if (!elems.mesh_id || !elems.mesh_config) {
			wpa_printf(MSG_DEBUG,
				   "MPM: No Mesh ID or Mesh Configuration element");
			return;
		}

		if (!matches_local(wpa_s, &elems)) {
			wpa_printf(MSG_DEBUG,
				   "MPM: Mesh ID or Mesh Configuration element do not match local MBSS");
			return;
		}
	}

	ret = mesh_mpm_parse_peer_mgmt(wpa_s, action_field,
				       elems.peer_mgmt,
				       elems.peer_mgmt_len,
				       &peer_mgmt_ie);
	if (ret) {
		wpa_printf(MSG_DEBUG, "MPM: Mesh parsing rejected frame");
		return;
	}

	/* the sender's llid is our plid and vice-versa */
	plid = WPA_GET_LE16(peer_mgmt_ie.llid);
	if (peer_mgmt_ie.plid)
		llid = WPA_GET_LE16(peer_mgmt_ie.plid);
	wpa_printf(MSG_DEBUG, "MPM: plid=0x%x llid=0x%x", plid, llid);

	if (action_field == PLINK_CLOSE)
		wpa_printf(MSG_DEBUG, "MPM: close reason=%u",
			   WPA_GET_LE16(peer_mgmt_ie.reason));

	sta = ap_get_sta(hapd, mgmt->sa);

	/*
	 * If this is an open frame from an unknown STA, and this is an
	 * open mesh, then go ahead and add the peer before proceeding.
	 */
	if (!sta && action_field == PLINK_OPEN &&
	    (!(mconf->security & MESH_CONF_SEC_AMPE) ||
	     wpa_auth_pmksa_get(hapd->wpa_auth, mgmt->sa, NULL)))
		sta = mesh_mpm_add_peer(wpa_s, mgmt->sa, &elems);

	if (!sta) {
		wpa_printf(MSG_DEBUG, "MPM: No STA entry for peer");
		return;
	}

#ifdef CONFIG_SAE
	/* peer is in sae_accepted? */
	if (sta->sae && sta->sae->state != SAE_ACCEPTED) {
		wpa_printf(MSG_DEBUG, "MPM: SAE not yet accepted for peer");
		return;
	}
#endif /* CONFIG_SAE */

	if (!sta->my_lid)
		mesh_mpm_init_link(wpa_s, sta);

	if (mconf->security & MESH_CONF_SEC_AMPE) {
		int res;

		res = mesh_rsn_process_ampe(wpa_s, sta, &elems,
					    &mgmt->u.action.category,
					    peer_mgmt_ie.chosen_pmk,
					    ies, ie_len);
		if (res) {
			wpa_printf(MSG_DEBUG,
				   "MPM: RSN process rejected frame (res=%d)",
				   res);
			if (action_field == PLINK_OPEN && res == -2) {
				/* AES-SIV decryption failed */
				mesh_mpm_fsm(wpa_s, sta, OPN_RJCT,
					     WLAN_REASON_MESH_INVALID_GTK);
			}
			return;
		}

#ifdef CONFIG_OCV
		if (action_field == PLINK_OPEN && elems.rsn_ie) {
			struct wpa_state_machine *sm = sta->wpa_sm;
			struct wpa_ie_data data;

			res = wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2,
						   elems.rsn_ie_len + 2,
						   &data);
			if (res) {
				wpa_printf(MSG_DEBUG,
					   "Failed to parse RSN IE (res=%d)",
					   res);
				wpa_hexdump(MSG_DEBUG, "RSN IE", elems.rsn_ie,
					    elems.rsn_ie_len);
				return;
			}

			wpa_auth_set_ocv(sm, mconf->ocv &&
					 (data.capabilities &
					  WPA_CAPABILITY_OCVC));
		}

		if (action_field != PLINK_CLOSE &&
		    wpa_auth_uses_ocv(sta->wpa_sm)) {
			struct wpa_channel_info ci;
			int tx_chanwidth;
			int tx_seg1_idx;

			if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
				wpa_printf(MSG_WARNING,
					   "MPM: Failed to get channel info to validate received OCI in MPM Confirm");
				return;
			}

			if (get_tx_parameters(
				    sta, channel_width_to_int(ci.chanwidth),
				    ci.seg1_idx, &tx_chanwidth,
				    &tx_seg1_idx) < 0)
				return;

			if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci,
						 tx_chanwidth, tx_seg1_idx) !=
			    OCI_SUCCESS) {
				wpa_printf(MSG_WARNING, "MPM: OCV failed: %s",
					   ocv_errorstr);
				return;
			}
		}
#endif /* CONFIG_OCV */
	}

	if (sta->plink_state == PLINK_BLOCKED) {
		wpa_printf(MSG_DEBUG, "MPM: PLINK_BLOCKED");
		return;
	}

	/* Now we will figure out the appropriate event... */
	switch (action_field) {
	case PLINK_OPEN:
		if (plink_free_count(hapd) == 0) {
			event = REQ_RJCT;
			reason = WLAN_REASON_MESH_MAX_PEERS;
			wpa_printf(MSG_INFO,
				   "MPM: Peer link num over quota(%d)",
				   hapd->max_plinks);
		} else if (sta->peer_lid && sta->peer_lid != plid) {
			wpa_printf(MSG_DEBUG,
				   "MPM: peer_lid mismatch: 0x%x != 0x%x",
				   sta->peer_lid, plid);
			return; /* no FSM event */
		} else {
			sta->peer_lid = plid;
			event = OPN_ACPT;
		}
		break;
	case PLINK_CONFIRM:
		if (plink_free_count(hapd) == 0) {
			event = REQ_RJCT;
			reason = WLAN_REASON_MESH_MAX_PEERS;
			wpa_printf(MSG_INFO,
				   "MPM: Peer link num over quota(%d)",
				   hapd->max_plinks);
		} else if (sta->my_lid != llid ||
			   (sta->peer_lid && sta->peer_lid != plid)) {
			wpa_printf(MSG_DEBUG,
				   "MPM: lid mismatch: my_lid: 0x%x != 0x%x or peer_lid: 0x%x != 0x%x",
				   sta->my_lid, llid, sta->peer_lid, plid);
			return; /* no FSM event */
		} else {
			if (!sta->peer_lid)
				sta->peer_lid = plid;
			sta->peer_aid = aid;
			event = CNF_ACPT;
		}
		break;
	case PLINK_CLOSE:
		if (sta->plink_state == PLINK_ESTAB)
			/* Do not check for llid or plid. This does not
			 * follow the standard but since multiple plinks
			 * per cand are not supported, it is necessary in
			 * order to avoid a livelock when MP A sees an
			 * establish peer link to MP B but MP B does not
			 * see it. This can be caused by a timeout in
			 * B's peer link establishment or B being
			 * restarted.
			 */
			event = CLS_ACPT;
		else if (sta->peer_lid != plid) {
			wpa_printf(MSG_DEBUG,
				   "MPM: peer_lid mismatch: 0x%x != 0x%x",
				   sta->peer_lid, plid);
			return; /* no FSM event */
		} else if (peer_mgmt_ie.plid && sta->my_lid != llid) {
			wpa_printf(MSG_DEBUG,
				   "MPM: my_lid mismatch: 0x%x != 0x%x",
				   sta->my_lid, llid);
			return; /* no FSM event */
		} else {
			event = CLS_ACPT;
		}
		break;
	default:
		/*
		 * This cannot be hit due to the action_field check above, but
		 * compilers may not be able to figure that out and can warn
		 * about uninitialized event below.
		 */
		return;
	}
	mesh_mpm_fsm(wpa_s, sta, event, reason);
}


/* called by ap_free_sta */
void mesh_mpm_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
{
	if (sta->plink_state == PLINK_ESTAB)
		hapd->num_plinks--;
	eloop_cancel_timeout(plink_timer, ELOOP_ALL_CTX, sta);
	eloop_cancel_timeout(mesh_auth_timer, ELOOP_ALL_CTX, sta);
}
