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 #ifdef CONFIG_OPEN_HARMONY_PATCH
hostapd_set_freq_failure_workround(struct hostapd_data * hapd,int freq)2494 static int hostapd_set_freq_failure_workround(struct hostapd_data *hapd, int freq)
2495 {
2496 if (hapd->iconf->ieee80211ac && hapd->iconf->vht_oper_chwidth) {
2497 hapd->iconf->ieee80211ac = 0;
2498 hapd->iconf->ieee80211ax = 0;
2499 hapd->iconf->ieee80211be = 0;
2500 hapd->iconf->secondary_channel = 0;
2501 hapd->iconf->vht_oper_chwidth = 0;
2502 hapd->iconf->vht_oper_centr_freq_seg0_idx = 0;
2503 hapd->iconf->vht_oper_centr_freq_seg1_idx = 0;
2504
2505 return hostapd_set_freq(hapd, hapd->iconf->hw_mode, freq,
2506 hapd->iconf->channel,
2507 hapd->iconf->enable_edmg,
2508 hapd->iconf->edmg_channel,
2509 hapd->iconf->ieee80211n,
2510 hapd->iconf->ieee80211ac,
2511 hapd->iconf->ieee80211ax,
2512 hapd->iconf->ieee80211be,
2513 hapd->iconf->secondary_channel,
2514 hapd->iconf->vht_oper_chwidth,
2515 hapd->iconf->vht_oper_centr_freq_seg0_idx,
2516 hapd->iconf->vht_oper_centr_freq_seg1_idx);
2517 }
2518
2519 return -1;
2520 }
2521 #endif
2522
hostapd_setup_interface_complete_sync(struct hostapd_iface * iface,int err)2523 static int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface,
2524 int err)
2525 {
2526 struct hostapd_data *hapd = iface->bss[0];
2527 size_t j;
2528 u8 *prev_addr;
2529 int delay_apply_cfg = 0;
2530 int res_dfs_offload = 0;
2531 #ifdef CONFIG_LIBWPA_VENDOR
2532 size_t contentLen;
2533 struct HostapdApCbParm hostapdApCbParm = {};
2534 hostapdApCbParm.id = 0;
2535 #endif
2536
2537 if (err)
2538 goto fail;
2539
2540 wpa_printf(MSG_DEBUG, "Completing interface initialization");
2541 if (iface->freq) {
2542 #ifdef NEED_AP_MLME
2543 int res;
2544 #endif /* NEED_AP_MLME */
2545
2546 wpa_printf(MSG_DEBUG, "Mode: %s Channel: %d "
2547 "Frequency: %d MHz",
2548 hostapd_hw_mode_txt(iface->conf->hw_mode),
2549 iface->conf->channel, iface->freq);
2550
2551 #ifdef NEED_AP_MLME
2552 /* Handle DFS only if it is not offloaded to the driver */
2553 if (!(iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)) {
2554 /* Check DFS */
2555 res = hostapd_handle_dfs(iface);
2556 if (res <= 0) {
2557 if (res < 0)
2558 goto fail;
2559 return res;
2560 }
2561 } else {
2562 /* If DFS is offloaded to the driver */
2563 res_dfs_offload = hostapd_handle_dfs_offload(iface);
2564 if (res_dfs_offload <= 0) {
2565 if (res_dfs_offload < 0)
2566 goto fail;
2567 } else {
2568 wpa_printf(MSG_EXCESSIVE,
2569 "Proceed with AP/channel setup");
2570 /*
2571 * If this is a DFS channel, move to completing
2572 * AP setup.
2573 */
2574 if (res_dfs_offload == 1)
2575 goto dfs_offload;
2576 /* Otherwise fall through. */
2577 }
2578 }
2579 #endif /* NEED_AP_MLME */
2580
2581 #ifdef CONFIG_MESH
2582 if (iface->mconf != NULL) {
2583 wpa_printf(MSG_DEBUG,
2584 "%s: Mesh configuration will be applied while joining the mesh network",
2585 iface->bss[0]->conf->iface);
2586 delay_apply_cfg = 1;
2587 }
2588 #endif /* CONFIG_MESH */
2589
2590 if (!delay_apply_cfg &&
2591 hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq,
2592 hapd->iconf->channel,
2593 hapd->iconf->enable_edmg,
2594 hapd->iconf->edmg_channel,
2595 hapd->iconf->ieee80211n,
2596 hapd->iconf->ieee80211ac,
2597 hapd->iconf->ieee80211ax,
2598 hapd->iconf->ieee80211be,
2599 hapd->iconf->secondary_channel,
2600 hostapd_get_oper_chwidth(hapd->iconf),
2601 hostapd_get_oper_centr_freq_seg0_idx(
2602 hapd->iconf),
2603 hostapd_get_oper_centr_freq_seg1_idx(
2604 hapd->iconf))) {
2605 wpa_printf(MSG_ERROR, "Could not set channel for "
2606 "kernel driver");
2607 #ifdef CONFIG_OPEN_HARMONY_PATCH
2608 if (hostapd_set_freq_failure_workround(hapd, iface->freq)) {
2609 wpa_printf(MSG_ERROR, "set channel %u failed", hapd->iconf->channel);
2610 goto fail;
2611 }
2612 #else
2613 goto fail;
2614 #endif
2615 }
2616 }
2617
2618 if (iface->current_mode) {
2619 if (hostapd_prepare_rates(iface, iface->current_mode)) {
2620 wpa_printf(MSG_ERROR, "Failed to prepare rates "
2621 "table.");
2622 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
2623 HOSTAPD_LEVEL_WARNING,
2624 "Failed to prepare rates table.");
2625 goto fail;
2626 }
2627 }
2628
2629 if (hapd->iconf->rts_threshold >= -1 &&
2630 hostapd_set_rts(hapd, hapd->iconf->rts_threshold) &&
2631 hapd->iconf->rts_threshold >= -1) {
2632 wpa_printf(MSG_ERROR, "Could not set RTS threshold for "
2633 "kernel driver");
2634 goto fail;
2635 }
2636
2637 if (hapd->iconf->fragm_threshold >= -1 &&
2638 hostapd_set_frag(hapd, hapd->iconf->fragm_threshold) &&
2639 hapd->iconf->fragm_threshold != -1) {
2640 wpa_printf(MSG_ERROR, "Could not set fragmentation threshold "
2641 "for kernel driver");
2642 goto fail;
2643 }
2644
2645 prev_addr = hapd->own_addr;
2646
2647 for (j = 0; j < iface->num_bss; j++) {
2648 hapd = iface->bss[j];
2649 if (j)
2650 os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN);
2651 if (hostapd_setup_bss(hapd, j == 0, !iface->conf->mbssid)) {
2652 for (;;) {
2653 hapd = iface->bss[j];
2654 hostapd_bss_deinit_no_free(hapd);
2655 hostapd_free_hapd_data(hapd);
2656 if (j == 0)
2657 break;
2658 j--;
2659 }
2660 goto fail;
2661 }
2662 if (is_zero_ether_addr(hapd->conf->bssid))
2663 prev_addr = hapd->own_addr;
2664 }
2665
2666 if (hapd->iconf->mbssid) {
2667 for (j = 0; hapd->iconf->mbssid && j < iface->num_bss; j++) {
2668 hapd = iface->bss[j];
2669 if (hostapd_start_beacon(hapd, true)) {
2670 for (;;) {
2671 hapd = iface->bss[j];
2672 hostapd_bss_deinit_no_free(hapd);
2673 hostapd_free_hapd_data(hapd);
2674 if (j == 0)
2675 break;
2676 j--;
2677 }
2678 goto fail;
2679 }
2680 }
2681 }
2682
2683 hapd = iface->bss[0];
2684
2685 hostapd_tx_queue_params(iface);
2686
2687 ap_list_init(iface);
2688
2689 hostapd_set_acl(hapd);
2690
2691 if (hostapd_driver_commit(hapd) < 0) {
2692 wpa_printf(MSG_ERROR, "%s: Failed to commit driver "
2693 "configuration", __func__);
2694 goto fail;
2695 }
2696
2697 /*
2698 * WPS UPnP module can be initialized only when the "upnp_iface" is up.
2699 * If "interface" and "upnp_iface" are the same (e.g., non-bridge
2700 * mode), the interface is up only after driver_commit, so initialize
2701 * WPS after driver_commit.
2702 */
2703 for (j = 0; j < iface->num_bss; j++) {
2704 if (hostapd_init_wps_complete(iface->bss[j]))
2705 goto fail;
2706 }
2707
2708 if ((iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
2709 !res_dfs_offload) {
2710 /*
2711 * If freq is DFS, and DFS is offloaded to the driver, then wait
2712 * for CAC to complete.
2713 */
2714 wpa_printf(MSG_DEBUG, "%s: Wait for CAC to complete", __func__);
2715 return res_dfs_offload;
2716 }
2717
2718 #ifdef NEED_AP_MLME
2719 dfs_offload:
2720 #endif /* NEED_AP_MLME */
2721
2722 #ifdef CONFIG_FST
2723 if (hapd->iconf->fst_cfg.group_id[0]) {
2724 struct fst_wpa_obj iface_obj;
2725
2726 fst_hostapd_fill_iface_obj(hapd, &iface_obj);
2727 iface->fst = fst_attach(hapd->conf->iface, hapd->own_addr,
2728 &iface_obj, &hapd->iconf->fst_cfg);
2729 if (!iface->fst) {
2730 wpa_printf(MSG_ERROR, "Could not attach to FST %s",
2731 hapd->iconf->fst_cfg.group_id);
2732 goto fail;
2733 }
2734 }
2735 #endif /* CONFIG_FST */
2736
2737 hostapd_set_state(iface, HAPD_IFACE_ENABLED);
2738 hostapd_owe_update_trans(iface);
2739 airtime_policy_update_init(iface);
2740 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_ENABLED);
2741 #ifdef CONFIG_LIBWPA_VENDOR
2742 contentLen = strlen(AP_EVENT_ENABLED);
2743 os_memcpy(hostapdApCbParm.content, AP_EVENT_ENABLED, contentLen);
2744 hostapdApCbParm.content[contentLen] = '\0';
2745 wpa_printf(MSG_INFO, "%s HOSTAPD_EVENT_AP_STATE %s%d", __func__, hostapdApCbParm.content, hostapdApCbParm.id);
2746 HostapdEventReport(iface->bss[0]->conf->iface, HOSTAPD_EVENT_AP_STATE, (void *) &hostapdApCbParm);
2747 #endif
2748 if (hapd->setup_complete_cb)
2749 hapd->setup_complete_cb(hapd->setup_complete_cb_ctx);
2750
2751 #ifdef CONFIG_MESH
2752 if (delay_apply_cfg && !iface->mconf) {
2753 wpa_printf(MSG_ERROR, "Error while completing mesh init");
2754 goto fail;
2755 }
2756 #endif /* CONFIG_MESH */
2757
2758 wpa_printf(MSG_INFO, "%s: Setup of interface done.",
2759 iface->bss[0]->conf->iface);
2760 if (iface->interfaces && iface->interfaces->terminate_on_error > 0)
2761 iface->interfaces->terminate_on_error--;
2762
2763 for (j = 0; j < iface->num_bss; j++)
2764 hostapd_neighbor_set_own_report(iface->bss[j]);
2765
2766 if (iface->interfaces && iface->interfaces->count > 1)
2767 ieee802_11_set_beacons(iface);
2768
2769 return 0;
2770
2771 fail:
2772 wpa_printf(MSG_ERROR, "Interface initialization failed");
2773
2774 if (iface->is_no_ir) {
2775 hostapd_set_state(iface, HAPD_IFACE_NO_IR);
2776 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_NO_IR);
2777 return 0;
2778 }
2779
2780 hostapd_set_state(iface, HAPD_IFACE_DISABLED);
2781 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
2782 #ifdef CONFIG_LIBWPA_VENDOR
2783 contentLen = strlen(AP_EVENT_DISABLED);
2784 os_memset(&hostapdApCbParm, 0, sizeof(hostapdApCbParm));
2785 os_memcpy(hostapdApCbParm.content, AP_EVENT_DISABLED, contentLen);
2786 hostapdApCbParm.content[contentLen] = '\0';
2787 wpa_printf(MSG_INFO, "%s HOSTAPD_EVENT_AP_STATE %s%d", __func__, hostapdApCbParm.content, hostapdApCbParm.id);
2788 HostapdEventReport(hapd->conf->iface, HOSTAPD_EVENT_AP_STATE, (void *) &hostapdApCbParm);
2789 #endif
2790 #ifdef CONFIG_FST
2791 if (iface->fst) {
2792 fst_detach(iface->fst);
2793 iface->fst = NULL;
2794 }
2795 #endif /* CONFIG_FST */
2796
2797 if (iface->interfaces && iface->interfaces->terminate_on_error) {
2798 eloop_terminate();
2799 } else if (hapd->setup_complete_cb) {
2800 /*
2801 * Calling hapd->setup_complete_cb directly may cause iface
2802 * deinitialization which may be accessed later by the caller.
2803 */
2804 eloop_register_timeout(0, 0,
2805 hostapd_interface_setup_failure_handler,
2806 iface, NULL);
2807 }
2808
2809 return -1;
2810 }
2811
2812
2813 /**
2814 * hostapd_setup_interface_complete - Complete interface setup
2815 *
2816 * This function is called when previous steps in the interface setup has been
2817 * completed. This can also start operations, e.g., DFS, that will require
2818 * additional processing before interface is ready to be enabled. Such
2819 * operations will call this function from eloop callbacks when finished.
2820 */
hostapd_setup_interface_complete(struct hostapd_iface * iface,int err)2821 int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)
2822 {
2823 struct hapd_interfaces *interfaces = iface->interfaces;
2824 struct hostapd_data *hapd = iface->bss[0];
2825 unsigned int i;
2826 int not_ready_in_sync_ifaces = 0;
2827
2828 if (!iface->need_to_start_in_sync)
2829 return hostapd_setup_interface_complete_sync(iface, err);
2830
2831 if (err) {
2832 wpa_printf(MSG_ERROR, "Interface initialization failed");
2833 iface->need_to_start_in_sync = 0;
2834
2835 if (iface->is_no_ir) {
2836 hostapd_set_state(iface, HAPD_IFACE_NO_IR);
2837 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_NO_IR);
2838 return 0;
2839 }
2840
2841 hostapd_set_state(iface, HAPD_IFACE_DISABLED);
2842 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
2843 #ifdef CONFIG_LIBWPA_VENDOR
2844 struct HostapdApCbParm hostapdApCbParm = {};
2845 size_t contentLen = strlen(AP_EVENT_DISABLED);
2846 os_memcpy(hostapdApCbParm.content, AP_EVENT_DISABLED, contentLen);
2847 hostapdApCbParm.content[contentLen] = '\0';
2848 hostapdApCbParm.id = 0;
2849 wpa_printf(MSG_INFO, "%s HOSTAPD_EVENT_AP_STATE %s%d", __func__, hostapdApCbParm.content, hostapdApCbParm.id);
2850 HostapdEventReport(hapd->conf->iface, HOSTAPD_EVENT_AP_STATE, (void *) &hostapdApCbParm);
2851 #endif
2852 if (interfaces && interfaces->terminate_on_error)
2853 eloop_terminate();
2854 return -1;
2855 }
2856
2857 if (iface->ready_to_start_in_sync) {
2858 /* Already in ready and waiting. should never happpen */
2859 return 0;
2860 }
2861
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 not_ready_in_sync_ifaces++;
2866 }
2867
2868 /*
2869 * Check if this is the last interface, if yes then start all the other
2870 * waiting interfaces. If not, add this interface to the waiting list.
2871 */
2872 if (not_ready_in_sync_ifaces > 1 && iface->state == HAPD_IFACE_DFS) {
2873 /*
2874 * If this interface went through CAC, do not synchronize, just
2875 * start immediately.
2876 */
2877 iface->need_to_start_in_sync = 0;
2878 wpa_printf(MSG_INFO,
2879 "%s: Finished CAC - bypass sync and start interface",
2880 iface->bss[0]->conf->iface);
2881 return hostapd_setup_interface_complete_sync(iface, err);
2882 }
2883
2884 if (not_ready_in_sync_ifaces > 1) {
2885 /* need to wait as there are other interfaces still coming up */
2886 iface->ready_to_start_in_sync = 1;
2887 wpa_printf(MSG_INFO,
2888 "%s: Interface waiting to sync with other interfaces",
2889 iface->bss[0]->conf->iface);
2890 return 0;
2891 }
2892
2893 wpa_printf(MSG_INFO,
2894 "%s: Last interface to sync - starting all interfaces",
2895 iface->bss[0]->conf->iface);
2896 iface->need_to_start_in_sync = 0;
2897 hostapd_setup_interface_complete_sync(iface, err);
2898 for (i = 0; i < interfaces->count; i++) {
2899 if (interfaces->iface[i]->need_to_start_in_sync &&
2900 interfaces->iface[i]->ready_to_start_in_sync) {
2901 hostapd_setup_interface_complete_sync(
2902 interfaces->iface[i], 0);
2903 /* Only once the interfaces are sync started */
2904 interfaces->iface[i]->need_to_start_in_sync = 0;
2905 }
2906 }
2907
2908 return 0;
2909 }
2910
2911
2912 /**
2913 * hostapd_setup_interface - Setup of an interface
2914 * @iface: Pointer to interface data.
2915 * Returns: 0 on success, -1 on failure
2916 *
2917 * Initializes the driver interface, validates the configuration,
2918 * and sets driver parameters based on the configuration.
2919 * Flushes old stations, sets the channel, encryption,
2920 * beacons, and WDS links based on the configuration.
2921 *
2922 * If interface setup requires more time, e.g., to perform HT co-ex scans, ACS,
2923 * or DFS operations, this function returns 0 before such operations have been
2924 * completed. The pending operations are registered into eloop and will be
2925 * completed from eloop callbacks. Those callbacks end up calling
2926 * hostapd_setup_interface_complete() once setup has been completed.
2927 */
hostapd_setup_interface(struct hostapd_iface * iface)2928 int hostapd_setup_interface(struct hostapd_iface *iface)
2929 {
2930 int ret;
2931
2932 if (!iface->conf) {
2933 wpa_printf(MSG_ERROR, "iface->conf already exists!.");
2934 return -1;
2935 }
2936 ret = setup_interface(iface);
2937 if (ret) {
2938 wpa_printf(MSG_ERROR, "%s: Unable to setup interface.",
2939 iface->conf->bss[0]->iface);
2940 return -1;
2941 }
2942
2943 return 0;
2944 }
2945
2946
2947 /**
2948 * hostapd_alloc_bss_data - Allocate and initialize per-BSS data
2949 * @hapd_iface: Pointer to interface data
2950 * @conf: Pointer to per-interface configuration
2951 * @bss: Pointer to per-BSS configuration for this BSS
2952 * Returns: Pointer to allocated BSS data
2953 *
2954 * This function is used to allocate per-BSS data structure. This data will be
2955 * freed after hostapd_cleanup() is called for it during interface
2956 * deinitialization.
2957 */
2958 struct hostapd_data *
hostapd_alloc_bss_data(struct hostapd_iface * hapd_iface,struct hostapd_config * conf,struct hostapd_bss_config * bss)2959 hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,
2960 struct hostapd_config *conf,
2961 struct hostapd_bss_config *bss)
2962 {
2963 struct hostapd_data *hapd;
2964
2965 hapd = os_zalloc(sizeof(*hapd));
2966 if (hapd == NULL)
2967 return NULL;
2968
2969 hapd->new_assoc_sta_cb = hostapd_new_assoc_sta;
2970 hapd->iconf = conf;
2971 hapd->conf = bss;
2972 hapd->iface = hapd_iface;
2973 if (conf)
2974 hapd->driver = conf->driver;
2975 hapd->ctrl_sock = -1;
2976 dl_list_init(&hapd->ctrl_dst);
2977 dl_list_init(&hapd->nr_db);
2978 hapd->dhcp_sock = -1;
2979 #ifdef CONFIG_IEEE80211R_AP
2980 dl_list_init(&hapd->l2_queue);
2981 dl_list_init(&hapd->l2_oui_queue);
2982 #endif /* CONFIG_IEEE80211R_AP */
2983 #ifdef CONFIG_SAE
2984 dl_list_init(&hapd->sae_commit_queue);
2985 #endif /* CONFIG_SAE */
2986
2987 return hapd;
2988 }
2989
2990
hostapd_bss_deinit(struct hostapd_data * hapd)2991 static void hostapd_bss_deinit(struct hostapd_data *hapd)
2992 {
2993 if (!hapd)
2994 return;
2995 wpa_printf(MSG_DEBUG, "%s: deinit bss %s", __func__,
2996 hapd->conf ? hapd->conf->iface : "N/A");
2997 hostapd_bss_deinit_no_free(hapd);
2998 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
2999 #ifdef CONFIG_LIBWPA_VENDOR
3000 struct HostapdApCbParm hostapdApCbParm = {};
3001 size_t contentLen = strlen(AP_EVENT_DISABLED);
3002 os_memcpy(hostapdApCbParm.content, AP_EVENT_DISABLED, contentLen);
3003 hostapdApCbParm.content[contentLen] = '\0';
3004 hostapdApCbParm.id = 0;
3005 wpa_printf(MSG_INFO, "%s HOSTAPD_EVENT_AP_STATE %s%d", __func__, hostapdApCbParm.content, hostapdApCbParm.id);
3006 HostapdEventReport(hapd->conf->iface, HOSTAPD_EVENT_AP_STATE, (void *) &hostapdApCbParm);
3007 #endif
3008 #ifdef CONFIG_SQLITE
3009 if (hapd->rad_attr_db) {
3010 sqlite3_close(hapd->rad_attr_db);
3011 hapd->rad_attr_db = NULL;
3012 }
3013 #endif /* CONFIG_SQLITE */
3014
3015 hostapd_bss_link_deinit(hapd);
3016 hostapd_cleanup(hapd);
3017 }
3018
3019
hostapd_interface_deinit(struct hostapd_iface * iface)3020 void hostapd_interface_deinit(struct hostapd_iface *iface)
3021 {
3022 int j;
3023
3024 wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
3025 if (iface == NULL)
3026 return;
3027
3028 hostapd_set_state(iface, HAPD_IFACE_DISABLED);
3029
3030 eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
3031 iface->wait_channel_update = 0;
3032 iface->is_no_ir = false;
3033
3034 #ifdef CONFIG_FST
3035 if (iface->fst) {
3036 fst_detach(iface->fst);
3037 iface->fst = NULL;
3038 }
3039 #endif /* CONFIG_FST */
3040
3041 for (j = (int) iface->num_bss - 1; j >= 0; j--) {
3042 if (!iface->bss)
3043 break;
3044 hostapd_bss_deinit(iface->bss[j]);
3045 }
3046
3047 #ifdef NEED_AP_MLME
3048 hostapd_stop_setup_timers(iface);
3049 eloop_cancel_timeout(ap_ht2040_timeout, iface, NULL);
3050 #endif /* NEED_AP_MLME */
3051 }
3052
3053
3054 #ifdef CONFIG_IEEE80211BE
3055
hostapd_mld_ref_inc(struct hostapd_mld * mld)3056 static void hostapd_mld_ref_inc(struct hostapd_mld *mld)
3057 {
3058 if (!mld)
3059 return;
3060
3061 if (mld->refcount == HOSTAPD_MLD_MAX_REF_COUNT) {
3062 wpa_printf(MSG_ERROR, "AP MLD %s: Ref count overflow",
3063 mld->name);
3064 return;
3065 }
3066
3067 mld->refcount++;
3068 }
3069
3070
hostapd_mld_ref_dec(struct hostapd_mld * mld)3071 static void hostapd_mld_ref_dec(struct hostapd_mld *mld)
3072 {
3073 if (!mld)
3074 return;
3075
3076 if (!mld->refcount) {
3077 wpa_printf(MSG_ERROR, "AP MLD %s: Ref count underflow",
3078 mld->name);
3079 return;
3080 }
3081
3082 mld->refcount--;
3083 }
3084
3085 #endif /* CONFIG_IEEE80211BE */
3086
3087
hostapd_interface_free(struct hostapd_iface * iface)3088 void hostapd_interface_free(struct hostapd_iface *iface)
3089 {
3090 size_t j;
3091 wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
3092 for (j = 0; j < iface->num_bss; j++) {
3093 if (!iface->bss)
3094 break;
3095 #ifdef CONFIG_IEEE80211BE
3096 if (iface->bss[j])
3097 hostapd_mld_ref_dec(iface->bss[j]->mld);
3098 #endif /* CONFIG_IEEE80211BE */
3099 wpa_printf(MSG_DEBUG, "%s: free hapd %p",
3100 __func__, iface->bss[j]);
3101 os_free(iface->bss[j]);
3102 }
3103 hostapd_cleanup_iface(iface);
3104 }
3105
3106
hostapd_alloc_iface(void)3107 struct hostapd_iface * hostapd_alloc_iface(void)
3108 {
3109 struct hostapd_iface *hapd_iface;
3110
3111 hapd_iface = os_zalloc(sizeof(*hapd_iface));
3112 if (!hapd_iface)
3113 return NULL;
3114
3115 dl_list_init(&hapd_iface->sta_seen);
3116
3117 return hapd_iface;
3118 }
3119
3120
3121 #ifdef CONFIG_IEEE80211BE
hostapd_bss_alloc_link_id(struct hostapd_data * hapd)3122 static void hostapd_bss_alloc_link_id(struct hostapd_data *hapd)
3123 {
3124 hapd->mld_link_id = hapd->mld->next_link_id++;
3125 wpa_printf(MSG_DEBUG, "AP MLD: %s: Link ID %d assigned.",
3126 hapd->mld->name, hapd->mld_link_id);
3127 }
3128 #endif /* CONFIG_IEEE80211BE */
3129
3130
hostapd_bss_setup_multi_link(struct hostapd_data * hapd,struct hapd_interfaces * interfaces)3131 static void hostapd_bss_setup_multi_link(struct hostapd_data *hapd,
3132 struct hapd_interfaces *interfaces)
3133 {
3134 #ifdef CONFIG_IEEE80211BE
3135 struct hostapd_mld *mld, **all_mld;
3136 struct hostapd_bss_config *conf;
3137 size_t i;
3138
3139 conf = hapd->conf;
3140
3141 if (!hapd->iconf || !hapd->iconf->ieee80211be || !conf->mld_ap ||
3142 conf->disable_11be)
3143 return;
3144
3145 for (i = 0; i < interfaces->mld_count; i++) {
3146 mld = interfaces->mld[i];
3147
3148 if (!mld || os_strcmp(conf->iface, mld->name) != 0)
3149 continue;
3150
3151 hapd->mld = mld;
3152 hostapd_mld_ref_inc(mld);
3153 hostapd_bss_alloc_link_id(hapd);
3154 break;
3155 }
3156
3157 if (hapd->mld)
3158 return;
3159
3160 mld = os_zalloc(sizeof(struct hostapd_mld));
3161 if (!mld)
3162 goto fail;
3163
3164 os_strlcpy(mld->name, conf->iface, sizeof(conf->iface));
3165 dl_list_init(&mld->links);
3166
3167 wpa_printf(MSG_DEBUG, "AP MLD %s created", mld->name);
3168
3169 hapd->mld = mld;
3170 hostapd_mld_ref_inc(mld);
3171 hostapd_bss_alloc_link_id(hapd);
3172
3173 all_mld = os_realloc_array(interfaces->mld, interfaces->mld_count + 1,
3174 sizeof(struct hostapd_mld *));
3175 if (!all_mld)
3176 goto fail;
3177
3178 interfaces->mld = all_mld;
3179 interfaces->mld[interfaces->mld_count] = mld;
3180 interfaces->mld_count++;
3181
3182 return;
3183 fail:
3184 if (!mld)
3185 return;
3186
3187 wpa_printf(MSG_DEBUG, "AP MLD %s: free mld %p", mld->name, mld);
3188 os_free(mld);
3189 hapd->mld = NULL;
3190 #endif /* CONFIG_IEEE80211BE */
3191 }
3192
3193
hostapd_cleanup_unused_mlds(struct hapd_interfaces * interfaces)3194 static void hostapd_cleanup_unused_mlds(struct hapd_interfaces *interfaces)
3195 {
3196 #ifdef CONFIG_IEEE80211BE
3197 struct hostapd_mld *mld, **all_mld;
3198 size_t i, j, num_mlds;
3199 bool forced_remove, remove;
3200
3201 if (!interfaces->mld)
3202 return;
3203
3204 num_mlds = interfaces->mld_count;
3205
3206 for (i = 0; i < interfaces->mld_count; i++) {
3207 mld = interfaces->mld[i];
3208 if (!mld)
3209 continue;
3210
3211 remove = false;
3212 forced_remove = false;
3213
3214 if (!mld->refcount)
3215 remove = true;
3216
3217 /* If MLD is still being referenced but the number of interfaces
3218 * is zero, it is safe to force its deletion. Normally, this
3219 * should not happen but even if it does, let us free the
3220 * memory.
3221 */
3222 if (!remove && !interfaces->count)
3223 forced_remove = true;
3224
3225 if (!remove && !forced_remove)
3226 continue;
3227
3228 wpa_printf(MSG_DEBUG, "AP MLD %s: Freed%s", mld->name,
3229 forced_remove ? " (forced)" : "");
3230 os_free(mld);
3231 interfaces->mld[i] = NULL;
3232 num_mlds--;
3233 }
3234
3235 if (!num_mlds) {
3236 interfaces->mld_count = 0;
3237 os_free(interfaces->mld);
3238 interfaces->mld = NULL;
3239 return;
3240 }
3241
3242 all_mld = os_zalloc(num_mlds * sizeof(struct hostapd_mld *));
3243 if (!all_mld) {
3244 wpa_printf(MSG_ERROR,
3245 "AP MLD: Failed to re-allocate the MLDs. Expect issues");
3246 return;
3247 }
3248
3249 for (i = 0, j = 0; i < interfaces->mld_count; i++) {
3250 mld = interfaces->mld[i];
3251 if (!mld)
3252 continue;
3253
3254 all_mld[j++] = mld;
3255 }
3256
3257 /* This should not happen */
3258 if (j != num_mlds) {
3259 wpa_printf(MSG_DEBUG,
3260 "AP MLD: Some error occurred while reallocating MLDs. Expect issues.");
3261 os_free(all_mld);
3262 return;
3263 }
3264
3265 os_free(interfaces->mld);
3266 interfaces->mld = all_mld;
3267 interfaces->mld_count = num_mlds;
3268 #endif /* CONFIG_IEEE80211BE */
3269 }
3270
3271
3272 /**
3273 * hostapd_init - Allocate and initialize per-interface data
3274 * @config_file: Path to the configuration file
3275 * Returns: Pointer to the allocated interface data or %NULL on failure
3276 *
3277 * This function is used to allocate main data structures for per-interface
3278 * data. The allocated data buffer will be freed by calling
3279 * hostapd_cleanup_iface().
3280 */
hostapd_init(struct hapd_interfaces * interfaces,const char * config_file)3281 struct hostapd_iface * hostapd_init(struct hapd_interfaces *interfaces,
3282 const char *config_file)
3283 {
3284 struct hostapd_iface *hapd_iface = NULL;
3285 struct hostapd_config *conf = NULL;
3286 struct hostapd_data *hapd;
3287 size_t i;
3288
3289 hapd_iface = hostapd_alloc_iface();
3290 if (hapd_iface == NULL)
3291 goto fail;
3292
3293 hapd_iface->config_fname = os_strdup(config_file);
3294 if (hapd_iface->config_fname == NULL)
3295 goto fail;
3296
3297 conf = interfaces->config_read_cb(hapd_iface->config_fname);
3298 if (conf == NULL)
3299 goto fail;
3300 hapd_iface->conf = conf;
3301
3302 hapd_iface->num_bss = conf->num_bss;
3303 hapd_iface->bss = os_calloc(conf->num_bss,
3304 sizeof(struct hostapd_data *));
3305 if (hapd_iface->bss == NULL)
3306 goto fail;
3307
3308 for (i = 0; i < conf->num_bss; i++) {
3309 hapd = hapd_iface->bss[i] =
3310 hostapd_alloc_bss_data(hapd_iface, conf,
3311 conf->bss[i]);
3312 if (hapd == NULL)
3313 goto fail;
3314 hapd->msg_ctx = hapd;
3315 hostapd_bss_setup_multi_link(hapd, interfaces);
3316 }
3317
3318 hapd_iface->is_ch_switch_dfs = false;
3319 return hapd_iface;
3320
3321 fail:
3322 wpa_printf(MSG_ERROR, "Failed to set up interface with %s",
3323 config_file);
3324 if (conf)
3325 hostapd_config_free(conf);
3326 if (hapd_iface) {
3327 os_free(hapd_iface->config_fname);
3328 os_free(hapd_iface->bss);
3329 wpa_printf(MSG_DEBUG, "%s: free iface %p",
3330 __func__, hapd_iface);
3331 os_free(hapd_iface);
3332 }
3333 return NULL;
3334 }
3335
3336
ifname_in_use(struct hapd_interfaces * interfaces,const char * ifname)3337 static int ifname_in_use(struct hapd_interfaces *interfaces, const char *ifname)
3338 {
3339 size_t i, j;
3340
3341 for (i = 0; i < interfaces->count; i++) {
3342 struct hostapd_iface *iface = interfaces->iface[i];
3343 for (j = 0; j < iface->num_bss; j++) {
3344 struct hostapd_data *hapd = iface->bss[j];
3345 if (os_strcmp(ifname, hapd->conf->iface) == 0)
3346 return 1;
3347 }
3348 }
3349
3350 return 0;
3351 }
3352
3353
3354 /**
3355 * hostapd_interface_init_bss - Read configuration file and init BSS data
3356 *
3357 * This function is used to parse configuration file for a BSS. This BSS is
3358 * added to an existing interface sharing the same radio (if any) or a new
3359 * interface is created if this is the first interface on a radio. This
3360 * allocate memory for the BSS. No actual driver operations are started.
3361 *
3362 * This is similar to hostapd_interface_init(), but for a case where the
3363 * configuration is used to add a single BSS instead of all BSSes for a radio.
3364 */
3365 struct hostapd_iface *
hostapd_interface_init_bss(struct hapd_interfaces * interfaces,const char * phy,const char * config_fname,int debug)3366 hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy,
3367 const char *config_fname, int debug)
3368 {
3369 struct hostapd_iface *new_iface = NULL, *iface = NULL;
3370 struct hostapd_data *hapd;
3371 int k;
3372 size_t i, bss_idx;
3373
3374 if (!phy || !*phy)
3375 return NULL;
3376
3377 for (i = 0; i < interfaces->count; i++) {
3378 if (os_strcmp(interfaces->iface[i]->phy, phy) == 0) {
3379 iface = interfaces->iface[i];
3380 break;
3381 }
3382 }
3383
3384 wpa_printf(MSG_INFO, "Configuration file: %s (phy %s)%s",
3385 config_fname, phy, iface ? "" : " --> new PHY");
3386 if (iface) {
3387 struct hostapd_config *conf;
3388 struct hostapd_bss_config **tmp_conf;
3389 struct hostapd_data **tmp_bss;
3390 struct hostapd_bss_config *bss;
3391 const char *ifname;
3392
3393 /* Add new BSS to existing iface */
3394 conf = interfaces->config_read_cb(config_fname);
3395 if (conf == NULL)
3396 return NULL;
3397 if (conf->num_bss > 1) {
3398 wpa_printf(MSG_ERROR, "Multiple BSSes specified in BSS-config");
3399 hostapd_config_free(conf);
3400 return NULL;
3401 }
3402
3403 ifname = conf->bss[0]->iface;
3404 if (ifname[0] != '\0' && ifname_in_use(interfaces, ifname)) {
3405 wpa_printf(MSG_ERROR,
3406 "Interface name %s already in use", ifname);
3407 hostapd_config_free(conf);
3408 return NULL;
3409 }
3410
3411 tmp_conf = os_realloc_array(
3412 iface->conf->bss, iface->conf->num_bss + 1,
3413 sizeof(struct hostapd_bss_config *));
3414 tmp_bss = os_realloc_array(iface->bss, iface->num_bss + 1,
3415 sizeof(struct hostapd_data *));
3416 if (tmp_bss)
3417 iface->bss = tmp_bss;
3418 if (tmp_conf) {
3419 iface->conf->bss = tmp_conf;
3420 iface->conf->last_bss = tmp_conf[0];
3421 }
3422 if (tmp_bss == NULL || tmp_conf == NULL) {
3423 hostapd_config_free(conf);
3424 return NULL;
3425 }
3426 bss = iface->conf->bss[iface->conf->num_bss] = conf->bss[0];
3427 iface->conf->num_bss++;
3428
3429 hapd = hostapd_alloc_bss_data(iface, iface->conf, bss);
3430 if (hapd == NULL) {
3431 iface->conf->num_bss--;
3432 hostapd_config_free(conf);
3433 return NULL;
3434 }
3435 iface->conf->last_bss = bss;
3436 iface->bss[iface->num_bss] = hapd;
3437 hapd->msg_ctx = hapd;
3438 hostapd_bss_setup_multi_link(hapd, interfaces);
3439
3440
3441 bss_idx = iface->num_bss++;
3442 conf->num_bss--;
3443 conf->bss[0] = NULL;
3444 hostapd_config_free(conf);
3445 } else {
3446 /* Add a new iface with the first BSS */
3447 new_iface = iface = hostapd_init(interfaces, config_fname);
3448 if (!iface)
3449 return NULL;
3450 os_strlcpy(iface->phy, phy, sizeof(iface->phy));
3451 iface->interfaces = interfaces;
3452 bss_idx = 0;
3453 }
3454
3455 for (k = 0; k < debug; k++) {
3456 if (iface->bss[bss_idx]->conf->logger_stdout_level > 0)
3457 iface->bss[bss_idx]->conf->logger_stdout_level--;
3458 }
3459
3460 if (iface->conf->bss[bss_idx]->iface[0] == '\0' &&
3461 !hostapd_drv_none(iface->bss[bss_idx])) {
3462 wpa_printf(MSG_ERROR, "Interface name not specified in %s",
3463 config_fname);
3464 if (new_iface)
3465 hostapd_interface_deinit_free(new_iface);
3466 return NULL;
3467 }
3468
3469 return iface;
3470 }
3471
3472
hostapd_cleanup_driver(const struct wpa_driver_ops * driver,void * drv_priv,struct hostapd_iface * iface)3473 static void hostapd_cleanup_driver(const struct wpa_driver_ops *driver,
3474 void *drv_priv, struct hostapd_iface *iface)
3475 {
3476 if (!driver || !driver->hapd_deinit || !drv_priv)
3477 return;
3478
3479 #ifdef CONFIG_IEEE80211BE
3480 /* In case of non-ML operation, de-init. But if ML operation exist,
3481 * even if that's the last BSS in the interface, the driver (drv) could
3482 * be in use for a different AP MLD. Hence, need to check if drv is
3483 * still being used by some other BSS before de-initiallizing. */
3484 if (!iface->bss[0]->conf->mld_ap) {
3485 driver->hapd_deinit(drv_priv);
3486 } else if (hostapd_mld_is_first_bss(iface->bss[0]) &&
3487 driver->is_drv_shared &&
3488 !driver->is_drv_shared(drv_priv, iface->bss[0])) {
3489 driver->hapd_deinit(drv_priv);
3490 } else if (hostapd_if_link_remove(iface->bss[0],
3491 WPA_IF_AP_BSS,
3492 iface->bss[0]->conf->iface,
3493 iface->bss[0]->mld_link_id)) {
3494 wpa_printf(MSG_WARNING, "Failed to remove BSS interface %s",
3495 iface->bss[0]->conf->iface);
3496 }
3497 #else /* CONFIG_IEEE80211BE */
3498 driver->hapd_deinit(drv_priv);
3499 #endif /* CONFIG_IEEE80211BE */
3500 iface->bss[0]->drv_priv = NULL;
3501 }
3502
3503
hostapd_interface_deinit_free(struct hostapd_iface * iface)3504 void hostapd_interface_deinit_free(struct hostapd_iface *iface)
3505 {
3506 const struct wpa_driver_ops *driver;
3507 void *drv_priv;
3508
3509 wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
3510 if (iface == NULL)
3511 return;
3512 wpa_printf(MSG_DEBUG, "%s: num_bss=%u conf->num_bss=%u",
3513 __func__, (unsigned int) iface->num_bss,
3514 (unsigned int) iface->conf->num_bss);
3515 driver = iface->bss[0]->driver;
3516 drv_priv = iface->bss[0]->drv_priv;
3517 hostapd_interface_deinit(iface);
3518 wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
3519 __func__, driver, drv_priv);
3520 hostapd_cleanup_driver(driver, drv_priv, iface);
3521 hostapd_interface_free(iface);
3522 }
3523
3524
hostapd_deinit_driver(const struct wpa_driver_ops * driver,void * drv_priv,struct hostapd_iface * hapd_iface)3525 static void hostapd_deinit_driver(const struct wpa_driver_ops *driver,
3526 void *drv_priv,
3527 struct hostapd_iface *hapd_iface)
3528 {
3529 size_t j;
3530
3531 wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
3532 __func__, driver, drv_priv);
3533
3534 hostapd_cleanup_driver(driver, drv_priv, hapd_iface);
3535
3536 if (driver && driver->hapd_deinit && drv_priv) {
3537 for (j = 0; j < hapd_iface->num_bss; j++) {
3538 wpa_printf(MSG_DEBUG, "%s:bss[%d]->drv_priv=%p",
3539 __func__, (int) j,
3540 hapd_iface->bss[j]->drv_priv);
3541 if (hapd_iface->bss[j]->drv_priv == drv_priv) {
3542 hapd_iface->bss[j]->drv_priv = NULL;
3543 hapd_iface->extended_capa = NULL;
3544 hapd_iface->extended_capa_mask = NULL;
3545 hapd_iface->extended_capa_len = 0;
3546 }
3547 }
3548 }
3549 }
3550
3551
hostapd_refresh_all_iface_beacons(struct hostapd_iface * hapd_iface)3552 static void hostapd_refresh_all_iface_beacons(struct hostapd_iface *hapd_iface)
3553 {
3554 size_t j;
3555
3556 if (!hapd_iface->interfaces || hapd_iface->interfaces->count <= 1)
3557 return;
3558
3559 for (j = 0; j < hapd_iface->interfaces->count; j++) {
3560 if (hapd_iface->interfaces->iface[j] == hapd_iface)
3561 continue;
3562
3563 ieee802_11_update_beacons(hapd_iface->interfaces->iface[j]);
3564 }
3565 }
3566
3567
hostapd_enable_iface(struct hostapd_iface * hapd_iface)3568 int hostapd_enable_iface(struct hostapd_iface *hapd_iface)
3569 {
3570 size_t j;
3571
3572 if (!hapd_iface) {
3573 wpa_printf(MSG_ERROR, "hapd_iface is NULL!");
3574 return -1;
3575 }
3576
3577 if (hapd_iface->enable_iface_cb)
3578 return hapd_iface->enable_iface_cb(hapd_iface);
3579
3580 if (hapd_iface->bss[0]->drv_priv != NULL) {
3581 wpa_printf(MSG_ERROR, "Interface %s already enabled",
3582 hapd_iface->conf->bss[0]->iface);
3583 return -1;
3584 }
3585
3586 wpa_printf(MSG_DEBUG, "Enable interface %s",
3587 hapd_iface->conf->bss[0]->iface);
3588
3589 for (j = 0; j < hapd_iface->num_bss; j++)
3590 hostapd_set_security_params(hapd_iface->conf->bss[j], 1);
3591 if (hostapd_config_check(hapd_iface->conf, 1) < 0) {
3592 wpa_printf(MSG_INFO, "Invalid configuration - cannot enable");
3593 return -1;
3594 }
3595
3596 if (hapd_iface->interfaces == NULL ||
3597 hapd_iface->interfaces->driver_init == NULL ||
3598 hapd_iface->interfaces->driver_init(hapd_iface))
3599 return -1;
3600
3601 if (hostapd_setup_interface(hapd_iface)) {
3602 hostapd_deinit_driver(hapd_iface->bss[0]->driver,
3603 hapd_iface->bss[0]->drv_priv,
3604 hapd_iface);
3605 wpa_printf(MSG_ERROR, "hostapd_setup_interface fail!");
3606 return -1;
3607 }
3608
3609 hostapd_refresh_all_iface_beacons(hapd_iface);
3610
3611 return 0;
3612 }
3613
3614
hostapd_reload_iface(struct hostapd_iface * hapd_iface)3615 int hostapd_reload_iface(struct hostapd_iface *hapd_iface)
3616 {
3617 size_t j;
3618
3619 wpa_printf(MSG_DEBUG, "Reload interface %s",
3620 hapd_iface->conf->bss[0]->iface);
3621 for (j = 0; j < hapd_iface->num_bss; j++)
3622 hostapd_set_security_params(hapd_iface->conf->bss[j], 1);
3623 if (hostapd_config_check(hapd_iface->conf, 1) < 0) {
3624 wpa_printf(MSG_ERROR, "Updated configuration is invalid");
3625 return -1;
3626 }
3627 hostapd_clear_old(hapd_iface);
3628 for (j = 0; j < hapd_iface->num_bss; j++)
3629 hostapd_reload_bss(hapd_iface->bss[j]);
3630
3631 return 0;
3632 }
3633
3634
hostapd_reload_bss_only(struct hostapd_data * bss)3635 int hostapd_reload_bss_only(struct hostapd_data *bss)
3636 {
3637
3638 wpa_printf(MSG_DEBUG, "Reload BSS %s", bss->conf->iface);
3639 hostapd_set_security_params(bss->conf, 1);
3640 if (hostapd_config_check(bss->iconf, 1) < 0) {
3641 wpa_printf(MSG_ERROR, "Updated BSS configuration is invalid");
3642 return -1;
3643 }
3644 hostapd_clear_old_bss(bss);
3645 hostapd_reload_bss(bss);
3646 return 0;
3647 }
3648
3649
hostapd_disable_iface(struct hostapd_iface * hapd_iface)3650 int hostapd_disable_iface(struct hostapd_iface *hapd_iface)
3651 {
3652 size_t j;
3653 const struct wpa_driver_ops *driver;
3654 void *drv_priv;
3655
3656 if (hapd_iface == NULL)
3657 return -1;
3658
3659 if (hapd_iface->disable_iface_cb)
3660 return hapd_iface->disable_iface_cb(hapd_iface);
3661
3662 if (hapd_iface->bss[0]->drv_priv == NULL) {
3663 wpa_printf(MSG_INFO, "Interface %s already disabled",
3664 hapd_iface->conf->bss[0]->iface);
3665 return -1;
3666 }
3667
3668 wpa_msg(hapd_iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
3669 #ifdef CONFIG_LIBWPA_VENDOR
3670 struct HostapdApCbParm hostapdApCbParm = {};
3671 size_t contentLen = strlen(AP_EVENT_DISABLED);
3672 os_memcpy(hostapdApCbParm.content, AP_EVENT_DISABLED, contentLen);
3673 hostapdApCbParm.content[contentLen] = '\0';
3674 hostapdApCbParm.id = 0;
3675 wpa_printf(MSG_INFO, "%s HOSTAPD_EVENT_AP_STATE %s%d", __func__, hostapdApCbParm.content, hostapdApCbParm.id);
3676 HostapdEventReport(hapd_iface->bss[0]->conf->iface, HOSTAPD_EVENT_AP_STATE, (void *) &hostapdApCbParm);
3677 #endif
3678 driver = hapd_iface->bss[0]->driver;
3679 drv_priv = hapd_iface->bss[0]->drv_priv;
3680
3681 hapd_iface->driver_ap_teardown =
3682 !!(hapd_iface->drv_flags &
3683 WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
3684
3685 #ifdef NEED_AP_MLME
3686 for (j = 0; j < hapd_iface->num_bss; j++)
3687 hostapd_cleanup_cs_params(hapd_iface->bss[j]);
3688 #endif /* NEED_AP_MLME */
3689
3690 /* same as hostapd_interface_deinit without deinitializing ctrl-iface */
3691 for (j = 0; j < hapd_iface->num_bss; j++) {
3692 struct hostapd_data *hapd = hapd_iface->bss[j];
3693 hostapd_bss_deinit_no_free(hapd);
3694 hostapd_bss_link_deinit(hapd);
3695 hostapd_free_hapd_data(hapd);
3696 }
3697
3698 hostapd_deinit_driver(driver, drv_priv, hapd_iface);
3699
3700 /* From hostapd_cleanup_iface: These were initialized in
3701 * hostapd_setup_interface and hostapd_setup_interface_complete
3702 */
3703 hostapd_cleanup_iface_partial(hapd_iface);
3704
3705 wpa_printf(MSG_DEBUG, "Interface %s disabled",
3706 hapd_iface->bss[0]->conf->iface);
3707 hostapd_set_state(hapd_iface, HAPD_IFACE_DISABLED);
3708 hostapd_refresh_all_iface_beacons(hapd_iface);
3709 return 0;
3710 }
3711
3712
3713 static struct hostapd_iface *
hostapd_iface_alloc(struct hapd_interfaces * interfaces)3714 hostapd_iface_alloc(struct hapd_interfaces *interfaces)
3715 {
3716 struct hostapd_iface **iface, *hapd_iface;
3717
3718 iface = os_realloc_array(interfaces->iface, interfaces->count + 1,
3719 sizeof(struct hostapd_iface *));
3720 if (iface == NULL)
3721 return NULL;
3722 interfaces->iface = iface;
3723 hapd_iface = interfaces->iface[interfaces->count] =
3724 hostapd_alloc_iface();
3725 if (hapd_iface == NULL) {
3726 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for "
3727 "the interface", __func__);
3728 return NULL;
3729 }
3730 interfaces->count++;
3731 hapd_iface->interfaces = interfaces;
3732
3733 return hapd_iface;
3734 }
3735
3736
3737 static struct hostapd_config *
hostapd_config_alloc(struct hapd_interfaces * interfaces,const char * ifname,const char * ctrl_iface,const char * driver)3738 hostapd_config_alloc(struct hapd_interfaces *interfaces, const char *ifname,
3739 const char *ctrl_iface, const char *driver)
3740 {
3741 struct hostapd_bss_config *bss;
3742 struct hostapd_config *conf;
3743
3744 /* Allocates memory for bss and conf */
3745 conf = hostapd_config_defaults();
3746 if (conf == NULL) {
3747 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for "
3748 "configuration", __func__);
3749 return NULL;
3750 }
3751
3752 if (driver) {
3753 int j;
3754
3755 for (j = 0; wpa_drivers[j]; j++) {
3756 if (os_strcmp(driver, wpa_drivers[j]->name) == 0) {
3757 conf->driver = wpa_drivers[j];
3758 goto skip;
3759 }
3760 }
3761
3762 wpa_printf(MSG_ERROR,
3763 "Invalid/unknown driver '%s' - registering the default driver",
3764 driver);
3765 }
3766
3767 conf->driver = wpa_drivers[0];
3768 if (conf->driver == NULL) {
3769 wpa_printf(MSG_ERROR, "No driver wrappers registered!");
3770 hostapd_config_free(conf);
3771 return NULL;
3772 }
3773
3774 skip:
3775 bss = conf->last_bss = conf->bss[0];
3776
3777 os_strlcpy(bss->iface, ifname, sizeof(bss->iface));
3778 bss->ctrl_interface = os_strdup(ctrl_iface);
3779 if (bss->ctrl_interface == NULL) {
3780 hostapd_config_free(conf);
3781 return NULL;
3782 }
3783
3784 /* Reading configuration file skipped, will be done in SET!
3785 * From reading the configuration till the end has to be done in
3786 * SET
3787 */
3788 return conf;
3789 }
3790
3791
hostapd_data_alloc(struct hostapd_iface * hapd_iface,struct hostapd_config * conf)3792 static int hostapd_data_alloc(struct hostapd_iface *hapd_iface,
3793 struct hostapd_config *conf)
3794 {
3795 size_t i;
3796 struct hostapd_data *hapd;
3797
3798 hapd_iface->bss = os_calloc(conf->num_bss,
3799 sizeof(struct hostapd_data *));
3800 if (hapd_iface->bss == NULL)
3801 return -1;
3802
3803 for (i = 0; i < conf->num_bss; i++) {
3804 hapd = hapd_iface->bss[i] =
3805 hostapd_alloc_bss_data(hapd_iface, conf, conf->bss[i]);
3806 if (hapd == NULL) {
3807 while (i > 0) {
3808 i--;
3809 os_free(hapd_iface->bss[i]);
3810 hapd_iface->bss[i] = NULL;
3811 }
3812 os_free(hapd_iface->bss);
3813 hapd_iface->bss = NULL;
3814 return -1;
3815 }
3816 hapd->msg_ctx = hapd;
3817 hostapd_bss_setup_multi_link(hapd, hapd_iface->interfaces);
3818 }
3819
3820 hapd_iface->conf = conf;
3821 hapd_iface->num_bss = conf->num_bss;
3822
3823 return 0;
3824 }
3825
3826
hostapd_add_iface(struct hapd_interfaces * interfaces,char * buf)3827 int hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf)
3828 {
3829 struct hostapd_config *conf = NULL;
3830 struct hostapd_iface *hapd_iface = NULL, *new_iface = NULL;
3831 struct hostapd_data *hapd;
3832 char *ptr;
3833 size_t i, j;
3834 const char *conf_file = NULL, *phy_name = NULL;
3835
3836 if (os_strncmp(buf, "bss_config=", 11) == 0) {
3837 char *pos;
3838 phy_name = buf + 11;
3839 pos = os_strchr(phy_name, ':');
3840 if (!pos)
3841 return -1;
3842 *pos++ = '\0';
3843 conf_file = pos;
3844 if (!os_strlen(conf_file))
3845 return -1;
3846
3847 hapd_iface = hostapd_interface_init_bss(interfaces, phy_name,
3848 conf_file, 0);
3849 if (!hapd_iface)
3850 return -1;
3851 for (j = 0; j < interfaces->count; j++) {
3852 if (interfaces->iface[j] == hapd_iface)
3853 break;
3854 }
3855 if (j == interfaces->count) {
3856 struct hostapd_iface **tmp;
3857 tmp = os_realloc_array(interfaces->iface,
3858 interfaces->count + 1,
3859 sizeof(struct hostapd_iface *));
3860 if (!tmp) {
3861 hostapd_interface_deinit_free(hapd_iface);
3862 return -1;
3863 }
3864 interfaces->iface = tmp;
3865 interfaces->iface[interfaces->count++] = hapd_iface;
3866 new_iface = hapd_iface;
3867 }
3868
3869 if (new_iface) {
3870 if (interfaces->driver_init(hapd_iface))
3871 goto fail;
3872
3873 if (hostapd_setup_interface(hapd_iface)) {
3874 hostapd_deinit_driver(
3875 hapd_iface->bss[0]->driver,
3876 hapd_iface->bss[0]->drv_priv,
3877 hapd_iface);
3878 goto fail;
3879 }
3880 } else {
3881 /* Assign new BSS with bss[0]'s driver info */
3882 hapd = hapd_iface->bss[hapd_iface->num_bss - 1];
3883 hapd->driver = hapd_iface->bss[0]->driver;
3884 hapd->drv_priv = hapd_iface->bss[0]->drv_priv;
3885 os_memcpy(hapd->own_addr, hapd_iface->bss[0]->own_addr,
3886 ETH_ALEN);
3887
3888 if (start_ctrl_iface_bss(hapd) < 0 ||
3889 (hapd_iface->state == HAPD_IFACE_ENABLED &&
3890 hostapd_setup_bss(hapd, -1, true))) {
3891 hostapd_bss_link_deinit(hapd);
3892 hostapd_cleanup(hapd);
3893 hapd_iface->bss[hapd_iface->num_bss - 1] = NULL;
3894 hapd_iface->conf->num_bss--;
3895 hapd_iface->num_bss--;
3896 wpa_printf(MSG_DEBUG, "%s: free hapd %p %s",
3897 __func__, hapd, hapd->conf->iface);
3898 hostapd_config_free_bss(hapd->conf);
3899 hapd->conf = NULL;
3900 #ifdef CONFIG_IEEE80211BE
3901 hostapd_mld_ref_dec(hapd->mld);
3902 #endif /* CONFIG_IEEE80211BE */
3903 os_free(hapd);
3904 return -1;
3905 }
3906 }
3907 hostapd_owe_update_trans(hapd_iface);
3908 return 0;
3909 }
3910
3911 ptr = os_strchr(buf, ' ');
3912 if (ptr == NULL)
3913 return -1;
3914 *ptr++ = '\0';
3915
3916 if (os_strncmp(ptr, "config=", 7) == 0)
3917 conf_file = ptr + 7;
3918
3919 for (i = 0; i < interfaces->count; i++) {
3920 bool mld_ap = false;
3921
3922 #ifdef CONFIG_IEEE80211BE
3923 mld_ap = interfaces->iface[i]->conf->bss[0]->mld_ap;
3924 #endif /* CONFIG_IEEE80211BE */
3925
3926 if (!os_strcmp(interfaces->iface[i]->conf->bss[0]->iface,
3927 buf) && !mld_ap) {
3928 wpa_printf(MSG_INFO, "Cannot add interface - it "
3929 "already exists");
3930 return -1;
3931 }
3932 }
3933
3934 hapd_iface = hostapd_iface_alloc(interfaces);
3935 if (hapd_iface == NULL) {
3936 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
3937 "for interface", __func__);
3938 goto fail;
3939 }
3940 new_iface = hapd_iface;
3941
3942 if (conf_file && interfaces->config_read_cb) {
3943 conf = interfaces->config_read_cb(conf_file);
3944 if (conf && conf->bss)
3945 os_strlcpy(conf->bss[0]->iface, buf,
3946 sizeof(conf->bss[0]->iface));
3947 } else {
3948 char *driver = os_strchr(ptr, ' ');
3949
3950 if (driver)
3951 *driver++ = '\0';
3952 conf = hostapd_config_alloc(interfaces, buf, ptr, driver);
3953 }
3954
3955 if (conf == NULL || conf->bss == NULL) {
3956 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
3957 "for configuration", __func__);
3958 goto fail;
3959 }
3960
3961 if (hostapd_data_alloc(hapd_iface, conf) < 0) {
3962 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
3963 "for hostapd", __func__);
3964 goto fail;
3965 }
3966 conf = NULL;
3967
3968 if (start_ctrl_iface(hapd_iface) < 0)
3969 goto fail;
3970
3971 wpa_printf(MSG_INFO, "Add interface '%s'",
3972 hapd_iface->conf->bss[0]->iface);
3973
3974 return 0;
3975
3976 fail:
3977 if (conf)
3978 hostapd_config_free(conf);
3979 if (hapd_iface) {
3980 if (hapd_iface->bss) {
3981 for (i = 0; i < hapd_iface->num_bss; i++) {
3982 hapd = hapd_iface->bss[i];
3983 if (!hapd)
3984 continue;
3985 if (hapd_iface->interfaces &&
3986 hapd_iface->interfaces->ctrl_iface_deinit)
3987 hapd_iface->interfaces->
3988 ctrl_iface_deinit(hapd);
3989 wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)",
3990 __func__, hapd_iface->bss[i],
3991 hapd->conf->iface);
3992 hostapd_bss_link_deinit(hapd);
3993 hostapd_cleanup(hapd);
3994 #ifdef CONFIG_IEEE80211BE
3995 hostapd_mld_ref_dec(hapd->mld);
3996 #endif /* CONFIG_IEEE80211BE */
3997 os_free(hapd);
3998 hapd_iface->bss[i] = NULL;
3999 }
4000 os_free(hapd_iface->bss);
4001 hapd_iface->bss = NULL;
4002 }
4003 if (new_iface) {
4004 interfaces->count--;
4005 interfaces->iface[interfaces->count] = NULL;
4006 hostapd_cleanup_unused_mlds(interfaces);
4007 }
4008 hostapd_cleanup_iface(hapd_iface);
4009 }
4010 return -1;
4011 }
4012
4013
hostapd_remove_bss(struct hostapd_iface * iface,unsigned int idx)4014 static int hostapd_remove_bss(struct hostapd_iface *iface, unsigned int idx)
4015 {
4016 size_t i;
4017
4018 wpa_printf(MSG_INFO, "Remove BSS '%s'", iface->conf->bss[idx]->iface);
4019
4020 /* Remove hostapd_data only if it has already been initialized */
4021 if (idx < iface->num_bss) {
4022 struct hostapd_data *hapd = iface->bss[idx];
4023
4024 hostapd_bss_deinit(hapd);
4025 wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)",
4026 __func__, hapd, hapd->conf->iface);
4027 hostapd_config_free_bss(hapd->conf);
4028 hapd->conf = NULL;
4029 #ifdef CONFIG_IEEE80211BE
4030 hostapd_mld_ref_dec(hapd->mld);
4031 #endif /* CONFIG_IEEE80211BE */
4032 os_free(hapd);
4033
4034 iface->num_bss--;
4035
4036 for (i = idx; i < iface->num_bss; i++)
4037 iface->bss[i] = iface->bss[i + 1];
4038 } else {
4039 hostapd_config_free_bss(iface->conf->bss[idx]);
4040 iface->conf->bss[idx] = NULL;
4041 }
4042
4043 iface->conf->num_bss--;
4044 for (i = idx; i < iface->conf->num_bss; i++)
4045 iface->conf->bss[i] = iface->conf->bss[i + 1];
4046
4047 return 0;
4048 }
4049
4050
hostapd_remove_iface(struct hapd_interfaces * interfaces,char * buf)4051 int hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf)
4052 {
4053 struct hostapd_iface *hapd_iface;
4054 size_t i, j, k = 0;
4055
4056 for (i = 0; i < interfaces->count; i++) {
4057 hapd_iface = interfaces->iface[i];
4058 if (hapd_iface == NULL)
4059 return -1;
4060 if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
4061 wpa_printf(MSG_INFO, "Remove interface '%s'", buf);
4062 hapd_iface->driver_ap_teardown =
4063 !!(hapd_iface->drv_flags &
4064 WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
4065
4066 hostapd_interface_deinit_free(hapd_iface);
4067 k = i;
4068 while (k < (interfaces->count - 1)) {
4069 interfaces->iface[k] =
4070 interfaces->iface[k + 1];
4071 k++;
4072 }
4073 interfaces->count--;
4074 hostapd_cleanup_unused_mlds(interfaces);
4075
4076 return 0;
4077 }
4078
4079 for (j = 0; j < hapd_iface->conf->num_bss; j++) {
4080 if (!os_strcmp(hapd_iface->conf->bss[j]->iface, buf)) {
4081 hapd_iface->driver_ap_teardown =
4082 !(hapd_iface->drv_flags &
4083 WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
4084 return hostapd_remove_bss(hapd_iface, j);
4085 }
4086 }
4087 }
4088 return -1;
4089 }
4090
4091
4092 /**
4093 * hostapd_new_assoc_sta - Notify that a new station associated with the AP
4094 * @hapd: Pointer to BSS data
4095 * @sta: Pointer to the associated STA data
4096 * @reassoc: 1 to indicate this was a re-association; 0 = first association
4097 *
4098 * This function will be called whenever a station associates with the AP. It
4099 * can be called from ieee802_11.c for drivers that export MLME to hostapd and
4100 * from drv_callbacks.c based on driver events for drivers that take care of
4101 * management frames (IEEE 802.11 authentication and association) internally.
4102 */
hostapd_new_assoc_sta(struct hostapd_data * hapd,struct sta_info * sta,int reassoc)4103 void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
4104 int reassoc)
4105 {
4106 if (hapd->tkip_countermeasures) {
4107 hostapd_drv_sta_deauth(hapd, sta->addr,
4108 WLAN_REASON_MICHAEL_MIC_FAILURE);
4109 return;
4110 }
4111
4112 #ifdef CONFIG_IEEE80211BE
4113 if (ap_sta_is_mld(hapd, sta) &&
4114 sta->mld_assoc_link_id != hapd->mld_link_id)
4115 return;
4116 #endif /* CONFIG_IEEE80211BE */
4117
4118 ap_sta_clear_disconnect_timeouts(hapd, sta);
4119 sta->post_csa_sa_query = 0;
4120
4121 #ifdef CONFIG_P2P
4122 if (sta->p2p_ie == NULL && !sta->no_p2p_set) {
4123 sta->no_p2p_set = 1;
4124 hapd->num_sta_no_p2p++;
4125 if (hapd->num_sta_no_p2p == 1)
4126 hostapd_p2p_non_p2p_sta_connected(hapd);
4127 }
4128 #endif /* CONFIG_P2P */
4129
4130 airtime_policy_new_sta(hapd, sta);
4131
4132 /* Start accounting here, if IEEE 802.1X and WPA are not used.
4133 * IEEE 802.1X/WPA code will start accounting after the station has
4134 * been authorized. */
4135 if (!hapd->conf->ieee802_1x && !hapd->conf->wpa && !hapd->conf->osen) {
4136 ap_sta_set_authorized(hapd, sta, 1);
4137 os_get_reltime(&sta->connected_time);
4138 accounting_sta_start(hapd, sta);
4139 }
4140
4141 /* Start IEEE 802.1X authentication process for new stations */
4142 ieee802_1x_new_station(hapd, sta);
4143 #ifdef CONFIG_P2P_CHR
4144 wpa_supplicant_upload_go_p2p_state(hapd, sta->addr,
4145 P2P_INTERFACE_STATE_ASSOCIATED, P2P_CHR_DEFAULT_REASON_CODE);
4146 #endif
4147 if (reassoc) {
4148 if (sta->auth_alg != WLAN_AUTH_FT &&
4149 sta->auth_alg != WLAN_AUTH_FILS_SK &&
4150 sta->auth_alg != WLAN_AUTH_FILS_SK_PFS &&
4151 sta->auth_alg != WLAN_AUTH_FILS_PK &&
4152 !(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)))
4153 wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH);
4154 } else if (!(hapd->iface->drv_flags2 &
4155 WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK)) {
4156 /* The 4-way handshake offloaded case will have this handled
4157 * based on the port authorized event. */
4158 wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm);
4159 }
4160
4161 if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_WIRED) {
4162 if (eloop_cancel_timeout(ap_handle_timer, hapd, sta) > 0) {
4163 wpa_printf(MSG_EXCESSIVE,
4164 "%s: %s: canceled wired ap_handle_timer timeout for "
4165 MACSTR_SEC,
4166 hapd->conf->iface, __func__,
4167 MAC2STR_SEC(sta->addr));
4168 }
4169 } else if (!(hapd->iface->drv_flags &
4170 WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) {
4171 wpa_printf(MSG_EXCESSIVE,
4172 "%s: %s: reschedule ap_handle_timer timeout for "
4173 MACSTR_SEC " (%d seconds - ap_max_inactivity)",
4174 hapd->conf->iface, __func__, MAC2STR_SEC(sta->addr),
4175 hapd->conf->ap_max_inactivity);
4176 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
4177 eloop_register_timeout(hapd->conf->ap_max_inactivity, 0,
4178 ap_handle_timer, hapd, sta);
4179 }
4180
4181 #ifdef CONFIG_MACSEC
4182 if (hapd->conf->wpa_key_mgmt == WPA_KEY_MGMT_NONE &&
4183 hapd->conf->mka_psk_set)
4184 ieee802_1x_create_preshared_mka_hapd(hapd, sta);
4185 else
4186 ieee802_1x_alloc_kay_sm_hapd(hapd, sta);
4187 #endif /* CONFIG_MACSEC */
4188 }
4189
4190
hostapd_state_text(enum hostapd_iface_state s)4191 const char * hostapd_state_text(enum hostapd_iface_state s)
4192 {
4193 switch (s) {
4194 case HAPD_IFACE_UNINITIALIZED:
4195 return "UNINITIALIZED";
4196 case HAPD_IFACE_DISABLED:
4197 return "DISABLED";
4198 case HAPD_IFACE_COUNTRY_UPDATE:
4199 return "COUNTRY_UPDATE";
4200 case HAPD_IFACE_ACS:
4201 return "ACS";
4202 case HAPD_IFACE_HT_SCAN:
4203 return "HT_SCAN";
4204 case HAPD_IFACE_DFS:
4205 return "DFS";
4206 case HAPD_IFACE_ENABLED:
4207 return "ENABLED";
4208 case HAPD_IFACE_NO_IR:
4209 return "NO_IR";
4210 }
4211
4212 return "UNKNOWN";
4213 }
4214
4215
hostapd_set_state(struct hostapd_iface * iface,enum hostapd_iface_state s)4216 void hostapd_set_state(struct hostapd_iface *iface, enum hostapd_iface_state s)
4217 {
4218 wpa_printf(MSG_INFO, "%s: interface state %s->%s",
4219 iface->conf ? iface->conf->bss[0]->iface : "N/A",
4220 hostapd_state_text(iface->state), hostapd_state_text(s));
4221 iface->state = s;
4222 }
4223
4224
hostapd_csa_in_progress(struct hostapd_iface * iface)4225 int hostapd_csa_in_progress(struct hostapd_iface *iface)
4226 {
4227 unsigned int i;
4228
4229 for (i = 0; i < iface->num_bss; i++)
4230 if (iface->bss[i]->csa_in_progress)
4231 return 1;
4232 return 0;
4233 }
4234
4235
4236 #ifdef NEED_AP_MLME
4237
free_beacon_data(struct beacon_data * beacon)4238 void free_beacon_data(struct beacon_data *beacon)
4239 {
4240 os_free(beacon->head);
4241 beacon->head = NULL;
4242 os_free(beacon->tail);
4243 beacon->tail = NULL;
4244 os_free(beacon->probe_resp);
4245 beacon->probe_resp = NULL;
4246 os_free(beacon->beacon_ies);
4247 beacon->beacon_ies = NULL;
4248 os_free(beacon->proberesp_ies);
4249 beacon->proberesp_ies = NULL;
4250 os_free(beacon->assocresp_ies);
4251 beacon->assocresp_ies = NULL;
4252 }
4253
4254
hostapd_build_beacon_data(struct hostapd_data * hapd,struct beacon_data * beacon)4255 static int hostapd_build_beacon_data(struct hostapd_data *hapd,
4256 struct beacon_data *beacon)
4257 {
4258 struct wpabuf *beacon_extra, *proberesp_extra, *assocresp_extra;
4259 struct wpa_driver_ap_params params;
4260 int ret;
4261
4262 os_memset(beacon, 0, sizeof(*beacon));
4263 ret = ieee802_11_build_ap_params(hapd, ¶ms);
4264 if (ret < 0)
4265 return ret;
4266
4267 ret = hostapd_build_ap_extra_ies(hapd, &beacon_extra,
4268 &proberesp_extra,
4269 &assocresp_extra);
4270 if (ret)
4271 goto free_ap_params;
4272
4273 ret = -1;
4274 beacon->head = os_memdup(params.head, params.head_len);
4275 if (!beacon->head)
4276 goto free_ap_extra_ies;
4277
4278 beacon->head_len = params.head_len;
4279
4280 beacon->tail = os_memdup(params.tail, params.tail_len);
4281 if (!beacon->tail)
4282 goto free_beacon;
4283
4284 beacon->tail_len = params.tail_len;
4285
4286 if (params.proberesp != NULL) {
4287 beacon->probe_resp = os_memdup(params.proberesp,
4288 params.proberesp_len);
4289 if (!beacon->probe_resp)
4290 goto free_beacon;
4291
4292 beacon->probe_resp_len = params.proberesp_len;
4293 }
4294
4295 /* copy the extra ies */
4296 if (beacon_extra) {
4297 beacon->beacon_ies = os_memdup(beacon_extra->buf,
4298 wpabuf_len(beacon_extra));
4299 if (!beacon->beacon_ies)
4300 goto free_beacon;
4301
4302 beacon->beacon_ies_len = wpabuf_len(beacon_extra);
4303 }
4304
4305 if (proberesp_extra) {
4306 beacon->proberesp_ies = os_memdup(proberesp_extra->buf,
4307 wpabuf_len(proberesp_extra));
4308 if (!beacon->proberesp_ies)
4309 goto free_beacon;
4310
4311 beacon->proberesp_ies_len = wpabuf_len(proberesp_extra);
4312 }
4313
4314 if (assocresp_extra) {
4315 beacon->assocresp_ies = os_memdup(assocresp_extra->buf,
4316 wpabuf_len(assocresp_extra));
4317 if (!beacon->assocresp_ies)
4318 goto free_beacon;
4319
4320 beacon->assocresp_ies_len = wpabuf_len(assocresp_extra);
4321 }
4322
4323 ret = 0;
4324 free_beacon:
4325 /* if the function fails, the caller should not free beacon data */
4326 if (ret)
4327 free_beacon_data(beacon);
4328
4329 free_ap_extra_ies:
4330 hostapd_free_ap_extra_ies(hapd, beacon_extra, proberesp_extra,
4331 assocresp_extra);
4332 free_ap_params:
4333 ieee802_11_free_ap_params(¶ms);
4334 return ret;
4335 }
4336
4337
4338 /*
4339 * TODO: This flow currently supports only changing channel and width within
4340 * the same hw_mode. Any other changes to MAC parameters or provided settings
4341 * are not supported.
4342 */
hostapd_change_config_freq(struct hostapd_data * hapd,struct hostapd_config * conf,struct hostapd_freq_params * params,struct hostapd_freq_params * old_params)4343 static int hostapd_change_config_freq(struct hostapd_data *hapd,
4344 struct hostapd_config *conf,
4345 struct hostapd_freq_params *params,
4346 struct hostapd_freq_params *old_params)
4347 {
4348 int channel;
4349 u8 seg0 = 0, seg1 = 0;
4350 struct hostapd_hw_modes *mode;
4351
4352 if (!params->channel) {
4353 /* check if the new channel is supported by hw */
4354 params->channel = hostapd_hw_get_channel(hapd, params->freq);
4355 }
4356
4357 channel = params->channel;
4358 if (!channel)
4359 return -1;
4360
4361 hostapd_determine_mode(hapd->iface);
4362 mode = hapd->iface->current_mode;
4363
4364 /* if a pointer to old_params is provided we save previous state */
4365 if (old_params &&
4366 hostapd_set_freq_params(old_params, conf->hw_mode,
4367 hostapd_hw_get_freq(hapd, conf->channel),
4368 conf->channel, conf->enable_edmg,
4369 conf->edmg_channel, conf->ieee80211n,
4370 conf->ieee80211ac, conf->ieee80211ax,
4371 conf->ieee80211be, conf->secondary_channel,
4372 hostapd_get_oper_chwidth(conf),
4373 hostapd_get_oper_centr_freq_seg0_idx(conf),
4374 hostapd_get_oper_centr_freq_seg1_idx(conf),
4375 conf->vht_capab,
4376 mode ? &mode->he_capab[IEEE80211_MODE_AP] :
4377 NULL,
4378 mode ? &mode->eht_capab[IEEE80211_MODE_AP] :
4379 NULL,
4380 hostapd_get_punct_bitmap(hapd)))
4381 return -1;
4382
4383 switch (params->bandwidth) {
4384 case 0:
4385 case 20:
4386 conf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
4387 break;
4388 case 40:
4389 case 80:
4390 case 160:
4391 case 320:
4392 conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
4393 break;
4394 default:
4395 return -1;
4396 }
4397
4398 switch (params->bandwidth) {
4399 case 0:
4400 case 20:
4401 case 40:
4402 hostapd_set_oper_chwidth(conf, CONF_OPER_CHWIDTH_USE_HT);
4403 break;
4404 case 80:
4405 if (params->center_freq2)
4406 hostapd_set_oper_chwidth(conf,
4407 CONF_OPER_CHWIDTH_80P80MHZ);
4408 else
4409 hostapd_set_oper_chwidth(conf,
4410 CONF_OPER_CHWIDTH_80MHZ);
4411 break;
4412 case 160:
4413 hostapd_set_oper_chwidth(conf, CONF_OPER_CHWIDTH_160MHZ);
4414 break;
4415 case 320:
4416 hostapd_set_oper_chwidth(conf, CONF_OPER_CHWIDTH_320MHZ);
4417 break;
4418 default:
4419 return -1;
4420 }
4421
4422 conf->channel = channel;
4423 conf->ieee80211n = params->ht_enabled;
4424 conf->ieee80211ac = params->vht_enabled;
4425 conf->secondary_channel = params->sec_channel_offset;
4426 if (params->center_freq1 &&
4427 ieee80211_freq_to_chan(params->center_freq1, &seg0) ==
4428 NUM_HOSTAPD_MODES)
4429 return -1;
4430 if (params->center_freq2 &&
4431 ieee80211_freq_to_chan(params->center_freq2,
4432 &seg1) == NUM_HOSTAPD_MODES)
4433 return -1;
4434 hostapd_set_oper_centr_freq_seg0_idx(conf, seg0);
4435 hostapd_set_oper_centr_freq_seg1_idx(conf, seg1);
4436
4437 /* TODO: maybe call here hostapd_config_check here? */
4438
4439 return 0;
4440 }
4441
4442
hostapd_fill_csa_settings(struct hostapd_data * hapd,struct csa_settings * settings)4443 static int hostapd_fill_csa_settings(struct hostapd_data *hapd,
4444 struct csa_settings *settings)
4445 {
4446 struct hostapd_iface *iface = hapd->iface;
4447 struct hostapd_freq_params old_freq;
4448 int ret;
4449 #ifdef CONFIG_IEEE80211BE
4450 u16 old_punct_bitmap;
4451 #endif /* CONFIG_IEEE80211BE */
4452 u8 chan, bandwidth;
4453
4454 os_memset(&old_freq, 0, sizeof(old_freq));
4455 if (!iface || !iface->freq || hapd->csa_in_progress)
4456 return -1;
4457
4458 switch (settings->freq_params.bandwidth) {
4459 case 80:
4460 if (settings->freq_params.center_freq2)
4461 bandwidth = CONF_OPER_CHWIDTH_80P80MHZ;
4462 else
4463 bandwidth = CONF_OPER_CHWIDTH_80MHZ;
4464 break;
4465 case 160:
4466 bandwidth = CONF_OPER_CHWIDTH_160MHZ;
4467 break;
4468 case 320:
4469 bandwidth = CONF_OPER_CHWIDTH_320MHZ;
4470 break;
4471 default:
4472 bandwidth = CONF_OPER_CHWIDTH_USE_HT;
4473 break;
4474 }
4475
4476 if (ieee80211_freq_to_channel_ext(
4477 settings->freq_params.freq,
4478 settings->freq_params.sec_channel_offset,
4479 bandwidth,
4480 &hapd->iface->cs_oper_class,
4481 &chan) == NUM_HOSTAPD_MODES) {
4482 wpa_printf(MSG_DEBUG,
4483 "invalid frequency for channel switch (freq=%d, sec_channel_offset=%d, vht_enabled=%d, he_enabled=%d, eht_enabled=%d)",
4484 settings->freq_params.freq,
4485 settings->freq_params.sec_channel_offset,
4486 settings->freq_params.vht_enabled,
4487 settings->freq_params.he_enabled,
4488 settings->freq_params.eht_enabled);
4489 return -1;
4490 }
4491
4492 settings->freq_params.channel = chan;
4493
4494 ret = hostapd_change_config_freq(iface->bss[0], iface->conf,
4495 &settings->freq_params,
4496 &old_freq);
4497 if (ret)
4498 return ret;
4499
4500 #ifdef CONFIG_IEEE80211BE
4501 old_punct_bitmap = iface->conf->punct_bitmap;
4502 iface->conf->punct_bitmap = settings->punct_bitmap;
4503 #endif /* CONFIG_IEEE80211BE */
4504 ret = hostapd_build_beacon_data(hapd, &settings->beacon_after);
4505
4506 /* change back the configuration */
4507 #ifdef CONFIG_IEEE80211BE
4508 iface->conf->punct_bitmap = old_punct_bitmap;
4509 #endif /* CONFIG_IEEE80211BE */
4510 hostapd_change_config_freq(iface->bss[0], iface->conf,
4511 &old_freq, NULL);
4512
4513 if (ret)
4514 return ret;
4515
4516 /* set channel switch parameters for csa ie */
4517 hapd->cs_freq_params = settings->freq_params;
4518 hapd->cs_count = settings->cs_count;
4519 hapd->cs_block_tx = settings->block_tx;
4520
4521 ret = hostapd_build_beacon_data(hapd, &settings->beacon_csa);
4522 if (ret) {
4523 free_beacon_data(&settings->beacon_after);
4524 return ret;
4525 }
4526
4527 settings->counter_offset_beacon[0] = hapd->cs_c_off_beacon;
4528 settings->counter_offset_presp[0] = hapd->cs_c_off_proberesp;
4529 settings->counter_offset_beacon[1] = hapd->cs_c_off_ecsa_beacon;
4530 settings->counter_offset_presp[1] = hapd->cs_c_off_ecsa_proberesp;
4531 settings->link_id = -1;
4532 #ifdef CONFIG_IEEE80211BE
4533 if (hapd->conf->mld_ap)
4534 settings->link_id = hapd->mld_link_id;
4535 #endif /* CONFIG_IEEE80211BE */
4536
4537 #ifdef CONFIG_IEEE80211AX
4538 settings->ubpr.unsol_bcast_probe_resp_tmpl =
4539 hostapd_unsol_bcast_probe_resp(hapd, &settings->ubpr);
4540 #endif /* CONFIG_IEEE80211AX */
4541
4542 return 0;
4543 }
4544
4545
hostapd_cleanup_cs_params(struct hostapd_data * hapd)4546 void hostapd_cleanup_cs_params(struct hostapd_data *hapd)
4547 {
4548 os_memset(&hapd->cs_freq_params, 0, sizeof(hapd->cs_freq_params));
4549 hapd->cs_count = 0;
4550 hapd->cs_block_tx = 0;
4551 hapd->cs_c_off_beacon = 0;
4552 hapd->cs_c_off_proberesp = 0;
4553 hapd->csa_in_progress = 0;
4554 hapd->cs_c_off_ecsa_beacon = 0;
4555 hapd->cs_c_off_ecsa_proberesp = 0;
4556 }
4557
4558
hostapd_chan_switch_config(struct hostapd_data * hapd,struct hostapd_freq_params * freq_params)4559 void hostapd_chan_switch_config(struct hostapd_data *hapd,
4560 struct hostapd_freq_params *freq_params)
4561 {
4562 if (freq_params->eht_enabled)
4563 hapd->iconf->ch_switch_eht_config |= CH_SWITCH_EHT_ENABLED;
4564 else
4565 hapd->iconf->ch_switch_eht_config |= CH_SWITCH_EHT_DISABLED;
4566
4567 if (freq_params->he_enabled)
4568 hapd->iconf->ch_switch_he_config |= CH_SWITCH_HE_ENABLED;
4569 else
4570 hapd->iconf->ch_switch_he_config |= CH_SWITCH_HE_DISABLED;
4571
4572 if (freq_params->vht_enabled)
4573 hapd->iconf->ch_switch_vht_config |= CH_SWITCH_VHT_ENABLED;
4574 else
4575 hapd->iconf->ch_switch_vht_config |= CH_SWITCH_VHT_DISABLED;
4576
4577 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
4578 HOSTAPD_LEVEL_INFO,
4579 "CHAN_SWITCH EHT config 0x%x HE config 0x%x VHT config 0x%x",
4580 hapd->iconf->ch_switch_eht_config,
4581 hapd->iconf->ch_switch_he_config,
4582 hapd->iconf->ch_switch_vht_config);
4583 }
4584
4585
hostapd_switch_channel(struct hostapd_data * hapd,struct csa_settings * settings)4586 int hostapd_switch_channel(struct hostapd_data *hapd,
4587 struct csa_settings *settings)
4588 {
4589 int ret;
4590
4591 if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA)) {
4592 wpa_printf(MSG_INFO, "CSA is not supported");
4593 return -1;
4594 }
4595
4596 ret = hostapd_fill_csa_settings(hapd, settings);
4597 if (ret)
4598 return ret;
4599
4600 ret = hostapd_drv_switch_channel(hapd, settings);
4601 free_beacon_data(&settings->beacon_csa);
4602 free_beacon_data(&settings->beacon_after);
4603 #ifdef CONFIG_IEEE80211AX
4604 os_free(settings->ubpr.unsol_bcast_probe_resp_tmpl);
4605 #endif /* CONFIG_IEEE80211AX */
4606
4607 if (ret) {
4608 /* if we failed, clean cs parameters */
4609 hostapd_cleanup_cs_params(hapd);
4610 return ret;
4611 }
4612
4613 hapd->csa_in_progress = 1;
4614 return 0;
4615 }
4616
4617
4618 void
hostapd_switch_channel_fallback(struct hostapd_iface * iface,const struct hostapd_freq_params * freq_params)4619 hostapd_switch_channel_fallback(struct hostapd_iface *iface,
4620 const struct hostapd_freq_params *freq_params)
4621 {
4622 u8 seg0_idx = 0, seg1_idx = 0;
4623 enum oper_chan_width bw = CONF_OPER_CHWIDTH_USE_HT;
4624 u8 op_class, chan = 0;
4625
4626 wpa_printf(MSG_DEBUG, "Restarting all CSA-related BSSes");
4627
4628 if (freq_params->center_freq1)
4629 ieee80211_freq_to_chan(freq_params->center_freq1, &seg0_idx);
4630 if (freq_params->center_freq2)
4631 ieee80211_freq_to_chan(freq_params->center_freq2, &seg1_idx);
4632
4633 switch (freq_params->bandwidth) {
4634 case 0:
4635 case 20:
4636 case 40:
4637 bw = CONF_OPER_CHWIDTH_USE_HT;
4638 break;
4639 case 80:
4640 if (freq_params->center_freq2) {
4641 bw = CONF_OPER_CHWIDTH_80P80MHZ;
4642 iface->conf->vht_capab |=
4643 VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
4644 } else {
4645 bw = CONF_OPER_CHWIDTH_80MHZ;
4646 }
4647 break;
4648 case 160:
4649 bw = CONF_OPER_CHWIDTH_160MHZ;
4650 iface->conf->vht_capab |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
4651 break;
4652 case 320:
4653 bw = CONF_OPER_CHWIDTH_320MHZ;
4654 break;
4655 default:
4656 wpa_printf(MSG_WARNING, "Unknown CSA bandwidth: %d",
4657 freq_params->bandwidth);
4658 break;
4659 }
4660
4661 iface->freq = freq_params->freq;
4662 iface->conf->channel = freq_params->channel;
4663 iface->conf->secondary_channel = freq_params->sec_channel_offset;
4664 if (ieee80211_freq_to_channel_ext(freq_params->freq,
4665 freq_params->sec_channel_offset, bw,
4666 &op_class, &chan) ==
4667 NUM_HOSTAPD_MODES ||
4668 chan != freq_params->channel)
4669 wpa_printf(MSG_INFO, "CSA: Channel mismatch: %d -> %d",
4670 freq_params->channel, chan);
4671
4672 iface->conf->op_class = op_class;
4673 hostapd_set_oper_centr_freq_seg0_idx(iface->conf, seg0_idx);
4674 hostapd_set_oper_centr_freq_seg1_idx(iface->conf, seg1_idx);
4675 hostapd_set_oper_chwidth(iface->conf, bw);
4676 iface->conf->ieee80211n = freq_params->ht_enabled;
4677 iface->conf->ieee80211ac = freq_params->vht_enabled;
4678 iface->conf->ieee80211ax = freq_params->he_enabled;
4679 iface->conf->ieee80211be = freq_params->eht_enabled;
4680
4681 /*
4682 * cs_params must not be cleared earlier because the freq_params
4683 * argument may actually point to one of these.
4684 * These params will be cleared during interface disable below.
4685 */
4686 hostapd_disable_iface(iface);
4687 hostapd_enable_iface(iface);
4688 }
4689
4690
4691 #ifdef CONFIG_IEEE80211AX
4692
hostapd_cleanup_cca_params(struct hostapd_data * hapd)4693 void hostapd_cleanup_cca_params(struct hostapd_data *hapd)
4694 {
4695 hapd->cca_count = 0;
4696 hapd->cca_color = 0;
4697 hapd->cca_c_off_beacon = 0;
4698 hapd->cca_c_off_proberesp = 0;
4699 hapd->cca_in_progress = false;
4700 }
4701
4702
hostapd_fill_cca_settings(struct hostapd_data * hapd,struct cca_settings * settings)4703 int hostapd_fill_cca_settings(struct hostapd_data *hapd,
4704 struct cca_settings *settings)
4705 {
4706 struct hostapd_iface *iface = hapd->iface;
4707 u8 old_color;
4708 int ret;
4709
4710 if (!iface || iface->conf->he_op.he_bss_color_disabled)
4711 return -1;
4712
4713 settings->link_id = -1;
4714 #ifdef CONFIG_IEEE80211BE
4715 if (hapd->conf->mld_ap)
4716 settings->link_id = hapd->mld_link_id;
4717 #endif /* CONFIG_IEEE80211BE */
4718
4719 old_color = iface->conf->he_op.he_bss_color;
4720 iface->conf->he_op.he_bss_color = hapd->cca_color;
4721 ret = hostapd_build_beacon_data(hapd, &settings->beacon_after);
4722 if (ret)
4723 return ret;
4724
4725 iface->conf->he_op.he_bss_color = old_color;
4726
4727 settings->cca_count = hapd->cca_count;
4728 settings->cca_color = hapd->cca_color,
4729 hapd->cca_in_progress = true;
4730
4731 ret = hostapd_build_beacon_data(hapd, &settings->beacon_cca);
4732 if (ret) {
4733 free_beacon_data(&settings->beacon_after);
4734 return ret;
4735 }
4736
4737 settings->ubpr.unsol_bcast_probe_resp_tmpl =
4738 hostapd_unsol_bcast_probe_resp(hapd, &settings->ubpr);
4739
4740 settings->counter_offset_beacon = hapd->cca_c_off_beacon;
4741 settings->counter_offset_presp = hapd->cca_c_off_proberesp;
4742
4743 return 0;
4744 }
4745
4746
hostapd_switch_color_timeout_handler(void * eloop_data,void * user_ctx)4747 static void hostapd_switch_color_timeout_handler(void *eloop_data,
4748 void *user_ctx)
4749 {
4750 struct hostapd_data *hapd = (struct hostapd_data *) eloop_data;
4751 os_time_t delta_t;
4752 unsigned int b;
4753 int i, r;
4754
4755 /* CCA can be triggered once the handler constantly receives
4756 * color collision events to for at least
4757 * DOT11BSS_COLOR_COLLISION_AP_PERIOD (50 s by default). */
4758 delta_t = hapd->last_color_collision.sec -
4759 hapd->first_color_collision.sec;
4760 if (delta_t < DOT11BSS_COLOR_COLLISION_AP_PERIOD)
4761 return;
4762
4763 r = os_random() % HE_OPERATION_BSS_COLOR_MAX;
4764 for (i = 0; i < HE_OPERATION_BSS_COLOR_MAX; i++) {
4765 if (r && !(hapd->color_collision_bitmap & (1ULL << r)))
4766 break;
4767
4768 r = (r + 1) % HE_OPERATION_BSS_COLOR_MAX;
4769 }
4770
4771 if (i == HE_OPERATION_BSS_COLOR_MAX) {
4772 /* There are no free colors so turn BSS coloring off */
4773 wpa_printf(MSG_INFO,
4774 "No free colors left, turning off BSS coloring");
4775 hapd->iface->conf->he_op.he_bss_color_disabled = 1;
4776 hapd->iface->conf->he_op.he_bss_color = os_random() % 63 + 1;
4777 for (b = 0; b < hapd->iface->num_bss; b++)
4778 ieee802_11_set_beacon(hapd->iface->bss[b]);
4779 return;
4780 }
4781
4782 for (b = 0; b < hapd->iface->num_bss; b++) {
4783 struct hostapd_data *bss = hapd->iface->bss[b];
4784 struct cca_settings settings;
4785 int ret;
4786
4787 hostapd_cleanup_cca_params(bss);
4788 bss->cca_color = r;
4789 bss->cca_count = 10;
4790
4791 if (hostapd_fill_cca_settings(bss, &settings)) {
4792 hostapd_cleanup_cca_params(bss);
4793 continue;
4794 }
4795
4796 ret = hostapd_drv_switch_color(bss, &settings);
4797 if (ret)
4798 hostapd_cleanup_cca_params(bss);
4799
4800 free_beacon_data(&settings.beacon_cca);
4801 free_beacon_data(&settings.beacon_after);
4802 os_free(settings.ubpr.unsol_bcast_probe_resp_tmpl);
4803 }
4804 }
4805
4806
hostapd_switch_color(struct hostapd_data * hapd,u64 bitmap)4807 void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap)
4808 {
4809 struct os_reltime now;
4810
4811 if (hapd->cca_in_progress)
4812 return;
4813
4814 if (os_get_reltime(&now))
4815 return;
4816
4817 hapd->color_collision_bitmap = bitmap;
4818 hapd->last_color_collision = now;
4819
4820 if (eloop_is_timeout_registered(hostapd_switch_color_timeout_handler,
4821 hapd, NULL))
4822 return;
4823
4824 hapd->first_color_collision = now;
4825 /* 10 s window as margin for persistent color collision reporting */
4826 eloop_register_timeout(DOT11BSS_COLOR_COLLISION_AP_PERIOD + 10, 0,
4827 hostapd_switch_color_timeout_handler,
4828 hapd, NULL);
4829 }
4830
4831 #endif /* CONFIG_IEEE80211AX */
4832
4833 #endif /* NEED_AP_MLME */
4834
4835
hostapd_get_iface(struct hapd_interfaces * interfaces,const char * ifname)4836 struct hostapd_data * hostapd_get_iface(struct hapd_interfaces *interfaces,
4837 const char *ifname)
4838 {
4839 size_t i, j;
4840
4841 for (i = 0; i < interfaces->count; i++) {
4842 struct hostapd_iface *iface = interfaces->iface[i];
4843
4844 for (j = 0; j < iface->num_bss; j++) {
4845 struct hostapd_data *hapd = iface->bss[j];
4846
4847 if (os_strcmp(ifname, hapd->conf->iface) == 0)
4848 return hapd;
4849 }
4850 }
4851
4852 return NULL;
4853 }
4854
4855
hostapd_periodic_iface(struct hostapd_iface * iface)4856 void hostapd_periodic_iface(struct hostapd_iface *iface)
4857 {
4858 size_t i;
4859
4860 ap_list_timer(iface);
4861
4862 for (i = 0; i < iface->num_bss; i++) {
4863 struct hostapd_data *hapd = iface->bss[i];
4864
4865 if (!hapd->started)
4866 continue;
4867
4868 #ifndef CONFIG_NO_RADIUS
4869 hostapd_acl_expire(hapd);
4870 #endif /* CONFIG_NO_RADIUS */
4871 }
4872 }
4873
4874
4875 #ifdef CONFIG_OCV
hostapd_ocv_check_csa_sa_query(void * eloop_ctx,void * timeout_ctx)4876 void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx)
4877 {
4878 struct hostapd_data *hapd = eloop_ctx;
4879 struct sta_info *sta;
4880
4881 wpa_printf(MSG_DEBUG, "OCV: Post-CSA SA Query initiation check");
4882
4883 for (sta = hapd->sta_list; sta; sta = sta->next) {
4884 if (!sta->post_csa_sa_query)
4885 continue;
4886
4887 wpa_printf(MSG_DEBUG, "OCV: OCVC STA " MACSTR_SEC
4888 " did not start SA Query after CSA - disconnect",
4889 MAC2STR_SEC(sta->addr));
4890 ap_sta_disconnect(hapd, sta, sta->addr,
4891 WLAN_REASON_PREV_AUTH_NOT_VALID);
4892 }
4893 }
4894 #endif /* CONFIG_OCV */
4895
4896
4897 #ifdef CONFIG_IEEE80211BE
4898
hostapd_mld_get_link_bss(struct hostapd_data * hapd,u8 link_id)4899 struct hostapd_data * hostapd_mld_get_link_bss(struct hostapd_data *hapd,
4900 u8 link_id)
4901 {
4902 struct hostapd_iface *iface;
4903 struct hostapd_data *bss;
4904 unsigned int i, j;
4905
4906 for (i = 0; i < hapd->iface->interfaces->count; i++) {
4907 iface = hapd->iface->interfaces->iface[i];
4908 if (!iface)
4909 continue;
4910
4911 for (j = 0; j < iface->num_bss; j++) {
4912 bss = iface->bss[j];
4913
4914 if (!bss->conf->mld_ap ||
4915 !hostapd_is_ml_partner(hapd, bss))
4916 continue;
4917
4918 if (!bss->drv_priv)
4919 continue;
4920
4921 if (bss->mld_link_id == link_id)
4922 return bss;
4923 }
4924 }
4925
4926 return NULL;
4927 }
4928
4929
hostapd_is_ml_partner(struct hostapd_data * hapd1,struct hostapd_data * hapd2)4930 bool hostapd_is_ml_partner(struct hostapd_data *hapd1,
4931 struct hostapd_data *hapd2)
4932 {
4933 if (!hapd1->conf->mld_ap || !hapd2->conf->mld_ap)
4934 return false;
4935
4936 return !os_strcmp(hapd1->conf->iface, hapd2->conf->iface);
4937 }
4938
4939
hostapd_get_mld_id(struct hostapd_data * hapd)4940 u8 hostapd_get_mld_id(struct hostapd_data *hapd)
4941 {
4942 if (!hapd->conf->mld_ap)
4943 return 255;
4944
4945 /* MLD ID 0 represents self */
4946 return 0;
4947
4948 /* TODO: MLD ID for Multiple BSS cases */
4949 }
4950
4951
hostapd_mld_add_link(struct hostapd_data * hapd)4952 int hostapd_mld_add_link(struct hostapd_data *hapd)
4953 {
4954 struct hostapd_mld *mld = hapd->mld;
4955
4956 if (!hapd->conf->mld_ap)
4957 return 0;
4958
4959 /* Should not happen */
4960 if (!mld)
4961 return -1;
4962
4963 dl_list_add_tail(&mld->links, &hapd->link);
4964 mld->num_links++;
4965
4966 wpa_printf(MSG_DEBUG, "AP MLD %s: Link ID %d added. num_links: %d",
4967 mld->name, hapd->mld_link_id, mld->num_links);
4968
4969 if (mld->fbss)
4970 return 0;
4971
4972 mld->fbss = hapd;
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_remove_link(struct hostapd_data * hapd)4979 int hostapd_mld_remove_link(struct hostapd_data *hapd)
4980 {
4981 struct hostapd_mld *mld = hapd->mld;
4982 struct hostapd_data *next_fbss;
4983
4984 if (!hapd->conf->mld_ap)
4985 return 0;
4986
4987 /* Should not happen */
4988 if (!mld)
4989 return -1;
4990
4991 dl_list_del(&hapd->link);
4992 mld->num_links--;
4993
4994 wpa_printf(MSG_DEBUG, "AP MLD %s: Link ID %d removed. num_links: %d",
4995 mld->name, hapd->mld_link_id, mld->num_links);
4996
4997 if (mld->fbss != hapd)
4998 return 0;
4999
5000 /* If the list is empty, all links are removed */
5001 if (dl_list_empty(&mld->links)) {
5002 mld->fbss = NULL;
5003 } else {
5004 next_fbss = dl_list_entry(mld->links.next, struct hostapd_data,
5005 link);
5006 mld->fbss = next_fbss;
5007 }
5008
5009 wpa_printf(MSG_DEBUG, "AP MLD %s: First link BSS set to %p",
5010 mld->name, mld->fbss);
5011 return 0;
5012 }
5013
5014
hostapd_mld_is_first_bss(struct hostapd_data * hapd)5015 bool hostapd_mld_is_first_bss(struct hostapd_data *hapd)
5016 {
5017 struct hostapd_mld *mld = hapd->mld;
5018
5019 if (!hapd->conf->mld_ap)
5020 return true;
5021
5022 /* Should not happen */
5023 if (!mld)
5024 return false;
5025
5026 /* If fbss is not set, it is safe to assume the caller is the first BSS.
5027 */
5028 if (!mld->fbss)
5029 return true;
5030
5031 return hapd == mld->fbss;
5032 }
5033
5034
hostapd_mld_get_first_bss(struct hostapd_data * hapd)5035 struct hostapd_data * hostapd_mld_get_first_bss(struct hostapd_data *hapd)
5036 {
5037 struct hostapd_mld *mld = hapd->mld;
5038
5039 if (!hapd->conf->mld_ap)
5040 return NULL;
5041
5042 /* Should not happen */
5043 if (!mld)
5044 return NULL;
5045
5046 return mld->fbss;
5047 }
5048
5049 #endif /* CONFIG_IEEE80211BE */
5050
5051
hostapd_get_punct_bitmap(struct hostapd_data * hapd)5052 u16 hostapd_get_punct_bitmap(struct hostapd_data *hapd)
5053 {
5054 u16 punct_bitmap = 0;
5055
5056 #ifdef CONFIG_IEEE80211BE
5057 punct_bitmap = hapd->iconf->punct_bitmap;
5058 #ifdef CONFIG_TESTING_OPTIONS
5059 if (!punct_bitmap)
5060 punct_bitmap = hapd->conf->eht_oper_puncturing_override;
5061 #endif /* CONFIG_TESTING_OPTIONS */
5062 #endif /* CONFIG_IEEE80211BE */
5063
5064 return punct_bitmap;
5065 }
5066