1 /*
2 * hostapd / Initialization and configuration
3 * Copyright (c) 2002-2021, Jouni Malinen <j@w1.fi>
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 #ifdef CONFIG_SQLITE
11 #include <sqlite3.h>
12 #endif /* CONFIG_SQLITE */
13
14 #include "utils/common.h"
15 #include "utils/eloop.h"
16 #include "utils/crc32.h"
17 #include "common/ieee802_11_defs.h"
18 #include "common/wpa_ctrl.h"
19 #include "common/hw_features_common.h"
20 #include "radius/radius_client.h"
21 #include "radius/radius_das.h"
22 #include "eap_server/tncs.h"
23 #include "eapol_auth/eapol_auth_sm.h"
24 #include "eapol_auth/eapol_auth_sm_i.h"
25 #include "fst/fst.h"
26 #include "hostapd.h"
27 #include "authsrv.h"
28 #include "sta_info.h"
29 #include "accounting.h"
30 #include "ap_list.h"
31 #include "beacon.h"
32 #include "ieee802_1x.h"
33 #include "ieee802_11_auth.h"
34 #include "vlan_init.h"
35 #include "wpa_auth.h"
36 #include "wps_hostapd.h"
37 #include "dpp_hostapd.h"
38 #include "nan_usd_ap.h"
39 #include "gas_query_ap.h"
40 #include "hw_features.h"
41 #include "wpa_auth_glue.h"
42 #include "ap_drv_ops.h"
43 #include "ap_config.h"
44 #include "p2p_hostapd.h"
45 #include "gas_serv.h"
46 #include "dfs.h"
47 #include "ieee802_11.h"
48 #include "bss_load.h"
49 #include "x_snoop.h"
50 #include "dhcp_snoop.h"
51 #include "ndisc_snoop.h"
52 #include "neighbor_db.h"
53 #include "rrm.h"
54 #include "fils_hlp.h"
55 #include "acs.h"
56 #include "hs20.h"
57 #include "airtime_policy.h"
58 #include "wpa_auth_kay.h"
59 #include "hw_features.h"
60 #ifdef CONFIG_LIBWPA_VENDOR
61 #include "hostapd_client.h"
62 #endif
63 #ifdef CONFIG_P2P_CHR
64 #include "wpa_hw_p2p_chr.h"
65 #endif
66
67 static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason);
68 #ifdef CONFIG_WEP
69 static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd);
70 static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd);
71 #endif /* CONFIG_WEP */
72 static int setup_interface2(struct hostapd_iface *iface);
73 static void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx);
74 static void hostapd_interface_setup_failure_handler(void *eloop_ctx,
75 void *timeout_ctx);
76 #ifdef CONFIG_IEEE80211AX
77 static void hostapd_switch_color_timeout_handler(void *eloop_data,
78 void *user_ctx);
79 #endif /* CONFIG_IEEE80211AX */
80
81
hostapd_for_each_interface(struct hapd_interfaces * interfaces,int (* cb)(struct hostapd_iface * iface,void * ctx),void * ctx)82 int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
83 int (*cb)(struct hostapd_iface *iface,
84 void *ctx), void *ctx)
85 {
86 size_t i;
87 int ret;
88
89 for (i = 0; i < interfaces->count; i++) {
90 if (!interfaces->iface[i])
91 continue;
92 ret = cb(interfaces->iface[i], ctx);
93 if (ret)
94 return ret;
95 }
96
97 return 0;
98 }
99
100
hostapd_mbssid_get_tx_bss(struct hostapd_data * hapd)101 struct hostapd_data * hostapd_mbssid_get_tx_bss(struct hostapd_data *hapd)
102 {
103 if (hapd->iconf->mbssid)
104 return hapd->iface->bss[0];
105
106 return hapd;
107 }
108
109
hostapd_mbssid_get_bss_index(struct hostapd_data * hapd)110 int hostapd_mbssid_get_bss_index(struct hostapd_data *hapd)
111 {
112 if (hapd->iconf->mbssid) {
113 size_t i;
114
115 for (i = 1; i < hapd->iface->num_bss; i++)
116 if (hapd->iface->bss[i] == hapd)
117 return i;
118 }
119
120 return 0;
121 }
122
123
hostapd_reconfig_encryption(struct hostapd_data * hapd)124 void hostapd_reconfig_encryption(struct hostapd_data *hapd)
125 {
126 if (hapd->wpa_auth)
127 return;
128
129 hostapd_set_privacy(hapd, 0);
130 #ifdef CONFIG_WEP
131 hostapd_setup_encryption(hapd->conf->iface, hapd);
132 #endif /* CONFIG_WEP */
133 }
134
135
hostapd_reload_bss(struct hostapd_data * hapd)136 static void hostapd_reload_bss(struct hostapd_data *hapd)
137 {
138 struct hostapd_ssid *ssid;
139
140 if (!hapd->started)
141 return;
142
143 if (hapd->conf->wmm_enabled < 0)
144 hapd->conf->wmm_enabled = hapd->iconf->ieee80211n |
145 hapd->iconf->ieee80211ax;
146
147 #ifndef CONFIG_NO_RADIUS
148 radius_client_reconfig(hapd->radius, hapd->conf->radius);
149 #endif /* CONFIG_NO_RADIUS */
150
151 ssid = &hapd->conf->ssid;
152 if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next &&
153 ssid->wpa_passphrase_set && ssid->wpa_passphrase) {
154 /*
155 * Force PSK to be derived again since SSID or passphrase may
156 * have changed.
157 */
158 hostapd_config_clear_wpa_psk(&hapd->conf->ssid.wpa_psk);
159 }
160 if (hostapd_setup_wpa_psk(hapd->conf)) {
161 wpa_printf(MSG_ERROR, "Failed to re-configure WPA PSK "
162 "after reloading configuration");
163 }
164
165 if (hapd->conf->ieee802_1x || hapd->conf->wpa)
166 hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 1);
167 else
168 hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 0);
169
170 if ((hapd->conf->wpa || hapd->conf->osen) && hapd->wpa_auth == NULL) {
171 hostapd_setup_wpa(hapd);
172 if (hapd->wpa_auth)
173 wpa_init_keys(hapd->wpa_auth);
174 } else if (hapd->conf->wpa) {
175 const u8 *wpa_ie;
176 size_t wpa_ie_len;
177 hostapd_reconfig_wpa(hapd);
178 wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len);
179 if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len))
180 wpa_printf(MSG_ERROR, "Failed to configure WPA IE for "
181 "the kernel driver.");
182 } else if (hapd->wpa_auth) {
183 wpa_deinit(hapd->wpa_auth);
184 hapd->wpa_auth = NULL;
185 hostapd_set_privacy(hapd, 0);
186 #ifdef CONFIG_WEP
187 hostapd_setup_encryption(hapd->conf->iface, hapd);
188 #endif /* CONFIG_WEP */
189 hostapd_set_generic_elem(hapd, (u8 *) "", 0);
190 }
191
192 hostapd_neighbor_sync_own_report(hapd);
193
194 ieee802_11_set_beacon(hapd);
195 hostapd_update_wps(hapd);
196
197 if (hapd->conf->ssid.ssid_set &&
198 hostapd_set_ssid(hapd, hapd->conf->ssid.ssid,
199 hapd->conf->ssid.ssid_len)) {
200 wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
201 /* try to continue */
202 }
203 wpa_printf(MSG_DEBUG, "Reconfigured interface %s", hapd->conf->iface);
204 }
205
206
hostapd_clear_old_bss(struct hostapd_data * bss)207 static void hostapd_clear_old_bss(struct hostapd_data *bss)
208 {
209 wpa_printf(MSG_DEBUG, "BSS %s changed - clear old state",
210 bss->conf->iface);
211
212 /*
213 * Deauthenticate all stations since the new configuration may not
214 * allow them to use the BSS anymore.
215 */
216 hostapd_flush_old_stations(bss, WLAN_REASON_PREV_AUTH_NOT_VALID);
217 #ifdef CONFIG_WEP
218 hostapd_broadcast_wep_clear(bss);
219 #endif /* CONFIG_WEP */
220
221 #ifndef CONFIG_NO_RADIUS
222 /* TODO: update dynamic data based on changed configuration
223 * items (e.g., open/close sockets, etc.) */
224 radius_client_flush(bss->radius, 0);
225 #endif /* CONFIG_NO_RADIUS */
226 }
227
228
hostapd_clear_old(struct hostapd_iface * iface)229 static void hostapd_clear_old(struct hostapd_iface *iface)
230 {
231 size_t j;
232
233 for (j = 0; j < iface->num_bss; j++)
234 hostapd_clear_old_bss(iface->bss[j]);
235 }
236
237
hostapd_iface_conf_changed(struct hostapd_config * newconf,struct hostapd_config * oldconf)238 static int hostapd_iface_conf_changed(struct hostapd_config *newconf,
239 struct hostapd_config *oldconf)
240 {
241 size_t i;
242
243 if (newconf->num_bss != oldconf->num_bss)
244 return 1;
245
246 for (i = 0; i < newconf->num_bss; i++) {
247 if (os_strcmp(newconf->bss[i]->iface,
248 oldconf->bss[i]->iface) != 0)
249 return 1;
250 }
251
252 return 0;
253 }
254
255
hostapd_reload_config(struct hostapd_iface * iface)256 int hostapd_reload_config(struct hostapd_iface *iface)
257 {
258 struct hapd_interfaces *interfaces = iface->interfaces;
259 struct hostapd_data *hapd = iface->bss[0];
260 struct hostapd_config *newconf, *oldconf;
261 size_t j;
262
263 if (iface->config_fname == NULL) {
264 /* Only in-memory config in use - assume it has been updated */
265 hostapd_clear_old(iface);
266 for (j = 0; j < iface->num_bss; j++)
267 hostapd_reload_bss(iface->bss[j]);
268 return 0;
269 }
270
271 if (iface->interfaces == NULL ||
272 iface->interfaces->config_read_cb == NULL)
273 return -1;
274 newconf = iface->interfaces->config_read_cb(iface->config_fname);
275 if (newconf == NULL)
276 return -1;
277
278 oldconf = hapd->iconf;
279 if (hostapd_iface_conf_changed(newconf, oldconf)) {
280 char *fname;
281 int res;
282
283 hostapd_clear_old(iface);
284
285 wpa_printf(MSG_DEBUG,
286 "Configuration changes include interface/BSS modification - force full disable+enable sequence");
287 fname = os_strdup(iface->config_fname);
288 if (!fname) {
289 hostapd_config_free(newconf);
290 return -1;
291 }
292 hostapd_remove_iface(interfaces, hapd->conf->iface);
293 iface = hostapd_init(interfaces, fname);
294 os_free(fname);
295 hostapd_config_free(newconf);
296 if (!iface) {
297 wpa_printf(MSG_ERROR,
298 "Failed to initialize interface on config reload");
299 return -1;
300 }
301 iface->interfaces = interfaces;
302 interfaces->iface[interfaces->count] = iface;
303 interfaces->count++;
304 res = hostapd_enable_iface(iface);
305 if (res < 0)
306 wpa_printf(MSG_ERROR,
307 "Failed to enable interface on config reload");
308 return res;
309 }
310 iface->conf = newconf;
311
312 for (j = 0; j < iface->num_bss; j++) {
313 hapd = iface->bss[j];
314 if (!hapd->conf->config_id || !newconf->bss[j]->config_id ||
315 os_strcmp(hapd->conf->config_id,
316 newconf->bss[j]->config_id) != 0)
317 hostapd_clear_old_bss(hapd);
318 hapd->iconf = newconf;
319 hapd->iconf->channel = oldconf->channel;
320 hapd->iconf->acs = oldconf->acs;
321 hapd->iconf->secondary_channel = oldconf->secondary_channel;
322 hapd->iconf->ieee80211n = oldconf->ieee80211n;
323 hapd->iconf->ieee80211ac = oldconf->ieee80211ac;
324 hapd->iconf->ht_capab = oldconf->ht_capab;
325 hapd->iconf->vht_capab = oldconf->vht_capab;
326 hostapd_set_oper_chwidth(hapd->iconf,
327 hostapd_get_oper_chwidth(oldconf));
328 hostapd_set_oper_centr_freq_seg0_idx(
329 hapd->iconf,
330 hostapd_get_oper_centr_freq_seg0_idx(oldconf));
331 hostapd_set_oper_centr_freq_seg1_idx(
332 hapd->iconf,
333 hostapd_get_oper_centr_freq_seg1_idx(oldconf));
334 hapd->conf = newconf->bss[j];
335 hostapd_reload_bss(hapd);
336 }
337
338 hostapd_config_free(oldconf);
339
340
341 return 0;
342 }
343
344
345 #ifdef CONFIG_WEP
346
hostapd_broadcast_key_clear_iface(struct hostapd_data * hapd,const char * ifname)347 static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd,
348 const char *ifname)
349 {
350 int i;
351
352 if (!ifname || !hapd->drv_priv)
353 return;
354 for (i = 0; i < NUM_WEP_KEYS; i++) {
355 if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, NULL, i, 0,
356 0, NULL, 0, NULL, 0, KEY_FLAG_GROUP)) {
357 wpa_printf(MSG_DEBUG, "Failed to clear default "
358 "encryption keys (ifname=%s keyidx=%d)",
359 ifname, i);
360 }
361 }
362 if (hapd->conf->ieee80211w) {
363 for (i = NUM_WEP_KEYS; i < NUM_WEP_KEYS + 2; i++) {
364 if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE,
365 NULL, i, 0, 0, NULL,
366 0, NULL, 0, KEY_FLAG_GROUP)) {
367 wpa_printf(MSG_DEBUG, "Failed to clear "
368 "default mgmt encryption keys "
369 "(ifname=%s keyidx=%d)", ifname, i);
370 }
371 }
372 }
373 }
374
375
hostapd_broadcast_wep_clear(struct hostapd_data * hapd)376 static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd)
377 {
378 hostapd_broadcast_key_clear_iface(hapd, hapd->conf->iface);
379 return 0;
380 }
381
382
hostapd_broadcast_wep_set(struct hostapd_data * hapd)383 static int hostapd_broadcast_wep_set(struct hostapd_data *hapd)
384 {
385 int errors = 0, idx;
386 struct hostapd_ssid *ssid = &hapd->conf->ssid;
387
388 idx = ssid->wep.idx;
389 if (ssid->wep.default_len && ssid->wep.key[idx] &&
390 hostapd_drv_set_key(hapd->conf->iface,
391 hapd, WPA_ALG_WEP, broadcast_ether_addr, idx, 0,
392 1, NULL, 0, ssid->wep.key[idx],
393 ssid->wep.len[idx],
394 KEY_FLAG_GROUP_RX_TX_DEFAULT)) {
395 wpa_printf(MSG_WARNING, "Could not set WEP encryption.");
396 errors++;
397 }
398
399 return errors;
400 }
401
402 #endif /* CONFIG_WEP */
403
404
405 #ifdef CONFIG_IEEE80211BE
406 #ifdef CONFIG_TESTING_OPTIONS
407
408 #define TU_TO_USEC(_val) ((_val) * 1024)
409
hostapd_link_remove_timeout_handler(void * eloop_data,void * user_ctx)410 static void hostapd_link_remove_timeout_handler(void *eloop_data,
411 void *user_ctx)
412 {
413 struct hostapd_data *hapd = (struct hostapd_data *) eloop_data;
414
415 if (hapd->eht_mld_link_removal_count == 0)
416 return;
417 hapd->eht_mld_link_removal_count--;
418
419 wpa_printf(MSG_DEBUG, "MLD: Remove link_id=%u in %u beacons",
420 hapd->mld_link_id,
421 hapd->eht_mld_link_removal_count);
422
423 ieee802_11_set_beacon(hapd);
424
425 if (!hapd->eht_mld_link_removal_count) {
426 hostapd_free_link_stas(hapd);
427 hostapd_disable_iface(hapd->iface);
428 return;
429 }
430
431 eloop_register_timeout(0, TU_TO_USEC(hapd->iconf->beacon_int),
432 hostapd_link_remove_timeout_handler,
433 hapd, NULL);
434 }
435
436
hostapd_link_remove(struct hostapd_data * hapd,u32 count)437 int hostapd_link_remove(struct hostapd_data *hapd, u32 count)
438 {
439 if (!hapd->conf->mld_ap)
440 return -1;
441
442 wpa_printf(MSG_DEBUG,
443 "MLD: Remove link_id=%u in %u beacons",
444 hapd->mld_link_id, count);
445
446 hapd->eht_mld_link_removal_count = count;
447 hapd->eht_mld_bss_param_change++;
448
449 eloop_register_timeout(0, TU_TO_USEC(hapd->iconf->beacon_int),
450 hostapd_link_remove_timeout_handler,
451 hapd, NULL);
452
453 ieee802_11_set_beacon(hapd);
454 return 0;
455 }
456
457 #endif /* CONFIG_TESTING_OPTIONS */
458 #endif /* CONFIG_IEEE80211BE */
459
460
hostapd_free_hapd_data(struct hostapd_data * hapd)461 void hostapd_free_hapd_data(struct hostapd_data *hapd)
462 {
463 os_free(hapd->probereq_cb);
464 hapd->probereq_cb = NULL;
465 hapd->num_probereq_cb = 0;
466
467 #ifdef CONFIG_P2P
468 wpabuf_free(hapd->p2p_beacon_ie);
469 hapd->p2p_beacon_ie = NULL;
470 wpabuf_free(hapd->p2p_probe_resp_ie);
471 hapd->p2p_probe_resp_ie = NULL;
472 #endif /* CONFIG_P2P */
473
474 if (!hapd->started) {
475 wpa_printf(MSG_ERROR, "%s: Interface %s wasn't started",
476 __func__, hapd->conf ? hapd->conf->iface : "N/A");
477 return;
478 }
479 hapd->started = 0;
480 hapd->beacon_set_done = 0;
481
482 wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface);
483 accounting_deinit(hapd);
484 hostapd_deinit_wpa(hapd);
485 vlan_deinit(hapd);
486 hostapd_acl_deinit(hapd);
487 #ifndef CONFIG_NO_RADIUS
488 if (hostapd_mld_is_first_bss(hapd)) {
489 #ifdef CONFIG_IEEE80211BE
490 struct hapd_interfaces *ifaces = hapd->iface->interfaces;
491 size_t i;
492
493 for (i = 0; i < ifaces->count; i++) {
494 struct hostapd_iface *iface = ifaces->iface[i];
495 size_t j;
496
497 for (j = 0; iface && j < iface->num_bss; j++) {
498 struct hostapd_data *h = iface->bss[j];
499
500 if (hapd == h)
501 continue;
502 if (h->radius == hapd->radius)
503 h->radius = NULL;
504 if (h->radius_das == hapd->radius_das)
505 h->radius_das = NULL;
506 }
507 }
508 #endif /* CONFIG_IEEE80211BE */
509 radius_client_deinit(hapd->radius);
510 radius_das_deinit(hapd->radius_das);
511 }
512 hapd->radius = NULL;
513 hapd->radius_das = NULL;
514 #endif /* CONFIG_NO_RADIUS */
515
516 hostapd_deinit_wps(hapd);
517 ieee802_1x_dealloc_kay_sm_hapd(hapd);
518 #ifdef CONFIG_DPP
519 hostapd_dpp_deinit(hapd);
520 gas_query_ap_deinit(hapd->gas);
521 hapd->gas = NULL;
522 #endif /* CONFIG_DPP */
523 #ifdef CONFIG_NAN_USD
524 hostapd_nan_usd_deinit(hapd);
525 #endif /* CONFIG_NAN_USD */
526
527 authsrv_deinit(hapd);
528
529 if (hapd->interface_added) {
530 hapd->interface_added = 0;
531 if (hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) {
532 wpa_printf(MSG_WARNING,
533 "Failed to remove BSS interface %s",
534 hapd->conf->iface);
535 hapd->interface_added = 1;
536 } else {
537 /*
538 * Since this was a dynamically added interface, the
539 * driver wrapper may have removed its internal instance
540 * and hapd->drv_priv is not valid anymore.
541 */
542 hapd->drv_priv = NULL;
543 }
544 }
545
546 #ifdef CONFIG_IEEE80211BE
547 /* If the interface was not added as well as it is not the first BSS,
548 * at least the link should be removed here since deinit will take care
549 * of only the first BSS. */
550 if (hapd->conf->mld_ap && !hapd->interface_added &&
551 hapd->iface->bss[0] != hapd)
552 hostapd_if_link_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface,
553 hapd->mld_link_id);
554 #endif /* CONFIG_IEEE80211BE */
555
556 wpabuf_free(hapd->time_adv);
557 hapd->time_adv = NULL;
558
559 #ifdef CONFIG_INTERWORKING
560 gas_serv_deinit(hapd);
561 #endif /* CONFIG_INTERWORKING */
562
563 bss_load_update_deinit(hapd);
564 ndisc_snoop_deinit(hapd);
565 dhcp_snoop_deinit(hapd);
566 x_snoop_deinit(hapd);
567
568 #ifdef CONFIG_SQLITE
569 bin_clear_free(hapd->tmp_eap_user.identity,
570 hapd->tmp_eap_user.identity_len);
571 bin_clear_free(hapd->tmp_eap_user.password,
572 hapd->tmp_eap_user.password_len);
573 os_memset(&hapd->tmp_eap_user, 0, sizeof(hapd->tmp_eap_user));
574 #endif /* CONFIG_SQLITE */
575
576 #ifdef CONFIG_MESH
577 wpabuf_free(hapd->mesh_pending_auth);
578 hapd->mesh_pending_auth = NULL;
579 /* handling setup failure is already done */
580 hapd->setup_complete_cb = NULL;
581 #endif /* CONFIG_MESH */
582
583 #ifndef CONFIG_NO_RRM
584 hostapd_clean_rrm(hapd);
585 #endif /* CONFIG_NO_RRM */
586 fils_hlp_deinit(hapd);
587
588 #ifdef CONFIG_OCV
589 eloop_cancel_timeout(hostapd_ocv_check_csa_sa_query, hapd, NULL);
590 #endif /* CONFIG_OCV */
591
592 #ifdef CONFIG_SAE
593 {
594 struct hostapd_sae_commit_queue *q;
595
596 while ((q = dl_list_first(&hapd->sae_commit_queue,
597 struct hostapd_sae_commit_queue,
598 list))) {
599 dl_list_del(&q->list);
600 os_free(q);
601 }
602 }
603 eloop_cancel_timeout(auth_sae_process_commit, hapd, NULL);
604 #endif /* CONFIG_SAE */
605
606 #ifdef CONFIG_IEEE80211AX
607 eloop_cancel_timeout(hostapd_switch_color_timeout_handler, hapd, NULL);
608 #ifdef CONFIG_TESTING_OPTIONS
609 #ifdef CONFIG_IEEE80211BE
610 eloop_cancel_timeout(hostapd_link_remove_timeout_handler, hapd, NULL);
611 #endif /* CONFIG_IEEE80211BE */
612 #endif /* CONFIG_TESTING_OPTIONS */
613
614 #endif /* CONFIG_IEEE80211AX */
615 }
616
617
618 /* hostapd_bss_link_deinit - Per-BSS ML cleanup (deinitialization)
619 * @hapd: Pointer to BSS data
620 *
621 * This function is used to unlink the BSS from the AP MLD.
622 * If the BSS being removed is the first link, the next link becomes the first
623 * link.
624 */
hostapd_bss_link_deinit(struct hostapd_data * hapd)625 static void hostapd_bss_link_deinit(struct hostapd_data *hapd)
626 {
627 #ifdef CONFIG_IEEE80211BE
628 if (!hapd->conf || !hapd->conf->mld_ap)
629 return;
630
631 if (!hapd->mld->num_links)
632 return;
633
634 /* If not started, not yet linked to the MLD. However, the first
635 * BSS is always linked since it is linked during driver_init(), and
636 * hence, need to remove it from the AP MLD.
637 */
638 if (!hapd->started && hapd->iface->bss[0] != hapd)
639 return;
640
641 /* The first BSS can also be only linked when at least driver_init() is
642 * executed. But if previous interface fails, it is not, and hence,
643 * safe to skip.
644 */
645 if (hapd->iface->bss[0] == hapd && !hapd->drv_priv)
646 return;
647
648 hostapd_mld_remove_link(hapd);
649 #endif /* CONFIG_IEEE80211BE */
650 }
651
652
653 /**
654 * hostapd_cleanup - Per-BSS cleanup (deinitialization)
655 * @hapd: Pointer to BSS data
656 *
657 * This function is used to free all per-BSS data structures and resources.
658 * Most of the modules that are initialized in hostapd_setup_bss() are
659 * deinitialized here.
660 */
hostapd_cleanup(struct hostapd_data * hapd)661 static void hostapd_cleanup(struct hostapd_data *hapd)
662 {
663 wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s))", __func__, hapd,
664 hapd->conf ? hapd->conf->iface : "N/A");
665 if (hapd->iface->interfaces &&
666 hapd->iface->interfaces->ctrl_iface_deinit) {
667 wpa_msg(hapd->msg_ctx, MSG_INFO, WPA_EVENT_TERMINATING);
668 #ifdef CONFIG_LIBWPA_VENDOR
669 struct HostapdApCbParm hostapdApCbParm = {};
670 size_t contentLen = strlen(WPA_EVENT_TERMINATING);
671 os_memcpy(hostapdApCbParm.content, WPA_EVENT_TERMINATING, contentLen);
672 hostapdApCbParm.content[contentLen] = '\0';
673 hostapdApCbParm.id = 0;
674 wpa_printf(MSG_INFO, "%s HOSTAPD_EVENT_AP_STATE %s%d", __func__, hostapdApCbParm.content, hostapdApCbParm.id);
675 HostapdEventReport(hapd->conf->iface, HOSTAPD_EVENT_AP_STATE, (void *) &hostapdApCbParm);
676 #endif
677 hapd->iface->interfaces->ctrl_iface_deinit(hapd);
678 }
679 hostapd_free_hapd_data(hapd);
680 }
681
682
sta_track_deinit(struct hostapd_iface * iface)683 static void sta_track_deinit(struct hostapd_iface *iface)
684 {
685 struct hostapd_sta_info *info;
686
687 if (!iface->num_sta_seen)
688 return;
689
690 while ((info = dl_list_first(&iface->sta_seen, struct hostapd_sta_info,
691 list))) {
692 dl_list_del(&info->list);
693 iface->num_sta_seen--;
694 sta_track_del(info);
695 }
696 }
697
698
hostapd_cleanup_iface_partial(struct hostapd_iface * iface)699 void hostapd_cleanup_iface_partial(struct hostapd_iface *iface)
700 {
701 wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
702 eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
703 #ifdef NEED_AP_MLME
704 hostapd_stop_setup_timers(iface);
705 #endif /* NEED_AP_MLME */
706 if (iface->current_mode)
707 acs_cleanup(iface);
708 hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);
709 iface->hw_features = NULL;
710 iface->current_mode = NULL;
711 os_free(iface->current_rates);
712 iface->current_rates = NULL;
713 os_free(iface->basic_rates);
714 iface->basic_rates = NULL;
715 iface->cac_started = 0;
716 ap_list_deinit(iface);
717 sta_track_deinit(iface);
718 airtime_policy_update_deinit(iface);
719 }
720
721
722 /**
723 * hostapd_cleanup_iface - Complete per-interface cleanup
724 * @iface: Pointer to interface data
725 *
726 * This function is called after per-BSS data structures are deinitialized
727 * with hostapd_cleanup().
728 */
hostapd_cleanup_iface(struct hostapd_iface * iface)729 static void hostapd_cleanup_iface(struct hostapd_iface *iface)
730 {
731 wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
732 eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface,
733 NULL);
734
735 hostapd_cleanup_iface_partial(iface);
736 hostapd_config_free(iface->conf);
737 iface->conf = NULL;
738
739 os_free(iface->config_fname);
740 os_free(iface->bss);
741 wpa_printf(MSG_DEBUG, "%s: free iface=%p", __func__, iface);
742 os_free(iface);
743 }
744
745
746 #ifdef CONFIG_WEP
747
hostapd_clear_wep(struct hostapd_data * hapd)748 static void hostapd_clear_wep(struct hostapd_data *hapd)
749 {
750 if (hapd->drv_priv && !hapd->iface->driver_ap_teardown && hapd->conf) {
751 hostapd_set_privacy(hapd, 0);
752 hostapd_broadcast_wep_clear(hapd);
753 }
754 }
755
756
hostapd_setup_encryption(char * iface,struct hostapd_data * hapd)757 static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd)
758 {
759 int i;
760
761 hostapd_broadcast_wep_set(hapd);
762
763 if (hapd->conf->ssid.wep.default_len) {
764 hostapd_set_privacy(hapd, 1);
765 return 0;
766 }
767
768 /*
769 * When IEEE 802.1X is not enabled, the driver may need to know how to
770 * set authentication algorithms for static WEP.
771 */
772 hostapd_drv_set_authmode(hapd, hapd->conf->auth_algs);
773
774 for (i = 0; i < 4; i++) {
775 if (hapd->conf->ssid.wep.key[i] &&
776 hostapd_drv_set_key(iface, hapd, WPA_ALG_WEP, NULL, i, 0,
777 i == hapd->conf->ssid.wep.idx, NULL, 0,
778 hapd->conf->ssid.wep.key[i],
779 hapd->conf->ssid.wep.len[i],
780 i == hapd->conf->ssid.wep.idx ?
781 KEY_FLAG_GROUP_RX_TX_DEFAULT :
782 KEY_FLAG_GROUP_RX_TX)) {
783 wpa_printf(MSG_WARNING, "Could not set WEP "
784 "encryption.");
785 return -1;
786 }
787 if (hapd->conf->ssid.wep.key[i] &&
788 i == hapd->conf->ssid.wep.idx)
789 hostapd_set_privacy(hapd, 1);
790 }
791
792 return 0;
793 }
794
795 #endif /* CONFIG_WEP */
796
797
hostapd_flush_old_stations(struct hostapd_data * hapd,u16 reason)798 static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason)
799 {
800 int ret = 0;
801 u8 addr[ETH_ALEN];
802
803 if (hostapd_drv_none(hapd) || hapd->drv_priv == NULL)
804 return 0;
805
806 if (!hapd->iface->driver_ap_teardown) {
807 wpa_dbg(hapd->msg_ctx, MSG_EXCESSIVE,
808 "Flushing old station entries");
809
810 if (hostapd_flush(hapd)) {
811 wpa_msg(hapd->msg_ctx, MSG_WARNING,
812 "Could not connect to kernel driver");
813 ret = -1;
814 }
815 }
816 if (hapd->conf && hapd->conf->broadcast_deauth) {
817 wpa_dbg(hapd->msg_ctx, MSG_EXCESSIVE,
818 "Deauthenticate all stations");
819 os_memset(addr, 0xff, ETH_ALEN);
820 hostapd_drv_sta_deauth(hapd, addr, reason);
821 }
822 hostapd_free_stas(hapd);
823
824 return ret;
825 }
826
827
hostapd_bss_deinit_no_free(struct hostapd_data * hapd)828 void hostapd_bss_deinit_no_free(struct hostapd_data *hapd)
829 {
830 hostapd_free_stas(hapd);
831 hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
832 #ifdef CONFIG_WEP
833 hostapd_clear_wep(hapd);
834 #endif /* CONFIG_WEP */
835 }
836
837
838 /**
839 * hostapd_validate_bssid_configuration - Validate BSSID configuration
840 * @iface: Pointer to interface data
841 * Returns: 0 on success, -1 on failure
842 *
843 * This function is used to validate that the configured BSSIDs are valid.
844 */
hostapd_validate_bssid_configuration(struct hostapd_iface * iface)845 static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface)
846 {
847 u8 mask[ETH_ALEN] = { 0 };
848 struct hostapd_data *hapd = iface->bss[0];
849 unsigned int i = iface->conf->num_bss, bits = 0, j;
850 int auto_addr = 0;
851
852 if (hostapd_drv_none(hapd))
853 return 0;
854
855 if (iface->conf->use_driver_iface_addr)
856 return 0;
857
858 /* Generate BSSID mask that is large enough to cover the BSSIDs. */
859
860 /* Determine the bits necessary to cover the number of BSSIDs. */
861 for (i--; i; i >>= 1)
862 bits++;
863
864 /* Determine the bits necessary to any configured BSSIDs,
865 if they are higher than the number of BSSIDs. */
866 for (j = 0; j < iface->conf->num_bss; j++) {
867 if (is_zero_ether_addr(iface->conf->bss[j]->bssid)) {
868 if (j)
869 auto_addr++;
870 continue;
871 }
872
873 for (i = 0; i < ETH_ALEN; i++) {
874 mask[i] |=
875 iface->conf->bss[j]->bssid[i] ^
876 hapd->own_addr[i];
877 }
878 }
879
880 if (!auto_addr)
881 goto skip_mask_ext;
882
883 for (i = 0; i < ETH_ALEN && mask[i] == 0; i++)
884 ;
885 j = 0;
886 if (i < ETH_ALEN) {
887 j = (5 - i) * 8;
888
889 while (mask[i] != 0) {
890 mask[i] >>= 1;
891 j++;
892 }
893 }
894
895 if (bits < j)
896 bits = j;
897
898 if (bits > 40) {
899 wpa_printf(MSG_ERROR, "Too many bits in the BSSID mask (%u)",
900 bits);
901 return -1;
902 }
903
904 os_memset(mask, 0xff, ETH_ALEN);
905 j = bits / 8;
906 for (i = 5; i > 5 - j; i--)
907 mask[i] = 0;
908 j = bits % 8;
909 while (j) {
910 j--;
911 mask[i] <<= 1;
912 }
913
914 skip_mask_ext:
915 wpa_printf(MSG_EXCESSIVE, "BSS count %lu, BSSID mask " MACSTR " (%d bits)",
916 (unsigned long) iface->conf->num_bss, MAC2STR(mask), bits);
917
918 if (!auto_addr)
919 return 0;
920
921 for (i = 0; i < ETH_ALEN; i++) {
922 if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) {
923 wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR_SEC
924 " for start address " MACSTR_SEC ".",
925 MAC2STR_SEC(mask), MAC2STR_SEC(hapd->own_addr));
926 wpa_printf(MSG_ERROR, "Start address must be the "
927 "first address in the block (i.e., addr "
928 "AND mask == addr).");
929 return -1;
930 }
931 }
932
933 return 0;
934 }
935
936
mac_in_conf(struct hostapd_config * conf,const void * a)937 static int mac_in_conf(struct hostapd_config *conf, const void *a)
938 {
939 size_t i;
940
941 for (i = 0; i < conf->num_bss; i++) {
942 if (hostapd_mac_comp(conf->bss[i]->bssid, a) == 0) {
943 return 1;
944 }
945 }
946
947 return 0;
948 }
949
950
951 #ifndef CONFIG_NO_RADIUS
952
hostapd_das_nas_mismatch(struct hostapd_data * hapd,struct radius_das_attrs * attr)953 static int hostapd_das_nas_mismatch(struct hostapd_data *hapd,
954 struct radius_das_attrs *attr)
955 {
956 if (attr->nas_identifier &&
957 (!hapd->conf->nas_identifier ||
958 os_strlen(hapd->conf->nas_identifier) !=
959 attr->nas_identifier_len ||
960 os_memcmp(hapd->conf->nas_identifier, attr->nas_identifier,
961 attr->nas_identifier_len) != 0)) {
962 wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-Identifier mismatch");
963 return 1;
964 }
965
966 if (attr->nas_ip_addr &&
967 (hapd->conf->own_ip_addr.af != AF_INET ||
968 os_memcmp(&hapd->conf->own_ip_addr.u.v4, attr->nas_ip_addr, 4) !=
969 0)) {
970 wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-IP-Address mismatch");
971 return 1;
972 }
973
974 #ifdef CONFIG_IPV6
975 if (attr->nas_ipv6_addr &&
976 (hapd->conf->own_ip_addr.af != AF_INET6 ||
977 os_memcmp(&hapd->conf->own_ip_addr.u.v6, attr->nas_ipv6_addr, 16)
978 != 0)) {
979 wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-IPv6-Address mismatch");
980 return 1;
981 }
982 #endif /* CONFIG_IPV6 */
983
984 return 0;
985 }
986
987
hostapd_das_find_sta(struct hostapd_data * hapd,struct radius_das_attrs * attr,int * multi)988 static struct sta_info * hostapd_das_find_sta(struct hostapd_data *hapd,
989 struct radius_das_attrs *attr,
990 int *multi)
991 {
992 struct sta_info *selected, *sta;
993 char buf[128];
994 int num_attr = 0;
995 int count;
996
997 *multi = 0;
998
999 for (sta = hapd->sta_list; sta; sta = sta->next)
1000 sta->radius_das_match = 1;
1001
1002 if (attr->sta_addr) {
1003 num_attr++;
1004 sta = ap_get_sta(hapd, attr->sta_addr);
1005 if (!sta) {
1006 wpa_printf(MSG_DEBUG,
1007 "RADIUS DAS: No Calling-Station-Id match");
1008 return NULL;
1009 }
1010
1011 selected = sta;
1012 for (sta = hapd->sta_list; sta; sta = sta->next) {
1013 if (sta != selected)
1014 sta->radius_das_match = 0;
1015 }
1016 wpa_printf(MSG_DEBUG, "RADIUS DAS: Calling-Station-Id match");
1017 }
1018
1019 if (attr->acct_session_id) {
1020 num_attr++;
1021 if (attr->acct_session_id_len != 16) {
1022 wpa_printf(MSG_DEBUG,
1023 "RADIUS DAS: Acct-Session-Id cannot match");
1024 return NULL;
1025 }
1026 count = 0;
1027
1028 for (sta = hapd->sta_list; sta; sta = sta->next) {
1029 if (!sta->radius_das_match)
1030 continue;
1031 os_snprintf(buf, sizeof(buf), "%016llX",
1032 (unsigned long long) sta->acct_session_id);
1033 if (os_memcmp(attr->acct_session_id, buf, 16) != 0)
1034 sta->radius_das_match = 0;
1035 else
1036 count++;
1037 }
1038
1039 if (count == 0) {
1040 wpa_printf(MSG_DEBUG,
1041 "RADIUS DAS: No matches remaining after Acct-Session-Id check");
1042 return NULL;
1043 }
1044 wpa_printf(MSG_DEBUG, "RADIUS DAS: Acct-Session-Id match");
1045 }
1046
1047 if (attr->acct_multi_session_id) {
1048 num_attr++;
1049 if (attr->acct_multi_session_id_len != 16) {
1050 wpa_printf(MSG_DEBUG,
1051 "RADIUS DAS: Acct-Multi-Session-Id cannot match");
1052 return NULL;
1053 }
1054 count = 0;
1055
1056 for (sta = hapd->sta_list; sta; sta = sta->next) {
1057 if (!sta->radius_das_match)
1058 continue;
1059 if (!sta->eapol_sm ||
1060 !sta->eapol_sm->acct_multi_session_id) {
1061 sta->radius_das_match = 0;
1062 continue;
1063 }
1064 os_snprintf(buf, sizeof(buf), "%016llX",
1065 (unsigned long long)
1066 sta->eapol_sm->acct_multi_session_id);
1067 if (os_memcmp(attr->acct_multi_session_id, buf, 16) !=
1068 0)
1069 sta->radius_das_match = 0;
1070 else
1071 count++;
1072 }
1073
1074 if (count == 0) {
1075 wpa_printf(MSG_DEBUG,
1076 "RADIUS DAS: No matches remaining after Acct-Multi-Session-Id check");
1077 return NULL;
1078 }
1079 wpa_printf(MSG_DEBUG,
1080 "RADIUS DAS: Acct-Multi-Session-Id match");
1081 }
1082
1083 if (attr->cui) {
1084 num_attr++;
1085 count = 0;
1086
1087 for (sta = hapd->sta_list; sta; sta = sta->next) {
1088 struct wpabuf *cui;
1089
1090 if (!sta->radius_das_match)
1091 continue;
1092 cui = ieee802_1x_get_radius_cui(sta->eapol_sm);
1093 if (!cui || wpabuf_len(cui) != attr->cui_len ||
1094 os_memcmp(wpabuf_head(cui), attr->cui,
1095 attr->cui_len) != 0)
1096 sta->radius_das_match = 0;
1097 else
1098 count++;
1099 }
1100
1101 if (count == 0) {
1102 wpa_printf(MSG_DEBUG,
1103 "RADIUS DAS: No matches remaining after Chargeable-User-Identity check");
1104 return NULL;
1105 }
1106 wpa_printf(MSG_DEBUG,
1107 "RADIUS DAS: Chargeable-User-Identity match");
1108 }
1109
1110 if (attr->user_name) {
1111 num_attr++;
1112 count = 0;
1113
1114 for (sta = hapd->sta_list; sta; sta = sta->next) {
1115 u8 *identity;
1116 size_t identity_len;
1117
1118 if (!sta->radius_das_match)
1119 continue;
1120 identity = ieee802_1x_get_identity(sta->eapol_sm,
1121 &identity_len);
1122 if (!identity ||
1123 identity_len != attr->user_name_len ||
1124 os_memcmp(identity, attr->user_name, identity_len)
1125 != 0)
1126 sta->radius_das_match = 0;
1127 else
1128 count++;
1129 }
1130
1131 if (count == 0) {
1132 wpa_printf(MSG_DEBUG,
1133 "RADIUS DAS: No matches remaining after User-Name check");
1134 return NULL;
1135 }
1136 wpa_printf(MSG_DEBUG,
1137 "RADIUS DAS: User-Name match");
1138 }
1139
1140 if (num_attr == 0) {
1141 /*
1142 * In theory, we could match all current associations, but it
1143 * seems safer to just reject requests that do not include any
1144 * session identification attributes.
1145 */
1146 wpa_printf(MSG_DEBUG,
1147 "RADIUS DAS: No session identification attributes included");
1148 return NULL;
1149 }
1150
1151 selected = NULL;
1152 for (sta = hapd->sta_list; sta; sta = sta->next) {
1153 if (sta->radius_das_match) {
1154 if (selected) {
1155 *multi = 1;
1156 return NULL;
1157 }
1158 selected = sta;
1159 }
1160 }
1161
1162 return selected;
1163 }
1164
1165
hostapd_das_disconnect_pmksa(struct hostapd_data * hapd,struct radius_das_attrs * attr)1166 static int hostapd_das_disconnect_pmksa(struct hostapd_data *hapd,
1167 struct radius_das_attrs *attr)
1168 {
1169 if (!hapd->wpa_auth)
1170 return -1;
1171 return wpa_auth_radius_das_disconnect_pmksa(hapd->wpa_auth, attr);
1172 }
1173
1174
1175 static enum radius_das_res
hostapd_das_disconnect(void * ctx,struct radius_das_attrs * attr)1176 hostapd_das_disconnect(void *ctx, struct radius_das_attrs *attr)
1177 {
1178 struct hostapd_data *hapd = ctx;
1179 struct sta_info *sta;
1180 int multi;
1181
1182 if (hostapd_das_nas_mismatch(hapd, attr))
1183 return RADIUS_DAS_NAS_MISMATCH;
1184
1185 sta = hostapd_das_find_sta(hapd, attr, &multi);
1186 if (sta == NULL) {
1187 if (multi) {
1188 wpa_printf(MSG_DEBUG,
1189 "RADIUS DAS: Multiple sessions match - not supported");
1190 return RADIUS_DAS_MULTI_SESSION_MATCH;
1191 }
1192 if (hostapd_das_disconnect_pmksa(hapd, attr) == 0) {
1193 wpa_printf(MSG_DEBUG,
1194 "RADIUS DAS: PMKSA cache entry matched");
1195 return RADIUS_DAS_SUCCESS;
1196 }
1197 wpa_printf(MSG_DEBUG, "RADIUS DAS: No matching session found");
1198 return RADIUS_DAS_SESSION_NOT_FOUND;
1199 }
1200
1201 wpa_printf(MSG_DEBUG, "RADIUS DAS: Found a matching session " MACSTR_SEC
1202 " - disconnecting", MAC2STR_SEC(sta->addr));
1203 wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
1204
1205 hostapd_drv_sta_deauth(hapd, sta->addr,
1206 WLAN_REASON_PREV_AUTH_NOT_VALID);
1207 ap_sta_deauthenticate(hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID);
1208
1209 return RADIUS_DAS_SUCCESS;
1210 }
1211
1212
1213 #ifdef CONFIG_HS20
1214 static enum radius_das_res
hostapd_das_coa(void * ctx,struct radius_das_attrs * attr)1215 hostapd_das_coa(void *ctx, struct radius_das_attrs *attr)
1216 {
1217 struct hostapd_data *hapd = ctx;
1218 struct sta_info *sta;
1219 int multi;
1220
1221 if (hostapd_das_nas_mismatch(hapd, attr))
1222 return RADIUS_DAS_NAS_MISMATCH;
1223
1224 sta = hostapd_das_find_sta(hapd, attr, &multi);
1225 if (!sta) {
1226 if (multi) {
1227 wpa_printf(MSG_DEBUG,
1228 "RADIUS DAS: Multiple sessions match - not supported");
1229 return RADIUS_DAS_MULTI_SESSION_MATCH;
1230 }
1231 wpa_printf(MSG_DEBUG, "RADIUS DAS: No matching session found");
1232 return RADIUS_DAS_SESSION_NOT_FOUND;
1233 }
1234
1235 wpa_printf(MSG_DEBUG, "RADIUS DAS: Found a matching session " MACSTR_SEC
1236 " - CoA", MAC2STR_SEC(sta->addr));
1237
1238 if (attr->hs20_t_c_filtering) {
1239 if (attr->hs20_t_c_filtering[0] & BIT(0)) {
1240 wpa_printf(MSG_DEBUG,
1241 "HS 2.0: Unexpected Terms and Conditions filtering required in CoA-Request");
1242 return RADIUS_DAS_COA_FAILED;
1243 }
1244
1245 hs20_t_c_filtering(hapd, sta, 0);
1246 }
1247
1248 return RADIUS_DAS_SUCCESS;
1249 }
1250 #else /* CONFIG_HS20 */
1251 #define hostapd_das_coa NULL
1252 #endif /* CONFIG_HS20 */
1253
1254
1255 #ifdef CONFIG_SQLITE
1256
db_table_exists(sqlite3 * db,const char * name)1257 static int db_table_exists(sqlite3 *db, const char *name)
1258 {
1259 char cmd[128];
1260
1261 os_snprintf(cmd, sizeof(cmd), "SELECT 1 FROM %s;", name);
1262 return sqlite3_exec(db, cmd, NULL, NULL, NULL) == SQLITE_OK;
1263 }
1264
1265
db_table_create_radius_attributes(sqlite3 * db)1266 static int db_table_create_radius_attributes(sqlite3 *db)
1267 {
1268 char *err = NULL;
1269 const char *sql =
1270 "CREATE TABLE radius_attributes("
1271 " id INTEGER PRIMARY KEY,"
1272 " sta TEXT,"
1273 " reqtype TEXT,"
1274 " attr TEXT"
1275 ");"
1276 "CREATE INDEX idx_sta_reqtype ON radius_attributes(sta,reqtype);";
1277
1278 wpa_printf(MSG_DEBUG,
1279 "Adding database table for RADIUS attribute information");
1280 if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) {
1281 wpa_printf(MSG_ERROR, "SQLite error: %s", err);
1282 sqlite3_free(err);
1283 return -1;
1284 }
1285
1286 return 0;
1287 }
1288
1289 #endif /* CONFIG_SQLITE */
1290
1291 #endif /* CONFIG_NO_RADIUS */
1292
1293
hostapd_start_beacon(struct hostapd_data * hapd,bool flush_old_stations)1294 static int hostapd_start_beacon(struct hostapd_data *hapd,
1295 bool flush_old_stations)
1296 {
1297 struct hostapd_bss_config *conf = hapd->conf;
1298
1299 if (!conf->start_disabled && ieee802_11_set_beacon(hapd) < 0)
1300 return -1;
1301
1302 if (flush_old_stations && !conf->start_disabled &&
1303 conf->broadcast_deauth) {
1304 u8 addr[ETH_ALEN];
1305
1306 /* Should any previously associated STA not have noticed that
1307 * the AP had stopped and restarted, send one more
1308 * deauthentication notification now that the AP is ready to
1309 * operate. */
1310 wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
1311 "Deauthenticate all stations at BSS start");
1312 os_memset(addr, 0xff, ETH_ALEN);
1313 hostapd_drv_sta_deauth(hapd, addr,
1314 WLAN_REASON_PREV_AUTH_NOT_VALID);
1315 }
1316
1317 if (hapd->driver && hapd->driver->set_operstate)
1318 hapd->driver->set_operstate(hapd->drv_priv, 1);
1319
1320 return 0;
1321 }
1322
1323
1324 #ifndef CONFIG_NO_RADIUS
hostapd_bss_radius_init(struct hostapd_data * hapd)1325 static int hostapd_bss_radius_init(struct hostapd_data *hapd)
1326 {
1327 struct hostapd_bss_config *conf;
1328
1329 if (!hapd)
1330 return -1;
1331
1332 conf = hapd->conf;
1333
1334 if (hapd->radius) {
1335 wpa_printf(MSG_DEBUG,
1336 "Skipping RADIUS client init (already done)");
1337 return 0;
1338 }
1339
1340 hapd->radius = radius_client_init(hapd, conf->radius);
1341 if (!hapd->radius) {
1342 wpa_printf(MSG_ERROR,
1343 "RADIUS client initialization failed.");
1344 return -1;
1345 }
1346
1347 if (conf->radius_das_port) {
1348 struct radius_das_conf das_conf;
1349
1350 os_memset(&das_conf, 0, sizeof(das_conf));
1351 das_conf.port = conf->radius_das_port;
1352 das_conf.shared_secret = conf->radius_das_shared_secret;
1353 das_conf.shared_secret_len =
1354 conf->radius_das_shared_secret_len;
1355 das_conf.client_addr = &conf->radius_das_client_addr;
1356 das_conf.time_window = conf->radius_das_time_window;
1357 das_conf.require_event_timestamp =
1358 conf->radius_das_require_event_timestamp;
1359 das_conf.require_message_authenticator =
1360 conf->radius_das_require_message_authenticator;
1361 das_conf.ctx = hapd;
1362 das_conf.disconnect = hostapd_das_disconnect;
1363 das_conf.coa = hostapd_das_coa;
1364 hapd->radius_das = radius_das_init(&das_conf);
1365 if (!hapd->radius_das) {
1366 wpa_printf(MSG_ERROR,
1367 "RADIUS DAS initialization failed.");
1368 return -1;
1369 }
1370 }
1371
1372 return 0;
1373 }
1374 #endif /* CONFIG_NO_RADIUS */
1375
1376
1377 /**
1378 * hostapd_setup_bss - Per-BSS setup (initialization)
1379 * @hapd: Pointer to BSS data
1380 * @first: Whether this BSS is the first BSS of an interface; -1 = not first,
1381 * but interface may exist
1382 * @start_beacon: Whether Beacon frame template should be configured and
1383 * transmission of Beaconf rames started at this time. This is used when
1384 * MBSSID element is enabled where the information regarding all BSSes
1385 * should be retrieved before configuring the Beacon frame template. The
1386 * calling functions are responsible for configuring the Beacon frame
1387 * explicitly if this is set to false.
1388 *
1389 * This function is used to initialize all per-BSS data structures and
1390 * resources. This gets called in a loop for each BSS when an interface is
1391 * initialized. Most of the modules that are initialized here will be
1392 * deinitialized in hostapd_cleanup().
1393 */
hostapd_setup_bss(struct hostapd_data * hapd,int first,bool start_beacon)1394 static int hostapd_setup_bss(struct hostapd_data *hapd, int first,
1395 bool start_beacon)
1396 {
1397 struct hostapd_bss_config *conf = hapd->conf;
1398 u8 ssid[SSID_MAX_LEN + 1];
1399 int ssid_len, set_ssid;
1400 char force_ifname[IFNAMSIZ];
1401 u8 if_addr[ETH_ALEN];
1402 int flush_old_stations = 1;
1403
1404 if (!hostapd_mld_is_first_bss(hapd))
1405 wpa_printf(MSG_DEBUG,
1406 "MLD: %s: Setting non-first BSS", __func__);
1407
1408 wpa_printf(MSG_EXCESSIVE, "%s(hapd=%p (%s), first=%d)",
1409 __func__, hapd, conf->iface, first);
1410
1411 #ifdef EAP_SERVER_TNC
1412 if (conf->tnc && tncs_global_init() < 0) {
1413 wpa_printf(MSG_ERROR, "Failed to initialize TNCS");
1414 return -1;
1415 }
1416 #endif /* EAP_SERVER_TNC */
1417
1418 if (hapd->started) {
1419 wpa_printf(MSG_ERROR, "%s: Interface %s was already started",
1420 __func__, conf->iface);
1421 return -1;
1422 }
1423 hapd->started = 1;
1424
1425 if (!first || first == -1) {
1426 u8 *addr = hapd->own_addr;
1427
1428 if (!is_zero_ether_addr(conf->bssid)) {
1429 /* Allocate the configured BSSID. */
1430 os_memcpy(hapd->own_addr, conf->bssid, ETH_ALEN);
1431
1432 if (hostapd_mac_comp(hapd->own_addr,
1433 hapd->iface->bss[0]->own_addr) ==
1434 0) {
1435 wpa_printf(MSG_ERROR, "BSS '%s' may not have "
1436 "BSSID set to the MAC address of "
1437 "the radio", conf->iface);
1438 return -1;
1439 }
1440 } else if (hapd->iconf->use_driver_iface_addr) {
1441 addr = NULL;
1442 } else {
1443 /* Allocate the next available BSSID. */
1444 do {
1445 inc_byte_array(hapd->own_addr, ETH_ALEN);
1446 } while (mac_in_conf(hapd->iconf, hapd->own_addr));
1447 }
1448
1449 #ifdef CONFIG_IEEE80211BE
1450 if (conf->mld_ap) {
1451 struct hostapd_data *h_hapd;
1452
1453 h_hapd = hostapd_mld_get_first_bss(hapd);
1454 if (h_hapd) {
1455 hapd->drv_priv = h_hapd->drv_priv;
1456 hapd->interface_added = h_hapd->interface_added;
1457 hostapd_mld_add_link(hapd);
1458 wpa_printf(MSG_DEBUG,
1459 "Setup of non first link (%d) BSS of MLD %s",
1460 hapd->mld_link_id, hapd->conf->iface);
1461 goto setup_mld;
1462 }
1463 }
1464 #endif /* CONFIG_IEEE80211BE */
1465
1466 hapd->interface_added = 1;
1467 if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS,
1468 conf->iface, addr, hapd,
1469 &hapd->drv_priv, force_ifname, if_addr,
1470 conf->bridge[0] ? conf->bridge : NULL,
1471 first == -1)) {
1472 wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID="
1473 MACSTR_SEC ")", MAC2STR_SEC(hapd->own_addr));
1474 hapd->interface_added = 0;
1475 return -1;
1476 }
1477
1478 if (!addr)
1479 os_memcpy(hapd->own_addr, if_addr, ETH_ALEN);
1480
1481 #ifdef CONFIG_IEEE80211BE
1482 if (hapd->conf->mld_ap) {
1483 wpa_printf(MSG_DEBUG,
1484 "Setup of first link (%d) BSS of MLD %s",
1485 hapd->mld_link_id, hapd->conf->iface);
1486 os_memcpy(hapd->mld->mld_addr, hapd->own_addr,
1487 ETH_ALEN);
1488 hostapd_mld_add_link(hapd);
1489 }
1490 #endif /* CONFIG_IEEE80211BE */
1491 }
1492
1493 #ifdef CONFIG_IEEE80211BE
1494 setup_mld:
1495 if (hapd->conf->mld_ap && !first) {
1496 wpa_printf(MSG_DEBUG,
1497 "MLD: Set link_id=%u, mld_addr=" MACSTR
1498 ", own_addr=" MACSTR,
1499 hapd->mld_link_id, MAC2STR(hapd->mld->mld_addr),
1500 MAC2STR(hapd->own_addr));
1501
1502 if (hostapd_drv_link_add(hapd, hapd->mld_link_id,
1503 hapd->own_addr))
1504 return -1;
1505 }
1506 #endif /* CONFIG_IEEE80211BE */
1507
1508 if (conf->wmm_enabled < 0)
1509 conf->wmm_enabled = hapd->iconf->ieee80211n |
1510 hapd->iconf->ieee80211ax;
1511
1512 #ifdef CONFIG_IEEE80211R_AP
1513 if (is_zero_ether_addr(conf->r1_key_holder))
1514 os_memcpy(conf->r1_key_holder, hapd->own_addr, ETH_ALEN);
1515 #endif /* CONFIG_IEEE80211R_AP */
1516
1517 #ifdef CONFIG_MESH
1518 if ((hapd->conf->mesh & MESH_ENABLED) && hapd->iface->mconf == NULL)
1519 flush_old_stations = 0;
1520 #endif /* CONFIG_MESH */
1521
1522 if (flush_old_stations)
1523 hostapd_flush(hapd);
1524 hostapd_set_privacy(hapd, 0);
1525
1526 #ifdef CONFIG_WEP
1527 if (!hostapd_drv_nl80211(hapd))
1528 hostapd_broadcast_wep_clear(hapd);
1529 if (hostapd_setup_encryption(conf->iface, hapd))
1530 return -1;
1531 #endif /* CONFIG_WEP */
1532
1533 /*
1534 * Fetch the SSID from the system and use it or,
1535 * if one was specified in the config file, verify they
1536 * match.
1537 */
1538 ssid_len = hostapd_get_ssid(hapd, ssid, sizeof(ssid));
1539 if (ssid_len < 0) {
1540 wpa_printf(MSG_ERROR, "Could not read SSID from system");
1541 return -1;
1542 }
1543 if (conf->ssid.ssid_set) {
1544 /*
1545 * If SSID is specified in the config file and it differs
1546 * from what is being used then force installation of the
1547 * new SSID.
1548 */
1549 set_ssid = (conf->ssid.ssid_len != (size_t) ssid_len ||
1550 os_memcmp(conf->ssid.ssid, ssid, ssid_len) != 0);
1551 } else {
1552 /*
1553 * No SSID in the config file; just use the one we got
1554 * from the system.
1555 */
1556 set_ssid = 0;
1557 conf->ssid.ssid_len = ssid_len;
1558 os_memcpy(conf->ssid.ssid, ssid, conf->ssid.ssid_len);
1559 }
1560
1561 /*
1562 * Short SSID calculation is identical to FCS and it is defined in
1563 * IEEE P802.11-REVmd/D3.0, 9.4.2.170.3 (Calculating the Short-SSID).
1564 */
1565 conf->ssid.short_ssid = ieee80211_crc32(conf->ssid.ssid,
1566 conf->ssid.ssid_len);
1567
1568 if (!hostapd_drv_none(hapd)) {
1569 wpa_printf(MSG_DEBUG, "Using interface %s with hwaddr " MACSTR_SEC
1570 " and ssid \"%s\"",
1571 conf->iface, MAC2STR_SEC(hapd->own_addr),
1572 anonymize_ssid(wpa_ssid_txt(conf->ssid.ssid, conf->ssid.ssid_len)));
1573 }
1574
1575 if (hostapd_setup_wpa_psk(conf)) {
1576 wpa_printf(MSG_ERROR, "WPA-PSK setup failed.");
1577 return -1;
1578 }
1579
1580 /* Set SSID for the kernel driver (to be used in beacon and probe
1581 * response frames) */
1582 if (set_ssid && hostapd_set_ssid(hapd, conf->ssid.ssid,
1583 conf->ssid.ssid_len)) {
1584 wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
1585 return -1;
1586 }
1587
1588 if (wpa_debug_level <= MSG_MSGDUMP)
1589 conf->radius->msg_dumps = 1;
1590 #ifndef CONFIG_NO_RADIUS
1591
1592 #ifdef CONFIG_SQLITE
1593 if (conf->radius_req_attr_sqlite) {
1594 if (sqlite3_open(conf->radius_req_attr_sqlite,
1595 &hapd->rad_attr_db)) {
1596 wpa_printf(MSG_ERROR, "Could not open SQLite file '%s'",
1597 conf->radius_req_attr_sqlite);
1598 return -1;
1599 }
1600
1601 wpa_printf(MSG_DEBUG, "Opening RADIUS attribute database: %s",
1602 conf->radius_req_attr_sqlite);
1603 if (!db_table_exists(hapd->rad_attr_db, "radius_attributes") &&
1604 db_table_create_radius_attributes(hapd->rad_attr_db) < 0)
1605 return -1;
1606 }
1607 #endif /* CONFIG_SQLITE */
1608
1609 if (hostapd_mld_is_first_bss(hapd)) {
1610 if (hostapd_bss_radius_init(hapd))
1611 return -1;
1612 } else {
1613 #ifdef CONFIG_IEEE80211BE
1614 struct hostapd_data *f_bss;
1615
1616 f_bss = hostapd_mld_get_first_bss(hapd);
1617 if (!f_bss)
1618 return -1;
1619
1620 if (!f_bss->radius) {
1621 wpa_printf(MSG_DEBUG,
1622 "MLD: First BSS RADIUS client does not exist. Init on its behalf");
1623
1624 if (hostapd_bss_radius_init(f_bss))
1625 return -1;
1626 }
1627
1628 wpa_printf(MSG_DEBUG,
1629 "MLD: Using RADIUS client of the first BSS");
1630 hapd->radius = f_bss->radius;
1631 hapd->radius_das = f_bss->radius_das;
1632 #endif /* CONFIG_IEEE80211BE */
1633 }
1634 #endif /* CONFIG_NO_RADIUS */
1635
1636 if (hostapd_acl_init(hapd)) {
1637 wpa_printf(MSG_ERROR, "ACL initialization failed.");
1638 return -1;
1639 }
1640 if (hostapd_init_wps(hapd, conf))
1641 return -1;
1642
1643 #ifdef CONFIG_DPP
1644 hapd->gas = gas_query_ap_init(hapd, hapd->msg_ctx);
1645 if (!hapd->gas)
1646 return -1;
1647 if (hostapd_dpp_init(hapd))
1648 return -1;
1649 #endif /* CONFIG_DPP */
1650
1651 #ifdef CONFIG_NAN_USD
1652 if (hostapd_nan_usd_init(hapd) < 0)
1653 return -1;
1654 #endif /* CONFIG_NAN_USD */
1655
1656 if (authsrv_init(hapd) < 0)
1657 return -1;
1658
1659 if (ieee802_1x_init(hapd)) {
1660 wpa_printf(MSG_ERROR, "IEEE 802.1X initialization failed.");
1661 return -1;
1662 }
1663
1664 if ((conf->wpa || conf->osen) && hostapd_setup_wpa(hapd))
1665 return -1;
1666
1667 if (accounting_init(hapd)) {
1668 wpa_printf(MSG_ERROR, "Accounting initialization failed.");
1669 return -1;
1670 }
1671
1672 #ifdef CONFIG_INTERWORKING
1673 if (gas_serv_init(hapd)) {
1674 wpa_printf(MSG_ERROR, "GAS server initialization failed");
1675 return -1;
1676 }
1677 #endif /* CONFIG_INTERWORKING */
1678
1679 if (conf->qos_map_set_len &&
1680 hostapd_drv_set_qos_map(hapd, conf->qos_map_set,
1681 conf->qos_map_set_len)) {
1682 wpa_printf(MSG_ERROR, "Failed to initialize QoS Map");
1683 return -1;
1684 }
1685
1686 if (conf->bss_load_update_period && bss_load_update_init(hapd)) {
1687 wpa_printf(MSG_ERROR, "BSS Load initialization failed");
1688 return -1;
1689 }
1690
1691 if (conf->bridge[0]) {
1692 /* Set explicitly configured bridge parameters that might have
1693 * been lost if the interface has been removed out of the
1694 * bridge. */
1695
1696 /* multicast to unicast on bridge ports */
1697 if (conf->bridge_multicast_to_unicast)
1698 hostapd_drv_br_port_set_attr(
1699 hapd, DRV_BR_PORT_ATTR_MCAST2UCAST, 1);
1700
1701 /* hairpin mode */
1702 if (conf->bridge_hairpin)
1703 hostapd_drv_br_port_set_attr(
1704 hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, 1);
1705 }
1706
1707 if (conf->proxy_arp) {
1708 if (x_snoop_init(hapd)) {
1709 wpa_printf(MSG_ERROR,
1710 "Generic snooping infrastructure initialization failed");
1711 return -1;
1712 }
1713
1714 if (dhcp_snoop_init(hapd)) {
1715 wpa_printf(MSG_ERROR,
1716 "DHCP snooping initialization failed");
1717 return -1;
1718 }
1719
1720 if (ndisc_snoop_init(hapd)) {
1721 wpa_printf(MSG_ERROR,
1722 "Neighbor Discovery snooping initialization failed");
1723 return -1;
1724 }
1725 }
1726
1727 if (!hostapd_drv_none(hapd) && vlan_init(hapd)) {
1728 wpa_printf(MSG_ERROR, "VLAN initialization failed.");
1729 return -1;
1730 }
1731
1732 if (start_beacon && hostapd_start_beacon(hapd, flush_old_stations) < 0)
1733 return -1;
1734
1735 if (hapd->wpa_auth && wpa_init_keys(hapd->wpa_auth) < 0)
1736 return -1;
1737
1738 return 0;
1739 }
1740
1741
hostapd_tx_queue_params(struct hostapd_iface * iface)1742 static void hostapd_tx_queue_params(struct hostapd_iface *iface)
1743 {
1744 struct hostapd_data *hapd = iface->bss[0];
1745 int i;
1746 struct hostapd_tx_queue_params *p;
1747
1748 #ifdef CONFIG_MESH
1749 if ((hapd->conf->mesh & MESH_ENABLED) && iface->mconf == NULL)
1750 return;
1751 #endif /* CONFIG_MESH */
1752
1753 for (i = 0; i < NUM_TX_QUEUES; i++) {
1754 p = &iface->conf->tx_queue[i];
1755
1756 if (hostapd_set_tx_queue_params(hapd, i, p->aifs, p->cwmin,
1757 p->cwmax, p->burst)) {
1758 wpa_printf(MSG_EXCESSIVE, "Failed to set TX queue "
1759 "parameters for queue %d.", i);
1760 /* Continue anyway */
1761 }
1762 }
1763 }
1764
1765
hostapd_set_acl_list(struct hostapd_data * hapd,struct mac_acl_entry * mac_acl,int n_entries,u8 accept_acl)1766 static int hostapd_set_acl_list(struct hostapd_data *hapd,
1767 struct mac_acl_entry *mac_acl,
1768 int n_entries, u8 accept_acl)
1769 {
1770 struct hostapd_acl_params *acl_params;
1771 int i, err;
1772
1773 acl_params = os_zalloc(sizeof(*acl_params) +
1774 (n_entries * sizeof(acl_params->mac_acl[0])));
1775 if (!acl_params)
1776 return -ENOMEM;
1777
1778 for (i = 0; i < n_entries; i++)
1779 os_memcpy(acl_params->mac_acl[i].addr, mac_acl[i].addr,
1780 ETH_ALEN);
1781
1782 acl_params->acl_policy = accept_acl;
1783 acl_params->num_mac_acl = n_entries;
1784
1785 err = hostapd_drv_set_acl(hapd, acl_params);
1786
1787 os_free(acl_params);
1788
1789 return err;
1790 }
1791
1792
hostapd_set_acl(struct hostapd_data * hapd)1793 int hostapd_set_acl(struct hostapd_data *hapd)
1794 {
1795 struct hostapd_config *conf = hapd->iconf;
1796 int err = 0;
1797 u8 accept_acl;
1798
1799 if (hapd->iface->drv_max_acl_mac_addrs == 0)
1800 return 0;
1801
1802 if (conf->bss[0]->macaddr_acl == DENY_UNLESS_ACCEPTED) {
1803 accept_acl = 1;
1804 err = hostapd_set_acl_list(hapd, conf->bss[0]->accept_mac,
1805 conf->bss[0]->num_accept_mac,
1806 accept_acl);
1807 if (err) {
1808 wpa_printf(MSG_DEBUG, "Failed to set accept acl");
1809 return -1;
1810 }
1811 } else if (conf->bss[0]->macaddr_acl == ACCEPT_UNLESS_DENIED) {
1812 accept_acl = 0;
1813 err = hostapd_set_acl_list(hapd, conf->bss[0]->deny_mac,
1814 conf->bss[0]->num_deny_mac,
1815 accept_acl);
1816 if (err) {
1817 wpa_printf(MSG_DEBUG, "Failed to set deny acl");
1818 return -1;
1819 }
1820 }
1821 return err;
1822 }
1823
1824
start_ctrl_iface_bss(struct hostapd_data * hapd)1825 static int start_ctrl_iface_bss(struct hostapd_data *hapd)
1826 {
1827 if (!hapd->iface->interfaces ||
1828 !hapd->iface->interfaces->ctrl_iface_init)
1829 return 0;
1830
1831 if (hapd->iface->interfaces->ctrl_iface_init(hapd)) {
1832 wpa_printf(MSG_ERROR,
1833 "Failed to setup control interface for %s",
1834 hapd->conf->iface);
1835 return -1;
1836 }
1837
1838 return 0;
1839 }
1840
1841
start_ctrl_iface(struct hostapd_iface * iface)1842 static int start_ctrl_iface(struct hostapd_iface *iface)
1843 {
1844 size_t i;
1845
1846 if (!iface->interfaces || !iface->interfaces->ctrl_iface_init)
1847 return 0;
1848
1849 for (i = 0; i < iface->num_bss; i++) {
1850 struct hostapd_data *hapd = iface->bss[i];
1851 if (iface->interfaces->ctrl_iface_init(hapd)) {
1852 wpa_printf(MSG_ERROR,
1853 "Failed to setup control interface for %s",
1854 hapd->conf->iface);
1855 return -1;
1856 }
1857 }
1858
1859 return 0;
1860 }
1861
1862
1863 /* When NO_IR flag is set and AP is stopped, clean up BSS parameters without
1864 * deinitializing the driver and the control interfaces. A subsequent
1865 * REG_CHANGE event can bring the AP back up.
1866 */
hostapd_no_ir_cleanup(struct hostapd_data * bss)1867 static void hostapd_no_ir_cleanup(struct hostapd_data *bss)
1868 {
1869 hostapd_bss_deinit_no_free(bss);
1870 hostapd_bss_link_deinit(bss);
1871 hostapd_free_hapd_data(bss);
1872 hostapd_cleanup_iface_partial(bss->iface);
1873 }
1874
1875
hostapd_no_ir_channel_list_updated(struct hostapd_iface * iface,void * ctx)1876 static int hostapd_no_ir_channel_list_updated(struct hostapd_iface *iface,
1877 void *ctx)
1878 {
1879 bool all_no_ir, is_6ghz;
1880 int i, j;
1881 struct hostapd_hw_modes *mode = NULL;
1882
1883 if (hostapd_get_hw_features(iface))
1884 return 0;
1885
1886 all_no_ir = true;
1887 is_6ghz = false;
1888
1889 for (i = 0; i < iface->num_hw_features; i++) {
1890 mode = &iface->hw_features[i];
1891
1892 if (mode->mode == iface->conf->hw_mode) {
1893 if (iface->freq > 0 &&
1894 !hw_mode_get_channel(mode, iface->freq, NULL)) {
1895 mode = NULL;
1896 continue;
1897 }
1898
1899 for (j = 0; j < mode->num_channels; j++) {
1900 if (!(mode->channels[j].flag &
1901 HOSTAPD_CHAN_NO_IR))
1902 all_no_ir = false;
1903
1904 if (is_6ghz_freq(mode->channels[j].freq))
1905 is_6ghz = true;
1906 }
1907 break;
1908 }
1909 }
1910
1911 if (!mode || !is_6ghz)
1912 return 0;
1913 iface->current_mode = mode;
1914
1915 if (iface->state == HAPD_IFACE_ENABLED) {
1916 if (!all_no_ir) {
1917 struct hostapd_channel_data *chan;
1918
1919 chan = hw_get_channel_freq(iface->current_mode->mode,
1920 iface->freq, NULL,
1921 iface->hw_features,
1922 iface->num_hw_features);
1923
1924 if (!chan) {
1925 wpa_printf(MSG_ERROR,
1926 "NO_IR: Could not derive chan from freq");
1927 return 0;
1928 }
1929
1930 if (!(chan->flag & HOSTAPD_CHAN_NO_IR))
1931 return 0;
1932 wpa_printf(MSG_DEBUG,
1933 "NO_IR: The current channel has NO_IR flag now, stop AP.");
1934 } else {
1935 wpa_printf(MSG_DEBUG,
1936 "NO_IR: All chan in new chanlist are NO_IR, stop AP.");
1937 }
1938
1939 hostapd_set_state(iface, HAPD_IFACE_NO_IR);
1940 iface->is_no_ir = true;
1941 hostapd_drv_stop_ap(iface->bss[0]);
1942 hostapd_no_ir_cleanup(iface->bss[0]);
1943 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_NO_IR);
1944 } else if (iface->state == HAPD_IFACE_NO_IR) {
1945 if (all_no_ir) {
1946 wpa_printf(MSG_DEBUG,
1947 "NO_IR: AP in NO_IR and all chan in the new chanlist are NO_IR. Ignore");
1948 return 0;
1949 }
1950
1951 if (!iface->conf->acs) {
1952 struct hostapd_channel_data *chan;
1953
1954 chan = hw_get_channel_freq(iface->current_mode->mode,
1955 iface->freq, NULL,
1956 iface->hw_features,
1957 iface->num_hw_features);
1958 if (!chan) {
1959 wpa_printf(MSG_ERROR,
1960 "NO_IR: Could not derive chan from freq");
1961 return 0;
1962 }
1963
1964 /* If the last operating channel is NO_IR, trigger ACS.
1965 */
1966 if (chan->flag & HOSTAPD_CHAN_NO_IR) {
1967 iface->freq = 0;
1968 iface->conf->channel = 0;
1969 if (acs_init(iface) != HOSTAPD_CHAN_ACS)
1970 wpa_printf(MSG_ERROR,
1971 "NO_IR: Could not start ACS");
1972 return 0;
1973 }
1974 }
1975
1976 setup_interface2(iface);
1977 }
1978
1979 return 0;
1980 }
1981
1982
channel_list_update_timeout(void * eloop_ctx,void * timeout_ctx)1983 static void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx)
1984 {
1985 struct hostapd_iface *iface = eloop_ctx;
1986
1987 if (!iface->wait_channel_update) {
1988 wpa_printf(MSG_INFO, "Channel list update timeout, but interface was not waiting for it");
1989 return;
1990 }
1991
1992 /*
1993 * It is possible that the existing channel list is acceptable, so try
1994 * to proceed.
1995 */
1996 wpa_printf(MSG_DEBUG, "Channel list update timeout - try to continue anyway");
1997 setup_interface2(iface);
1998 }
1999
2000
hostapd_channel_list_updated(struct hostapd_iface * iface,int initiator)2001 void hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator)
2002 {
2003 if (initiator == REGDOM_SET_BY_DRIVER) {
2004 hostapd_for_each_interface(iface->interfaces,
2005 hostapd_no_ir_channel_list_updated,
2006 NULL);
2007 return;
2008 }
2009
2010 if (!iface->wait_channel_update || initiator != REGDOM_SET_BY_USER)
2011 return;
2012
2013 wpa_printf(MSG_DEBUG, "Channel list updated - continue setup");
2014 eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
2015 setup_interface2(iface);
2016 }
2017
2018
setup_interface(struct hostapd_iface * iface)2019 static int setup_interface(struct hostapd_iface *iface)
2020 {
2021 struct hostapd_data *hapd = iface->bss[0];
2022 size_t i;
2023
2024 /*
2025 * It is possible that setup_interface() is called after the interface
2026 * was disabled etc., in which case driver_ap_teardown is possibly set
2027 * to 1. Clear it here so any other key/station deletion, which is not
2028 * part of a teardown flow, would also call the relevant driver
2029 * callbacks.
2030 */
2031 iface->driver_ap_teardown = 0;
2032
2033 if (!iface->phy[0]) {
2034 const char *phy = hostapd_drv_get_radio_name(hapd);
2035 if (phy) {
2036 wpa_printf(MSG_EXCESSIVE, "phy: %s", phy);
2037 os_strlcpy(iface->phy, phy, sizeof(iface->phy));
2038 }
2039 }
2040
2041 /*
2042 * Make sure that all BSSes get configured with a pointer to the same
2043 * driver interface.
2044 */
2045 for (i = 1; i < iface->num_bss; i++) {
2046 iface->bss[i]->driver = hapd->driver;
2047 iface->bss[i]->drv_priv = hapd->drv_priv;
2048 }
2049
2050 if (hostapd_validate_bssid_configuration(iface))
2051 return -1;
2052
2053 /*
2054 * Initialize control interfaces early to allow external monitoring of
2055 * channel setup operations that may take considerable amount of time
2056 * especially for DFS cases.
2057 */
2058 if (start_ctrl_iface(iface))
2059 return -1;
2060
2061 if (hapd->iconf->country[0] && hapd->iconf->country[1]) {
2062 char country[4], previous_country[4];
2063
2064 hostapd_set_state(iface, HAPD_IFACE_COUNTRY_UPDATE);
2065 if (hostapd_get_country(hapd, previous_country) < 0)
2066 previous_country[0] = '\0';
2067
2068 os_memcpy(country, hapd->iconf->country, 3);
2069 country[3] = '\0';
2070 if (hostapd_set_country(hapd, country) < 0) {
2071 wpa_printf(MSG_ERROR, "Failed to set country code");
2072 return -1;
2073 }
2074
2075 wpa_printf(MSG_DEBUG, "Previous country code **, new country code **");
2076
2077 if (os_strncmp(previous_country, country, 2) != 0) {
2078 wpa_printf(MSG_DEBUG, "Continue interface setup after channel list update");
2079 iface->wait_channel_update = 1;
2080 eloop_register_timeout(5, 0,
2081 channel_list_update_timeout,
2082 iface, NULL);
2083 return 0;
2084 }
2085 }
2086
2087 return setup_interface2(iface);
2088 }
2089
2090
configured_fixed_chan_to_freq(struct hostapd_iface * iface)2091 static int configured_fixed_chan_to_freq(struct hostapd_iface *iface)
2092 {
2093 int freq, i, j;
2094
2095 if (!iface->conf->channel)
2096 return 0;
2097 if (iface->conf->op_class) {
2098 freq = ieee80211_chan_to_freq(NULL, iface->conf->op_class,
2099 iface->conf->channel);
2100 if (freq < 0) {
2101 wpa_printf(MSG_INFO,
2102 "Could not convert op_class %u channel %u to operating frequency",
2103 iface->conf->op_class, iface->conf->channel);
2104 return -1;
2105 }
2106 iface->freq = freq;
2107 return 0;
2108 }
2109
2110 /* Old configurations using only 2.4/5/60 GHz bands may not specify the
2111 * op_class parameter. Select a matching channel from the configured
2112 * mode using the channel parameter for these cases.
2113 */
2114 for (j = 0; j < iface->num_hw_features; j++) {
2115 struct hostapd_hw_modes *mode = &iface->hw_features[j];
2116
2117 if (iface->conf->hw_mode != HOSTAPD_MODE_IEEE80211ANY &&
2118 iface->conf->hw_mode != mode->mode)
2119 continue;
2120 for (i = 0; i < mode->num_channels; i++) {
2121 struct hostapd_channel_data *chan = &mode->channels[i];
2122
2123 if (chan->chan == iface->conf->channel &&
2124 !is_6ghz_freq(chan->freq)) {
2125 iface->freq = chan->freq;
2126 return 0;
2127 }
2128 }
2129 }
2130
2131 wpa_printf(MSG_INFO, "Could not determine operating frequency");
2132 return -1;
2133 }
2134
2135
hostapd_set_6ghz_sec_chan(struct hostapd_iface * iface)2136 static void hostapd_set_6ghz_sec_chan(struct hostapd_iface *iface)
2137 {
2138 int bw;
2139
2140 if (!is_6ghz_op_class(iface->conf->op_class))
2141 return;
2142
2143 bw = op_class_to_bandwidth(iface->conf->op_class);
2144 /* Assign the secondary channel if absent in config for
2145 * bandwidths > 20 MHz */
2146 if (bw >= 40 && !iface->conf->secondary_channel) {
2147 if (((iface->conf->channel - 1) / 4) % 2)
2148 iface->conf->secondary_channel = -1;
2149 else
2150 iface->conf->secondary_channel = 1;
2151 }
2152 }
2153
2154
setup_interface2(struct hostapd_iface * iface)2155 static int setup_interface2(struct hostapd_iface *iface)
2156 {
2157 iface->wait_channel_update = 0;
2158 iface->is_no_ir = false;
2159
2160 if (hostapd_get_hw_features(iface)) {
2161 /* Not all drivers support this yet, so continue without hw
2162 * feature data. */
2163 } else {
2164 int ret;
2165
2166 if (iface->conf->acs && !iface->is_ch_switch_dfs) {
2167 iface->freq = 0;
2168 iface->conf->channel = 0;
2169 }
2170 iface->is_ch_switch_dfs = false;
2171
2172 ret = configured_fixed_chan_to_freq(iface);
2173 if (ret < 0)
2174 goto fail;
2175
2176 if (iface->conf->op_class) {
2177 enum oper_chan_width ch_width;
2178
2179 ch_width = op_class_to_ch_width(iface->conf->op_class);
2180 hostapd_set_oper_chwidth(iface->conf, ch_width);
2181 hostapd_set_6ghz_sec_chan(iface);
2182 }
2183
2184 ret = hostapd_select_hw_mode(iface);
2185 if (ret < 0) {
2186 wpa_printf(MSG_ERROR, "Could not select hw_mode and "
2187 "channel. (%d)", ret);
2188 goto fail;
2189 }
2190 if (ret == 1) {
2191 wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback (ACS)");
2192 return 0;
2193 }
2194 ret = hostapd_check_edmg_capab(iface);
2195 if (ret < 0)
2196 goto fail;
2197 ret = hostapd_check_he_6ghz_capab(iface);
2198 if (ret < 0)
2199 goto fail;
2200 ret = hostapd_check_ht_capab(iface);
2201 if (ret < 0)
2202 goto fail;
2203 if (ret == 1) {
2204 wpa_printf(MSG_DEBUG, "Interface initialization will "
2205 "be completed in a callback");
2206 return 0;
2207 }
2208
2209 if (iface->conf->ieee80211h)
2210 wpa_printf(MSG_DEBUG, "DFS support is enabled");
2211 }
2212 return hostapd_setup_interface_complete(iface, 0);
2213
2214 fail:
2215 if (iface->is_no_ir) {
2216 /* If AP is in NO_IR state, it can be reenabled by the driver
2217 * regulatory update and EVENT_CHANNEL_LIST_CHANGED. */
2218 hostapd_set_state(iface, HAPD_IFACE_NO_IR);
2219 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_NO_IR);
2220 return 0;
2221 }
2222
2223 hostapd_set_state(iface, HAPD_IFACE_DISABLED);
2224 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
2225 #ifdef CONFIG_LIBWPA_VENDOR
2226 struct HostapdApCbParm hostapdApCbParm = {};
2227 size_t contentLen = strlen(AP_EVENT_DISABLED);
2228 os_memcpy(hostapdApCbParm.content, AP_EVENT_DISABLED, contentLen);
2229 hostapdApCbParm.content[contentLen] = '\0';
2230 hostapdApCbParm.id = 0;
2231 wpa_printf(MSG_INFO, "%s HOSTAPD_EVENT_AP_STATE %s%d", __func__, hostapdApCbParm.content, hostapdApCbParm.id);
2232 HostapdEventReport(iface->bss[0]->conf->iface, HOSTAPD_EVENT_AP_STATE, (void *) &hostapdApCbParm);
2233 #endif
2234 if (iface->interfaces && iface->interfaces->terminate_on_error)
2235 eloop_terminate();
2236 return -1;
2237 }
2238
2239
2240 #ifdef CONFIG_FST
2241
fst_hostapd_get_bssid_cb(void * ctx)2242 static const u8 * fst_hostapd_get_bssid_cb(void *ctx)
2243 {
2244 struct hostapd_data *hapd = ctx;
2245
2246 return hapd->own_addr;
2247 }
2248
2249
fst_hostapd_get_channel_info_cb(void * ctx,enum hostapd_hw_mode * hw_mode,u8 * channel)2250 static void fst_hostapd_get_channel_info_cb(void *ctx,
2251 enum hostapd_hw_mode *hw_mode,
2252 u8 *channel)
2253 {
2254 struct hostapd_data *hapd = ctx;
2255
2256 *hw_mode = ieee80211_freq_to_chan(hapd->iface->freq, channel);
2257 }
2258
2259
fst_hostapd_get_hw_modes_cb(void * ctx,struct hostapd_hw_modes ** modes)2260 static int fst_hostapd_get_hw_modes_cb(void *ctx,
2261 struct hostapd_hw_modes **modes)
2262 {
2263 struct hostapd_data *hapd = ctx;
2264
2265 *modes = hapd->iface->hw_features;
2266 return hapd->iface->num_hw_features;
2267 }
2268
2269
fst_hostapd_set_ies_cb(void * ctx,const struct wpabuf * fst_ies)2270 static void fst_hostapd_set_ies_cb(void *ctx, const struct wpabuf *fst_ies)
2271 {
2272 struct hostapd_data *hapd = ctx;
2273
2274 if (hapd->iface->fst_ies != fst_ies) {
2275 hapd->iface->fst_ies = fst_ies;
2276 if (ieee802_11_set_beacon(hapd))
2277 wpa_printf(MSG_WARNING, "FST: Cannot set beacon");
2278 }
2279 }
2280
2281
fst_hostapd_send_action_cb(void * ctx,const u8 * da,struct wpabuf * buf)2282 static int fst_hostapd_send_action_cb(void *ctx, const u8 *da,
2283 struct wpabuf *buf)
2284 {
2285 struct hostapd_data *hapd = ctx;
2286
2287 return hostapd_drv_send_action(hapd, hapd->iface->freq, 0, da,
2288 wpabuf_head(buf), wpabuf_len(buf));
2289 }
2290
2291
fst_hostapd_get_mb_ie_cb(void * ctx,const u8 * addr)2292 static const struct wpabuf * fst_hostapd_get_mb_ie_cb(void *ctx, const u8 *addr)
2293 {
2294 struct hostapd_data *hapd = ctx;
2295 struct sta_info *sta = ap_get_sta(hapd, addr);
2296
2297 return sta ? sta->mb_ies : NULL;
2298 }
2299
2300
fst_hostapd_update_mb_ie_cb(void * ctx,const u8 * addr,const u8 * buf,size_t size)2301 static void fst_hostapd_update_mb_ie_cb(void *ctx, const u8 *addr,
2302 const u8 *buf, size_t size)
2303 {
2304 struct hostapd_data *hapd = ctx;
2305 struct sta_info *sta = ap_get_sta(hapd, addr);
2306
2307 if (sta) {
2308 struct mb_ies_info info;
2309
2310 if (!mb_ies_info_by_ies(&info, buf, size)) {
2311 wpabuf_free(sta->mb_ies);
2312 sta->mb_ies = mb_ies_by_info(&info);
2313 }
2314 }
2315 }
2316
2317
fst_hostapd_get_sta(struct fst_get_peer_ctx ** get_ctx,bool mb_only)2318 static const u8 * fst_hostapd_get_sta(struct fst_get_peer_ctx **get_ctx,
2319 bool mb_only)
2320 {
2321 struct sta_info *s = (struct sta_info *) *get_ctx;
2322
2323 if (mb_only) {
2324 for (; s && !s->mb_ies; s = s->next)
2325 ;
2326 }
2327
2328 if (s) {
2329 *get_ctx = (struct fst_get_peer_ctx *) s->next;
2330
2331 return s->addr;
2332 }
2333
2334 *get_ctx = NULL;
2335 return NULL;
2336 }
2337
2338
fst_hostapd_get_peer_first(void * ctx,struct fst_get_peer_ctx ** get_ctx,bool mb_only)2339 static const u8 * fst_hostapd_get_peer_first(void *ctx,
2340 struct fst_get_peer_ctx **get_ctx,
2341 bool mb_only)
2342 {
2343 struct hostapd_data *hapd = ctx;
2344
2345 *get_ctx = (struct fst_get_peer_ctx *) hapd->sta_list;
2346
2347 return fst_hostapd_get_sta(get_ctx, mb_only);
2348 }
2349
2350
fst_hostapd_get_peer_next(void * ctx,struct fst_get_peer_ctx ** get_ctx,bool mb_only)2351 static const u8 * fst_hostapd_get_peer_next(void *ctx,
2352 struct fst_get_peer_ctx **get_ctx,
2353 bool mb_only)
2354 {
2355 return fst_hostapd_get_sta(get_ctx, mb_only);
2356 }
2357
2358
fst_hostapd_fill_iface_obj(struct hostapd_data * hapd,struct fst_wpa_obj * iface_obj)2359 void fst_hostapd_fill_iface_obj(struct hostapd_data *hapd,
2360 struct fst_wpa_obj *iface_obj)
2361 {
2362 os_memset(iface_obj, 0, sizeof(*iface_obj));
2363 iface_obj->ctx = hapd;
2364 iface_obj->get_bssid = fst_hostapd_get_bssid_cb;
2365 iface_obj->get_channel_info = fst_hostapd_get_channel_info_cb;
2366 iface_obj->get_hw_modes = fst_hostapd_get_hw_modes_cb;
2367 iface_obj->set_ies = fst_hostapd_set_ies_cb;
2368 iface_obj->send_action = fst_hostapd_send_action_cb;
2369 iface_obj->get_mb_ie = fst_hostapd_get_mb_ie_cb;
2370 iface_obj->update_mb_ie = fst_hostapd_update_mb_ie_cb;
2371 iface_obj->get_peer_first = fst_hostapd_get_peer_first;
2372 iface_obj->get_peer_next = fst_hostapd_get_peer_next;
2373 }
2374
2375 #endif /* CONFIG_FST */
2376
2377 #ifdef CONFIG_OWE
2378
hostapd_owe_iface_iter(struct hostapd_iface * iface,void * ctx)2379 static int hostapd_owe_iface_iter(struct hostapd_iface *iface, void *ctx)
2380 {
2381 struct hostapd_data *hapd = ctx;
2382 size_t i;
2383
2384 for (i = 0; i < iface->num_bss; i++) {
2385 struct hostapd_data *bss = iface->bss[i];
2386
2387 if (os_strcmp(hapd->conf->owe_transition_ifname,
2388 bss->conf->iface) != 0)
2389 continue;
2390
2391 wpa_printf(MSG_DEBUG,
2392 "OWE: ifname=%s found transition mode ifname=%s BSSID "
2393 MACSTR_SEC " SSID %s",
2394 hapd->conf->iface, bss->conf->iface,
2395 MAC2STR_SEC(bss->own_addr),
2396 anonymize_ssid(wpa_ssid_txt(bss->conf->ssid.ssid,
2397 bss->conf->ssid.ssid_len)));
2398 if (!bss->conf->ssid.ssid_set || !bss->conf->ssid.ssid_len ||
2399 is_zero_ether_addr(bss->own_addr))
2400 continue;
2401
2402 os_memcpy(hapd->conf->owe_transition_bssid, bss->own_addr,
2403 ETH_ALEN);
2404 os_memcpy(hapd->conf->owe_transition_ssid,
2405 bss->conf->ssid.ssid, bss->conf->ssid.ssid_len);
2406 hapd->conf->owe_transition_ssid_len = bss->conf->ssid.ssid_len;
2407 wpa_printf(MSG_DEBUG,
2408 "OWE: Copied transition mode information");
2409 return 1;
2410 }
2411
2412 return 0;
2413 }
2414
2415
hostapd_owe_trans_get_info(struct hostapd_data * hapd)2416 int hostapd_owe_trans_get_info(struct hostapd_data *hapd)
2417 {
2418 if (hapd->conf->owe_transition_ssid_len > 0 &&
2419 !is_zero_ether_addr(hapd->conf->owe_transition_bssid))
2420 return 0;
2421
2422 /* Find transition mode SSID/BSSID information from a BSS operated by
2423 * this hostapd instance. */
2424 if (!hapd->iface->interfaces ||
2425 !hapd->iface->interfaces->for_each_interface)
2426 return hostapd_owe_iface_iter(hapd->iface, hapd);
2427 else
2428 return hapd->iface->interfaces->for_each_interface(
2429 hapd->iface->interfaces, hostapd_owe_iface_iter, hapd);
2430 }
2431
2432
hostapd_owe_iface_iter2(struct hostapd_iface * iface,void * ctx)2433 static int hostapd_owe_iface_iter2(struct hostapd_iface *iface, void *ctx)
2434 {
2435 size_t i;
2436
2437 for (i = 0; i < iface->num_bss; i++) {
2438 struct hostapd_data *bss = iface->bss[i];
2439 int res;
2440
2441 if (!bss->conf->owe_transition_ifname[0])
2442 continue;
2443 if (bss->iface->state != HAPD_IFACE_ENABLED) {
2444 wpa_printf(MSG_DEBUG,
2445 "OWE: Interface %s state %s - defer beacon update",
2446 bss->conf->iface,
2447 hostapd_state_text(bss->iface->state));
2448 continue;
2449 }
2450 res = hostapd_owe_trans_get_info(bss);
2451 if (res == 0)
2452 continue;
2453 wpa_printf(MSG_DEBUG,
2454 "OWE: Matching transition mode interface enabled - update beacon data for %s",
2455 bss->conf->iface);
2456 ieee802_11_set_beacon(bss);
2457 }
2458
2459 return 0;
2460 }
2461
2462 #endif /* CONFIG_OWE */
2463
2464
hostapd_owe_update_trans(struct hostapd_iface * iface)2465 static void hostapd_owe_update_trans(struct hostapd_iface *iface)
2466 {
2467 #ifdef CONFIG_OWE
2468 /* Check whether the enabled BSS can complete OWE transition mode
2469 * configuration for any pending interface. */
2470 if (!iface->interfaces ||
2471 !iface->interfaces->for_each_interface)
2472 hostapd_owe_iface_iter2(iface, NULL);
2473 else
2474 iface->interfaces->for_each_interface(
2475 iface->interfaces, hostapd_owe_iface_iter2, NULL);
2476 #endif /* CONFIG_OWE */
2477 }
2478
2479
hostapd_interface_setup_failure_handler(void * eloop_ctx,void * timeout_ctx)2480 static void hostapd_interface_setup_failure_handler(void *eloop_ctx,
2481 void *timeout_ctx)
2482 {
2483 struct hostapd_iface *iface = eloop_ctx;
2484 struct hostapd_data *hapd;
2485
2486 if (iface->num_bss < 1 || !iface->bss || !iface->bss[0])
2487 return;
2488 hapd = iface->bss[0];
2489 if (hapd->setup_complete_cb)
2490 hapd->setup_complete_cb(hapd->setup_complete_cb_ctx);
2491 }
2492
2493
hostapd_setup_interface_complete_sync(struct hostapd_iface * iface,int err)2494 static int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface,
2495 int err)
2496 {
2497 struct hostapd_data *hapd = iface->bss[0];
2498 size_t j;
2499 u8 *prev_addr;
2500 int delay_apply_cfg = 0;
2501 int res_dfs_offload = 0;
2502 #ifdef CONFIG_LIBWPA_VENDOR
2503 size_t contentLen;
2504 struct HostapdApCbParm hostapdApCbParm = {};
2505 hostapdApCbParm.id = 0;
2506 #endif
2507
2508 if (err)
2509 goto fail;
2510
2511 wpa_printf(MSG_DEBUG, "Completing interface initialization");
2512 if (iface->freq) {
2513 #ifdef NEED_AP_MLME
2514 int res;
2515 #endif /* NEED_AP_MLME */
2516
2517 wpa_printf(MSG_DEBUG, "Mode: %s Channel: %d "
2518 "Frequency: %d MHz",
2519 hostapd_hw_mode_txt(iface->conf->hw_mode),
2520 iface->conf->channel, iface->freq);
2521
2522 #ifdef NEED_AP_MLME
2523 /* Handle DFS only if it is not offloaded to the driver */
2524 if (!(iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)) {
2525 /* Check DFS */
2526 res = hostapd_handle_dfs(iface);
2527 if (res <= 0) {
2528 if (res < 0)
2529 goto fail;
2530 return res;
2531 }
2532 } else {
2533 /* If DFS is offloaded to the driver */
2534 res_dfs_offload = hostapd_handle_dfs_offload(iface);
2535 if (res_dfs_offload <= 0) {
2536 if (res_dfs_offload < 0)
2537 goto fail;
2538 } else {
2539 wpa_printf(MSG_EXCESSIVE,
2540 "Proceed with AP/channel setup");
2541 /*
2542 * If this is a DFS channel, move to completing
2543 * AP setup.
2544 */
2545 if (res_dfs_offload == 1)
2546 goto dfs_offload;
2547 /* Otherwise fall through. */
2548 }
2549 }
2550 #endif /* NEED_AP_MLME */
2551
2552 #ifdef CONFIG_MESH
2553 if (iface->mconf != NULL) {
2554 wpa_printf(MSG_DEBUG,
2555 "%s: Mesh configuration will be applied while joining the mesh network",
2556 iface->bss[0]->conf->iface);
2557 delay_apply_cfg = 1;
2558 }
2559 #endif /* CONFIG_MESH */
2560
2561 if (!delay_apply_cfg &&
2562 hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq,
2563 hapd->iconf->channel,
2564 hapd->iconf->enable_edmg,
2565 hapd->iconf->edmg_channel,
2566 hapd->iconf->ieee80211n,
2567 hapd->iconf->ieee80211ac,
2568 hapd->iconf->ieee80211ax,
2569 hapd->iconf->ieee80211be,
2570 hapd->iconf->secondary_channel,
2571 hostapd_get_oper_chwidth(hapd->iconf),
2572 hostapd_get_oper_centr_freq_seg0_idx(
2573 hapd->iconf),
2574 hostapd_get_oper_centr_freq_seg1_idx(
2575 hapd->iconf))) {
2576 wpa_printf(MSG_ERROR, "Could not set channel for "
2577 "kernel driver");
2578 goto fail;
2579 }
2580 }
2581
2582 if (iface->current_mode) {
2583 if (hostapd_prepare_rates(iface, iface->current_mode)) {
2584 wpa_printf(MSG_ERROR, "Failed to prepare rates "
2585 "table.");
2586 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
2587 HOSTAPD_LEVEL_WARNING,
2588 "Failed to prepare rates table.");
2589 goto fail;
2590 }
2591 }
2592
2593 if (hapd->iconf->rts_threshold >= -1 &&
2594 hostapd_set_rts(hapd, hapd->iconf->rts_threshold) &&
2595 hapd->iconf->rts_threshold >= -1) {
2596 wpa_printf(MSG_ERROR, "Could not set RTS threshold for "
2597 "kernel driver");
2598 goto fail;
2599 }
2600
2601 if (hapd->iconf->fragm_threshold >= -1 &&
2602 hostapd_set_frag(hapd, hapd->iconf->fragm_threshold) &&
2603 hapd->iconf->fragm_threshold != -1) {
2604 wpa_printf(MSG_ERROR, "Could not set fragmentation threshold "
2605 "for kernel driver");
2606 goto fail;
2607 }
2608
2609 prev_addr = hapd->own_addr;
2610
2611 for (j = 0; j < iface->num_bss; j++) {
2612 hapd = iface->bss[j];
2613 if (j)
2614 os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN);
2615 if (hostapd_setup_bss(hapd, j == 0, !iface->conf->mbssid)) {
2616 for (;;) {
2617 hapd = iface->bss[j];
2618 hostapd_bss_deinit_no_free(hapd);
2619 hostapd_free_hapd_data(hapd);
2620 if (j == 0)
2621 break;
2622 j--;
2623 }
2624 goto fail;
2625 }
2626 if (is_zero_ether_addr(hapd->conf->bssid))
2627 prev_addr = hapd->own_addr;
2628 }
2629
2630 if (hapd->iconf->mbssid) {
2631 for (j = 0; hapd->iconf->mbssid && j < iface->num_bss; j++) {
2632 hapd = iface->bss[j];
2633 if (hostapd_start_beacon(hapd, true)) {
2634 for (;;) {
2635 hapd = iface->bss[j];
2636 hostapd_bss_deinit_no_free(hapd);
2637 hostapd_free_hapd_data(hapd);
2638 if (j == 0)
2639 break;
2640 j--;
2641 }
2642 goto fail;
2643 }
2644 }
2645 }
2646
2647 hapd = iface->bss[0];
2648
2649 hostapd_tx_queue_params(iface);
2650
2651 ap_list_init(iface);
2652
2653 hostapd_set_acl(hapd);
2654
2655 if (hostapd_driver_commit(hapd) < 0) {
2656 wpa_printf(MSG_ERROR, "%s: Failed to commit driver "
2657 "configuration", __func__);
2658 goto fail;
2659 }
2660
2661 /*
2662 * WPS UPnP module can be initialized only when the "upnp_iface" is up.
2663 * If "interface" and "upnp_iface" are the same (e.g., non-bridge
2664 * mode), the interface is up only after driver_commit, so initialize
2665 * WPS after driver_commit.
2666 */
2667 for (j = 0; j < iface->num_bss; j++) {
2668 if (hostapd_init_wps_complete(iface->bss[j]))
2669 goto fail;
2670 }
2671
2672 if ((iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
2673 !res_dfs_offload) {
2674 /*
2675 * If freq is DFS, and DFS is offloaded to the driver, then wait
2676 * for CAC to complete.
2677 */
2678 wpa_printf(MSG_DEBUG, "%s: Wait for CAC to complete", __func__);
2679 return res_dfs_offload;
2680 }
2681
2682 #ifdef NEED_AP_MLME
2683 dfs_offload:
2684 #endif /* NEED_AP_MLME */
2685
2686 #ifdef CONFIG_FST
2687 if (hapd->iconf->fst_cfg.group_id[0]) {
2688 struct fst_wpa_obj iface_obj;
2689
2690 fst_hostapd_fill_iface_obj(hapd, &iface_obj);
2691 iface->fst = fst_attach(hapd->conf->iface, hapd->own_addr,
2692 &iface_obj, &hapd->iconf->fst_cfg);
2693 if (!iface->fst) {
2694 wpa_printf(MSG_ERROR, "Could not attach to FST %s",
2695 hapd->iconf->fst_cfg.group_id);
2696 goto fail;
2697 }
2698 }
2699 #endif /* CONFIG_FST */
2700
2701 hostapd_set_state(iface, HAPD_IFACE_ENABLED);
2702 hostapd_owe_update_trans(iface);
2703 airtime_policy_update_init(iface);
2704 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_ENABLED);
2705 #ifdef CONFIG_LIBWPA_VENDOR
2706 contentLen = strlen(AP_EVENT_ENABLED);
2707 os_memcpy(hostapdApCbParm.content, AP_EVENT_ENABLED, contentLen);
2708 hostapdApCbParm.content[contentLen] = '\0';
2709 wpa_printf(MSG_INFO, "%s HOSTAPD_EVENT_AP_STATE %s%d", __func__, hostapdApCbParm.content, hostapdApCbParm.id);
2710 HostapdEventReport(iface->bss[0]->conf->iface, HOSTAPD_EVENT_AP_STATE, (void *) &hostapdApCbParm);
2711 #endif
2712 if (hapd->setup_complete_cb)
2713 hapd->setup_complete_cb(hapd->setup_complete_cb_ctx);
2714
2715 #ifdef CONFIG_MESH
2716 if (delay_apply_cfg && !iface->mconf) {
2717 wpa_printf(MSG_ERROR, "Error while completing mesh init");
2718 goto fail;
2719 }
2720 #endif /* CONFIG_MESH */
2721
2722 wpa_printf(MSG_INFO, "%s: Setup of interface done.",
2723 iface->bss[0]->conf->iface);
2724 if (iface->interfaces && iface->interfaces->terminate_on_error > 0)
2725 iface->interfaces->terminate_on_error--;
2726
2727 for (j = 0; j < iface->num_bss; j++)
2728 hostapd_neighbor_set_own_report(iface->bss[j]);
2729
2730 if (iface->interfaces && iface->interfaces->count > 1)
2731 ieee802_11_set_beacons(iface);
2732
2733 return 0;
2734
2735 fail:
2736 wpa_printf(MSG_ERROR, "Interface initialization failed");
2737
2738 if (iface->is_no_ir) {
2739 hostapd_set_state(iface, HAPD_IFACE_NO_IR);
2740 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_NO_IR);
2741 return 0;
2742 }
2743
2744 hostapd_set_state(iface, HAPD_IFACE_DISABLED);
2745 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
2746 #ifdef CONFIG_LIBWPA_VENDOR
2747 contentLen = strlen(AP_EVENT_DISABLED);
2748 os_memset(&hostapdApCbParm, 0, sizeof(hostapdApCbParm));
2749 os_memcpy(hostapdApCbParm.content, AP_EVENT_DISABLED, contentLen);
2750 hostapdApCbParm.content[contentLen] = '\0';
2751 wpa_printf(MSG_INFO, "%s HOSTAPD_EVENT_AP_STATE %s%d", __func__, hostapdApCbParm.content, hostapdApCbParm.id);
2752 HostapdEventReport(hapd->conf->iface, HOSTAPD_EVENT_AP_STATE, (void *) &hostapdApCbParm);
2753 #endif
2754 #ifdef CONFIG_FST
2755 if (iface->fst) {
2756 fst_detach(iface->fst);
2757 iface->fst = NULL;
2758 }
2759 #endif /* CONFIG_FST */
2760
2761 if (iface->interfaces && iface->interfaces->terminate_on_error) {
2762 eloop_terminate();
2763 } else if (hapd->setup_complete_cb) {
2764 /*
2765 * Calling hapd->setup_complete_cb directly may cause iface
2766 * deinitialization which may be accessed later by the caller.
2767 */
2768 eloop_register_timeout(0, 0,
2769 hostapd_interface_setup_failure_handler,
2770 iface, NULL);
2771 }
2772
2773 return -1;
2774 }
2775
2776
2777 /**
2778 * hostapd_setup_interface_complete - Complete interface setup
2779 *
2780 * This function is called when previous steps in the interface setup has been
2781 * completed. This can also start operations, e.g., DFS, that will require
2782 * additional processing before interface is ready to be enabled. Such
2783 * operations will call this function from eloop callbacks when finished.
2784 */
hostapd_setup_interface_complete(struct hostapd_iface * iface,int err)2785 int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)
2786 {
2787 struct hapd_interfaces *interfaces = iface->interfaces;
2788 struct hostapd_data *hapd = iface->bss[0];
2789 unsigned int i;
2790 int not_ready_in_sync_ifaces = 0;
2791
2792 if (!iface->need_to_start_in_sync)
2793 return hostapd_setup_interface_complete_sync(iface, err);
2794
2795 if (err) {
2796 wpa_printf(MSG_ERROR, "Interface initialization failed");
2797 iface->need_to_start_in_sync = 0;
2798
2799 if (iface->is_no_ir) {
2800 hostapd_set_state(iface, HAPD_IFACE_NO_IR);
2801 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_NO_IR);
2802 return 0;
2803 }
2804
2805 hostapd_set_state(iface, HAPD_IFACE_DISABLED);
2806 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
2807 #ifdef CONFIG_LIBWPA_VENDOR
2808 struct HostapdApCbParm hostapdApCbParm = {};
2809 size_t contentLen = strlen(AP_EVENT_DISABLED);
2810 os_memcpy(hostapdApCbParm.content, AP_EVENT_DISABLED, contentLen);
2811 hostapdApCbParm.content[contentLen] = '\0';
2812 hostapdApCbParm.id = 0;
2813 wpa_printf(MSG_INFO, "%s HOSTAPD_EVENT_AP_STATE %s%d", __func__, hostapdApCbParm.content, hostapdApCbParm.id);
2814 HostapdEventReport(hapd->conf->iface, HOSTAPD_EVENT_AP_STATE, (void *) &hostapdApCbParm);
2815 #endif
2816 if (interfaces && interfaces->terminate_on_error)
2817 eloop_terminate();
2818 return -1;
2819 }
2820
2821 if (iface->ready_to_start_in_sync) {
2822 /* Already in ready and waiting. should never happpen */
2823 return 0;
2824 }
2825
2826 for (i = 0; i < interfaces->count; i++) {
2827 if (interfaces->iface[i]->need_to_start_in_sync &&
2828 !interfaces->iface[i]->ready_to_start_in_sync)
2829 not_ready_in_sync_ifaces++;
2830 }
2831
2832 /*
2833 * Check if this is the last interface, if yes then start all the other
2834 * waiting interfaces. If not, add this interface to the waiting list.
2835 */
2836 if (not_ready_in_sync_ifaces > 1 && iface->state == HAPD_IFACE_DFS) {
2837 /*
2838 * If this interface went through CAC, do not synchronize, just
2839 * start immediately.
2840 */
2841 iface->need_to_start_in_sync = 0;
2842 wpa_printf(MSG_INFO,
2843 "%s: Finished CAC - bypass sync and start interface",
2844 iface->bss[0]->conf->iface);
2845 return hostapd_setup_interface_complete_sync(iface, err);
2846 }
2847
2848 if (not_ready_in_sync_ifaces > 1) {
2849 /* need to wait as there are other interfaces still coming up */
2850 iface->ready_to_start_in_sync = 1;
2851 wpa_printf(MSG_INFO,
2852 "%s: Interface waiting to sync with other interfaces",
2853 iface->bss[0]->conf->iface);
2854 return 0;
2855 }
2856
2857 wpa_printf(MSG_INFO,
2858 "%s: Last interface to sync - starting all interfaces",
2859 iface->bss[0]->conf->iface);
2860 iface->need_to_start_in_sync = 0;
2861 hostapd_setup_interface_complete_sync(iface, err);
2862 for (i = 0; i < interfaces->count; i++) {
2863 if (interfaces->iface[i]->need_to_start_in_sync &&
2864 interfaces->iface[i]->ready_to_start_in_sync) {
2865 hostapd_setup_interface_complete_sync(
2866 interfaces->iface[i], 0);
2867 /* Only once the interfaces are sync started */
2868 interfaces->iface[i]->need_to_start_in_sync = 0;
2869 }
2870 }
2871
2872 return 0;
2873 }
2874
2875
2876 /**
2877 * hostapd_setup_interface - Setup of an interface
2878 * @iface: Pointer to interface data.
2879 * Returns: 0 on success, -1 on failure
2880 *
2881 * Initializes the driver interface, validates the configuration,
2882 * and sets driver parameters based on the configuration.
2883 * Flushes old stations, sets the channel, encryption,
2884 * beacons, and WDS links based on the configuration.
2885 *
2886 * If interface setup requires more time, e.g., to perform HT co-ex scans, ACS,
2887 * or DFS operations, this function returns 0 before such operations have been
2888 * completed. The pending operations are registered into eloop and will be
2889 * completed from eloop callbacks. Those callbacks end up calling
2890 * hostapd_setup_interface_complete() once setup has been completed.
2891 */
hostapd_setup_interface(struct hostapd_iface * iface)2892 int hostapd_setup_interface(struct hostapd_iface *iface)
2893 {
2894 int ret;
2895
2896 if (!iface->conf) {
2897 wpa_printf(MSG_ERROR, "iface->conf already exists!.");
2898 return -1;
2899 }
2900 ret = setup_interface(iface);
2901 if (ret) {
2902 wpa_printf(MSG_ERROR, "%s: Unable to setup interface.",
2903 iface->conf->bss[0]->iface);
2904 return -1;
2905 }
2906
2907 return 0;
2908 }
2909
2910
2911 /**
2912 * hostapd_alloc_bss_data - Allocate and initialize per-BSS data
2913 * @hapd_iface: Pointer to interface data
2914 * @conf: Pointer to per-interface configuration
2915 * @bss: Pointer to per-BSS configuration for this BSS
2916 * Returns: Pointer to allocated BSS data
2917 *
2918 * This function is used to allocate per-BSS data structure. This data will be
2919 * freed after hostapd_cleanup() is called for it during interface
2920 * deinitialization.
2921 */
2922 struct hostapd_data *
hostapd_alloc_bss_data(struct hostapd_iface * hapd_iface,struct hostapd_config * conf,struct hostapd_bss_config * bss)2923 hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,
2924 struct hostapd_config *conf,
2925 struct hostapd_bss_config *bss)
2926 {
2927 struct hostapd_data *hapd;
2928
2929 hapd = os_zalloc(sizeof(*hapd));
2930 if (hapd == NULL)
2931 return NULL;
2932
2933 hapd->new_assoc_sta_cb = hostapd_new_assoc_sta;
2934 hapd->iconf = conf;
2935 hapd->conf = bss;
2936 hapd->iface = hapd_iface;
2937 if (conf)
2938 hapd->driver = conf->driver;
2939 hapd->ctrl_sock = -1;
2940 dl_list_init(&hapd->ctrl_dst);
2941 dl_list_init(&hapd->nr_db);
2942 hapd->dhcp_sock = -1;
2943 #ifdef CONFIG_IEEE80211R_AP
2944 dl_list_init(&hapd->l2_queue);
2945 dl_list_init(&hapd->l2_oui_queue);
2946 #endif /* CONFIG_IEEE80211R_AP */
2947 #ifdef CONFIG_SAE
2948 dl_list_init(&hapd->sae_commit_queue);
2949 #endif /* CONFIG_SAE */
2950
2951 return hapd;
2952 }
2953
2954
hostapd_bss_deinit(struct hostapd_data * hapd)2955 static void hostapd_bss_deinit(struct hostapd_data *hapd)
2956 {
2957 if (!hapd)
2958 return;
2959 wpa_printf(MSG_DEBUG, "%s: deinit bss %s", __func__,
2960 hapd->conf ? hapd->conf->iface : "N/A");
2961 hostapd_bss_deinit_no_free(hapd);
2962 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
2963 #ifdef CONFIG_LIBWPA_VENDOR
2964 struct HostapdApCbParm hostapdApCbParm = {};
2965 size_t contentLen = strlen(AP_EVENT_DISABLED);
2966 os_memcpy(hostapdApCbParm.content, AP_EVENT_DISABLED, contentLen);
2967 hostapdApCbParm.content[contentLen] = '\0';
2968 hostapdApCbParm.id = 0;
2969 wpa_printf(MSG_INFO, "%s HOSTAPD_EVENT_AP_STATE %s%d", __func__, hostapdApCbParm.content, hostapdApCbParm.id);
2970 HostapdEventReport(hapd->conf->iface, HOSTAPD_EVENT_AP_STATE, (void *) &hostapdApCbParm);
2971 #endif
2972 #ifdef CONFIG_SQLITE
2973 if (hapd->rad_attr_db) {
2974 sqlite3_close(hapd->rad_attr_db);
2975 hapd->rad_attr_db = NULL;
2976 }
2977 #endif /* CONFIG_SQLITE */
2978
2979 hostapd_bss_link_deinit(hapd);
2980 hostapd_cleanup(hapd);
2981 }
2982
2983
hostapd_interface_deinit(struct hostapd_iface * iface)2984 void hostapd_interface_deinit(struct hostapd_iface *iface)
2985 {
2986 int j;
2987
2988 wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
2989 if (iface == NULL)
2990 return;
2991
2992 hostapd_set_state(iface, HAPD_IFACE_DISABLED);
2993
2994 eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
2995 iface->wait_channel_update = 0;
2996 iface->is_no_ir = false;
2997
2998 #ifdef CONFIG_FST
2999 if (iface->fst) {
3000 fst_detach(iface->fst);
3001 iface->fst = NULL;
3002 }
3003 #endif /* CONFIG_FST */
3004
3005 for (j = (int) iface->num_bss - 1; j >= 0; j--) {
3006 if (!iface->bss)
3007 break;
3008 hostapd_bss_deinit(iface->bss[j]);
3009 }
3010
3011 #ifdef NEED_AP_MLME
3012 hostapd_stop_setup_timers(iface);
3013 eloop_cancel_timeout(ap_ht2040_timeout, iface, NULL);
3014 #endif /* NEED_AP_MLME */
3015 }
3016
3017
3018 #ifdef CONFIG_IEEE80211BE
3019
hostapd_mld_ref_inc(struct hostapd_mld * mld)3020 static void hostapd_mld_ref_inc(struct hostapd_mld *mld)
3021 {
3022 if (!mld)
3023 return;
3024
3025 if (mld->refcount == HOSTAPD_MLD_MAX_REF_COUNT) {
3026 wpa_printf(MSG_ERROR, "AP MLD %s: Ref count overflow",
3027 mld->name);
3028 return;
3029 }
3030
3031 mld->refcount++;
3032 }
3033
3034
hostapd_mld_ref_dec(struct hostapd_mld * mld)3035 static void hostapd_mld_ref_dec(struct hostapd_mld *mld)
3036 {
3037 if (!mld)
3038 return;
3039
3040 if (!mld->refcount) {
3041 wpa_printf(MSG_ERROR, "AP MLD %s: Ref count underflow",
3042 mld->name);
3043 return;
3044 }
3045
3046 mld->refcount--;
3047 }
3048
3049 #endif /* CONFIG_IEEE80211BE */
3050
3051
hostapd_interface_free(struct hostapd_iface * iface)3052 void hostapd_interface_free(struct hostapd_iface *iface)
3053 {
3054 size_t j;
3055 wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
3056 for (j = 0; j < iface->num_bss; j++) {
3057 if (!iface->bss)
3058 break;
3059 #ifdef CONFIG_IEEE80211BE
3060 if (iface->bss[j])
3061 hostapd_mld_ref_dec(iface->bss[j]->mld);
3062 #endif /* CONFIG_IEEE80211BE */
3063 wpa_printf(MSG_DEBUG, "%s: free hapd %p",
3064 __func__, iface->bss[j]);
3065 os_free(iface->bss[j]);
3066 }
3067 hostapd_cleanup_iface(iface);
3068 }
3069
3070
hostapd_alloc_iface(void)3071 struct hostapd_iface * hostapd_alloc_iface(void)
3072 {
3073 struct hostapd_iface *hapd_iface;
3074
3075 hapd_iface = os_zalloc(sizeof(*hapd_iface));
3076 if (!hapd_iface)
3077 return NULL;
3078
3079 dl_list_init(&hapd_iface->sta_seen);
3080
3081 return hapd_iface;
3082 }
3083
3084
3085 #ifdef CONFIG_IEEE80211BE
hostapd_bss_alloc_link_id(struct hostapd_data * hapd)3086 static void hostapd_bss_alloc_link_id(struct hostapd_data *hapd)
3087 {
3088 hapd->mld_link_id = hapd->mld->next_link_id++;
3089 wpa_printf(MSG_DEBUG, "AP MLD: %s: Link ID %d assigned.",
3090 hapd->mld->name, hapd->mld_link_id);
3091 }
3092 #endif /* CONFIG_IEEE80211BE */
3093
3094
hostapd_bss_setup_multi_link(struct hostapd_data * hapd,struct hapd_interfaces * interfaces)3095 static void hostapd_bss_setup_multi_link(struct hostapd_data *hapd,
3096 struct hapd_interfaces *interfaces)
3097 {
3098 #ifdef CONFIG_IEEE80211BE
3099 struct hostapd_mld *mld, **all_mld;
3100 struct hostapd_bss_config *conf;
3101 size_t i;
3102
3103 conf = hapd->conf;
3104
3105 if (!hapd->iconf || !hapd->iconf->ieee80211be || !conf->mld_ap ||
3106 conf->disable_11be)
3107 return;
3108
3109 for (i = 0; i < interfaces->mld_count; i++) {
3110 mld = interfaces->mld[i];
3111
3112 if (!mld || os_strcmp(conf->iface, mld->name) != 0)
3113 continue;
3114
3115 hapd->mld = mld;
3116 hostapd_mld_ref_inc(mld);
3117 hostapd_bss_alloc_link_id(hapd);
3118 break;
3119 }
3120
3121 if (hapd->mld)
3122 return;
3123
3124 mld = os_zalloc(sizeof(struct hostapd_mld));
3125 if (!mld)
3126 goto fail;
3127
3128 os_strlcpy(mld->name, conf->iface, sizeof(conf->iface));
3129 dl_list_init(&mld->links);
3130
3131 wpa_printf(MSG_DEBUG, "AP MLD %s created", mld->name);
3132
3133 hapd->mld = mld;
3134 hostapd_mld_ref_inc(mld);
3135 hostapd_bss_alloc_link_id(hapd);
3136
3137 all_mld = os_realloc_array(interfaces->mld, interfaces->mld_count + 1,
3138 sizeof(struct hostapd_mld *));
3139 if (!all_mld)
3140 goto fail;
3141
3142 interfaces->mld = all_mld;
3143 interfaces->mld[interfaces->mld_count] = mld;
3144 interfaces->mld_count++;
3145
3146 return;
3147 fail:
3148 if (!mld)
3149 return;
3150
3151 wpa_printf(MSG_DEBUG, "AP MLD %s: free mld %p", mld->name, mld);
3152 os_free(mld);
3153 hapd->mld = NULL;
3154 #endif /* CONFIG_IEEE80211BE */
3155 }
3156
3157
hostapd_cleanup_unused_mlds(struct hapd_interfaces * interfaces)3158 static void hostapd_cleanup_unused_mlds(struct hapd_interfaces *interfaces)
3159 {
3160 #ifdef CONFIG_IEEE80211BE
3161 struct hostapd_mld *mld, **all_mld;
3162 size_t i, j, num_mlds;
3163 bool forced_remove, remove;
3164
3165 if (!interfaces->mld)
3166 return;
3167
3168 num_mlds = interfaces->mld_count;
3169
3170 for (i = 0; i < interfaces->mld_count; i++) {
3171 mld = interfaces->mld[i];
3172 if (!mld)
3173 continue;
3174
3175 remove = false;
3176 forced_remove = false;
3177
3178 if (!mld->refcount)
3179 remove = true;
3180
3181 /* If MLD is still being referenced but the number of interfaces
3182 * is zero, it is safe to force its deletion. Normally, this
3183 * should not happen but even if it does, let us free the
3184 * memory.
3185 */
3186 if (!remove && !interfaces->count)
3187 forced_remove = true;
3188
3189 if (!remove && !forced_remove)
3190 continue;
3191
3192 wpa_printf(MSG_DEBUG, "AP MLD %s: Freed%s", mld->name,
3193 forced_remove ? " (forced)" : "");
3194 os_free(mld);
3195 interfaces->mld[i] = NULL;
3196 num_mlds--;
3197 }
3198
3199 if (!num_mlds) {
3200 interfaces->mld_count = 0;
3201 os_free(interfaces->mld);
3202 interfaces->mld = NULL;
3203 return;
3204 }
3205
3206 all_mld = os_zalloc(num_mlds * sizeof(struct hostapd_mld *));
3207 if (!all_mld) {
3208 wpa_printf(MSG_ERROR,
3209 "AP MLD: Failed to re-allocate the MLDs. Expect issues");
3210 return;
3211 }
3212
3213 for (i = 0, j = 0; i < interfaces->mld_count; i++) {
3214 mld = interfaces->mld[i];
3215 if (!mld)
3216 continue;
3217
3218 all_mld[j++] = mld;
3219 }
3220
3221 /* This should not happen */
3222 if (j != num_mlds) {
3223 wpa_printf(MSG_DEBUG,
3224 "AP MLD: Some error occurred while reallocating MLDs. Expect issues.");
3225 os_free(all_mld);
3226 return;
3227 }
3228
3229 os_free(interfaces->mld);
3230 interfaces->mld = all_mld;
3231 interfaces->mld_count = num_mlds;
3232 #endif /* CONFIG_IEEE80211BE */
3233 }
3234
3235
3236 /**
3237 * hostapd_init - Allocate and initialize per-interface data
3238 * @config_file: Path to the configuration file
3239 * Returns: Pointer to the allocated interface data or %NULL on failure
3240 *
3241 * This function is used to allocate main data structures for per-interface
3242 * data. The allocated data buffer will be freed by calling
3243 * hostapd_cleanup_iface().
3244 */
hostapd_init(struct hapd_interfaces * interfaces,const char * config_file)3245 struct hostapd_iface * hostapd_init(struct hapd_interfaces *interfaces,
3246 const char *config_file)
3247 {
3248 struct hostapd_iface *hapd_iface = NULL;
3249 struct hostapd_config *conf = NULL;
3250 struct hostapd_data *hapd;
3251 size_t i;
3252
3253 hapd_iface = hostapd_alloc_iface();
3254 if (hapd_iface == NULL)
3255 goto fail;
3256
3257 hapd_iface->config_fname = os_strdup(config_file);
3258 if (hapd_iface->config_fname == NULL)
3259 goto fail;
3260
3261 conf = interfaces->config_read_cb(hapd_iface->config_fname);
3262 if (conf == NULL)
3263 goto fail;
3264 hapd_iface->conf = conf;
3265
3266 hapd_iface->num_bss = conf->num_bss;
3267 hapd_iface->bss = os_calloc(conf->num_bss,
3268 sizeof(struct hostapd_data *));
3269 if (hapd_iface->bss == NULL)
3270 goto fail;
3271
3272 for (i = 0; i < conf->num_bss; i++) {
3273 hapd = hapd_iface->bss[i] =
3274 hostapd_alloc_bss_data(hapd_iface, conf,
3275 conf->bss[i]);
3276 if (hapd == NULL)
3277 goto fail;
3278 hapd->msg_ctx = hapd;
3279 hostapd_bss_setup_multi_link(hapd, interfaces);
3280 }
3281
3282 hapd_iface->is_ch_switch_dfs = false;
3283 return hapd_iface;
3284
3285 fail:
3286 wpa_printf(MSG_ERROR, "Failed to set up interface with %s",
3287 config_file);
3288 if (conf)
3289 hostapd_config_free(conf);
3290 if (hapd_iface) {
3291 os_free(hapd_iface->config_fname);
3292 os_free(hapd_iface->bss);
3293 wpa_printf(MSG_DEBUG, "%s: free iface %p",
3294 __func__, hapd_iface);
3295 os_free(hapd_iface);
3296 }
3297 return NULL;
3298 }
3299
3300
ifname_in_use(struct hapd_interfaces * interfaces,const char * ifname)3301 static int ifname_in_use(struct hapd_interfaces *interfaces, const char *ifname)
3302 {
3303 size_t i, j;
3304
3305 for (i = 0; i < interfaces->count; i++) {
3306 struct hostapd_iface *iface = interfaces->iface[i];
3307 for (j = 0; j < iface->num_bss; j++) {
3308 struct hostapd_data *hapd = iface->bss[j];
3309 if (os_strcmp(ifname, hapd->conf->iface) == 0)
3310 return 1;
3311 }
3312 }
3313
3314 return 0;
3315 }
3316
3317
3318 /**
3319 * hostapd_interface_init_bss - Read configuration file and init BSS data
3320 *
3321 * This function is used to parse configuration file for a BSS. This BSS is
3322 * added to an existing interface sharing the same radio (if any) or a new
3323 * interface is created if this is the first interface on a radio. This
3324 * allocate memory for the BSS. No actual driver operations are started.
3325 *
3326 * This is similar to hostapd_interface_init(), but for a case where the
3327 * configuration is used to add a single BSS instead of all BSSes for a radio.
3328 */
3329 struct hostapd_iface *
hostapd_interface_init_bss(struct hapd_interfaces * interfaces,const char * phy,const char * config_fname,int debug)3330 hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy,
3331 const char *config_fname, int debug)
3332 {
3333 struct hostapd_iface *new_iface = NULL, *iface = NULL;
3334 struct hostapd_data *hapd;
3335 int k;
3336 size_t i, bss_idx;
3337
3338 if (!phy || !*phy)
3339 return NULL;
3340
3341 for (i = 0; i < interfaces->count; i++) {
3342 if (os_strcmp(interfaces->iface[i]->phy, phy) == 0) {
3343 iface = interfaces->iface[i];
3344 break;
3345 }
3346 }
3347
3348 wpa_printf(MSG_INFO, "Configuration file: %s (phy %s)%s",
3349 config_fname, phy, iface ? "" : " --> new PHY");
3350 if (iface) {
3351 struct hostapd_config *conf;
3352 struct hostapd_bss_config **tmp_conf;
3353 struct hostapd_data **tmp_bss;
3354 struct hostapd_bss_config *bss;
3355 const char *ifname;
3356
3357 /* Add new BSS to existing iface */
3358 conf = interfaces->config_read_cb(config_fname);
3359 if (conf == NULL)
3360 return NULL;
3361 if (conf->num_bss > 1) {
3362 wpa_printf(MSG_ERROR, "Multiple BSSes specified in BSS-config");
3363 hostapd_config_free(conf);
3364 return NULL;
3365 }
3366
3367 ifname = conf->bss[0]->iface;
3368 if (ifname[0] != '\0' && ifname_in_use(interfaces, ifname)) {
3369 wpa_printf(MSG_ERROR,
3370 "Interface name %s already in use", ifname);
3371 hostapd_config_free(conf);
3372 return NULL;
3373 }
3374
3375 tmp_conf = os_realloc_array(
3376 iface->conf->bss, iface->conf->num_bss + 1,
3377 sizeof(struct hostapd_bss_config *));
3378 tmp_bss = os_realloc_array(iface->bss, iface->num_bss + 1,
3379 sizeof(struct hostapd_data *));
3380 if (tmp_bss)
3381 iface->bss = tmp_bss;
3382 if (tmp_conf) {
3383 iface->conf->bss = tmp_conf;
3384 iface->conf->last_bss = tmp_conf[0];
3385 }
3386 if (tmp_bss == NULL || tmp_conf == NULL) {
3387 hostapd_config_free(conf);
3388 return NULL;
3389 }
3390 bss = iface->conf->bss[iface->conf->num_bss] = conf->bss[0];
3391 iface->conf->num_bss++;
3392
3393 hapd = hostapd_alloc_bss_data(iface, iface->conf, bss);
3394 if (hapd == NULL) {
3395 iface->conf->num_bss--;
3396 hostapd_config_free(conf);
3397 return NULL;
3398 }
3399 iface->conf->last_bss = bss;
3400 iface->bss[iface->num_bss] = hapd;
3401 hapd->msg_ctx = hapd;
3402 hostapd_bss_setup_multi_link(hapd, interfaces);
3403
3404
3405 bss_idx = iface->num_bss++;
3406 conf->num_bss--;
3407 conf->bss[0] = NULL;
3408 hostapd_config_free(conf);
3409 } else {
3410 /* Add a new iface with the first BSS */
3411 new_iface = iface = hostapd_init(interfaces, config_fname);
3412 if (!iface)
3413 return NULL;
3414 os_strlcpy(iface->phy, phy, sizeof(iface->phy));
3415 iface->interfaces = interfaces;
3416 bss_idx = 0;
3417 }
3418
3419 for (k = 0; k < debug; k++) {
3420 if (iface->bss[bss_idx]->conf->logger_stdout_level > 0)
3421 iface->bss[bss_idx]->conf->logger_stdout_level--;
3422 }
3423
3424 if (iface->conf->bss[bss_idx]->iface[0] == '\0' &&
3425 !hostapd_drv_none(iface->bss[bss_idx])) {
3426 wpa_printf(MSG_ERROR, "Interface name not specified in %s",
3427 config_fname);
3428 if (new_iface)
3429 hostapd_interface_deinit_free(new_iface);
3430 return NULL;
3431 }
3432
3433 return iface;
3434 }
3435
3436
hostapd_cleanup_driver(const struct wpa_driver_ops * driver,void * drv_priv,struct hostapd_iface * iface)3437 static void hostapd_cleanup_driver(const struct wpa_driver_ops *driver,
3438 void *drv_priv, struct hostapd_iface *iface)
3439 {
3440 if (!driver || !driver->hapd_deinit || !drv_priv)
3441 return;
3442
3443 #ifdef CONFIG_IEEE80211BE
3444 /* In case of non-ML operation, de-init. But if ML operation exist,
3445 * even if that's the last BSS in the interface, the driver (drv) could
3446 * be in use for a different AP MLD. Hence, need to check if drv is
3447 * still being used by some other BSS before de-initiallizing. */
3448 if (!iface->bss[0]->conf->mld_ap) {
3449 driver->hapd_deinit(drv_priv);
3450 } else if (hostapd_mld_is_first_bss(iface->bss[0]) &&
3451 driver->is_drv_shared &&
3452 !driver->is_drv_shared(drv_priv, iface->bss[0])) {
3453 driver->hapd_deinit(drv_priv);
3454 } else if (hostapd_if_link_remove(iface->bss[0],
3455 WPA_IF_AP_BSS,
3456 iface->bss[0]->conf->iface,
3457 iface->bss[0]->mld_link_id)) {
3458 wpa_printf(MSG_WARNING, "Failed to remove BSS interface %s",
3459 iface->bss[0]->conf->iface);
3460 }
3461 #else /* CONFIG_IEEE80211BE */
3462 driver->hapd_deinit(drv_priv);
3463 #endif /* CONFIG_IEEE80211BE */
3464 iface->bss[0]->drv_priv = NULL;
3465 }
3466
3467
hostapd_interface_deinit_free(struct hostapd_iface * iface)3468 void hostapd_interface_deinit_free(struct hostapd_iface *iface)
3469 {
3470 const struct wpa_driver_ops *driver;
3471 void *drv_priv;
3472
3473 wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
3474 if (iface == NULL)
3475 return;
3476 wpa_printf(MSG_DEBUG, "%s: num_bss=%u conf->num_bss=%u",
3477 __func__, (unsigned int) iface->num_bss,
3478 (unsigned int) iface->conf->num_bss);
3479 driver = iface->bss[0]->driver;
3480 drv_priv = iface->bss[0]->drv_priv;
3481 hostapd_interface_deinit(iface);
3482 wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
3483 __func__, driver, drv_priv);
3484 hostapd_cleanup_driver(driver, drv_priv, iface);
3485 hostapd_interface_free(iface);
3486 }
3487
3488
hostapd_deinit_driver(const struct wpa_driver_ops * driver,void * drv_priv,struct hostapd_iface * hapd_iface)3489 static void hostapd_deinit_driver(const struct wpa_driver_ops *driver,
3490 void *drv_priv,
3491 struct hostapd_iface *hapd_iface)
3492 {
3493 size_t j;
3494
3495 wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
3496 __func__, driver, drv_priv);
3497
3498 hostapd_cleanup_driver(driver, drv_priv, hapd_iface);
3499
3500 if (driver && driver->hapd_deinit && drv_priv) {
3501 for (j = 0; j < hapd_iface->num_bss; j++) {
3502 wpa_printf(MSG_DEBUG, "%s:bss[%d]->drv_priv=%p",
3503 __func__, (int) j,
3504 hapd_iface->bss[j]->drv_priv);
3505 if (hapd_iface->bss[j]->drv_priv == drv_priv) {
3506 hapd_iface->bss[j]->drv_priv = NULL;
3507 hapd_iface->extended_capa = NULL;
3508 hapd_iface->extended_capa_mask = NULL;
3509 hapd_iface->extended_capa_len = 0;
3510 }
3511 }
3512 }
3513 }
3514
3515
hostapd_refresh_all_iface_beacons(struct hostapd_iface * hapd_iface)3516 static void hostapd_refresh_all_iface_beacons(struct hostapd_iface *hapd_iface)
3517 {
3518 size_t j;
3519
3520 if (!hapd_iface->interfaces || hapd_iface->interfaces->count <= 1)
3521 return;
3522
3523 for (j = 0; j < hapd_iface->interfaces->count; j++) {
3524 if (hapd_iface->interfaces->iface[j] == hapd_iface)
3525 continue;
3526
3527 ieee802_11_update_beacons(hapd_iface->interfaces->iface[j]);
3528 }
3529 }
3530
3531
hostapd_enable_iface(struct hostapd_iface * hapd_iface)3532 int hostapd_enable_iface(struct hostapd_iface *hapd_iface)
3533 {
3534 size_t j;
3535
3536 if (!hapd_iface) {
3537 wpa_printf(MSG_ERROR, "hapd_iface is NULL!");
3538 return -1;
3539 }
3540
3541 if (hapd_iface->enable_iface_cb)
3542 return hapd_iface->enable_iface_cb(hapd_iface);
3543
3544 if (hapd_iface->bss[0]->drv_priv != NULL) {
3545 wpa_printf(MSG_ERROR, "Interface %s already enabled",
3546 hapd_iface->conf->bss[0]->iface);
3547 return -1;
3548 }
3549
3550 wpa_printf(MSG_DEBUG, "Enable interface %s",
3551 hapd_iface->conf->bss[0]->iface);
3552
3553 for (j = 0; j < hapd_iface->num_bss; j++)
3554 hostapd_set_security_params(hapd_iface->conf->bss[j], 1);
3555 if (hostapd_config_check(hapd_iface->conf, 1) < 0) {
3556 wpa_printf(MSG_INFO, "Invalid configuration - cannot enable");
3557 return -1;
3558 }
3559
3560 if (hapd_iface->interfaces == NULL ||
3561 hapd_iface->interfaces->driver_init == NULL ||
3562 hapd_iface->interfaces->driver_init(hapd_iface))
3563 return -1;
3564
3565 if (hostapd_setup_interface(hapd_iface)) {
3566 hostapd_deinit_driver(hapd_iface->bss[0]->driver,
3567 hapd_iface->bss[0]->drv_priv,
3568 hapd_iface);
3569 wpa_printf(MSG_ERROR, "hostapd_setup_interface fail!");
3570 return -1;
3571 }
3572
3573 hostapd_refresh_all_iface_beacons(hapd_iface);
3574
3575 return 0;
3576 }
3577
3578
hostapd_reload_iface(struct hostapd_iface * hapd_iface)3579 int hostapd_reload_iface(struct hostapd_iface *hapd_iface)
3580 {
3581 size_t j;
3582
3583 wpa_printf(MSG_DEBUG, "Reload interface %s",
3584 hapd_iface->conf->bss[0]->iface);
3585 for (j = 0; j < hapd_iface->num_bss; j++)
3586 hostapd_set_security_params(hapd_iface->conf->bss[j], 1);
3587 if (hostapd_config_check(hapd_iface->conf, 1) < 0) {
3588 wpa_printf(MSG_ERROR, "Updated configuration is invalid");
3589 return -1;
3590 }
3591 hostapd_clear_old(hapd_iface);
3592 for (j = 0; j < hapd_iface->num_bss; j++)
3593 hostapd_reload_bss(hapd_iface->bss[j]);
3594
3595 return 0;
3596 }
3597
3598
hostapd_reload_bss_only(struct hostapd_data * bss)3599 int hostapd_reload_bss_only(struct hostapd_data *bss)
3600 {
3601
3602 wpa_printf(MSG_DEBUG, "Reload BSS %s", bss->conf->iface);
3603 hostapd_set_security_params(bss->conf, 1);
3604 if (hostapd_config_check(bss->iconf, 1) < 0) {
3605 wpa_printf(MSG_ERROR, "Updated BSS configuration is invalid");
3606 return -1;
3607 }
3608 hostapd_clear_old_bss(bss);
3609 hostapd_reload_bss(bss);
3610 return 0;
3611 }
3612
3613
hostapd_disable_iface(struct hostapd_iface * hapd_iface)3614 int hostapd_disable_iface(struct hostapd_iface *hapd_iface)
3615 {
3616 size_t j;
3617 const struct wpa_driver_ops *driver;
3618 void *drv_priv;
3619
3620 if (hapd_iface == NULL)
3621 return -1;
3622
3623 if (hapd_iface->disable_iface_cb)
3624 return hapd_iface->disable_iface_cb(hapd_iface);
3625
3626 if (hapd_iface->bss[0]->drv_priv == NULL) {
3627 wpa_printf(MSG_INFO, "Interface %s already disabled",
3628 hapd_iface->conf->bss[0]->iface);
3629 return -1;
3630 }
3631
3632 wpa_msg(hapd_iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
3633 #ifdef CONFIG_LIBWPA_VENDOR
3634 struct HostapdApCbParm hostapdApCbParm = {};
3635 size_t contentLen = strlen(AP_EVENT_DISABLED);
3636 os_memcpy(hostapdApCbParm.content, AP_EVENT_DISABLED, contentLen);
3637 hostapdApCbParm.content[contentLen] = '\0';
3638 hostapdApCbParm.id = 0;
3639 wpa_printf(MSG_INFO, "%s HOSTAPD_EVENT_AP_STATE %s%d", __func__, hostapdApCbParm.content, hostapdApCbParm.id);
3640 HostapdEventReport(hapd_iface->bss[0]->conf->iface, HOSTAPD_EVENT_AP_STATE, (void *) &hostapdApCbParm);
3641 #endif
3642 driver = hapd_iface->bss[0]->driver;
3643 drv_priv = hapd_iface->bss[0]->drv_priv;
3644
3645 hapd_iface->driver_ap_teardown =
3646 !!(hapd_iface->drv_flags &
3647 WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
3648
3649 #ifdef NEED_AP_MLME
3650 for (j = 0; j < hapd_iface->num_bss; j++)
3651 hostapd_cleanup_cs_params(hapd_iface->bss[j]);
3652 #endif /* NEED_AP_MLME */
3653
3654 /* same as hostapd_interface_deinit without deinitializing ctrl-iface */
3655 for (j = 0; j < hapd_iface->num_bss; j++) {
3656 struct hostapd_data *hapd = hapd_iface->bss[j];
3657 hostapd_bss_deinit_no_free(hapd);
3658 hostapd_bss_link_deinit(hapd);
3659 hostapd_free_hapd_data(hapd);
3660 }
3661
3662 hostapd_deinit_driver(driver, drv_priv, hapd_iface);
3663
3664 /* From hostapd_cleanup_iface: These were initialized in
3665 * hostapd_setup_interface and hostapd_setup_interface_complete
3666 */
3667 hostapd_cleanup_iface_partial(hapd_iface);
3668
3669 wpa_printf(MSG_DEBUG, "Interface %s disabled",
3670 hapd_iface->bss[0]->conf->iface);
3671 hostapd_set_state(hapd_iface, HAPD_IFACE_DISABLED);
3672 hostapd_refresh_all_iface_beacons(hapd_iface);
3673 return 0;
3674 }
3675
3676
3677 static struct hostapd_iface *
hostapd_iface_alloc(struct hapd_interfaces * interfaces)3678 hostapd_iface_alloc(struct hapd_interfaces *interfaces)
3679 {
3680 struct hostapd_iface **iface, *hapd_iface;
3681
3682 iface = os_realloc_array(interfaces->iface, interfaces->count + 1,
3683 sizeof(struct hostapd_iface *));
3684 if (iface == NULL)
3685 return NULL;
3686 interfaces->iface = iface;
3687 hapd_iface = interfaces->iface[interfaces->count] =
3688 hostapd_alloc_iface();
3689 if (hapd_iface == NULL) {
3690 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for "
3691 "the interface", __func__);
3692 return NULL;
3693 }
3694 interfaces->count++;
3695 hapd_iface->interfaces = interfaces;
3696
3697 return hapd_iface;
3698 }
3699
3700
3701 static struct hostapd_config *
hostapd_config_alloc(struct hapd_interfaces * interfaces,const char * ifname,const char * ctrl_iface,const char * driver)3702 hostapd_config_alloc(struct hapd_interfaces *interfaces, const char *ifname,
3703 const char *ctrl_iface, const char *driver)
3704 {
3705 struct hostapd_bss_config *bss;
3706 struct hostapd_config *conf;
3707
3708 /* Allocates memory for bss and conf */
3709 conf = hostapd_config_defaults();
3710 if (conf == NULL) {
3711 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for "
3712 "configuration", __func__);
3713 return NULL;
3714 }
3715
3716 if (driver) {
3717 int j;
3718
3719 for (j = 0; wpa_drivers[j]; j++) {
3720 if (os_strcmp(driver, wpa_drivers[j]->name) == 0) {
3721 conf->driver = wpa_drivers[j];
3722 goto skip;
3723 }
3724 }
3725
3726 wpa_printf(MSG_ERROR,
3727 "Invalid/unknown driver '%s' - registering the default driver",
3728 driver);
3729 }
3730
3731 conf->driver = wpa_drivers[0];
3732 if (conf->driver == NULL) {
3733 wpa_printf(MSG_ERROR, "No driver wrappers registered!");
3734 hostapd_config_free(conf);
3735 return NULL;
3736 }
3737
3738 skip:
3739 bss = conf->last_bss = conf->bss[0];
3740
3741 os_strlcpy(bss->iface, ifname, sizeof(bss->iface));
3742 bss->ctrl_interface = os_strdup(ctrl_iface);
3743 if (bss->ctrl_interface == NULL) {
3744 hostapd_config_free(conf);
3745 return NULL;
3746 }
3747
3748 /* Reading configuration file skipped, will be done in SET!
3749 * From reading the configuration till the end has to be done in
3750 * SET
3751 */
3752 return conf;
3753 }
3754
3755
hostapd_data_alloc(struct hostapd_iface * hapd_iface,struct hostapd_config * conf)3756 static int hostapd_data_alloc(struct hostapd_iface *hapd_iface,
3757 struct hostapd_config *conf)
3758 {
3759 size_t i;
3760 struct hostapd_data *hapd;
3761
3762 hapd_iface->bss = os_calloc(conf->num_bss,
3763 sizeof(struct hostapd_data *));
3764 if (hapd_iface->bss == NULL)
3765 return -1;
3766
3767 for (i = 0; i < conf->num_bss; i++) {
3768 hapd = hapd_iface->bss[i] =
3769 hostapd_alloc_bss_data(hapd_iface, conf, conf->bss[i]);
3770 if (hapd == NULL) {
3771 while (i > 0) {
3772 i--;
3773 os_free(hapd_iface->bss[i]);
3774 hapd_iface->bss[i] = NULL;
3775 }
3776 os_free(hapd_iface->bss);
3777 hapd_iface->bss = NULL;
3778 return -1;
3779 }
3780 hapd->msg_ctx = hapd;
3781 hostapd_bss_setup_multi_link(hapd, hapd_iface->interfaces);
3782 }
3783
3784 hapd_iface->conf = conf;
3785 hapd_iface->num_bss = conf->num_bss;
3786
3787 return 0;
3788 }
3789
3790
hostapd_add_iface(struct hapd_interfaces * interfaces,char * buf)3791 int hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf)
3792 {
3793 struct hostapd_config *conf = NULL;
3794 struct hostapd_iface *hapd_iface = NULL, *new_iface = NULL;
3795 struct hostapd_data *hapd;
3796 char *ptr;
3797 size_t i, j;
3798 const char *conf_file = NULL, *phy_name = NULL;
3799
3800 if (os_strncmp(buf, "bss_config=", 11) == 0) {
3801 char *pos;
3802 phy_name = buf + 11;
3803 pos = os_strchr(phy_name, ':');
3804 if (!pos)
3805 return -1;
3806 *pos++ = '\0';
3807 conf_file = pos;
3808 if (!os_strlen(conf_file))
3809 return -1;
3810
3811 hapd_iface = hostapd_interface_init_bss(interfaces, phy_name,
3812 conf_file, 0);
3813 if (!hapd_iface)
3814 return -1;
3815 for (j = 0; j < interfaces->count; j++) {
3816 if (interfaces->iface[j] == hapd_iface)
3817 break;
3818 }
3819 if (j == interfaces->count) {
3820 struct hostapd_iface **tmp;
3821 tmp = os_realloc_array(interfaces->iface,
3822 interfaces->count + 1,
3823 sizeof(struct hostapd_iface *));
3824 if (!tmp) {
3825 hostapd_interface_deinit_free(hapd_iface);
3826 return -1;
3827 }
3828 interfaces->iface = tmp;
3829 interfaces->iface[interfaces->count++] = hapd_iface;
3830 new_iface = hapd_iface;
3831 }
3832
3833 if (new_iface) {
3834 if (interfaces->driver_init(hapd_iface))
3835 goto fail;
3836
3837 if (hostapd_setup_interface(hapd_iface)) {
3838 hostapd_deinit_driver(
3839 hapd_iface->bss[0]->driver,
3840 hapd_iface->bss[0]->drv_priv,
3841 hapd_iface);
3842 goto fail;
3843 }
3844 } else {
3845 /* Assign new BSS with bss[0]'s driver info */
3846 hapd = hapd_iface->bss[hapd_iface->num_bss - 1];
3847 hapd->driver = hapd_iface->bss[0]->driver;
3848 hapd->drv_priv = hapd_iface->bss[0]->drv_priv;
3849 os_memcpy(hapd->own_addr, hapd_iface->bss[0]->own_addr,
3850 ETH_ALEN);
3851
3852 if (start_ctrl_iface_bss(hapd) < 0 ||
3853 (hapd_iface->state == HAPD_IFACE_ENABLED &&
3854 hostapd_setup_bss(hapd, -1, true))) {
3855 hostapd_bss_link_deinit(hapd);
3856 hostapd_cleanup(hapd);
3857 hapd_iface->bss[hapd_iface->num_bss - 1] = NULL;
3858 hapd_iface->conf->num_bss--;
3859 hapd_iface->num_bss--;
3860 wpa_printf(MSG_DEBUG, "%s: free hapd %p %s",
3861 __func__, hapd, hapd->conf->iface);
3862 hostapd_config_free_bss(hapd->conf);
3863 hapd->conf = NULL;
3864 #ifdef CONFIG_IEEE80211BE
3865 hostapd_mld_ref_dec(hapd->mld);
3866 #endif /* CONFIG_IEEE80211BE */
3867 os_free(hapd);
3868 return -1;
3869 }
3870 }
3871 hostapd_owe_update_trans(hapd_iface);
3872 return 0;
3873 }
3874
3875 ptr = os_strchr(buf, ' ');
3876 if (ptr == NULL)
3877 return -1;
3878 *ptr++ = '\0';
3879
3880 if (os_strncmp(ptr, "config=", 7) == 0)
3881 conf_file = ptr + 7;
3882
3883 for (i = 0; i < interfaces->count; i++) {
3884 bool mld_ap = false;
3885
3886 #ifdef CONFIG_IEEE80211BE
3887 mld_ap = interfaces->iface[i]->conf->bss[0]->mld_ap;
3888 #endif /* CONFIG_IEEE80211BE */
3889
3890 if (!os_strcmp(interfaces->iface[i]->conf->bss[0]->iface,
3891 buf) && !mld_ap) {
3892 wpa_printf(MSG_INFO, "Cannot add interface - it "
3893 "already exists");
3894 return -1;
3895 }
3896 }
3897
3898 hapd_iface = hostapd_iface_alloc(interfaces);
3899 if (hapd_iface == NULL) {
3900 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
3901 "for interface", __func__);
3902 goto fail;
3903 }
3904 new_iface = hapd_iface;
3905
3906 if (conf_file && interfaces->config_read_cb) {
3907 conf = interfaces->config_read_cb(conf_file);
3908 if (conf && conf->bss)
3909 os_strlcpy(conf->bss[0]->iface, buf,
3910 sizeof(conf->bss[0]->iface));
3911 } else {
3912 char *driver = os_strchr(ptr, ' ');
3913
3914 if (driver)
3915 *driver++ = '\0';
3916 conf = hostapd_config_alloc(interfaces, buf, ptr, driver);
3917 }
3918
3919 if (conf == NULL || conf->bss == NULL) {
3920 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
3921 "for configuration", __func__);
3922 goto fail;
3923 }
3924
3925 if (hostapd_data_alloc(hapd_iface, conf) < 0) {
3926 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
3927 "for hostapd", __func__);
3928 goto fail;
3929 }
3930 conf = NULL;
3931
3932 if (start_ctrl_iface(hapd_iface) < 0)
3933 goto fail;
3934
3935 wpa_printf(MSG_INFO, "Add interface '%s'",
3936 hapd_iface->conf->bss[0]->iface);
3937
3938 return 0;
3939
3940 fail:
3941 if (conf)
3942 hostapd_config_free(conf);
3943 if (hapd_iface) {
3944 if (hapd_iface->bss) {
3945 for (i = 0; i < hapd_iface->num_bss; i++) {
3946 hapd = hapd_iface->bss[i];
3947 if (!hapd)
3948 continue;
3949 if (hapd_iface->interfaces &&
3950 hapd_iface->interfaces->ctrl_iface_deinit)
3951 hapd_iface->interfaces->
3952 ctrl_iface_deinit(hapd);
3953 wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)",
3954 __func__, hapd_iface->bss[i],
3955 hapd->conf->iface);
3956 hostapd_bss_link_deinit(hapd);
3957 hostapd_cleanup(hapd);
3958 #ifdef CONFIG_IEEE80211BE
3959 hostapd_mld_ref_dec(hapd->mld);
3960 #endif /* CONFIG_IEEE80211BE */
3961 os_free(hapd);
3962 hapd_iface->bss[i] = NULL;
3963 }
3964 os_free(hapd_iface->bss);
3965 hapd_iface->bss = NULL;
3966 }
3967 if (new_iface) {
3968 interfaces->count--;
3969 interfaces->iface[interfaces->count] = NULL;
3970 hostapd_cleanup_unused_mlds(interfaces);
3971 }
3972 hostapd_cleanup_iface(hapd_iface);
3973 }
3974 return -1;
3975 }
3976
3977
hostapd_remove_bss(struct hostapd_iface * iface,unsigned int idx)3978 static int hostapd_remove_bss(struct hostapd_iface *iface, unsigned int idx)
3979 {
3980 size_t i;
3981
3982 wpa_printf(MSG_INFO, "Remove BSS '%s'", iface->conf->bss[idx]->iface);
3983
3984 /* Remove hostapd_data only if it has already been initialized */
3985 if (idx < iface->num_bss) {
3986 struct hostapd_data *hapd = iface->bss[idx];
3987
3988 hostapd_bss_deinit(hapd);
3989 wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)",
3990 __func__, hapd, hapd->conf->iface);
3991 hostapd_config_free_bss(hapd->conf);
3992 hapd->conf = NULL;
3993 #ifdef CONFIG_IEEE80211BE
3994 hostapd_mld_ref_dec(hapd->mld);
3995 #endif /* CONFIG_IEEE80211BE */
3996 os_free(hapd);
3997
3998 iface->num_bss--;
3999
4000 for (i = idx; i < iface->num_bss; i++)
4001 iface->bss[i] = iface->bss[i + 1];
4002 } else {
4003 hostapd_config_free_bss(iface->conf->bss[idx]);
4004 iface->conf->bss[idx] = NULL;
4005 }
4006
4007 iface->conf->num_bss--;
4008 for (i = idx; i < iface->conf->num_bss; i++)
4009 iface->conf->bss[i] = iface->conf->bss[i + 1];
4010
4011 return 0;
4012 }
4013
4014
hostapd_remove_iface(struct hapd_interfaces * interfaces,char * buf)4015 int hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf)
4016 {
4017 struct hostapd_iface *hapd_iface;
4018 size_t i, j, k = 0;
4019
4020 for (i = 0; i < interfaces->count; i++) {
4021 hapd_iface = interfaces->iface[i];
4022 if (hapd_iface == NULL)
4023 return -1;
4024 if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
4025 wpa_printf(MSG_INFO, "Remove interface '%s'", buf);
4026 hapd_iface->driver_ap_teardown =
4027 !!(hapd_iface->drv_flags &
4028 WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
4029
4030 hostapd_interface_deinit_free(hapd_iface);
4031 k = i;
4032 while (k < (interfaces->count - 1)) {
4033 interfaces->iface[k] =
4034 interfaces->iface[k + 1];
4035 k++;
4036 }
4037 interfaces->count--;
4038 hostapd_cleanup_unused_mlds(interfaces);
4039
4040 return 0;
4041 }
4042
4043 for (j = 0; j < hapd_iface->conf->num_bss; j++) {
4044 if (!os_strcmp(hapd_iface->conf->bss[j]->iface, buf)) {
4045 hapd_iface->driver_ap_teardown =
4046 !(hapd_iface->drv_flags &
4047 WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
4048 return hostapd_remove_bss(hapd_iface, j);
4049 }
4050 }
4051 }
4052 return -1;
4053 }
4054
4055
4056 /**
4057 * hostapd_new_assoc_sta - Notify that a new station associated with the AP
4058 * @hapd: Pointer to BSS data
4059 * @sta: Pointer to the associated STA data
4060 * @reassoc: 1 to indicate this was a re-association; 0 = first association
4061 *
4062 * This function will be called whenever a station associates with the AP. It
4063 * can be called from ieee802_11.c for drivers that export MLME to hostapd and
4064 * from drv_callbacks.c based on driver events for drivers that take care of
4065 * management frames (IEEE 802.11 authentication and association) internally.
4066 */
hostapd_new_assoc_sta(struct hostapd_data * hapd,struct sta_info * sta,int reassoc)4067 void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
4068 int reassoc)
4069 {
4070 if (hapd->tkip_countermeasures) {
4071 hostapd_drv_sta_deauth(hapd, sta->addr,
4072 WLAN_REASON_MICHAEL_MIC_FAILURE);
4073 return;
4074 }
4075
4076 #ifdef CONFIG_IEEE80211BE
4077 if (ap_sta_is_mld(hapd, sta) &&
4078 sta->mld_assoc_link_id != hapd->mld_link_id)
4079 return;
4080 #endif /* CONFIG_IEEE80211BE */
4081
4082 ap_sta_clear_disconnect_timeouts(hapd, sta);
4083 sta->post_csa_sa_query = 0;
4084
4085 #ifdef CONFIG_P2P
4086 if (sta->p2p_ie == NULL && !sta->no_p2p_set) {
4087 sta->no_p2p_set = 1;
4088 hapd->num_sta_no_p2p++;
4089 if (hapd->num_sta_no_p2p == 1)
4090 hostapd_p2p_non_p2p_sta_connected(hapd);
4091 }
4092 #endif /* CONFIG_P2P */
4093
4094 airtime_policy_new_sta(hapd, sta);
4095
4096 /* Start accounting here, if IEEE 802.1X and WPA are not used.
4097 * IEEE 802.1X/WPA code will start accounting after the station has
4098 * been authorized. */
4099 if (!hapd->conf->ieee802_1x && !hapd->conf->wpa && !hapd->conf->osen) {
4100 ap_sta_set_authorized(hapd, sta, 1);
4101 os_get_reltime(&sta->connected_time);
4102 accounting_sta_start(hapd, sta);
4103 }
4104
4105 /* Start IEEE 802.1X authentication process for new stations */
4106 ieee802_1x_new_station(hapd, sta);
4107 #ifdef CONFIG_P2P_CHR
4108 wpa_supplicant_upload_go_p2p_state(hapd, sta->addr,
4109 P2P_INTERFACE_STATE_ASSOCIATED, P2P_CHR_DEFAULT_REASON_CODE);
4110 #endif
4111 if (reassoc) {
4112 if (sta->auth_alg != WLAN_AUTH_FT &&
4113 sta->auth_alg != WLAN_AUTH_FILS_SK &&
4114 sta->auth_alg != WLAN_AUTH_FILS_SK_PFS &&
4115 sta->auth_alg != WLAN_AUTH_FILS_PK &&
4116 !(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)))
4117 wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH);
4118 } else if (!(hapd->iface->drv_flags2 &
4119 WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK)) {
4120 /* The 4-way handshake offloaded case will have this handled
4121 * based on the port authorized event. */
4122 wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm);
4123 }
4124
4125 if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_WIRED) {
4126 if (eloop_cancel_timeout(ap_handle_timer, hapd, sta) > 0) {
4127 wpa_printf(MSG_EXCESSIVE,
4128 "%s: %s: canceled wired ap_handle_timer timeout for "
4129 MACSTR_SEC,
4130 hapd->conf->iface, __func__,
4131 MAC2STR_SEC(sta->addr));
4132 }
4133 } else if (!(hapd->iface->drv_flags &
4134 WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) {
4135 wpa_printf(MSG_EXCESSIVE,
4136 "%s: %s: reschedule ap_handle_timer timeout for "
4137 MACSTR_SEC " (%d seconds - ap_max_inactivity)",
4138 hapd->conf->iface, __func__, MAC2STR_SEC(sta->addr),
4139 hapd->conf->ap_max_inactivity);
4140 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
4141 eloop_register_timeout(hapd->conf->ap_max_inactivity, 0,
4142 ap_handle_timer, hapd, sta);
4143 }
4144
4145 #ifdef CONFIG_MACSEC
4146 if (hapd->conf->wpa_key_mgmt == WPA_KEY_MGMT_NONE &&
4147 hapd->conf->mka_psk_set)
4148 ieee802_1x_create_preshared_mka_hapd(hapd, sta);
4149 else
4150 ieee802_1x_alloc_kay_sm_hapd(hapd, sta);
4151 #endif /* CONFIG_MACSEC */
4152 }
4153
4154
hostapd_state_text(enum hostapd_iface_state s)4155 const char * hostapd_state_text(enum hostapd_iface_state s)
4156 {
4157 switch (s) {
4158 case HAPD_IFACE_UNINITIALIZED:
4159 return "UNINITIALIZED";
4160 case HAPD_IFACE_DISABLED:
4161 return "DISABLED";
4162 case HAPD_IFACE_COUNTRY_UPDATE:
4163 return "COUNTRY_UPDATE";
4164 case HAPD_IFACE_ACS:
4165 return "ACS";
4166 case HAPD_IFACE_HT_SCAN:
4167 return "HT_SCAN";
4168 case HAPD_IFACE_DFS:
4169 return "DFS";
4170 case HAPD_IFACE_ENABLED:
4171 return "ENABLED";
4172 case HAPD_IFACE_NO_IR:
4173 return "NO_IR";
4174 }
4175
4176 return "UNKNOWN";
4177 }
4178
4179
hostapd_set_state(struct hostapd_iface * iface,enum hostapd_iface_state s)4180 void hostapd_set_state(struct hostapd_iface *iface, enum hostapd_iface_state s)
4181 {
4182 wpa_printf(MSG_INFO, "%s: interface state %s->%s",
4183 iface->conf ? iface->conf->bss[0]->iface : "N/A",
4184 hostapd_state_text(iface->state), hostapd_state_text(s));
4185 iface->state = s;
4186 }
4187
4188
hostapd_csa_in_progress(struct hostapd_iface * iface)4189 int hostapd_csa_in_progress(struct hostapd_iface *iface)
4190 {
4191 unsigned int i;
4192
4193 for (i = 0; i < iface->num_bss; i++)
4194 if (iface->bss[i]->csa_in_progress)
4195 return 1;
4196 return 0;
4197 }
4198
4199
4200 #ifdef NEED_AP_MLME
4201
free_beacon_data(struct beacon_data * beacon)4202 void free_beacon_data(struct beacon_data *beacon)
4203 {
4204 os_free(beacon->head);
4205 beacon->head = NULL;
4206 os_free(beacon->tail);
4207 beacon->tail = NULL;
4208 os_free(beacon->probe_resp);
4209 beacon->probe_resp = NULL;
4210 os_free(beacon->beacon_ies);
4211 beacon->beacon_ies = NULL;
4212 os_free(beacon->proberesp_ies);
4213 beacon->proberesp_ies = NULL;
4214 os_free(beacon->assocresp_ies);
4215 beacon->assocresp_ies = NULL;
4216 }
4217
4218
hostapd_build_beacon_data(struct hostapd_data * hapd,struct beacon_data * beacon)4219 static int hostapd_build_beacon_data(struct hostapd_data *hapd,
4220 struct beacon_data *beacon)
4221 {
4222 struct wpabuf *beacon_extra, *proberesp_extra, *assocresp_extra;
4223 struct wpa_driver_ap_params params;
4224 int ret;
4225
4226 os_memset(beacon, 0, sizeof(*beacon));
4227 ret = ieee802_11_build_ap_params(hapd, ¶ms);
4228 if (ret < 0)
4229 return ret;
4230
4231 ret = hostapd_build_ap_extra_ies(hapd, &beacon_extra,
4232 &proberesp_extra,
4233 &assocresp_extra);
4234 if (ret)
4235 goto free_ap_params;
4236
4237 ret = -1;
4238 beacon->head = os_memdup(params.head, params.head_len);
4239 if (!beacon->head)
4240 goto free_ap_extra_ies;
4241
4242 beacon->head_len = params.head_len;
4243
4244 beacon->tail = os_memdup(params.tail, params.tail_len);
4245 if (!beacon->tail)
4246 goto free_beacon;
4247
4248 beacon->tail_len = params.tail_len;
4249
4250 if (params.proberesp != NULL) {
4251 beacon->probe_resp = os_memdup(params.proberesp,
4252 params.proberesp_len);
4253 if (!beacon->probe_resp)
4254 goto free_beacon;
4255
4256 beacon->probe_resp_len = params.proberesp_len;
4257 }
4258
4259 /* copy the extra ies */
4260 if (beacon_extra) {
4261 beacon->beacon_ies = os_memdup(beacon_extra->buf,
4262 wpabuf_len(beacon_extra));
4263 if (!beacon->beacon_ies)
4264 goto free_beacon;
4265
4266 beacon->beacon_ies_len = wpabuf_len(beacon_extra);
4267 }
4268
4269 if (proberesp_extra) {
4270 beacon->proberesp_ies = os_memdup(proberesp_extra->buf,
4271 wpabuf_len(proberesp_extra));
4272 if (!beacon->proberesp_ies)
4273 goto free_beacon;
4274
4275 beacon->proberesp_ies_len = wpabuf_len(proberesp_extra);
4276 }
4277
4278 if (assocresp_extra) {
4279 beacon->assocresp_ies = os_memdup(assocresp_extra->buf,
4280 wpabuf_len(assocresp_extra));
4281 if (!beacon->assocresp_ies)
4282 goto free_beacon;
4283
4284 beacon->assocresp_ies_len = wpabuf_len(assocresp_extra);
4285 }
4286
4287 ret = 0;
4288 free_beacon:
4289 /* if the function fails, the caller should not free beacon data */
4290 if (ret)
4291 free_beacon_data(beacon);
4292
4293 free_ap_extra_ies:
4294 hostapd_free_ap_extra_ies(hapd, beacon_extra, proberesp_extra,
4295 assocresp_extra);
4296 free_ap_params:
4297 ieee802_11_free_ap_params(¶ms);
4298 return ret;
4299 }
4300
4301
4302 /*
4303 * TODO: This flow currently supports only changing channel and width within
4304 * the same hw_mode. Any other changes to MAC parameters or provided settings
4305 * are not supported.
4306 */
hostapd_change_config_freq(struct hostapd_data * hapd,struct hostapd_config * conf,struct hostapd_freq_params * params,struct hostapd_freq_params * old_params)4307 static int hostapd_change_config_freq(struct hostapd_data *hapd,
4308 struct hostapd_config *conf,
4309 struct hostapd_freq_params *params,
4310 struct hostapd_freq_params *old_params)
4311 {
4312 int channel;
4313 u8 seg0 = 0, seg1 = 0;
4314 struct hostapd_hw_modes *mode;
4315
4316 if (!params->channel) {
4317 /* check if the new channel is supported by hw */
4318 params->channel = hostapd_hw_get_channel(hapd, params->freq);
4319 }
4320
4321 channel = params->channel;
4322 if (!channel)
4323 return -1;
4324
4325 hostapd_determine_mode(hapd->iface);
4326 mode = hapd->iface->current_mode;
4327
4328 /* if a pointer to old_params is provided we save previous state */
4329 if (old_params &&
4330 hostapd_set_freq_params(old_params, conf->hw_mode,
4331 hostapd_hw_get_freq(hapd, conf->channel),
4332 conf->channel, conf->enable_edmg,
4333 conf->edmg_channel, conf->ieee80211n,
4334 conf->ieee80211ac, conf->ieee80211ax,
4335 conf->ieee80211be, conf->secondary_channel,
4336 hostapd_get_oper_chwidth(conf),
4337 hostapd_get_oper_centr_freq_seg0_idx(conf),
4338 hostapd_get_oper_centr_freq_seg1_idx(conf),
4339 conf->vht_capab,
4340 mode ? &mode->he_capab[IEEE80211_MODE_AP] :
4341 NULL,
4342 mode ? &mode->eht_capab[IEEE80211_MODE_AP] :
4343 NULL,
4344 hostapd_get_punct_bitmap(hapd)))
4345 return -1;
4346
4347 switch (params->bandwidth) {
4348 case 0:
4349 case 20:
4350 conf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
4351 break;
4352 case 40:
4353 case 80:
4354 case 160:
4355 case 320:
4356 conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
4357 break;
4358 default:
4359 return -1;
4360 }
4361
4362 switch (params->bandwidth) {
4363 case 0:
4364 case 20:
4365 case 40:
4366 hostapd_set_oper_chwidth(conf, CONF_OPER_CHWIDTH_USE_HT);
4367 break;
4368 case 80:
4369 if (params->center_freq2)
4370 hostapd_set_oper_chwidth(conf,
4371 CONF_OPER_CHWIDTH_80P80MHZ);
4372 else
4373 hostapd_set_oper_chwidth(conf,
4374 CONF_OPER_CHWIDTH_80MHZ);
4375 break;
4376 case 160:
4377 hostapd_set_oper_chwidth(conf, CONF_OPER_CHWIDTH_160MHZ);
4378 break;
4379 case 320:
4380 hostapd_set_oper_chwidth(conf, CONF_OPER_CHWIDTH_320MHZ);
4381 break;
4382 default:
4383 return -1;
4384 }
4385
4386 conf->channel = channel;
4387 conf->ieee80211n = params->ht_enabled;
4388 conf->ieee80211ac = params->vht_enabled;
4389 conf->secondary_channel = params->sec_channel_offset;
4390 if (params->center_freq1 &&
4391 ieee80211_freq_to_chan(params->center_freq1, &seg0) ==
4392 NUM_HOSTAPD_MODES)
4393 return -1;
4394 if (params->center_freq2 &&
4395 ieee80211_freq_to_chan(params->center_freq2,
4396 &seg1) == NUM_HOSTAPD_MODES)
4397 return -1;
4398 hostapd_set_oper_centr_freq_seg0_idx(conf, seg0);
4399 hostapd_set_oper_centr_freq_seg1_idx(conf, seg1);
4400
4401 /* TODO: maybe call here hostapd_config_check here? */
4402
4403 return 0;
4404 }
4405
4406
hostapd_fill_csa_settings(struct hostapd_data * hapd,struct csa_settings * settings)4407 static int hostapd_fill_csa_settings(struct hostapd_data *hapd,
4408 struct csa_settings *settings)
4409 {
4410 struct hostapd_iface *iface = hapd->iface;
4411 struct hostapd_freq_params old_freq;
4412 int ret;
4413 #ifdef CONFIG_IEEE80211BE
4414 u16 old_punct_bitmap;
4415 #endif /* CONFIG_IEEE80211BE */
4416 u8 chan, bandwidth;
4417
4418 os_memset(&old_freq, 0, sizeof(old_freq));
4419 if (!iface || !iface->freq || hapd->csa_in_progress)
4420 return -1;
4421
4422 switch (settings->freq_params.bandwidth) {
4423 case 80:
4424 if (settings->freq_params.center_freq2)
4425 bandwidth = CONF_OPER_CHWIDTH_80P80MHZ;
4426 else
4427 bandwidth = CONF_OPER_CHWIDTH_80MHZ;
4428 break;
4429 case 160:
4430 bandwidth = CONF_OPER_CHWIDTH_160MHZ;
4431 break;
4432 case 320:
4433 bandwidth = CONF_OPER_CHWIDTH_320MHZ;
4434 break;
4435 default:
4436 bandwidth = CONF_OPER_CHWIDTH_USE_HT;
4437 break;
4438 }
4439
4440 if (ieee80211_freq_to_channel_ext(
4441 settings->freq_params.freq,
4442 settings->freq_params.sec_channel_offset,
4443 bandwidth,
4444 &hapd->iface->cs_oper_class,
4445 &chan) == NUM_HOSTAPD_MODES) {
4446 wpa_printf(MSG_DEBUG,
4447 "invalid frequency for channel switch (freq=%d, sec_channel_offset=%d, vht_enabled=%d, he_enabled=%d, eht_enabled=%d)",
4448 settings->freq_params.freq,
4449 settings->freq_params.sec_channel_offset,
4450 settings->freq_params.vht_enabled,
4451 settings->freq_params.he_enabled,
4452 settings->freq_params.eht_enabled);
4453 return -1;
4454 }
4455
4456 settings->freq_params.channel = chan;
4457
4458 ret = hostapd_change_config_freq(iface->bss[0], iface->conf,
4459 &settings->freq_params,
4460 &old_freq);
4461 if (ret)
4462 return ret;
4463
4464 #ifdef CONFIG_IEEE80211BE
4465 old_punct_bitmap = iface->conf->punct_bitmap;
4466 iface->conf->punct_bitmap = settings->punct_bitmap;
4467 #endif /* CONFIG_IEEE80211BE */
4468 ret = hostapd_build_beacon_data(hapd, &settings->beacon_after);
4469
4470 /* change back the configuration */
4471 #ifdef CONFIG_IEEE80211BE
4472 iface->conf->punct_bitmap = old_punct_bitmap;
4473 #endif /* CONFIG_IEEE80211BE */
4474 hostapd_change_config_freq(iface->bss[0], iface->conf,
4475 &old_freq, NULL);
4476
4477 if (ret)
4478 return ret;
4479
4480 /* set channel switch parameters for csa ie */
4481 hapd->cs_freq_params = settings->freq_params;
4482 hapd->cs_count = settings->cs_count;
4483 hapd->cs_block_tx = settings->block_tx;
4484
4485 ret = hostapd_build_beacon_data(hapd, &settings->beacon_csa);
4486 if (ret) {
4487 free_beacon_data(&settings->beacon_after);
4488 return ret;
4489 }
4490
4491 settings->counter_offset_beacon[0] = hapd->cs_c_off_beacon;
4492 settings->counter_offset_presp[0] = hapd->cs_c_off_proberesp;
4493 settings->counter_offset_beacon[1] = hapd->cs_c_off_ecsa_beacon;
4494 settings->counter_offset_presp[1] = hapd->cs_c_off_ecsa_proberesp;
4495 settings->link_id = -1;
4496 #ifdef CONFIG_IEEE80211BE
4497 if (hapd->conf->mld_ap)
4498 settings->link_id = hapd->mld_link_id;
4499 #endif /* CONFIG_IEEE80211BE */
4500
4501 #ifdef CONFIG_IEEE80211AX
4502 settings->ubpr.unsol_bcast_probe_resp_tmpl =
4503 hostapd_unsol_bcast_probe_resp(hapd, &settings->ubpr);
4504 #endif /* CONFIG_IEEE80211AX */
4505
4506 return 0;
4507 }
4508
4509
hostapd_cleanup_cs_params(struct hostapd_data * hapd)4510 void hostapd_cleanup_cs_params(struct hostapd_data *hapd)
4511 {
4512 os_memset(&hapd->cs_freq_params, 0, sizeof(hapd->cs_freq_params));
4513 hapd->cs_count = 0;
4514 hapd->cs_block_tx = 0;
4515 hapd->cs_c_off_beacon = 0;
4516 hapd->cs_c_off_proberesp = 0;
4517 hapd->csa_in_progress = 0;
4518 hapd->cs_c_off_ecsa_beacon = 0;
4519 hapd->cs_c_off_ecsa_proberesp = 0;
4520 }
4521
4522
hostapd_chan_switch_config(struct hostapd_data * hapd,struct hostapd_freq_params * freq_params)4523 void hostapd_chan_switch_config(struct hostapd_data *hapd,
4524 struct hostapd_freq_params *freq_params)
4525 {
4526 if (freq_params->eht_enabled)
4527 hapd->iconf->ch_switch_eht_config |= CH_SWITCH_EHT_ENABLED;
4528 else
4529 hapd->iconf->ch_switch_eht_config |= CH_SWITCH_EHT_DISABLED;
4530
4531 if (freq_params->he_enabled)
4532 hapd->iconf->ch_switch_he_config |= CH_SWITCH_HE_ENABLED;
4533 else
4534 hapd->iconf->ch_switch_he_config |= CH_SWITCH_HE_DISABLED;
4535
4536 if (freq_params->vht_enabled)
4537 hapd->iconf->ch_switch_vht_config |= CH_SWITCH_VHT_ENABLED;
4538 else
4539 hapd->iconf->ch_switch_vht_config |= CH_SWITCH_VHT_DISABLED;
4540
4541 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
4542 HOSTAPD_LEVEL_INFO,
4543 "CHAN_SWITCH EHT config 0x%x HE config 0x%x VHT config 0x%x",
4544 hapd->iconf->ch_switch_eht_config,
4545 hapd->iconf->ch_switch_he_config,
4546 hapd->iconf->ch_switch_vht_config);
4547 }
4548
4549
hostapd_switch_channel(struct hostapd_data * hapd,struct csa_settings * settings)4550 int hostapd_switch_channel(struct hostapd_data *hapd,
4551 struct csa_settings *settings)
4552 {
4553 int ret;
4554
4555 if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA)) {
4556 wpa_printf(MSG_INFO, "CSA is not supported");
4557 return -1;
4558 }
4559
4560 ret = hostapd_fill_csa_settings(hapd, settings);
4561 if (ret)
4562 return ret;
4563
4564 ret = hostapd_drv_switch_channel(hapd, settings);
4565 free_beacon_data(&settings->beacon_csa);
4566 free_beacon_data(&settings->beacon_after);
4567 #ifdef CONFIG_IEEE80211AX
4568 os_free(settings->ubpr.unsol_bcast_probe_resp_tmpl);
4569 #endif /* CONFIG_IEEE80211AX */
4570
4571 if (ret) {
4572 /* if we failed, clean cs parameters */
4573 hostapd_cleanup_cs_params(hapd);
4574 return ret;
4575 }
4576
4577 hapd->csa_in_progress = 1;
4578 return 0;
4579 }
4580
4581
4582 void
hostapd_switch_channel_fallback(struct hostapd_iface * iface,const struct hostapd_freq_params * freq_params)4583 hostapd_switch_channel_fallback(struct hostapd_iface *iface,
4584 const struct hostapd_freq_params *freq_params)
4585 {
4586 u8 seg0_idx = 0, seg1_idx = 0;
4587 enum oper_chan_width bw = CONF_OPER_CHWIDTH_USE_HT;
4588 u8 op_class, chan = 0;
4589
4590 wpa_printf(MSG_DEBUG, "Restarting all CSA-related BSSes");
4591
4592 if (freq_params->center_freq1)
4593 ieee80211_freq_to_chan(freq_params->center_freq1, &seg0_idx);
4594 if (freq_params->center_freq2)
4595 ieee80211_freq_to_chan(freq_params->center_freq2, &seg1_idx);
4596
4597 switch (freq_params->bandwidth) {
4598 case 0:
4599 case 20:
4600 case 40:
4601 bw = CONF_OPER_CHWIDTH_USE_HT;
4602 break;
4603 case 80:
4604 if (freq_params->center_freq2) {
4605 bw = CONF_OPER_CHWIDTH_80P80MHZ;
4606 iface->conf->vht_capab |=
4607 VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
4608 } else {
4609 bw = CONF_OPER_CHWIDTH_80MHZ;
4610 }
4611 break;
4612 case 160:
4613 bw = CONF_OPER_CHWIDTH_160MHZ;
4614 iface->conf->vht_capab |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
4615 break;
4616 case 320:
4617 bw = CONF_OPER_CHWIDTH_320MHZ;
4618 break;
4619 default:
4620 wpa_printf(MSG_WARNING, "Unknown CSA bandwidth: %d",
4621 freq_params->bandwidth);
4622 break;
4623 }
4624
4625 iface->freq = freq_params->freq;
4626 iface->conf->channel = freq_params->channel;
4627 iface->conf->secondary_channel = freq_params->sec_channel_offset;
4628 if (ieee80211_freq_to_channel_ext(freq_params->freq,
4629 freq_params->sec_channel_offset, bw,
4630 &op_class, &chan) ==
4631 NUM_HOSTAPD_MODES ||
4632 chan != freq_params->channel)
4633 wpa_printf(MSG_INFO, "CSA: Channel mismatch: %d -> %d",
4634 freq_params->channel, chan);
4635
4636 iface->conf->op_class = op_class;
4637 hostapd_set_oper_centr_freq_seg0_idx(iface->conf, seg0_idx);
4638 hostapd_set_oper_centr_freq_seg1_idx(iface->conf, seg1_idx);
4639 hostapd_set_oper_chwidth(iface->conf, bw);
4640 iface->conf->ieee80211n = freq_params->ht_enabled;
4641 iface->conf->ieee80211ac = freq_params->vht_enabled;
4642 iface->conf->ieee80211ax = freq_params->he_enabled;
4643 iface->conf->ieee80211be = freq_params->eht_enabled;
4644
4645 /*
4646 * cs_params must not be cleared earlier because the freq_params
4647 * argument may actually point to one of these.
4648 * These params will be cleared during interface disable below.
4649 */
4650 hostapd_disable_iface(iface);
4651 hostapd_enable_iface(iface);
4652 }
4653
4654
4655 #ifdef CONFIG_IEEE80211AX
4656
hostapd_cleanup_cca_params(struct hostapd_data * hapd)4657 void hostapd_cleanup_cca_params(struct hostapd_data *hapd)
4658 {
4659 hapd->cca_count = 0;
4660 hapd->cca_color = 0;
4661 hapd->cca_c_off_beacon = 0;
4662 hapd->cca_c_off_proberesp = 0;
4663 hapd->cca_in_progress = false;
4664 }
4665
4666
hostapd_fill_cca_settings(struct hostapd_data * hapd,struct cca_settings * settings)4667 int hostapd_fill_cca_settings(struct hostapd_data *hapd,
4668 struct cca_settings *settings)
4669 {
4670 struct hostapd_iface *iface = hapd->iface;
4671 u8 old_color;
4672 int ret;
4673
4674 if (!iface || iface->conf->he_op.he_bss_color_disabled)
4675 return -1;
4676
4677 settings->link_id = -1;
4678 #ifdef CONFIG_IEEE80211BE
4679 if (hapd->conf->mld_ap)
4680 settings->link_id = hapd->mld_link_id;
4681 #endif /* CONFIG_IEEE80211BE */
4682
4683 old_color = iface->conf->he_op.he_bss_color;
4684 iface->conf->he_op.he_bss_color = hapd->cca_color;
4685 ret = hostapd_build_beacon_data(hapd, &settings->beacon_after);
4686 if (ret)
4687 return ret;
4688
4689 iface->conf->he_op.he_bss_color = old_color;
4690
4691 settings->cca_count = hapd->cca_count;
4692 settings->cca_color = hapd->cca_color,
4693 hapd->cca_in_progress = true;
4694
4695 ret = hostapd_build_beacon_data(hapd, &settings->beacon_cca);
4696 if (ret) {
4697 free_beacon_data(&settings->beacon_after);
4698 return ret;
4699 }
4700
4701 settings->ubpr.unsol_bcast_probe_resp_tmpl =
4702 hostapd_unsol_bcast_probe_resp(hapd, &settings->ubpr);
4703
4704 settings->counter_offset_beacon = hapd->cca_c_off_beacon;
4705 settings->counter_offset_presp = hapd->cca_c_off_proberesp;
4706
4707 return 0;
4708 }
4709
4710
hostapd_switch_color_timeout_handler(void * eloop_data,void * user_ctx)4711 static void hostapd_switch_color_timeout_handler(void *eloop_data,
4712 void *user_ctx)
4713 {
4714 struct hostapd_data *hapd = (struct hostapd_data *) eloop_data;
4715 os_time_t delta_t;
4716 unsigned int b;
4717 int i, r;
4718
4719 /* CCA can be triggered once the handler constantly receives
4720 * color collision events to for at least
4721 * DOT11BSS_COLOR_COLLISION_AP_PERIOD (50 s by default). */
4722 delta_t = hapd->last_color_collision.sec -
4723 hapd->first_color_collision.sec;
4724 if (delta_t < DOT11BSS_COLOR_COLLISION_AP_PERIOD)
4725 return;
4726
4727 r = os_random() % HE_OPERATION_BSS_COLOR_MAX;
4728 for (i = 0; i < HE_OPERATION_BSS_COLOR_MAX; i++) {
4729 if (r && !(hapd->color_collision_bitmap & (1ULL << r)))
4730 break;
4731
4732 r = (r + 1) % HE_OPERATION_BSS_COLOR_MAX;
4733 }
4734
4735 if (i == HE_OPERATION_BSS_COLOR_MAX) {
4736 /* There are no free colors so turn BSS coloring off */
4737 wpa_printf(MSG_INFO,
4738 "No free colors left, turning off BSS coloring");
4739 hapd->iface->conf->he_op.he_bss_color_disabled = 1;
4740 hapd->iface->conf->he_op.he_bss_color = os_random() % 63 + 1;
4741 for (b = 0; b < hapd->iface->num_bss; b++)
4742 ieee802_11_set_beacon(hapd->iface->bss[b]);
4743 return;
4744 }
4745
4746 for (b = 0; b < hapd->iface->num_bss; b++) {
4747 struct hostapd_data *bss = hapd->iface->bss[b];
4748 struct cca_settings settings;
4749 int ret;
4750
4751 hostapd_cleanup_cca_params(bss);
4752 bss->cca_color = r;
4753 bss->cca_count = 10;
4754
4755 if (hostapd_fill_cca_settings(bss, &settings)) {
4756 hostapd_cleanup_cca_params(bss);
4757 continue;
4758 }
4759
4760 ret = hostapd_drv_switch_color(bss, &settings);
4761 if (ret)
4762 hostapd_cleanup_cca_params(bss);
4763
4764 free_beacon_data(&settings.beacon_cca);
4765 free_beacon_data(&settings.beacon_after);
4766 os_free(settings.ubpr.unsol_bcast_probe_resp_tmpl);
4767 }
4768 }
4769
4770
hostapd_switch_color(struct hostapd_data * hapd,u64 bitmap)4771 void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap)
4772 {
4773 struct os_reltime now;
4774
4775 if (hapd->cca_in_progress)
4776 return;
4777
4778 if (os_get_reltime(&now))
4779 return;
4780
4781 hapd->color_collision_bitmap = bitmap;
4782 hapd->last_color_collision = now;
4783
4784 if (eloop_is_timeout_registered(hostapd_switch_color_timeout_handler,
4785 hapd, NULL))
4786 return;
4787
4788 hapd->first_color_collision = now;
4789 /* 10 s window as margin for persistent color collision reporting */
4790 eloop_register_timeout(DOT11BSS_COLOR_COLLISION_AP_PERIOD + 10, 0,
4791 hostapd_switch_color_timeout_handler,
4792 hapd, NULL);
4793 }
4794
4795 #endif /* CONFIG_IEEE80211AX */
4796
4797 #endif /* NEED_AP_MLME */
4798
4799
hostapd_get_iface(struct hapd_interfaces * interfaces,const char * ifname)4800 struct hostapd_data * hostapd_get_iface(struct hapd_interfaces *interfaces,
4801 const char *ifname)
4802 {
4803 size_t i, j;
4804
4805 for (i = 0; i < interfaces->count; i++) {
4806 struct hostapd_iface *iface = interfaces->iface[i];
4807
4808 for (j = 0; j < iface->num_bss; j++) {
4809 struct hostapd_data *hapd = iface->bss[j];
4810
4811 if (os_strcmp(ifname, hapd->conf->iface) == 0)
4812 return hapd;
4813 }
4814 }
4815
4816 return NULL;
4817 }
4818
4819
hostapd_periodic_iface(struct hostapd_iface * iface)4820 void hostapd_periodic_iface(struct hostapd_iface *iface)
4821 {
4822 size_t i;
4823
4824 ap_list_timer(iface);
4825
4826 for (i = 0; i < iface->num_bss; i++) {
4827 struct hostapd_data *hapd = iface->bss[i];
4828
4829 if (!hapd->started)
4830 continue;
4831
4832 #ifndef CONFIG_NO_RADIUS
4833 hostapd_acl_expire(hapd);
4834 #endif /* CONFIG_NO_RADIUS */
4835 }
4836 }
4837
4838
4839 #ifdef CONFIG_OCV
hostapd_ocv_check_csa_sa_query(void * eloop_ctx,void * timeout_ctx)4840 void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx)
4841 {
4842 struct hostapd_data *hapd = eloop_ctx;
4843 struct sta_info *sta;
4844
4845 wpa_printf(MSG_DEBUG, "OCV: Post-CSA SA Query initiation check");
4846
4847 for (sta = hapd->sta_list; sta; sta = sta->next) {
4848 if (!sta->post_csa_sa_query)
4849 continue;
4850
4851 wpa_printf(MSG_DEBUG, "OCV: OCVC STA " MACSTR_SEC
4852 " did not start SA Query after CSA - disconnect",
4853 MAC2STR_SEC(sta->addr));
4854 ap_sta_disconnect(hapd, sta, sta->addr,
4855 WLAN_REASON_PREV_AUTH_NOT_VALID);
4856 }
4857 }
4858 #endif /* CONFIG_OCV */
4859
4860
4861 #ifdef CONFIG_IEEE80211BE
4862
hostapd_mld_get_link_bss(struct hostapd_data * hapd,u8 link_id)4863 struct hostapd_data * hostapd_mld_get_link_bss(struct hostapd_data *hapd,
4864 u8 link_id)
4865 {
4866 struct hostapd_iface *iface;
4867 struct hostapd_data *bss;
4868 unsigned int i, j;
4869
4870 for (i = 0; i < hapd->iface->interfaces->count; i++) {
4871 iface = hapd->iface->interfaces->iface[i];
4872 if (!iface)
4873 continue;
4874
4875 for (j = 0; j < iface->num_bss; j++) {
4876 bss = iface->bss[j];
4877
4878 if (!bss->conf->mld_ap ||
4879 !hostapd_is_ml_partner(hapd, bss))
4880 continue;
4881
4882 if (!bss->drv_priv)
4883 continue;
4884
4885 if (bss->mld_link_id == link_id)
4886 return bss;
4887 }
4888 }
4889
4890 return NULL;
4891 }
4892
4893
hostapd_is_ml_partner(struct hostapd_data * hapd1,struct hostapd_data * hapd2)4894 bool hostapd_is_ml_partner(struct hostapd_data *hapd1,
4895 struct hostapd_data *hapd2)
4896 {
4897 if (!hapd1->conf->mld_ap || !hapd2->conf->mld_ap)
4898 return false;
4899
4900 return !os_strcmp(hapd1->conf->iface, hapd2->conf->iface);
4901 }
4902
4903
hostapd_get_mld_id(struct hostapd_data * hapd)4904 u8 hostapd_get_mld_id(struct hostapd_data *hapd)
4905 {
4906 if (!hapd->conf->mld_ap)
4907 return 255;
4908
4909 /* MLD ID 0 represents self */
4910 return 0;
4911
4912 /* TODO: MLD ID for Multiple BSS cases */
4913 }
4914
4915
hostapd_mld_add_link(struct hostapd_data * hapd)4916 int hostapd_mld_add_link(struct hostapd_data *hapd)
4917 {
4918 struct hostapd_mld *mld = hapd->mld;
4919
4920 if (!hapd->conf->mld_ap)
4921 return 0;
4922
4923 /* Should not happen */
4924 if (!mld)
4925 return -1;
4926
4927 dl_list_add_tail(&mld->links, &hapd->link);
4928 mld->num_links++;
4929
4930 wpa_printf(MSG_DEBUG, "AP MLD %s: Link ID %d added. num_links: %d",
4931 mld->name, hapd->mld_link_id, mld->num_links);
4932
4933 if (mld->fbss)
4934 return 0;
4935
4936 mld->fbss = hapd;
4937 wpa_printf(MSG_DEBUG, "AP MLD %s: First link BSS set to %p",
4938 mld->name, mld->fbss);
4939 return 0;
4940 }
4941
4942
hostapd_mld_remove_link(struct hostapd_data * hapd)4943 int hostapd_mld_remove_link(struct hostapd_data *hapd)
4944 {
4945 struct hostapd_mld *mld = hapd->mld;
4946 struct hostapd_data *next_fbss;
4947
4948 if (!hapd->conf->mld_ap)
4949 return 0;
4950
4951 /* Should not happen */
4952 if (!mld)
4953 return -1;
4954
4955 dl_list_del(&hapd->link);
4956 mld->num_links--;
4957
4958 wpa_printf(MSG_DEBUG, "AP MLD %s: Link ID %d removed. num_links: %d",
4959 mld->name, hapd->mld_link_id, mld->num_links);
4960
4961 if (mld->fbss != hapd)
4962 return 0;
4963
4964 /* If the list is empty, all links are removed */
4965 if (dl_list_empty(&mld->links)) {
4966 mld->fbss = NULL;
4967 } else {
4968 next_fbss = dl_list_entry(mld->links.next, struct hostapd_data,
4969 link);
4970 mld->fbss = next_fbss;
4971 }
4972
4973 wpa_printf(MSG_DEBUG, "AP MLD %s: First link BSS set to %p",
4974 mld->name, mld->fbss);
4975 return 0;
4976 }
4977
4978
hostapd_mld_is_first_bss(struct hostapd_data * hapd)4979 bool hostapd_mld_is_first_bss(struct hostapd_data *hapd)
4980 {
4981 struct hostapd_mld *mld = hapd->mld;
4982
4983 if (!hapd->conf->mld_ap)
4984 return true;
4985
4986 /* Should not happen */
4987 if (!mld)
4988 return false;
4989
4990 /* If fbss is not set, it is safe to assume the caller is the first BSS.
4991 */
4992 if (!mld->fbss)
4993 return true;
4994
4995 return hapd == mld->fbss;
4996 }
4997
4998
hostapd_mld_get_first_bss(struct hostapd_data * hapd)4999 struct hostapd_data * hostapd_mld_get_first_bss(struct hostapd_data *hapd)
5000 {
5001 struct hostapd_mld *mld = hapd->mld;
5002
5003 if (!hapd->conf->mld_ap)
5004 return NULL;
5005
5006 /* Should not happen */
5007 if (!mld)
5008 return NULL;
5009
5010 return mld->fbss;
5011 }
5012
5013 #endif /* CONFIG_IEEE80211BE */
5014
5015
hostapd_get_punct_bitmap(struct hostapd_data * hapd)5016 u16 hostapd_get_punct_bitmap(struct hostapd_data *hapd)
5017 {
5018 u16 punct_bitmap = 0;
5019
5020 #ifdef CONFIG_IEEE80211BE
5021 punct_bitmap = hapd->iconf->punct_bitmap;
5022 #ifdef CONFIG_TESTING_OPTIONS
5023 if (!punct_bitmap)
5024 punct_bitmap = hapd->conf->eht_oper_puncturing_override;
5025 #endif /* CONFIG_TESTING_OPTIONS */
5026 #endif /* CONFIG_IEEE80211BE */
5027
5028 return punct_bitmap;
5029 }
5030