1  /*
2   * WPA Supplicant - Basic mesh mode routines
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 "utils/uuid.h"
14  #include "common/ieee802_11_defs.h"
15  #include "common/wpa_ctrl.h"
16  #include "common/hw_features_common.h"
17  #include "ap/sta_info.h"
18  #include "ap/hostapd.h"
19  #include "ap/ieee802_11.h"
20  #include "config_ssid.h"
21  #include "config.h"
22  #include "wpa_supplicant_i.h"
23  #include "driver_i.h"
24  #include "notify.h"
25  #include "ap.h"
26  #include "mesh_mpm.h"
27  #include "mesh_rsn.h"
28  #include "mesh.h"
29  
30  
wpa_supplicant_mesh_deinit(struct wpa_supplicant * wpa_s,bool also_clear_hostapd)31  static void wpa_supplicant_mesh_deinit(struct wpa_supplicant *wpa_s,
32  				       bool also_clear_hostapd)
33  {
34  	wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh,
35  					 also_clear_hostapd);
36  
37  	if (also_clear_hostapd) {
38  		wpa_s->ifmsh = NULL;
39  		wpa_s->current_ssid = NULL;
40  		os_free(wpa_s->mesh_params);
41  		wpa_s->mesh_params = NULL;
42  	}
43  
44  	os_free(wpa_s->mesh_rsn);
45  	wpa_s->mesh_rsn = NULL;
46  
47  	if (!also_clear_hostapd)
48  		wpa_supplicant_leave_mesh(wpa_s, false);
49  }
50  
51  
wpa_supplicant_mesh_iface_deinit(struct wpa_supplicant * wpa_s,struct hostapd_iface * ifmsh,bool also_clear_hostapd)52  void wpa_supplicant_mesh_iface_deinit(struct wpa_supplicant *wpa_s,
53  				      struct hostapd_iface *ifmsh,
54  				      bool also_clear_hostapd)
55  {
56  	if (!ifmsh)
57  		return;
58  
59  	if (ifmsh->mconf) {
60  		mesh_mpm_deinit(wpa_s, ifmsh);
61  		if (ifmsh->mconf->rsn_ie) {
62  			ifmsh->mconf->rsn_ie = NULL;
63  			/* We cannot free this struct
64  			 * because wpa_authenticator on
65  			 * hostapd side is also using it
66  			 * for now just set to NULL and
67  			 * let hostapd code free it.
68  			 */
69  		}
70  		os_free(ifmsh->mconf);
71  		ifmsh->mconf = NULL;
72  	}
73  
74  	/* take care of shared data */
75  	if (also_clear_hostapd) {
76  		hostapd_interface_deinit(ifmsh);
77  		hostapd_interface_free(ifmsh);
78  	}
79  }
80  
81  
mesh_config_create(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)82  static struct mesh_conf * mesh_config_create(struct wpa_supplicant *wpa_s,
83  					     struct wpa_ssid *ssid)
84  {
85  	struct mesh_conf *conf;
86  	int cipher;
87  
88  	conf = os_zalloc(sizeof(struct mesh_conf));
89  	if (!conf)
90  		return NULL;
91  
92  	os_memcpy(conf->meshid, ssid->ssid, ssid->ssid_len);
93  	conf->meshid_len = ssid->ssid_len;
94  
95  	if (ssid->key_mgmt & WPA_KEY_MGMT_SAE)
96  		conf->security |= MESH_CONF_SEC_AUTH |
97  			MESH_CONF_SEC_AMPE;
98  	else
99  		conf->security |= MESH_CONF_SEC_NONE;
100  	conf->ieee80211w = ssid->ieee80211w;
101  	if (conf->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT) {
102  		if (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_BIP)
103  			conf->ieee80211w = wpa_s->conf->pmf;
104  		else
105  			conf->ieee80211w = NO_MGMT_FRAME_PROTECTION;
106  	}
107  #ifdef CONFIG_OCV
108  	conf->ocv = ssid->ocv;
109  #endif /* CONFIG_OCV */
110  
111  	cipher = wpa_pick_pairwise_cipher(ssid->pairwise_cipher, 0);
112  	if (cipher < 0 || cipher == WPA_CIPHER_TKIP) {
113  		wpa_msg(wpa_s, MSG_INFO, "mesh: Invalid pairwise cipher");
114  		os_free(conf);
115  		return NULL;
116  	}
117  	conf->pairwise_cipher = cipher;
118  
119  	cipher = wpa_pick_group_cipher(ssid->group_cipher);
120  	if (cipher < 0 || cipher == WPA_CIPHER_TKIP ||
121  	    cipher == WPA_CIPHER_GTK_NOT_USED) {
122  		wpa_msg(wpa_s, MSG_INFO, "mesh: Invalid group cipher");
123  		os_free(conf);
124  		return NULL;
125  	}
126  
127  	conf->group_cipher = cipher;
128  	if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
129  		if (ssid->group_mgmt_cipher == WPA_CIPHER_BIP_GMAC_128 ||
130  		    ssid->group_mgmt_cipher == WPA_CIPHER_BIP_GMAC_256 ||
131  		    ssid->group_mgmt_cipher == WPA_CIPHER_BIP_CMAC_256)
132  			conf->mgmt_group_cipher = ssid->group_mgmt_cipher;
133  		else
134  			conf->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
135  	}
136  
137  	/* defaults */
138  	conf->mesh_pp_id = MESH_PATH_PROTOCOL_HWMP;
139  	conf->mesh_pm_id = MESH_PATH_METRIC_AIRTIME;
140  	conf->mesh_cc_id = 0;
141  	conf->mesh_sp_id = MESH_SYNC_METHOD_NEIGHBOR_OFFSET;
142  	conf->mesh_auth_id = (conf->security & MESH_CONF_SEC_AUTH) ? 1 : 0;
143  	conf->mesh_fwding = ssid->mesh_fwding;
144  	conf->dot11MeshMaxRetries = ssid->dot11MeshMaxRetries;
145  	conf->dot11MeshRetryTimeout = ssid->dot11MeshRetryTimeout;
146  	conf->dot11MeshConfirmTimeout = ssid->dot11MeshConfirmTimeout;
147  	conf->dot11MeshHoldingTimeout = ssid->dot11MeshHoldingTimeout;
148  
149  	return conf;
150  }
151  
152  
wpas_mesh_copy_groups(struct hostapd_data * bss,struct wpa_supplicant * wpa_s)153  static void wpas_mesh_copy_groups(struct hostapd_data *bss,
154  				  struct wpa_supplicant *wpa_s)
155  {
156  	int num_groups;
157  	size_t groups_size;
158  
159  	for (num_groups = 0; wpa_s->conf->sae_groups[num_groups] > 0;
160  	     num_groups++)
161  		;
162  
163  	groups_size = (num_groups + 1) * sizeof(wpa_s->conf->sae_groups[0]);
164  	bss->conf->sae_groups = os_malloc(groups_size);
165  	if (bss->conf->sae_groups)
166  		os_memcpy(bss->conf->sae_groups, wpa_s->conf->sae_groups,
167  			  groups_size);
168  }
169  
170  
wpas_mesh_init_rsn(struct wpa_supplicant * wpa_s)171  static int wpas_mesh_init_rsn(struct wpa_supplicant *wpa_s)
172  {
173  	struct hostapd_iface *ifmsh = wpa_s->ifmsh;
174  	struct wpa_ssid *ssid = wpa_s->current_ssid;
175  	struct hostapd_data *bss = ifmsh->bss[0];
176  	static int default_groups[] = { 19, 20, 21, 25, 26, -1 };
177  	const char *password;
178  	size_t len;
179  
180  	password = ssid->sae_password;
181  	if (!password)
182  		password = ssid->passphrase;
183  	if (!password) {
184  		wpa_printf(MSG_ERROR,
185  			   "mesh: Passphrase for SAE not configured");
186  		return -1;
187  	}
188  
189  	bss->conf->wpa = ssid->proto;
190  	bss->conf->wpa_key_mgmt = ssid->key_mgmt;
191  
192  	if (wpa_s->conf->sae_groups && wpa_s->conf->sae_groups[0] > 0) {
193  		wpas_mesh_copy_groups(bss, wpa_s);
194  	} else {
195  		bss->conf->sae_groups = os_memdup(default_groups,
196  						  sizeof(default_groups));
197  		if (!bss->conf->sae_groups)
198  			return -1;
199  	}
200  
201  	len = os_strlen(password);
202  	bss->conf->ssid.wpa_passphrase = dup_binstr(password, len);
203  
204  	wpa_s->mesh_rsn = mesh_rsn_auth_init(wpa_s, ifmsh->mconf);
205  	return !wpa_s->mesh_rsn ? -1 : 0;
206  }
207  
208  
wpas_mesh_update_freq_params(struct wpa_supplicant * wpa_s)209  static int wpas_mesh_update_freq_params(struct wpa_supplicant *wpa_s)
210  {
211  	struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
212  	struct hostapd_iface *ifmsh = wpa_s->ifmsh;
213  	struct he_capabilities *he_capab = NULL;
214  
215  	if (ifmsh->current_mode)
216  		he_capab = &ifmsh->current_mode->he_capab[IEEE80211_MODE_MESH];
217  
218  	if (hostapd_set_freq_params(
219  		    &params->freq,
220  		    ifmsh->conf->hw_mode,
221  		    ifmsh->freq,
222  		    ifmsh->conf->channel,
223  		    ifmsh->conf->enable_edmg,
224  		    ifmsh->conf->edmg_channel,
225  		    ifmsh->conf->ieee80211n,
226  		    ifmsh->conf->ieee80211ac,
227  		    ifmsh->conf->ieee80211ax,
228  		    ifmsh->conf->ieee80211be,
229  		    ifmsh->conf->secondary_channel,
230  		    hostapd_get_oper_chwidth(ifmsh->conf),
231  		    hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf),
232  		    hostapd_get_oper_centr_freq_seg1_idx(ifmsh->conf),
233  		    ifmsh->conf->vht_capab,
234  		    he_capab, NULL, 0)) {
235  		wpa_printf(MSG_ERROR, "Error updating mesh frequency params");
236  		wpa_supplicant_mesh_deinit(wpa_s, true);
237  		return -1;
238  	}
239  
240  	return 0;
241  }
242  
243  
wpas_mesh_complete(struct wpa_supplicant * wpa_s)244  static int wpas_mesh_complete(struct wpa_supplicant *wpa_s)
245  {
246  	struct hostapd_iface *ifmsh = wpa_s->ifmsh;
247  	struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
248  	struct wpa_ssid *ssid = wpa_s->current_ssid;
249  	int ret;
250  
251  	if (!params || !ssid || !ifmsh) {
252  		wpa_printf(MSG_ERROR, "mesh: %s called without active mesh",
253  			   __func__);
254  		return -1;
255  	}
256  
257  	/*
258  	 * Update channel configuration if the channel has changed since the
259  	 * initial setting, i.e., due to DFS radar detection during CAC.
260  	 */
261  	if (ifmsh->freq > 0 && ifmsh->freq != params->freq.freq) {
262  		wpa_s->assoc_freq = ifmsh->freq;
263  		ssid->frequency = ifmsh->freq;
264  		if (wpas_mesh_update_freq_params(wpa_s) < 0)
265  			return -1;
266  	}
267  
268  	if (ifmsh->mconf->security != MESH_CONF_SEC_NONE &&
269  	    wpas_mesh_init_rsn(wpa_s)) {
270  		wpa_printf(MSG_ERROR,
271  			   "mesh: RSN initialization failed - deinit mesh");
272  		wpa_supplicant_mesh_deinit(wpa_s, false);
273  		return -1;
274  	}
275  
276  	if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
277  		wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher;
278  		wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher;
279  		wpa_s->mgmt_group_cipher = wpa_s->mesh_rsn->mgmt_group_cipher;
280  	}
281  
282  	params->ies = ifmsh->mconf->rsn_ie;
283  	params->ie_len = ifmsh->mconf->rsn_ie_len;
284  	params->basic_rates = ifmsh->basic_rates;
285  	params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE;
286  	params->conf.ht_opmode = ifmsh->bss[0]->iface->ht_op_mode;
287  
288  	wpa_msg(wpa_s, MSG_INFO, "joining mesh %s",
289  		wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
290  	ret = wpa_drv_join_mesh(wpa_s, params);
291  	if (ret)
292  		wpa_msg(wpa_s, MSG_ERROR, "mesh join error=%d", ret);
293  
294  	/* hostapd sets the interface down until we associate */
295  	wpa_drv_set_operstate(wpa_s, 1);
296  
297  	if (!ret) {
298  		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
299  
300  		wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_STARTED "ssid=\"%s\" id=%d",
301  			wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
302  			ssid->id);
303  		wpas_notify_mesh_group_started(wpa_s, ssid);
304  	}
305  
306  	return ret;
307  }
308  
309  
wpas_mesh_complete_cb(void * arg)310  static void wpas_mesh_complete_cb(void *arg)
311  {
312  	struct wpa_supplicant *wpa_s = arg;
313  
314  	wpas_mesh_complete(wpa_s);
315  }
316  
317  
wpa_supplicant_mesh_enable_iface_cb(struct hostapd_iface * ifmsh)318  static int wpa_supplicant_mesh_enable_iface_cb(struct hostapd_iface *ifmsh)
319  {
320  	struct wpa_supplicant *wpa_s = ifmsh->owner;
321  	struct hostapd_data *bss;
322  
323  	ifmsh->mconf = mesh_config_create(wpa_s, wpa_s->current_ssid);
324  
325  	bss = ifmsh->bss[0];
326  	bss->msg_ctx = wpa_s;
327  	os_memcpy(bss->own_addr, wpa_s->own_addr, ETH_ALEN);
328  	bss->driver = wpa_s->driver;
329  	bss->drv_priv = wpa_s->drv_priv;
330  	bss->iface = ifmsh;
331  	bss->mesh_sta_free_cb = mesh_mpm_free_sta;
332  	bss->setup_complete_cb = wpas_mesh_complete_cb;
333  	bss->setup_complete_cb_ctx = wpa_s;
334  
335  	bss->conf->start_disabled = 1;
336  	bss->conf->mesh = MESH_ENABLED;
337  	bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity;
338  
339  	if (wpa_drv_init_mesh(wpa_s)) {
340  		wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
341  		return -1;
342  	}
343  
344  	if (hostapd_setup_interface(ifmsh)) {
345  		wpa_printf(MSG_ERROR,
346  			   "Failed to initialize hostapd interface for mesh");
347  		return -1;
348  	}
349  
350  	return 0;
351  }
352  
353  
wpa_supplicant_mesh_disable_iface_cb(struct hostapd_iface * ifmsh)354  static int wpa_supplicant_mesh_disable_iface_cb(struct hostapd_iface *ifmsh)
355  {
356  	struct wpa_supplicant *wpa_s = ifmsh->owner;
357  	size_t j;
358  
359  	wpa_supplicant_mesh_deinit(wpa_s, false);
360  
361  #ifdef NEED_AP_MLME
362  	for (j = 0; j < ifmsh->num_bss; j++)
363  		hostapd_cleanup_cs_params(ifmsh->bss[j]);
364  #endif /* NEED_AP_MLME */
365  
366  	/* Same as hostapd_interface_deinit() without deinitializing control
367  	 * interface */
368  	for (j = 0; j < ifmsh->num_bss; j++) {
369  		struct hostapd_data *hapd = ifmsh->bss[j];
370  
371  		hostapd_bss_deinit_no_free(hapd);
372  		hostapd_free_hapd_data(hapd);
373  	}
374  
375  	hostapd_cleanup_iface_partial(ifmsh);
376  
377  	return 0;
378  }
379  
380  
wpa_supplicant_mesh_init(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid,struct hostapd_freq_params * freq)381  static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
382  				    struct wpa_ssid *ssid,
383  				    struct hostapd_freq_params *freq)
384  {
385  	struct hostapd_iface *ifmsh;
386  	struct hostapd_data *bss;
387  	struct hostapd_config *conf;
388  	struct mesh_conf *mconf;
389  	int basic_rates_erp[] = { 10, 20, 55, 60, 110, 120, 240, -1 };
390  	int rate_len;
391  	int frequency;
392  
393  	if (!wpa_s->conf->user_mpm) {
394  		/* not much for us to do here */
395  		wpa_msg(wpa_s, MSG_WARNING,
396  			"user_mpm is not enabled in configuration");
397  		return 0;
398  	}
399  
400  	wpa_s->ifmsh = ifmsh = hostapd_alloc_iface();
401  	if (!ifmsh)
402  		return -ENOMEM;
403  
404  	ifmsh->owner = wpa_s;
405  	ifmsh->drv_flags = wpa_s->drv_flags;
406  	ifmsh->drv_flags2 = wpa_s->drv_flags2;
407  	ifmsh->num_bss = 1;
408  	ifmsh->enable_iface_cb = wpa_supplicant_mesh_enable_iface_cb;
409  	ifmsh->disable_iface_cb = wpa_supplicant_mesh_disable_iface_cb;
410  	ifmsh->bss = os_calloc(wpa_s->ifmsh->num_bss,
411  			       sizeof(struct hostapd_data *));
412  	if (!ifmsh->bss)
413  		goto out_free;
414  
415  	ifmsh->bss[0] = bss = hostapd_alloc_bss_data(NULL, NULL, NULL);
416  	if (!bss)
417  		goto out_free;
418  
419  	ifmsh->bss[0]->msg_ctx = wpa_s;
420  	os_memcpy(bss->own_addr, wpa_s->own_addr, ETH_ALEN);
421  	bss->driver = wpa_s->driver;
422  	bss->drv_priv = wpa_s->drv_priv;
423  	bss->iface = ifmsh;
424  	bss->mesh_sta_free_cb = mesh_mpm_free_sta;
425  	bss->setup_complete_cb = wpas_mesh_complete_cb;
426  	bss->setup_complete_cb_ctx = wpa_s;
427  	frequency = ssid->frequency;
428  	if (frequency != freq->freq &&
429  	    frequency == freq->freq + freq->sec_channel_offset * 20) {
430  		wpa_printf(MSG_DEBUG, "mesh: pri/sec channels switched");
431  		frequency = freq->freq;
432  		ssid->frequency = frequency;
433  	}
434  	wpa_s->assoc_freq = frequency;
435  	wpa_s->current_ssid = ssid;
436  
437  	/* setup an AP config for auth processing */
438  	conf = hostapd_config_defaults();
439  	if (!conf)
440  		goto out_free;
441  
442  	if (is_6ghz_freq(freq->freq)) {
443  		/*
444  		 * IEEE Std 802.11ax-2021, 12.12.2:
445  		 * The STA shall use management frame protection (MFPR=1) when
446  		 * using RSN.
447  		 */
448  		ssid->ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED;
449  
450  		/* Set mandatory op_class parameter for setting up BSS */
451  		switch (freq->bandwidth) {
452  		case 20:
453  			if (freq->freq == 5935)
454  				conf->op_class = 136;
455  			else
456  				conf->op_class = 131;
457  			break;
458  		case 40:
459  			conf->op_class = 132;
460  			break;
461  		case 80:
462  			conf->op_class = 133;
463  			break;
464  		case 160:
465  			conf->op_class = 134;
466  			break;
467  		case 320:
468  			conf->op_class = 137;
469  			break;
470  		default:
471  			conf->op_class = 131;
472  			break;
473  		}
474  	}
475  
476  	bss->conf = *conf->bss;
477  	bss->conf->start_disabled = 1;
478  	bss->conf->mesh = MESH_ENABLED;
479  	bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity;
480  	bss->conf->mesh_fwding = wpa_s->conf->mesh_fwding;
481  
482  	if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes,
483  			     wpa_s->hw.num_modes) && wpa_s->conf->country[0]) {
484  		conf->ieee80211h = 1;
485  		conf->ieee80211d = 1;
486  		conf->country[0] = wpa_s->conf->country[0];
487  		conf->country[1] = wpa_s->conf->country[1];
488  		conf->country[2] = ' ';
489  		wpa_s->mesh_params->handle_dfs = true;
490  	}
491  
492  	bss->iconf = conf;
493  	ifmsh->conf = conf;
494  
495  	ifmsh->bss[0]->max_plinks = wpa_s->conf->max_peer_links;
496  	ifmsh->bss[0]->dot11RSNASAERetransPeriod =
497  		wpa_s->conf->dot11RSNASAERetransPeriod;
498  	os_strlcpy(bss->conf->iface, wpa_s->ifname, sizeof(bss->conf->iface));
499  
500  	mconf = mesh_config_create(wpa_s, ssid);
501  	if (!mconf)
502  		goto out_free;
503  	ifmsh->mconf = mconf;
504  
505  	/* need conf->hw_mode for supported rates. */
506  	conf->hw_mode = ieee80211_freq_to_chan(frequency, &conf->channel);
507  	if (conf->hw_mode == NUM_HOSTAPD_MODES) {
508  		wpa_printf(MSG_ERROR, "Unsupported mesh mode frequency: %d MHz",
509  			   frequency);
510  		goto out_free;
511  	}
512  
513  	if (ssid->mesh_basic_rates == NULL) {
514  		/*
515  		 * XXX: Hack! This is so an MPM which correctly sets the ERP
516  		 * mandatory rates as BSSBasicRateSet doesn't reject us. We
517  		 * could add a new hw_mode HOSTAPD_MODE_IEEE80211G_ERP, but
518  		 * this is way easier. This also makes our BSSBasicRateSet
519  		 * advertised in beacons match the one in peering frames, sigh.
520  		 */
521  		if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
522  			conf->basic_rates = os_memdup(basic_rates_erp,
523  						      sizeof(basic_rates_erp));
524  			if (!conf->basic_rates)
525  				goto out_free;
526  		}
527  	} else {
528  		rate_len = 0;
529  		while (1) {
530  			if (ssid->mesh_basic_rates[rate_len] < 1)
531  				break;
532  			rate_len++;
533  		}
534  		conf->basic_rates = os_calloc(rate_len + 1, sizeof(int));
535  		if (conf->basic_rates == NULL)
536  			goto out_free;
537  		os_memcpy(conf->basic_rates, ssid->mesh_basic_rates,
538  			  rate_len * sizeof(int));
539  		conf->basic_rates[rate_len] = -1;
540  	}
541  
542  	/* While it can enhance performance to switch the primary channel, which
543  	 * is also the secondary channel of another network at the same time),
544  	 * to the other primary channel, problems exist with this in mesh
545  	 * networks.
546  	 *
547  	 * Example with problems:
548  	 *     - 3 mesh nodes M1-M3, freq (5200, 5180)
549  	 *     - other node O1, e.g. AP mode, freq (5180, 5200),
550  	 * Locations: O1 M1      M2      M3
551  	 *
552  	 * M3 can only send frames to M1 over M2, no direct connection is
553  	 * possible
554  	 * Start O1, M1 and M3 first, M1 or O1 will switch channels to align
555  	 * with* each other. M3 does not swap, because M1 or O1 cannot be
556  	 * reached. M2 is started afterwards and can either connect to M3 or M1
557  	 * because of this primary secondary channel switch.
558  	 *
559  	 * Solutions: (1) central coordination -> not always possible
560  	 *            (2) disable pri/sec channel switch in mesh networks
561  	 *
562  	 * In AP mode, when all nodes can work independently, this poses of
563  	 * course no problem, therefore disable it only in mesh mode. */
564  	conf->no_pri_sec_switch = 1;
565  	wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
566  
567  	if (wpa_drv_init_mesh(wpa_s)) {
568  		wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
569  		return -1;
570  	}
571  
572  	if (hostapd_setup_interface(ifmsh)) {
573  		wpa_printf(MSG_ERROR,
574  			   "Failed to initialize hostapd interface for mesh");
575  		return -1;
576  	}
577  
578  	return 0;
579  out_free:
580  	wpa_supplicant_mesh_deinit(wpa_s, true);
581  	return -ENOMEM;
582  }
583  
584  
wpa_mesh_notify_peer(struct wpa_supplicant * wpa_s,const u8 * addr,const u8 * ies,size_t ie_len)585  void wpa_mesh_notify_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
586  			  const u8 *ies, size_t ie_len)
587  {
588  	struct ieee802_11_elems elems;
589  
590  	wpa_msg(wpa_s, MSG_INFO,
591  		"new peer notification for " MACSTR, MAC2STR(addr));
592  
593  	if (ieee802_11_parse_elems(ies, ie_len, &elems, 0) == ParseFailed) {
594  		wpa_msg(wpa_s, MSG_INFO, "Could not parse beacon from " MACSTR,
595  			MAC2STR(addr));
596  		return;
597  	}
598  	wpa_mesh_new_mesh_peer(wpa_s, addr, &elems);
599  }
600  
601  
wpa_supplicant_mesh_add_scan_ie(struct wpa_supplicant * wpa_s,struct wpabuf ** extra_ie)602  void wpa_supplicant_mesh_add_scan_ie(struct wpa_supplicant *wpa_s,
603  				     struct wpabuf **extra_ie)
604  {
605  	/* EID + 0-length (wildcard) mesh-id */
606  	size_t ielen = 2;
607  
608  	if (ielen <= wpa_s->drv_max_probe_req_ie_len &&
609  	    wpabuf_resize(extra_ie, ielen) == 0) {
610  		wpabuf_put_u8(*extra_ie, WLAN_EID_MESH_ID);
611  		wpabuf_put_u8(*extra_ie, 0);
612  	}
613  }
614  
615  
wpa_supplicant_join_mesh(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)616  int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s,
617  			     struct wpa_ssid *ssid)
618  {
619  	struct wpa_driver_mesh_join_params *params = os_zalloc(sizeof(*params));
620  	int ret = 0;
621  
622  	if (!ssid || !ssid->ssid || !ssid->ssid_len || !ssid->frequency ||
623  	    !params) {
624  		ret = -ENOENT;
625  		os_free(params);
626  		goto out;
627  	}
628  
629  	wpa_supplicant_mesh_deinit(wpa_s, true);
630  
631  	wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
632  	wpa_s->group_cipher = WPA_CIPHER_NONE;
633  	wpa_s->mgmt_group_cipher = 0;
634  
635  	params->meshid = ssid->ssid;
636  	params->meshid_len = ssid->ssid_len;
637  	ibss_mesh_setup_freq(wpa_s, ssid, &params->freq);
638  	wpa_s->mesh_ht_enabled = !!params->freq.ht_enabled;
639  	wpa_s->mesh_vht_enabled = !!params->freq.vht_enabled;
640  	wpa_s->mesh_he_enabled = !!params->freq.he_enabled;
641  	wpa_s->mesh_eht_enabled = !!params->freq.eht_enabled;
642  	if (params->freq.ht_enabled && params->freq.sec_channel_offset)
643  		ssid->ht40 = params->freq.sec_channel_offset;
644  
645  	if (wpa_s->mesh_vht_enabled) {
646  		ssid->vht = 1;
647  		ssid->vht_center_freq1 = params->freq.center_freq1;
648  		switch (params->freq.bandwidth) {
649  		case 80:
650  			if (params->freq.center_freq2) {
651  				ssid->max_oper_chwidth =
652  					CONF_OPER_CHWIDTH_80P80MHZ;
653  				ssid->vht_center_freq2 =
654  					params->freq.center_freq2;
655  			} else {
656  				ssid->max_oper_chwidth =
657  					CONF_OPER_CHWIDTH_80MHZ;
658  			}
659  			break;
660  		case 160:
661  			ssid->max_oper_chwidth = CONF_OPER_CHWIDTH_160MHZ;
662  			break;
663  		default:
664  			ssid->max_oper_chwidth = CONF_OPER_CHWIDTH_USE_HT;
665  			break;
666  		}
667  	}
668  	if (wpa_s->mesh_he_enabled)
669  		ssid->he = 1;
670  	if (wpa_s->mesh_eht_enabled)
671  		ssid->eht = 1;
672  	if (ssid->beacon_int > 0)
673  		params->beacon_int = ssid->beacon_int;
674  	else if (wpa_s->conf->beacon_int > 0)
675  		params->beacon_int = wpa_s->conf->beacon_int;
676  	if (ssid->dtim_period > 0)
677  		params->dtim_period = ssid->dtim_period;
678  	else if (wpa_s->conf->dtim_period > 0)
679  		params->dtim_period = wpa_s->conf->dtim_period;
680  	params->conf.max_peer_links = wpa_s->conf->max_peer_links;
681  	if (ssid->mesh_rssi_threshold < DEFAULT_MESH_RSSI_THRESHOLD) {
682  		params->conf.rssi_threshold = ssid->mesh_rssi_threshold;
683  		params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD;
684  	}
685  
686  	if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
687  		params->flags |= WPA_DRIVER_MESH_FLAG_SAE_AUTH;
688  		params->flags |= WPA_DRIVER_MESH_FLAG_AMPE;
689  		wpa_s->conf->user_mpm = 1;
690  	}
691  
692  	if (wpa_s->conf->user_mpm) {
693  		params->flags |= WPA_DRIVER_MESH_FLAG_USER_MPM;
694  		params->conf.auto_plinks = 0;
695  	} else {
696  		params->flags |= WPA_DRIVER_MESH_FLAG_DRIVER_MPM;
697  		params->conf.auto_plinks = 1;
698  	}
699  	params->conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity;
700  
701  	/* Always explicitely set forwarding to on or off for now */
702  	params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_FORWARDING;
703  	params->conf.forwarding = ssid->mesh_fwding;
704  
705  	os_free(wpa_s->mesh_params);
706  	wpa_s->mesh_params = params;
707  	if (wpa_supplicant_mesh_init(wpa_s, ssid, &params->freq)) {
708  		wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh");
709  		wpa_supplicant_leave_mesh(wpa_s, true);
710  		ret = -1;
711  		goto out;
712  	}
713  
714  out:
715  	return ret;
716  }
717  
718  
wpa_supplicant_leave_mesh(struct wpa_supplicant * wpa_s,bool need_deinit)719  int wpa_supplicant_leave_mesh(struct wpa_supplicant *wpa_s, bool need_deinit)
720  {
721  	int ret = 0;
722  
723  	wpa_msg(wpa_s, MSG_INFO, "leaving mesh");
724  
725  	/* Need to send peering close messages first */
726  	if (need_deinit)
727  		wpa_supplicant_mesh_deinit(wpa_s, true);
728  
729  	ret = wpa_drv_leave_mesh(wpa_s);
730  	if (ret)
731  		wpa_msg(wpa_s, MSG_ERROR, "mesh leave error=%d", ret);
732  
733  	wpa_drv_set_operstate(wpa_s, 1);
734  
735  	return ret;
736  }
737  
738  
mesh_attr_text(const u8 * ies,size_t ies_len,char * buf,char * end)739  static int mesh_attr_text(const u8 *ies, size_t ies_len, char *buf, char *end)
740  {
741  	struct ieee802_11_elems elems;
742  	char *mesh_id, *pos = buf;
743  	u8 *bss_basic_rate_set;
744  	int bss_basic_rate_set_len, ret, i;
745  
746  	if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) == ParseFailed)
747  		return -1;
748  
749  	if (elems.mesh_id_len < 1)
750  		return 0;
751  
752  	mesh_id = os_malloc(elems.mesh_id_len + 1);
753  	if (mesh_id == NULL)
754  		return -1;
755  
756  	os_memcpy(mesh_id, elems.mesh_id, elems.mesh_id_len);
757  	mesh_id[elems.mesh_id_len] = '\0';
758  	ret = os_snprintf(pos, end - pos, "mesh_id=%s\n", mesh_id);
759  	os_free(mesh_id);
760  	if (os_snprintf_error(end - pos, ret))
761  		return pos - buf;
762  	pos += ret;
763  
764  	if (elems.mesh_config_len > 6) {
765  		ret = os_snprintf(pos, end - pos,
766  				  "active_path_selection_protocol_id=0x%02x\n"
767  				  "active_path_selection_metric_id=0x%02x\n"
768  				  "congestion_control_mode_id=0x%02x\n"
769  				  "synchronization_method_id=0x%02x\n"
770  				  "authentication_protocol_id=0x%02x\n"
771  				  "mesh_formation_info=0x%02x\n"
772  				  "mesh_capability=0x%02x\n",
773  				  elems.mesh_config[0], elems.mesh_config[1],
774  				  elems.mesh_config[2], elems.mesh_config[3],
775  				  elems.mesh_config[4], elems.mesh_config[5],
776  				  elems.mesh_config[6]);
777  		if (os_snprintf_error(end - pos, ret))
778  			return pos - buf;
779  		pos += ret;
780  	}
781  
782  	bss_basic_rate_set = os_malloc(elems.supp_rates_len +
783  		elems.ext_supp_rates_len);
784  	if (bss_basic_rate_set == NULL)
785  		return -1;
786  
787  	bss_basic_rate_set_len = 0;
788  	for (i = 0; i < elems.supp_rates_len; i++) {
789  		if (elems.supp_rates[i] & 0x80) {
790  			bss_basic_rate_set[bss_basic_rate_set_len++] =
791  				(elems.supp_rates[i] & 0x7f) * 5;
792  		}
793  	}
794  	for (i = 0; i < elems.ext_supp_rates_len; i++) {
795  		if (elems.ext_supp_rates[i] & 0x80) {
796  			bss_basic_rate_set[bss_basic_rate_set_len++] =
797  				(elems.ext_supp_rates[i] & 0x7f) * 5;
798  		}
799  	}
800  	if (bss_basic_rate_set_len > 0) {
801  		ret = os_snprintf(pos, end - pos, "bss_basic_rate_set=%d",
802  				  bss_basic_rate_set[0]);
803  		if (os_snprintf_error(end - pos, ret))
804  			goto fail;
805  		pos += ret;
806  
807  		for (i = 1; i < bss_basic_rate_set_len; i++) {
808  			ret = os_snprintf(pos, end - pos, " %d",
809  					  bss_basic_rate_set[i]);
810  			if (os_snprintf_error(end - pos, ret))
811  				goto fail;
812  			pos += ret;
813  		}
814  
815  		ret = os_snprintf(pos, end - pos, "\n");
816  		if (os_snprintf_error(end - pos, ret))
817  			goto fail;
818  		pos += ret;
819  	}
820  fail:
821  	os_free(bss_basic_rate_set);
822  
823  	return pos - buf;
824  }
825  
826  
wpas_mesh_scan_result_text(const u8 * ies,size_t ies_len,char * buf,char * end)827  int wpas_mesh_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
828  			       char *end)
829  {
830  	return mesh_attr_text(ies, ies_len, buf, end);
831  }
832  
833  
wpas_mesh_get_ifname(struct wpa_supplicant * wpa_s,char * ifname,size_t len)834  static int wpas_mesh_get_ifname(struct wpa_supplicant *wpa_s, char *ifname,
835  				size_t len)
836  {
837  	char *ifname_ptr = wpa_s->ifname;
838  	int res;
839  
840  	res = os_snprintf(ifname, len, "mesh-%s-%d", ifname_ptr,
841  			  wpa_s->mesh_if_idx);
842  	if (os_snprintf_error(len, res) ||
843  	    (os_strlen(ifname) >= IFNAMSIZ &&
844  	     os_strlen(wpa_s->ifname) < IFNAMSIZ)) {
845  		/* Try to avoid going over the IFNAMSIZ length limit */
846  		res = os_snprintf(ifname, len, "mesh-%d", wpa_s->mesh_if_idx);
847  		if (os_snprintf_error(len, res))
848  			return -1;
849  	}
850  	wpa_s->mesh_if_idx++;
851  	return 0;
852  }
853  
854  
wpas_mesh_add_interface(struct wpa_supplicant * wpa_s,char * ifname,size_t len)855  int wpas_mesh_add_interface(struct wpa_supplicant *wpa_s, char *ifname,
856  			    size_t len)
857  {
858  	struct wpa_interface iface;
859  	struct wpa_supplicant *mesh_wpa_s;
860  	u8 addr[ETH_ALEN];
861  
862  	if (ifname[0] == '\0' && wpas_mesh_get_ifname(wpa_s, ifname, len) < 0)
863  		return -1;
864  
865  	if (wpa_drv_if_add(wpa_s, WPA_IF_MESH, ifname, NULL, NULL, NULL, addr,
866  			   NULL) < 0) {
867  		wpa_printf(MSG_ERROR,
868  			   "mesh: Failed to create new mesh interface");
869  		return -1;
870  	}
871  	wpa_printf(MSG_INFO, "mesh: Created virtual interface %s addr "
872  		   MACSTR, ifname, MAC2STR(addr));
873  
874  	os_memset(&iface, 0, sizeof(iface));
875  	iface.ifname = ifname;
876  	iface.driver = wpa_s->driver->name;
877  	iface.driver_param = wpa_s->conf->driver_param;
878  	iface.ctrl_interface = wpa_s->conf->ctrl_interface;
879  
880  	mesh_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface, wpa_s);
881  	if (!mesh_wpa_s) {
882  		wpa_printf(MSG_ERROR,
883  			   "mesh: Failed to create new wpa_supplicant interface");
884  		wpa_drv_if_remove(wpa_s, WPA_IF_MESH, ifname);
885  		return -1;
886  	}
887  	mesh_wpa_s->mesh_if_created = 1;
888  	return 0;
889  }
890  
891  
wpas_mesh_peer_remove(struct wpa_supplicant * wpa_s,const u8 * addr)892  int wpas_mesh_peer_remove(struct wpa_supplicant *wpa_s, const u8 *addr)
893  {
894  	return mesh_mpm_close_peer(wpa_s, addr);
895  }
896  
897  
wpas_mesh_peer_add(struct wpa_supplicant * wpa_s,const u8 * addr,int duration)898  int wpas_mesh_peer_add(struct wpa_supplicant *wpa_s, const u8 *addr,
899  		       int duration)
900  {
901  	return mesh_mpm_connect_peer(wpa_s, addr, duration);
902  }
903