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