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(&params, 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, &params);
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(&params, 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, &params);
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(&params, 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, &params);
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