]> git.ipfire.org Git - thirdparty/hostap.git/blame - src/ap/hostapd.c
Generate BIGTK and rekey it with IGTK
[thirdparty/hostap.git] / src / ap / hostapd.c
CommitLineData
6fc6879b
JM
1/*
2 * hostapd / Initialization and configuration
1b85cad2 3 * Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi>
6fc6879b 4 *
0f3d578e
JM
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
6fc6879b
JM
7 */
8
6226e38d 9#include "utils/includes.h"
f4111ff3
TB
10#ifdef CONFIG_SQLITE
11#include <sqlite3.h>
12#endif /* CONFIG_SQLITE */
6fc6879b 13
6226e38d
JM
14#include "utils/common.h"
15#include "utils/eloop.h"
522450b7 16#include "utils/crc32.h"
03da66bd 17#include "common/ieee802_11_defs.h"
7d6d7370 18#include "common/wpa_ctrl.h"
982896ff 19#include "common/hw_features_common.h"
03da66bd 20#include "radius/radius_client.h"
b031338c 21#include "radius/radius_das.h"
10b58b50 22#include "eap_server/tncs.h"
4e871ed1
JM
23#include "eapol_auth/eapol_auth_sm.h"
24#include "eapol_auth/eapol_auth_sm_i.h"
6959145b 25#include "fst/fst.h"
6226e38d
JM
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"
6226e38d
JM
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"
9c2b8204
JM
37#include "dpp_hostapd.h"
38#include "gas_query_ap.h"
6fc6879b 39#include "hw_features.h"
c442055e 40#include "wpa_auth_glue.h"
a4f21109 41#include "ap_drv_ops.h"
8b06c1ed 42#include "ap_config.h"
aefb53bd 43#include "p2p_hostapd.h"
dca30c3f 44#include "gas_serv.h"
e76da505 45#include "dfs.h"
9c47f6a2 46#include "ieee802_11.h"
ec8f36af 47#include "bss_load.h"
1d783762 48#include "x_snoop.h"
7d597d46 49#include "dhcp_snoop.h"
bd00c431 50#include "ndisc_snoop.h"
9b4b2264 51#include "neighbor_db.h"
f4f185a2 52#include "rrm.h"
91d91abf 53#include "fils_hlp.h"
4c803dfc 54#include "acs.h"
f456940e 55#include "hs20.h"
ef721751 56#include "airtime_policy.h"
a93b369c 57#include "wpa_auth_kay.h"
6fc6879b
JM
58
59
52b20042 60static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason);
ad08c363 61static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd);
a3e685a0 62static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd);
f0793bf1
JM
63static int setup_interface2(struct hostapd_iface *iface);
64static void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx);
c4315e66
TM
65static void hostapd_interface_setup_failure_handler(void *eloop_ctx,
66 void *timeout_ctx);
6fc6879b 67
6fc6879b 68
07bcdbb1
JM
69int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
70 int (*cb)(struct hostapd_iface *iface,
71 void *ctx), void *ctx)
72{
73 size_t i;
74 int ret;
75
76 for (i = 0; i < interfaces->count; i++) {
77 ret = cb(interfaces->iface[i], ctx);
78 if (ret)
79 return ret;
80 }
81
82 return 0;
83}
84
85
567df550
HW
86void hostapd_reconfig_encryption(struct hostapd_data *hapd)
87{
88 if (hapd->wpa_auth)
89 return;
90
91 hostapd_set_privacy(hapd, 0);
92 hostapd_setup_encryption(hapd->conf->iface, hapd);
93}
94
95
c2aa25fb 96static void hostapd_reload_bss(struct hostapd_data *hapd)
ad08c363 97{
a781e211
JM
98 struct hostapd_ssid *ssid;
99
1dfd25a6
JM
100 if (!hapd->started)
101 return;
102
4d6eb9f2
JM
103 if (hapd->conf->wmm_enabled < 0)
104 hapd->conf->wmm_enabled = hapd->iconf->ieee80211n;
105
e3e52e36
JM
106#ifndef CONFIG_NO_RADIUS
107 radius_client_reconfig(hapd->radius, hapd->conf->radius);
108#endif /* CONFIG_NO_RADIUS */
109
a781e211
JM
110 ssid = &hapd->conf->ssid;
111 if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next &&
112 ssid->wpa_passphrase_set && ssid->wpa_passphrase) {
113 /*
114 * Force PSK to be derived again since SSID or passphrase may
115 * have changed.
116 */
891dfb33 117 hostapd_config_clear_wpa_psk(&hapd->conf->ssid.wpa_psk);
a781e211 118 }
ad08c363
JM
119 if (hostapd_setup_wpa_psk(hapd->conf)) {
120 wpa_printf(MSG_ERROR, "Failed to re-configure WPA PSK "
121 "after reloading configuration");
122 }
123
84b2f990 124 if (hapd->conf->ieee802_1x || hapd->conf->wpa)
0e8a96a9 125 hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 1);
84b2f990 126 else
0e8a96a9 127 hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 0);
84b2f990 128
a14896e8 129 if ((hapd->conf->wpa || hapd->conf->osen) && hapd->wpa_auth == NULL) {
ad08c363 130 hostapd_setup_wpa(hapd);
bdffdc5d
JM
131 if (hapd->wpa_auth)
132 wpa_init_keys(hapd->wpa_auth);
133 } else if (hapd->conf->wpa) {
99f4ae67
AT
134 const u8 *wpa_ie;
135 size_t wpa_ie_len;
c442055e 136 hostapd_reconfig_wpa(hapd);
99f4ae67
AT
137 wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len);
138 if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len))
139 wpa_printf(MSG_ERROR, "Failed to configure WPA IE for "
140 "the kernel driver.");
141 } else if (hapd->wpa_auth) {
ad08c363
JM
142 wpa_deinit(hapd->wpa_auth);
143 hapd->wpa_auth = NULL;
144 hostapd_set_privacy(hapd, 0);
145 hostapd_setup_encryption(hapd->conf->iface, hapd);
99f4ae67 146 hostapd_set_generic_elem(hapd, (u8 *) "", 0);
ad08c363
JM
147 }
148
149 ieee802_11_set_beacon(hapd);
6deb41e7 150 hostapd_update_wps(hapd);
ad08c363 151
c813b695 152 if (hapd->conf->ssid.ssid_set &&
986de33d 153 hostapd_set_ssid(hapd, hapd->conf->ssid.ssid,
c813b695
JM
154 hapd->conf->ssid.ssid_len)) {
155 wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
156 /* try to continue */
157 }
c2aa25fb
FF
158 wpa_printf(MSG_DEBUG, "Reconfigured interface %s", hapd->conf->iface);
159}
160
161
ccdff940 162static void hostapd_clear_old(struct hostapd_iface *iface)
c2aa25fb 163{
c2aa25fb
FF
164 size_t j;
165
c2aa25fb
FF
166 /*
167 * Deauthenticate all stations since the new configuration may not
168 * allow them to use the BSS anymore.
169 */
e3e52e36 170 for (j = 0; j < iface->num_bss; j++) {
52b20042
JM
171 hostapd_flush_old_stations(iface->bss[j],
172 WLAN_REASON_PREV_AUTH_NOT_VALID);
a3e685a0 173 hostapd_broadcast_wep_clear(iface->bss[j]);
c2aa25fb
FF
174
175#ifndef CONFIG_NO_RADIUS
e3e52e36
JM
176 /* TODO: update dynamic data based on changed configuration
177 * items (e.g., open/close sockets, etc.) */
178 radius_client_flush(iface->bss[j]->radius, 0);
c2aa25fb 179#endif /* CONFIG_NO_RADIUS */
e3e52e36 180 }
ccdff940
JM
181}
182
183
6e7b4c45
JM
184static int hostapd_iface_conf_changed(struct hostapd_config *newconf,
185 struct hostapd_config *oldconf)
186{
187 size_t i;
188
189 if (newconf->num_bss != oldconf->num_bss)
190 return 1;
191
192 for (i = 0; i < newconf->num_bss; i++) {
193 if (os_strcmp(newconf->bss[i]->iface,
194 oldconf->bss[i]->iface) != 0)
195 return 1;
196 }
197
198 return 0;
199}
200
201
ccdff940
JM
202int hostapd_reload_config(struct hostapd_iface *iface)
203{
6e7b4c45 204 struct hapd_interfaces *interfaces = iface->interfaces;
ccdff940
JM
205 struct hostapd_data *hapd = iface->bss[0];
206 struct hostapd_config *newconf, *oldconf;
207 size_t j;
208
209 if (iface->config_fname == NULL) {
210 /* Only in-memory config in use - assume it has been updated */
211 hostapd_clear_old(iface);
212 for (j = 0; j < iface->num_bss; j++)
213 hostapd_reload_bss(iface->bss[j]);
214 return 0;
215 }
216
217 if (iface->interfaces == NULL ||
218 iface->interfaces->config_read_cb == NULL)
219 return -1;
220 newconf = iface->interfaces->config_read_cb(iface->config_fname);
221 if (newconf == NULL)
222 return -1;
223
224 hostapd_clear_old(iface);
c2aa25fb
FF
225
226 oldconf = hapd->iconf;
6e7b4c45
JM
227 if (hostapd_iface_conf_changed(newconf, oldconf)) {
228 char *fname;
229 int res;
230
231 wpa_printf(MSG_DEBUG,
232 "Configuration changes include interface/BSS modification - force full disable+enable sequence");
233 fname = os_strdup(iface->config_fname);
234 if (!fname) {
235 hostapd_config_free(newconf);
236 return -1;
237 }
238 hostapd_remove_iface(interfaces, hapd->conf->iface);
239 iface = hostapd_init(interfaces, fname);
240 os_free(fname);
241 hostapd_config_free(newconf);
242 if (!iface) {
243 wpa_printf(MSG_ERROR,
244 "Failed to initialize interface on config reload");
245 return -1;
246 }
247 iface->interfaces = interfaces;
248 interfaces->iface[interfaces->count] = iface;
249 interfaces->count++;
250 res = hostapd_enable_iface(iface);
251 if (res < 0)
252 wpa_printf(MSG_ERROR,
253 "Failed to enable interface on config reload");
254 return res;
255 }
c2aa25fb
FF
256 iface->conf = newconf;
257
258 for (j = 0; j < iface->num_bss; j++) {
259 hapd = iface->bss[j];
260 hapd->iconf = newconf;
513dcec6 261 hapd->iconf->channel = oldconf->channel;
857d9422 262 hapd->iconf->acs = oldconf->acs;
74a1319e 263 hapd->iconf->secondary_channel = oldconf->secondary_channel;
513dcec6
PK
264 hapd->iconf->ieee80211n = oldconf->ieee80211n;
265 hapd->iconf->ieee80211ac = oldconf->ieee80211ac;
266 hapd->iconf->ht_capab = oldconf->ht_capab;
267 hapd->iconf->vht_capab = oldconf->vht_capab;
c6b7ac07
JC
268 hostapd_set_oper_chwidth(hapd->iconf,
269 hostapd_get_oper_chwidth(oldconf));
270 hostapd_set_oper_centr_freq_seg0_idx(
271 hapd->iconf,
272 hostapd_get_oper_centr_freq_seg0_idx(oldconf));
273 hostapd_set_oper_centr_freq_seg1_idx(
274 hapd->iconf,
275 hostapd_get_oper_centr_freq_seg1_idx(oldconf));
ebd79f07 276 hapd->conf = newconf->bss[j];
c2aa25fb
FF
277 hostapd_reload_bss(hapd);
278 }
c813b695 279
ad08c363
JM
280 hostapd_config_free(oldconf);
281
ad08c363
JM
282
283 return 0;
284}
285
286
6fc6879b 287static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd,
9c10be3f 288 const char *ifname)
6fc6879b
JM
289{
290 int i;
291
1dfd25a6 292 if (!ifname || !hapd->drv_priv)
9c10be3f 293 return;
6fc6879b 294 for (i = 0; i < NUM_WEP_KEYS; i++) {
4d3ae54f 295 if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, NULL, i, 0,
a919a260 296 0, NULL, 0, NULL, 0, KEY_FLAG_GROUP)) {
bb305cbd
JM
297 wpa_printf(MSG_DEBUG, "Failed to clear default "
298 "encryption keys (ifname=%s keyidx=%d)",
299 ifname, i);
6fc6879b
JM
300 }
301 }
1aa5c134
JM
302 if (hapd->conf->ieee80211w) {
303 for (i = NUM_WEP_KEYS; i < NUM_WEP_KEYS + 2; i++) {
3acdf771 304 if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE,
4d3ae54f 305 NULL, i, 0, 0, NULL,
a919a260 306 0, NULL, 0, KEY_FLAG_GROUP)) {
bb305cbd
JM
307 wpa_printf(MSG_DEBUG, "Failed to clear "
308 "default mgmt encryption keys "
309 "(ifname=%s keyidx=%d)", ifname, i);
1aa5c134
JM
310 }
311 }
312 }
6fc6879b
JM
313}
314
315
316static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd)
317{
318 hostapd_broadcast_key_clear_iface(hapd, hapd->conf->iface);
319 return 0;
320}
321
322
323static int hostapd_broadcast_wep_set(struct hostapd_data *hapd)
324{
325 int errors = 0, idx;
326 struct hostapd_ssid *ssid = &hapd->conf->ssid;
327
328 idx = ssid->wep.idx;
329 if (ssid->wep.default_len &&
3acdf771 330 hostapd_drv_set_key(hapd->conf->iface,
4d3ae54f 331 hapd, WPA_ALG_WEP, broadcast_ether_addr, idx, 0,
0382097e 332 1, NULL, 0, ssid->wep.key[idx],
a919a260
AW
333 ssid->wep.len[idx],
334 KEY_FLAG_GROUP_RX_TX_DEFAULT)) {
bb305cbd 335 wpa_printf(MSG_WARNING, "Could not set WEP encryption.");
6fc6879b
JM
336 errors++;
337 }
338
6fc6879b
JM
339 return errors;
340}
341
6fc6879b 342
ed53dec0
SP
343static void hostapd_free_hapd_data(struct hostapd_data *hapd)
344{
eae3df7e
JM
345 os_free(hapd->probereq_cb);
346 hapd->probereq_cb = NULL;
24fd2043 347 hapd->num_probereq_cb = 0;
eae3df7e
JM
348
349#ifdef CONFIG_P2P
350 wpabuf_free(hapd->p2p_beacon_ie);
351 hapd->p2p_beacon_ie = NULL;
352 wpabuf_free(hapd->p2p_probe_resp_ie);
353 hapd->p2p_probe_resp_ie = NULL;
354#endif /* CONFIG_P2P */
355
68d628ac
MK
356 if (!hapd->started) {
357 wpa_printf(MSG_ERROR, "%s: Interface %s wasn't started",
8fc22fdd 358 __func__, hapd->conf ? hapd->conf->iface : "N/A");
68d628ac
MK
359 return;
360 }
361 hapd->started = 0;
2ab19f4b 362 hapd->beacon_set_done = 0;
68d628ac 363
747c85f9 364 wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface);
6fc6879b 365 accounting_deinit(hapd);
c442055e 366 hostapd_deinit_wpa(hapd);
6fc6879b
JM
367 vlan_deinit(hapd);
368 hostapd_acl_deinit(hapd);
74784010 369#ifndef CONFIG_NO_RADIUS
6fc6879b
JM
370 radius_client_deinit(hapd->radius);
371 hapd->radius = NULL;
b031338c
JM
372 radius_das_deinit(hapd->radius_das);
373 hapd->radius_das = NULL;
74784010 374#endif /* CONFIG_NO_RADIUS */
6fc6879b 375
ad08c363 376 hostapd_deinit_wps(hapd);
a93b369c 377 ieee802_1x_dealloc_kay_sm_hapd(hapd);
9c2b8204
JM
378#ifdef CONFIG_DPP
379 hostapd_dpp_deinit(hapd);
380 gas_query_ap_deinit(hapd->gas);
381#endif /* CONFIG_DPP */
ad08c363 382
2586bc64 383 authsrv_deinit(hapd);
6fc6879b 384
81c4fca1
MK
385 if (hapd->interface_added) {
386 hapd->interface_added = 0;
387 if (hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) {
388 wpa_printf(MSG_WARNING,
389 "Failed to remove BSS interface %s",
390 hapd->conf->iface);
391 hapd->interface_added = 1;
d92bdf96
JM
392 } else {
393 /*
394 * Since this was a dynamically added interface, the
395 * driver wrapper may have removed its internal instance
396 * and hapd->drv_priv is not valid anymore.
397 */
398 hapd->drv_priv = NULL;
81c4fca1 399 }
6fc6879b 400 }
fa16028d 401
39b97072 402 wpabuf_free(hapd->time_adv);
dca30c3f
JK
403
404#ifdef CONFIG_INTERWORKING
405 gas_serv_deinit(hapd);
406#endif /* CONFIG_INTERWORKING */
ee431d77 407
ec8f36af 408 bss_load_update_deinit(hapd);
bd00c431 409 ndisc_snoop_deinit(hapd);
7d597d46 410 dhcp_snoop_deinit(hapd);
1d783762 411 x_snoop_deinit(hapd);
ec8f36af 412
ee431d77 413#ifdef CONFIG_SQLITE
b7175b4d
JM
414 bin_clear_free(hapd->tmp_eap_user.identity,
415 hapd->tmp_eap_user.identity_len);
416 bin_clear_free(hapd->tmp_eap_user.password,
417 hapd->tmp_eap_user.password_len);
ee431d77 418#endif /* CONFIG_SQLITE */
3a322496
JM
419
420#ifdef CONFIG_MESH
421 wpabuf_free(hapd->mesh_pending_auth);
422 hapd->mesh_pending_auth = NULL;
423#endif /* CONFIG_MESH */
9b4b2264 424
f4f185a2 425 hostapd_clean_rrm(hapd);
91d91abf 426 fils_hlp_deinit(hapd);
ff9f40ae
JM
427
428#ifdef CONFIG_SAE
429 {
430 struct hostapd_sae_commit_queue *q;
431
432 while ((q = dl_list_first(&hapd->sae_commit_queue,
433 struct hostapd_sae_commit_queue,
434 list))) {
435 dl_list_del(&q->list);
436 os_free(q);
437 }
438 }
439 eloop_cancel_timeout(auth_sae_process_commit, hapd, NULL);
440#endif /* CONFIG_SAE */
6fc6879b
JM
441}
442
443
ed53dec0
SP
444/**
445 * hostapd_cleanup - Per-BSS cleanup (deinitialization)
446 * @hapd: Pointer to BSS data
447 *
448 * This function is used to free all per-BSS data structures and resources.
6d1ca81e
JM
449 * Most of the modules that are initialized in hostapd_setup_bss() are
450 * deinitialized here.
ed53dec0
SP
451 */
452static void hostapd_cleanup(struct hostapd_data *hapd)
453{
36501a22 454 wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s))", __func__, hapd,
8fc22fdd 455 hapd->conf ? hapd->conf->iface : "N/A");
3776ac73 456 if (hapd->iface->interfaces &&
655dc4a4
DN
457 hapd->iface->interfaces->ctrl_iface_deinit) {
458 wpa_msg(hapd->msg_ctx, MSG_INFO, WPA_EVENT_TERMINATING);
3776ac73 459 hapd->iface->interfaces->ctrl_iface_deinit(hapd);
655dc4a4 460 }
ed53dec0
SP
461 hostapd_free_hapd_data(hapd);
462}
463
464
a65a9b8d
JM
465static void sta_track_deinit(struct hostapd_iface *iface)
466{
467 struct hostapd_sta_info *info;
468
469 if (!iface->num_sta_seen)
470 return;
471
472 while ((info = dl_list_first(&iface->sta_seen, struct hostapd_sta_info,
473 list))) {
474 dl_list_del(&info->list);
475 iface->num_sta_seen--;
44281940 476 sta_track_del(info);
a65a9b8d
JM
477 }
478}
479
480
4b8a59e4
SP
481static void hostapd_cleanup_iface_partial(struct hostapd_iface *iface)
482{
747c85f9 483 wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
4fada121
JM
484#ifdef CONFIG_IEEE80211N
485#ifdef NEED_AP_MLME
486 hostapd_stop_setup_timers(iface);
487#endif /* NEED_AP_MLME */
488#endif /* CONFIG_IEEE80211N */
4c803dfc
JM
489 if (iface->current_mode)
490 acs_cleanup(iface);
4b8a59e4
SP
491 hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);
492 iface->hw_features = NULL;
4c803dfc 493 iface->current_mode = NULL;
4b8a59e4
SP
494 os_free(iface->current_rates);
495 iface->current_rates = NULL;
496 os_free(iface->basic_rates);
497 iface->basic_rates = NULL;
498 ap_list_deinit(iface);
a65a9b8d 499 sta_track_deinit(iface);
ef721751 500 airtime_policy_update_deinit(iface);
4b8a59e4
SP
501}
502
503
6fc6879b
JM
504/**
505 * hostapd_cleanup_iface - Complete per-interface cleanup
506 * @iface: Pointer to interface data
507 *
508 * This function is called after per-BSS data structures are deinitialized
509 * with hostapd_cleanup().
510 */
511static void hostapd_cleanup_iface(struct hostapd_iface *iface)
512{
747c85f9 513 wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
f0793bf1 514 eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
c4315e66
TM
515 eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface,
516 NULL);
f0793bf1 517
4b8a59e4 518 hostapd_cleanup_iface_partial(iface);
6fc6879b
JM
519 hostapd_config_free(iface->conf);
520 iface->conf = NULL;
521
522 os_free(iface->config_fname);
523 os_free(iface->bss);
747c85f9 524 wpa_printf(MSG_DEBUG, "%s: free iface=%p", __func__, iface);
6fc6879b
JM
525 os_free(iface);
526}
527
528
e03c3069
SP
529static void hostapd_clear_wep(struct hostapd_data *hapd)
530{
8fc22fdd 531 if (hapd->drv_priv && !hapd->iface->driver_ap_teardown && hapd->conf) {
e03c3069
SP
532 hostapd_set_privacy(hapd, 0);
533 hostapd_broadcast_wep_clear(hapd);
534 }
535}
536
537
6fc6879b
JM
538static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd)
539{
540 int i;
541
542 hostapd_broadcast_wep_set(hapd);
543
579bc0e6
JM
544 if (hapd->conf->ssid.wep.default_len) {
545 hostapd_set_privacy(hapd, 1);
6fc6879b 546 return 0;
579bc0e6 547 }
6fc6879b 548
41fd1d9e
KZ
549 /*
550 * When IEEE 802.1X is not enabled, the driver may need to know how to
551 * set authentication algorithms for static WEP.
552 */
553 hostapd_drv_set_authmode(hapd, hapd->conf->auth_algs);
554
6fc6879b
JM
555 for (i = 0; i < 4; i++) {
556 if (hapd->conf->ssid.wep.key[i] &&
4d3ae54f 557 hostapd_drv_set_key(iface, hapd, WPA_ALG_WEP, NULL, i, 0,
3acdf771
JM
558 i == hapd->conf->ssid.wep.idx, NULL, 0,
559 hapd->conf->ssid.wep.key[i],
a919a260
AW
560 hapd->conf->ssid.wep.len[i],
561 i == hapd->conf->ssid.wep.idx ?
562 KEY_FLAG_GROUP_RX_TX_DEFAULT :
563 KEY_FLAG_GROUP_RX_TX)) {
bb305cbd
JM
564 wpa_printf(MSG_WARNING, "Could not set WEP "
565 "encryption.");
6fc6879b
JM
566 return -1;
567 }
568 if (hapd->conf->ssid.wep.key[i] &&
569 i == hapd->conf->ssid.wep.idx)
570 hostapd_set_privacy(hapd, 1);
571 }
572
573 return 0;
574}
575
576
52b20042 577static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason)
6fc6879b
JM
578{
579 int ret = 0;
4d379f12 580 u8 addr[ETH_ALEN];
6fc6879b 581
70a8419f 582 if (hostapd_drv_none(hapd) || hapd->drv_priv == NULL)
85141289
JM
583 return 0;
584
354c903f
MB
585 if (!hapd->iface->driver_ap_teardown) {
586 wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
587 "Flushing old station entries");
588
589 if (hostapd_flush(hapd)) {
590 wpa_msg(hapd->msg_ctx, MSG_WARNING,
591 "Could not connect to kernel driver");
592 ret = -1;
593 }
6fc6879b 594 }
57a2aaca
JM
595 if (hapd->conf && hapd->conf->broadcast_deauth) {
596 wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
597 "Deauthenticate all stations");
598 os_memset(addr, 0xff, ETH_ALEN);
599 hostapd_drv_sta_deauth(hapd, addr, reason);
600 }
6603a966 601 hostapd_free_stas(hapd);
6fc6879b
JM
602
603 return ret;
604}
605
606
438e1333
JM
607static void hostapd_bss_deinit_no_free(struct hostapd_data *hapd)
608{
609 hostapd_free_stas(hapd);
610 hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
611 hostapd_clear_wep(hapd);
612}
613
614
6fc6879b
JM
615/**
616 * hostapd_validate_bssid_configuration - Validate BSSID configuration
617 * @iface: Pointer to interface data
618 * Returns: 0 on success, -1 on failure
619 *
620 * This function is used to validate that the configured BSSIDs are valid.
621 */
622static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface)
623{
624 u8 mask[ETH_ALEN] = { 0 };
625 struct hostapd_data *hapd = iface->bss[0];
626 unsigned int i = iface->conf->num_bss, bits = 0, j;
90ac1f9f 627 int auto_addr = 0;
6fc6879b 628
85141289
JM
629 if (hostapd_drv_none(hapd))
630 return 0;
631
6448e064
EP
632 if (iface->conf->use_driver_iface_addr)
633 return 0;
634
6fc6879b
JM
635 /* Generate BSSID mask that is large enough to cover the BSSIDs. */
636
637 /* Determine the bits necessary to cover the number of BSSIDs. */
638 for (i--; i; i >>= 1)
639 bits++;
640
641 /* Determine the bits necessary to any configured BSSIDs,
642 if they are higher than the number of BSSIDs. */
643 for (j = 0; j < iface->conf->num_bss; j++) {
902c07a7 644 if (is_zero_ether_addr(iface->conf->bss[j]->bssid)) {
90ac1f9f
JM
645 if (j)
646 auto_addr++;
6fc6879b 647 continue;
90ac1f9f 648 }
6fc6879b
JM
649
650 for (i = 0; i < ETH_ALEN; i++) {
651 mask[i] |=
ebd79f07 652 iface->conf->bss[j]->bssid[i] ^
6fc6879b
JM
653 hapd->own_addr[i];
654 }
655 }
656
90ac1f9f
JM
657 if (!auto_addr)
658 goto skip_mask_ext;
659
6fc6879b
JM
660 for (i = 0; i < ETH_ALEN && mask[i] == 0; i++)
661 ;
662 j = 0;
663 if (i < ETH_ALEN) {
664 j = (5 - i) * 8;
665
666 while (mask[i] != 0) {
667 mask[i] >>= 1;
668 j++;
669 }
670 }
671
672 if (bits < j)
673 bits = j;
674
90ac1f9f
JM
675 if (bits > 40) {
676 wpa_printf(MSG_ERROR, "Too many bits in the BSSID mask (%u)",
677 bits);
6fc6879b 678 return -1;
90ac1f9f 679 }
6fc6879b
JM
680
681 os_memset(mask, 0xff, ETH_ALEN);
682 j = bits / 8;
683 for (i = 5; i > 5 - j; i--)
684 mask[i] = 0;
685 j = bits % 8;
b3957edb
JM
686 while (j) {
687 j--;
6fc6879b 688 mask[i] <<= 1;
b3957edb 689 }
6fc6879b 690
90ac1f9f 691skip_mask_ext:
6fc6879b
JM
692 wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR " (%d bits)",
693 (unsigned long) iface->conf->num_bss, MAC2STR(mask), bits);
694
90ac1f9f
JM
695 if (!auto_addr)
696 return 0;
697
6fc6879b
JM
698 for (i = 0; i < ETH_ALEN; i++) {
699 if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) {
bb305cbd
JM
700 wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR
701 " for start address " MACSTR ".",
702 MAC2STR(mask), MAC2STR(hapd->own_addr));
703 wpa_printf(MSG_ERROR, "Start address must be the "
704 "first address in the block (i.e., addr "
705 "AND mask == addr).");
6fc6879b
JM
706 return -1;
707 }
708 }
709
710 return 0;
711}
712
713
714static int mac_in_conf(struct hostapd_config *conf, const void *a)
715{
716 size_t i;
717
718 for (i = 0; i < conf->num_bss; i++) {
ebd79f07 719 if (hostapd_mac_comp(conf->bss[i]->bssid, a) == 0) {
6fc6879b
JM
720 return 1;
721 }
722 }
723
724 return 0;
725}
726
727
8047a958
JM
728#ifndef CONFIG_NO_RADIUS
729
730static int hostapd_das_nas_mismatch(struct hostapd_data *hapd,
731 struct radius_das_attrs *attr)
732{
cb10c7d1
JM
733 if (attr->nas_identifier &&
734 (!hapd->conf->nas_identifier ||
735 os_strlen(hapd->conf->nas_identifier) !=
736 attr->nas_identifier_len ||
737 os_memcmp(hapd->conf->nas_identifier, attr->nas_identifier,
738 attr->nas_identifier_len) != 0)) {
739 wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-Identifier mismatch");
740 return 1;
741 }
742
743 if (attr->nas_ip_addr &&
744 (hapd->conf->own_ip_addr.af != AF_INET ||
745 os_memcmp(&hapd->conf->own_ip_addr.u.v4, attr->nas_ip_addr, 4) !=
746 0)) {
747 wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-IP-Address mismatch");
748 return 1;
749 }
750
751#ifdef CONFIG_IPV6
752 if (attr->nas_ipv6_addr &&
753 (hapd->conf->own_ip_addr.af != AF_INET6 ||
754 os_memcmp(&hapd->conf->own_ip_addr.u.v6, attr->nas_ipv6_addr, 16)
755 != 0)) {
756 wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-IPv6-Address mismatch");
757 return 1;
758 }
759#endif /* CONFIG_IPV6 */
760
8047a958
JM
761 return 0;
762}
763
764
765static struct sta_info * hostapd_das_find_sta(struct hostapd_data *hapd,
861beb72
JM
766 struct radius_das_attrs *attr,
767 int *multi)
8047a958 768{
861beb72 769 struct sta_info *selected, *sta;
8047a958 770 char buf[128];
861beb72
JM
771 int num_attr = 0;
772 int count;
8047a958 773
861beb72
JM
774 *multi = 0;
775
776 for (sta = hapd->sta_list; sta; sta = sta->next)
777 sta->radius_das_match = 1;
778
779 if (attr->sta_addr) {
780 num_attr++;
8047a958 781 sta = ap_get_sta(hapd, attr->sta_addr);
861beb72
JM
782 if (!sta) {
783 wpa_printf(MSG_DEBUG,
784 "RADIUS DAS: No Calling-Station-Id match");
785 return NULL;
786 }
8047a958 787
861beb72 788 selected = sta;
8047a958 789 for (sta = hapd->sta_list; sta; sta = sta->next) {
861beb72
JM
790 if (sta != selected)
791 sta->radius_das_match = 0;
792 }
793 wpa_printf(MSG_DEBUG, "RADIUS DAS: Calling-Station-Id match");
794 }
795
796 if (attr->acct_session_id) {
797 num_attr++;
d72a0053 798 if (attr->acct_session_id_len != 16) {
861beb72
JM
799 wpa_printf(MSG_DEBUG,
800 "RADIUS DAS: Acct-Session-Id cannot match");
801 return NULL;
802 }
803 count = 0;
804
805 for (sta = hapd->sta_list; sta; sta = sta->next) {
806 if (!sta->radius_das_match)
807 continue;
1492fbb9
NL
808 os_snprintf(buf, sizeof(buf), "%016llX",
809 (unsigned long long) sta->acct_session_id);
d72a0053 810 if (os_memcmp(attr->acct_session_id, buf, 16) != 0)
861beb72
JM
811 sta->radius_das_match = 0;
812 else
813 count++;
814 }
815
816 if (count == 0) {
817 wpa_printf(MSG_DEBUG,
818 "RADIUS DAS: No matches remaining after Acct-Session-Id check");
819 return NULL;
8047a958 820 }
861beb72 821 wpa_printf(MSG_DEBUG, "RADIUS DAS: Acct-Session-Id match");
8047a958
JM
822 }
823
4e871ed1
JM
824 if (attr->acct_multi_session_id) {
825 num_attr++;
d72a0053 826 if (attr->acct_multi_session_id_len != 16) {
4e871ed1
JM
827 wpa_printf(MSG_DEBUG,
828 "RADIUS DAS: Acct-Multi-Session-Id cannot match");
829 return NULL;
830 }
831 count = 0;
832
833 for (sta = hapd->sta_list; sta; sta = sta->next) {
834 if (!sta->radius_das_match)
835 continue;
836 if (!sta->eapol_sm ||
d72a0053 837 !sta->eapol_sm->acct_multi_session_id) {
4e871ed1
JM
838 sta->radius_das_match = 0;
839 continue;
840 }
1492fbb9
NL
841 os_snprintf(buf, sizeof(buf), "%016llX",
842 (unsigned long long)
d72a0053
NL
843 sta->eapol_sm->acct_multi_session_id);
844 if (os_memcmp(attr->acct_multi_session_id, buf, 16) !=
4e871ed1
JM
845 0)
846 sta->radius_das_match = 0;
847 else
848 count++;
849 }
850
851 if (count == 0) {
852 wpa_printf(MSG_DEBUG,
853 "RADIUS DAS: No matches remaining after Acct-Multi-Session-Id check");
854 return NULL;
855 }
856 wpa_printf(MSG_DEBUG,
857 "RADIUS DAS: Acct-Multi-Session-Id match");
858 }
859
861beb72
JM
860 if (attr->cui) {
861 num_attr++;
862 count = 0;
863
302fc0a3
JM
864 for (sta = hapd->sta_list; sta; sta = sta->next) {
865 struct wpabuf *cui;
861beb72
JM
866
867 if (!sta->radius_das_match)
868 continue;
302fc0a3 869 cui = ieee802_1x_get_radius_cui(sta->eapol_sm);
861beb72 870 if (!cui || wpabuf_len(cui) != attr->cui_len ||
302fc0a3 871 os_memcmp(wpabuf_head(cui), attr->cui,
861beb72
JM
872 attr->cui_len) != 0)
873 sta->radius_das_match = 0;
874 else
875 count++;
876 }
877
878 if (count == 0) {
879 wpa_printf(MSG_DEBUG,
880 "RADIUS DAS: No matches remaining after Chargeable-User-Identity check");
881 return NULL;
302fc0a3 882 }
861beb72
JM
883 wpa_printf(MSG_DEBUG,
884 "RADIUS DAS: Chargeable-User-Identity match");
302fc0a3
JM
885 }
886
861beb72
JM
887 if (attr->user_name) {
888 num_attr++;
889 count = 0;
890
8047a958
JM
891 for (sta = hapd->sta_list; sta; sta = sta->next) {
892 u8 *identity;
893 size_t identity_len;
861beb72
JM
894
895 if (!sta->radius_das_match)
896 continue;
8047a958
JM
897 identity = ieee802_1x_get_identity(sta->eapol_sm,
898 &identity_len);
861beb72
JM
899 if (!identity ||
900 identity_len != attr->user_name_len ||
8047a958 901 os_memcmp(identity, attr->user_name, identity_len)
861beb72
JM
902 != 0)
903 sta->radius_das_match = 0;
904 else
905 count++;
906 }
907
908 if (count == 0) {
909 wpa_printf(MSG_DEBUG,
910 "RADIUS DAS: No matches remaining after User-Name check");
911 return NULL;
912 }
913 wpa_printf(MSG_DEBUG,
914 "RADIUS DAS: User-Name match");
915 }
916
917 if (num_attr == 0) {
918 /*
919 * In theory, we could match all current associations, but it
920 * seems safer to just reject requests that do not include any
921 * session identification attributes.
922 */
923 wpa_printf(MSG_DEBUG,
924 "RADIUS DAS: No session identification attributes included");
925 return NULL;
926 }
927
928 selected = NULL;
929 for (sta = hapd->sta_list; sta; sta = sta->next) {
930 if (sta->radius_das_match) {
931 if (selected) {
932 *multi = 1;
933 return NULL;
934 }
935 selected = sta;
8047a958
JM
936 }
937 }
938
861beb72 939 return selected;
8047a958
JM
940}
941
942
cbc210de
JM
943static int hostapd_das_disconnect_pmksa(struct hostapd_data *hapd,
944 struct radius_das_attrs *attr)
945{
946 if (!hapd->wpa_auth)
947 return -1;
948 return wpa_auth_radius_das_disconnect_pmksa(hapd->wpa_auth, attr);
949}
950
951
8047a958
JM
952static enum radius_das_res
953hostapd_das_disconnect(void *ctx, struct radius_das_attrs *attr)
954{
955 struct hostapd_data *hapd = ctx;
956 struct sta_info *sta;
861beb72 957 int multi;
8047a958
JM
958
959 if (hostapd_das_nas_mismatch(hapd, attr))
960 return RADIUS_DAS_NAS_MISMATCH;
961
861beb72
JM
962 sta = hostapd_das_find_sta(hapd, attr, &multi);
963 if (sta == NULL) {
964 if (multi) {
965 wpa_printf(MSG_DEBUG,
966 "RADIUS DAS: Multiple sessions match - not supported");
967 return RADIUS_DAS_MULTI_SESSION_MATCH;
968 }
cbc210de
JM
969 if (hostapd_das_disconnect_pmksa(hapd, attr) == 0) {
970 wpa_printf(MSG_DEBUG,
971 "RADIUS DAS: PMKSA cache entry matched");
972 return RADIUS_DAS_SUCCESS;
973 }
861beb72 974 wpa_printf(MSG_DEBUG, "RADIUS DAS: No matching session found");
8047a958 975 return RADIUS_DAS_SESSION_NOT_FOUND;
861beb72 976 }
8047a958 977
861beb72
JM
978 wpa_printf(MSG_DEBUG, "RADIUS DAS: Found a matching session " MACSTR
979 " - disconnecting", MAC2STR(sta->addr));
0d7c5e1d
JM
980 wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
981
8047a958
JM
982 hostapd_drv_sta_deauth(hapd, sta->addr,
983 WLAN_REASON_PREV_AUTH_NOT_VALID);
984 ap_sta_deauthenticate(hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID);
985
986 return RADIUS_DAS_SUCCESS;
987}
988
f456940e
JM
989
990#ifdef CONFIG_HS20
991static enum radius_das_res
992hostapd_das_coa(void *ctx, struct radius_das_attrs *attr)
993{
994 struct hostapd_data *hapd = ctx;
995 struct sta_info *sta;
996 int multi;
997
998 if (hostapd_das_nas_mismatch(hapd, attr))
999 return RADIUS_DAS_NAS_MISMATCH;
1000
1001 sta = hostapd_das_find_sta(hapd, attr, &multi);
1002 if (!sta) {
1003 if (multi) {
1004 wpa_printf(MSG_DEBUG,
1005 "RADIUS DAS: Multiple sessions match - not supported");
1006 return RADIUS_DAS_MULTI_SESSION_MATCH;
1007 }
1008 wpa_printf(MSG_DEBUG, "RADIUS DAS: No matching session found");
1009 return RADIUS_DAS_SESSION_NOT_FOUND;
1010 }
1011
1012 wpa_printf(MSG_DEBUG, "RADIUS DAS: Found a matching session " MACSTR
1013 " - CoA", MAC2STR(sta->addr));
1014
1015 if (attr->hs20_t_c_filtering) {
1016 if (attr->hs20_t_c_filtering[0] & BIT(0)) {
1017 wpa_printf(MSG_DEBUG,
1018 "HS 2.0: Unexpected Terms and Conditions filtering required in CoA-Request");
1019 return RADIUS_DAS_COA_FAILED;
1020 }
1021
1022 hs20_t_c_filtering(hapd, sta, 0);
1023 }
1024
1025 return RADIUS_DAS_SUCCESS;
1026}
1027#else /* CONFIG_HS20 */
1028#define hostapd_das_coa NULL
1029#endif /* CONFIG_HS20 */
1030
f4111ff3
TB
1031
1032#ifdef CONFIG_SQLITE
1033
1034static int db_table_exists(sqlite3 *db, const char *name)
1035{
1036 char cmd[128];
1037
1038 os_snprintf(cmd, sizeof(cmd), "SELECT 1 FROM %s;", name);
1039 return sqlite3_exec(db, cmd, NULL, NULL, NULL) == SQLITE_OK;
1040}
1041
1042
1043static int db_table_create_radius_attributes(sqlite3 *db)
1044{
1045 char *err = NULL;
1046 const char *sql =
1047 "CREATE TABLE radius_attributes("
1048 " id INTEGER PRIMARY KEY,"
1049 " sta TEXT,"
1050 " reqtype TEXT,"
1051 " attr TEXT"
1052 ");"
1053 "CREATE INDEX idx_sta_reqtype ON radius_attributes(sta,reqtype);";
1054
1055 wpa_printf(MSG_DEBUG,
1056 "Adding database table for RADIUS attribute information");
1057 if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) {
1058 wpa_printf(MSG_ERROR, "SQLite error: %s", err);
1059 sqlite3_free(err);
1060 return -1;
1061 }
1062
1063 return 0;
1064}
1065
1066#endif /* CONFIG_SQLITE */
1067
8047a958 1068#endif /* CONFIG_NO_RADIUS */
6fc6879b
JM
1069
1070
6fc6879b
JM
1071/**
1072 * hostapd_setup_bss - Per-BSS setup (initialization)
1073 * @hapd: Pointer to BSS data
2aec4f3c
JM
1074 * @first: Whether this BSS is the first BSS of an interface; -1 = not first,
1075 * but interface may exist
6fc6879b
JM
1076 *
1077 * This function is used to initialize all per-BSS data structures and
1078 * resources. This gets called in a loop for each BSS when an interface is
1079 * initialized. Most of the modules that are initialized here will be
1080 * deinitialized in hostapd_cleanup().
1081 */
1082static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
1083{
1084 struct hostapd_bss_config *conf = hapd->conf;
81847c22 1085 u8 ssid[SSID_MAX_LEN + 1];
6fc6879b 1086 int ssid_len, set_ssid;
f3585c8a
JM
1087 char force_ifname[IFNAMSIZ];
1088 u8 if_addr[ETH_ALEN];
01e2231f 1089 int flush_old_stations = 1;
6fc6879b 1090
36501a22 1091 wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s), first=%d)",
39323bc1 1092 __func__, hapd, conf->iface, first);
36501a22 1093
10b58b50 1094#ifdef EAP_SERVER_TNC
39323bc1 1095 if (conf->tnc && tncs_global_init() < 0) {
10b58b50
JM
1096 wpa_printf(MSG_ERROR, "Failed to initialize TNCS");
1097 return -1;
1098 }
1099#endif /* EAP_SERVER_TNC */
1100
36501a22
JM
1101 if (hapd->started) {
1102 wpa_printf(MSG_ERROR, "%s: Interface %s was already started",
39323bc1 1103 __func__, conf->iface);
36501a22
JM
1104 return -1;
1105 }
1106 hapd->started = 1;
1107
2aec4f3c 1108 if (!first || first == -1) {
6448e064
EP
1109 u8 *addr = hapd->own_addr;
1110
1111 if (!is_zero_ether_addr(conf->bssid)) {
6fc6879b 1112 /* Allocate the configured BSSID. */
39323bc1 1113 os_memcpy(hapd->own_addr, conf->bssid, ETH_ALEN);
6fc6879b
JM
1114
1115 if (hostapd_mac_comp(hapd->own_addr,
1116 hapd->iface->bss[0]->own_addr) ==
1117 0) {
bb305cbd
JM
1118 wpa_printf(MSG_ERROR, "BSS '%s' may not have "
1119 "BSSID set to the MAC address of "
39323bc1 1120 "the radio", conf->iface);
6fc6879b
JM
1121 return -1;
1122 }
6448e064
EP
1123 } else if (hapd->iconf->use_driver_iface_addr) {
1124 addr = NULL;
1125 } else {
1126 /* Allocate the next available BSSID. */
1127 do {
1128 inc_byte_array(hapd->own_addr, ETH_ALEN);
1129 } while (mac_in_conf(hapd->iconf, hapd->own_addr));
6fc6879b
JM
1130 }
1131
6023a788 1132 hapd->interface_added = 1;
22a7c9d7 1133 if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS,
6448e064 1134 conf->iface, addr, hapd,
e17a2477 1135 &hapd->drv_priv, force_ifname, if_addr,
39323bc1
KP
1136 conf->bridge[0] ? conf->bridge : NULL,
1137 first == -1)) {
bb305cbd
JM
1138 wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID="
1139 MACSTR ")", MAC2STR(hapd->own_addr));
493ba877 1140 hapd->interface_added = 0;
6fc6879b
JM
1141 return -1;
1142 }
6448e064
EP
1143
1144 if (!addr)
1145 os_memcpy(hapd->own_addr, if_addr, ETH_ALEN);
6fc6879b
JM
1146 }
1147
d2da2249
JB
1148 if (conf->wmm_enabled < 0)
1149 conf->wmm_enabled = hapd->iconf->ieee80211n;
1150
4ec1fd8e 1151#ifdef CONFIG_IEEE80211R_AP
d48d1b88
MB
1152 if (is_zero_ether_addr(conf->r1_key_holder))
1153 os_memcpy(conf->r1_key_holder, hapd->own_addr, ETH_ALEN);
4ec1fd8e 1154#endif /* CONFIG_IEEE80211R_AP */
d48d1b88 1155
01e2231f 1156#ifdef CONFIG_MESH
21ed24f5 1157 if ((hapd->conf->mesh & MESH_ENABLED) && hapd->iface->mconf == NULL)
01e2231f
JL
1158 flush_old_stations = 0;
1159#endif /* CONFIG_MESH */
1160
1161 if (flush_old_stations)
1162 hostapd_flush_old_stations(hapd,
1163 WLAN_REASON_PREV_AUTH_NOT_VALID);
c213cc04
JM
1164 hostapd_set_privacy(hapd, 0);
1165
1166 hostapd_broadcast_wep_clear(hapd);
39323bc1 1167 if (hostapd_setup_encryption(conf->iface, hapd))
c213cc04
JM
1168 return -1;
1169
6fc6879b
JM
1170 /*
1171 * Fetch the SSID from the system and use it or,
1172 * if one was specified in the config file, verify they
1173 * match.
1174 */
1175 ssid_len = hostapd_get_ssid(hapd, ssid, sizeof(ssid));
1176 if (ssid_len < 0) {
bb305cbd 1177 wpa_printf(MSG_ERROR, "Could not read SSID from system");
6fc6879b
JM
1178 return -1;
1179 }
1180 if (conf->ssid.ssid_set) {
1181 /*
1182 * If SSID is specified in the config file and it differs
1183 * from what is being used then force installation of the
1184 * new SSID.
1185 */
1186 set_ssid = (conf->ssid.ssid_len != (size_t) ssid_len ||
1187 os_memcmp(conf->ssid.ssid, ssid, ssid_len) != 0);
1188 } else {
1189 /*
1190 * No SSID in the config file; just use the one we got
1191 * from the system.
1192 */
1193 set_ssid = 0;
1194 conf->ssid.ssid_len = ssid_len;
1195 os_memcpy(conf->ssid.ssid, ssid, conf->ssid.ssid_len);
6fc6879b
JM
1196 }
1197
522450b7
AO
1198 /*
1199 * Short SSID calculation is identical to FCS and it is defined in
1200 * IEEE P802.11-REVmd/D3.0, 9.4.2.170.3 (Calculating the Short-SSID).
1201 */
1202 conf->ssid.short_ssid = crc32(conf->ssid.ssid, conf->ssid.ssid_len);
1203
85141289 1204 if (!hostapd_drv_none(hapd)) {
1ace2f7c 1205 wpa_printf(MSG_DEBUG, "Using interface %s with hwaddr " MACSTR
986de33d 1206 " and ssid \"%s\"",
39323bc1
KP
1207 conf->iface, MAC2STR(hapd->own_addr),
1208 wpa_ssid_txt(conf->ssid.ssid, conf->ssid.ssid_len));
85141289 1209 }
6fc6879b
JM
1210
1211 if (hostapd_setup_wpa_psk(conf)) {
bb305cbd 1212 wpa_printf(MSG_ERROR, "WPA-PSK setup failed.");
6fc6879b
JM
1213 return -1;
1214 }
1215
6fc6879b
JM
1216 /* Set SSID for the kernel driver (to be used in beacon and probe
1217 * response frames) */
986de33d 1218 if (set_ssid && hostapd_set_ssid(hapd, conf->ssid.ssid,
6fc6879b 1219 conf->ssid.ssid_len)) {
bb305cbd 1220 wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
6fc6879b
JM
1221 return -1;
1222 }
1223
ec33bc67 1224 if (wpa_debug_level <= MSG_MSGDUMP)
6fc6879b 1225 conf->radius->msg_dumps = 1;
74784010 1226#ifndef CONFIG_NO_RADIUS
f4111ff3
TB
1227
1228#ifdef CONFIG_SQLITE
1229 if (conf->radius_req_attr_sqlite) {
1230 if (sqlite3_open(conf->radius_req_attr_sqlite,
1231 &hapd->rad_attr_db)) {
1232 wpa_printf(MSG_ERROR, "Could not open SQLite file '%s'",
1233 conf->radius_req_attr_sqlite);
1234 return -1;
1235 }
1236
1237 wpa_printf(MSG_DEBUG, "Opening RADIUS attribute database: %s",
1238 conf->radius_req_attr_sqlite);
1239 if (!db_table_exists(hapd->rad_attr_db, "radius_attributes") &&
1240 db_table_create_radius_attributes(hapd->rad_attr_db) < 0)
1241 return -1;
1242 }
1243#endif /* CONFIG_SQLITE */
1244
6fc6879b
JM
1245 hapd->radius = radius_client_init(hapd, conf->radius);
1246 if (hapd->radius == NULL) {
bb305cbd 1247 wpa_printf(MSG_ERROR, "RADIUS client initialization failed.");
6fc6879b
JM
1248 return -1;
1249 }
b031338c 1250
39323bc1 1251 if (conf->radius_das_port) {
b031338c
JM
1252 struct radius_das_conf das_conf;
1253 os_memset(&das_conf, 0, sizeof(das_conf));
39323bc1
KP
1254 das_conf.port = conf->radius_das_port;
1255 das_conf.shared_secret = conf->radius_das_shared_secret;
b031338c 1256 das_conf.shared_secret_len =
39323bc1
KP
1257 conf->radius_das_shared_secret_len;
1258 das_conf.client_addr = &conf->radius_das_client_addr;
1259 das_conf.time_window = conf->radius_das_time_window;
bde7ba6c 1260 das_conf.require_event_timestamp =
39323bc1 1261 conf->radius_das_require_event_timestamp;
42d30e9e
NL
1262 das_conf.require_message_authenticator =
1263 conf->radius_das_require_message_authenticator;
8047a958
JM
1264 das_conf.ctx = hapd;
1265 das_conf.disconnect = hostapd_das_disconnect;
f456940e 1266 das_conf.coa = hostapd_das_coa;
b031338c
JM
1267 hapd->radius_das = radius_das_init(&das_conf);
1268 if (hapd->radius_das == NULL) {
1269 wpa_printf(MSG_ERROR, "RADIUS DAS initialization "
1270 "failed.");
1271 return -1;
1272 }
1273 }
74784010 1274#endif /* CONFIG_NO_RADIUS */
6fc6879b
JM
1275
1276 if (hostapd_acl_init(hapd)) {
bb305cbd 1277 wpa_printf(MSG_ERROR, "ACL initialization failed.");
6fc6879b
JM
1278 return -1;
1279 }
ad08c363
JM
1280 if (hostapd_init_wps(hapd, conf))
1281 return -1;
6fc6879b 1282
9c2b8204
JM
1283#ifdef CONFIG_DPP
1284 hapd->gas = gas_query_ap_init(hapd, hapd->msg_ctx);
1285 if (!hapd->gas)
1286 return -1;
1287 if (hostapd_dpp_init(hapd))
1288 return -1;
1289#endif /* CONFIG_DPP */
1290
43a7fe2e
CL
1291 if (authsrv_init(hapd) < 0)
1292 return -1;
1293
6fc6879b 1294 if (ieee802_1x_init(hapd)) {
bb305cbd 1295 wpa_printf(MSG_ERROR, "IEEE 802.1X initialization failed.");
6fc6879b
JM
1296 return -1;
1297 }
1298
39323bc1 1299 if ((conf->wpa || conf->osen) && hostapd_setup_wpa(hapd))
6fc6879b
JM
1300 return -1;
1301
1302 if (accounting_init(hapd)) {
bb305cbd 1303 wpa_printf(MSG_ERROR, "Accounting initialization failed.");
6fc6879b
JM
1304 return -1;
1305 }
1306
dca30c3f
JK
1307#ifdef CONFIG_INTERWORKING
1308 if (gas_serv_init(hapd)) {
1309 wpa_printf(MSG_ERROR, "GAS server initialization failed");
1310 return -1;
1311 }
bf7f09bd
JM
1312
1313 if (conf->qos_map_set_len &&
1314 hostapd_drv_set_qos_map(hapd, conf->qos_map_set,
1315 conf->qos_map_set_len)) {
1316 wpa_printf(MSG_ERROR, "Failed to initialize QoS Map");
1317 return -1;
1318 }
dca30c3f
JK
1319#endif /* CONFIG_INTERWORKING */
1320
ec8f36af
KP
1321 if (conf->bss_load_update_period && bss_load_update_init(hapd)) {
1322 wpa_printf(MSG_ERROR, "BSS Load initialization failed");
1323 return -1;
1324 }
1325
1d783762
KP
1326 if (conf->proxy_arp) {
1327 if (x_snoop_init(hapd)) {
1328 wpa_printf(MSG_ERROR,
1329 "Generic snooping infrastructure initialization failed");
1330 return -1;
1331 }
1332
1333 if (dhcp_snoop_init(hapd)) {
1334 wpa_printf(MSG_ERROR,
1335 "DHCP snooping initialization failed");
1336 return -1;
1337 }
bd00c431
KP
1338
1339 if (ndisc_snoop_init(hapd)) {
1340 wpa_printf(MSG_ERROR,
1341 "Neighbor Discovery snooping initialization failed");
1342 return -1;
1343 }
7d597d46
KP
1344 }
1345
85141289 1346 if (!hostapd_drv_none(hapd) && vlan_init(hapd)) {
bb305cbd 1347 wpa_printf(MSG_ERROR, "VLAN initialization failed.");
6fc6879b
JM
1348 return -1;
1349 }
1350
39323bc1 1351 if (!conf->start_disabled && ieee802_11_set_beacon(hapd) < 0)
bad5cdf4 1352 return -1;
6fc6879b 1353
bdffdc5d
JM
1354 if (hapd->wpa_auth && wpa_init_keys(hapd->wpa_auth) < 0)
1355 return -1;
1356
e11f5a2c
JM
1357 if (hapd->driver && hapd->driver->set_operstate)
1358 hapd->driver->set_operstate(hapd->drv_priv, 1);
1359
6fc6879b
JM
1360 return 0;
1361}
1362
1363
990ec378
JM
1364static void hostapd_tx_queue_params(struct hostapd_iface *iface)
1365{
1366 struct hostapd_data *hapd = iface->bss[0];
1367 int i;
1368 struct hostapd_tx_queue_params *p;
1369
01e2231f 1370#ifdef CONFIG_MESH
21ed24f5 1371 if ((hapd->conf->mesh & MESH_ENABLED) && iface->mconf == NULL)
01e2231f
JL
1372 return;
1373#endif /* CONFIG_MESH */
1374
990ec378
JM
1375 for (i = 0; i < NUM_TX_QUEUES; i++) {
1376 p = &iface->conf->tx_queue[i];
1377
990ec378
JM
1378 if (hostapd_set_tx_queue_params(hapd, i, p->aifs, p->cwmin,
1379 p->cwmax, p->burst)) {
bb305cbd
JM
1380 wpa_printf(MSG_DEBUG, "Failed to set TX queue "
1381 "parameters for queue %d.", i);
990ec378
JM
1382 /* Continue anyway */
1383 }
1384 }
1385}
1386
1387
3c4ca363
VN
1388static int hostapd_set_acl_list(struct hostapd_data *hapd,
1389 struct mac_acl_entry *mac_acl,
1390 int n_entries, u8 accept_acl)
1391{
1392 struct hostapd_acl_params *acl_params;
1393 int i, err;
1394
1395 acl_params = os_zalloc(sizeof(*acl_params) +
1396 (n_entries * sizeof(acl_params->mac_acl[0])));
1397 if (!acl_params)
1398 return -ENOMEM;
1399
1400 for (i = 0; i < n_entries; i++)
1401 os_memcpy(acl_params->mac_acl[i].addr, mac_acl[i].addr,
1402 ETH_ALEN);
1403
1404 acl_params->acl_policy = accept_acl;
1405 acl_params->num_mac_acl = n_entries;
1406
1407 err = hostapd_drv_set_acl(hapd, acl_params);
1408
1409 os_free(acl_params);
1410
1411 return err;
1412}
1413
1414
1415static void hostapd_set_acl(struct hostapd_data *hapd)
1416{
1417 struct hostapd_config *conf = hapd->iconf;
1418 int err;
1419 u8 accept_acl;
1420
3cb953e4
JM
1421 if (hapd->iface->drv_max_acl_mac_addrs == 0)
1422 return;
3c4ca363 1423
ebd79f07 1424 if (conf->bss[0]->macaddr_acl == DENY_UNLESS_ACCEPTED) {
cf1600ac
AHS
1425 accept_acl = 1;
1426 err = hostapd_set_acl_list(hapd, conf->bss[0]->accept_mac,
1427 conf->bss[0]->num_accept_mac,
1428 accept_acl);
1429 if (err) {
1430 wpa_printf(MSG_DEBUG, "Failed to set accept acl");
1431 return;
3c4ca363 1432 }
ebd79f07 1433 } else if (conf->bss[0]->macaddr_acl == ACCEPT_UNLESS_DENIED) {
cf1600ac
AHS
1434 accept_acl = 0;
1435 err = hostapd_set_acl_list(hapd, conf->bss[0]->deny_mac,
1436 conf->bss[0]->num_deny_mac,
1437 accept_acl);
1438 if (err) {
1439 wpa_printf(MSG_DEBUG, "Failed to set deny acl");
1440 return;
3c4ca363
VN
1441 }
1442 }
1443}
1444
1445
ad08e141
JM
1446static int start_ctrl_iface_bss(struct hostapd_data *hapd)
1447{
1448 if (!hapd->iface->interfaces ||
1449 !hapd->iface->interfaces->ctrl_iface_init)
1450 return 0;
1451
1452 if (hapd->iface->interfaces->ctrl_iface_init(hapd)) {
1453 wpa_printf(MSG_ERROR,
1454 "Failed to setup control interface for %s",
1455 hapd->conf->iface);
1456 return -1;
1457 }
1458
1459 return 0;
1460}
1461
1462
1463static int start_ctrl_iface(struct hostapd_iface *iface)
1464{
1465 size_t i;
1466
1467 if (!iface->interfaces || !iface->interfaces->ctrl_iface_init)
1468 return 0;
1469
1470 for (i = 0; i < iface->num_bss; i++) {
1471 struct hostapd_data *hapd = iface->bss[i];
1472 if (iface->interfaces->ctrl_iface_init(hapd)) {
1473 wpa_printf(MSG_ERROR,
1474 "Failed to setup control interface for %s",
1475 hapd->conf->iface);
1476 return -1;
1477 }
1478 }
1479
1480 return 0;
1481}
1482
1483
f0793bf1
JM
1484static void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx)
1485{
1486 struct hostapd_iface *iface = eloop_ctx;
1487
1488 if (!iface->wait_channel_update) {
1489 wpa_printf(MSG_INFO, "Channel list update timeout, but interface was not waiting for it");
1490 return;
1491 }
1492
1493 /*
1494 * It is possible that the existing channel list is acceptable, so try
1495 * to proceed.
1496 */
1497 wpa_printf(MSG_DEBUG, "Channel list update timeout - try to continue anyway");
1498 setup_interface2(iface);
1499}
1500
1501
795baf77 1502void hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator)
f0793bf1 1503{
795baf77 1504 if (!iface->wait_channel_update || initiator != REGDOM_SET_BY_USER)
f0793bf1
JM
1505 return;
1506
1507 wpa_printf(MSG_DEBUG, "Channel list updated - continue setup");
1508 eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
1509 setup_interface2(iface);
1510}
1511
1512
ddaa83eb 1513static int setup_interface(struct hostapd_iface *iface)
6fc6879b
JM
1514{
1515 struct hostapd_data *hapd = iface->bss[0];
6fc6879b 1516 size_t i;
6fc6879b 1517
354c903f
MB
1518 /*
1519 * It is possible that setup_interface() is called after the interface
1520 * was disabled etc., in which case driver_ap_teardown is possibly set
1521 * to 1. Clear it here so any other key/station deletion, which is not
1522 * part of a teardown flow, would also call the relevant driver
1523 * callbacks.
1524 */
1525 iface->driver_ap_teardown = 0;
1526
2db938e8
JM
1527 if (!iface->phy[0]) {
1528 const char *phy = hostapd_drv_get_radio_name(hapd);
1529 if (phy) {
1530 wpa_printf(MSG_DEBUG, "phy: %s", phy);
1531 os_strlcpy(iface->phy, phy, sizeof(iface->phy));
1532 }
1533 }
1534
6fc6879b 1535 /*
e5f2b59c
JM
1536 * Make sure that all BSSes get configured with a pointer to the same
1537 * driver interface.
6fc6879b 1538 */
e5f2b59c 1539 for (i = 1; i < iface->num_bss; i++) {
6fc6879b
JM
1540 iface->bss[i]->driver = hapd->driver;
1541 iface->bss[i]->drv_priv = hapd->drv_priv;
1542 }
1543
1544 if (hostapd_validate_bssid_configuration(iface))
1545 return -1;
1546
ad08e141
JM
1547 /*
1548 * Initialize control interfaces early to allow external monitoring of
1549 * channel setup operations that may take considerable amount of time
1550 * especially for DFS cases.
1551 */
1552 if (start_ctrl_iface(iface))
1553 return -1;
1554
6f4071c0 1555 if (hapd->iconf->country[0] && hapd->iconf->country[1]) {
f0793bf1
JM
1556 char country[4], previous_country[4];
1557
e1c5faf0 1558 hostapd_set_state(iface, HAPD_IFACE_COUNTRY_UPDATE);
f0793bf1
JM
1559 if (hostapd_get_country(hapd, previous_country) < 0)
1560 previous_country[0] = '\0';
1561
6f4071c0
JM
1562 os_memcpy(country, hapd->iconf->country, 3);
1563 country[3] = '\0';
1564 if (hostapd_set_country(hapd, country) < 0) {
1565 wpa_printf(MSG_ERROR, "Failed to set country code");
1566 return -1;
1567 }
f0793bf1
JM
1568
1569 wpa_printf(MSG_DEBUG, "Previous country code %s, new country code %s",
1570 previous_country, country);
1571
1572 if (os_strncmp(previous_country, country, 2) != 0) {
1573 wpa_printf(MSG_DEBUG, "Continue interface setup after channel list update");
1574 iface->wait_channel_update = 1;
fd924134 1575 eloop_register_timeout(5, 0,
f0793bf1
JM
1576 channel_list_update_timeout,
1577 iface, NULL);
1578 return 0;
1579 }
6fc6879b
JM
1580 }
1581
f0793bf1
JM
1582 return setup_interface2(iface);
1583}
1584
1585
bb781c76
AB
1586static int configured_fixed_chan_to_freq(struct hostapd_iface *iface)
1587{
1588 int freq, i, j;
1589
1590 if (!iface->conf->channel)
1591 return 0;
1592 if (iface->conf->op_class) {
1593 freq = ieee80211_chan_to_freq(NULL, iface->conf->op_class,
1594 iface->conf->channel);
1595 if (freq < 0) {
1596 wpa_printf(MSG_INFO,
1597 "Could not convert op_class %u channel %u to operating frequency",
1598 iface->conf->op_class, iface->conf->channel);
1599 return -1;
1600 }
1601 iface->freq = freq;
1602 return 0;
1603 }
1604
1605 /* Old configurations using only 2.4/5/60 GHz bands may not specify the
1606 * op_class parameter. Select a matching channel from the configured
1607 * mode using the channel parameter for these cases.
1608 */
1609 for (j = 0; j < iface->num_hw_features; j++) {
1610 struct hostapd_hw_modes *mode = &iface->hw_features[j];
1611
1612 if (iface->conf->hw_mode != HOSTAPD_MODE_IEEE80211ANY &&
1613 iface->conf->hw_mode != mode->mode)
1614 continue;
1615 for (i = 0; i < mode->num_channels; i++) {
1616 struct hostapd_channel_data *chan = &mode->channels[i];
1617
1618 if (chan->chan == iface->conf->channel &&
1619 !is_6ghz_freq(chan->freq)) {
1620 iface->freq = chan->freq;
1621 return 0;
1622 }
1623 }
1624 }
1625
1626 wpa_printf(MSG_INFO, "Could not determine operating frequency");
1627 return -1;
1628}
1629
1630
f0793bf1
JM
1631static int setup_interface2(struct hostapd_iface *iface)
1632{
1633 iface->wait_channel_update = 0;
1634
6fc6879b
JM
1635 if (hostapd_get_hw_features(iface)) {
1636 /* Not all drivers support this yet, so continue without hw
1637 * feature data. */
1638 } else {
bb781c76
AB
1639 int ret;
1640
1641 ret = configured_fixed_chan_to_freq(iface);
1642 if (ret < 0)
1643 goto fail;
1644
e5620bf0
VK
1645 if (iface->conf->op_class) {
1646 int ch_width;
1647
1648 ch_width = op_class_to_ch_width(iface->conf->op_class);
1649 hostapd_set_oper_chwidth(iface->conf, ch_width);
1650 }
1651
bb781c76 1652 ret = hostapd_select_hw_mode(iface);
ddaa83eb 1653 if (ret < 0) {
bb305cbd
JM
1654 wpa_printf(MSG_ERROR, "Could not select hw_mode and "
1655 "channel. (%d)", ret);
0f23a5e7 1656 goto fail;
ddaa83eb 1657 }
50f4f2a0
MK
1658 if (ret == 1) {
1659 wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback (ACS)");
1660 return 0;
1661 }
241dd76c
AAL
1662 ret = hostapd_check_edmg_capab(iface);
1663 if (ret < 0)
1664 goto fail;
ad1e68e6
JM
1665 ret = hostapd_check_ht_capab(iface);
1666 if (ret < 0)
0f23a5e7 1667 goto fail;
ad1e68e6
JM
1668 if (ret == 1) {
1669 wpa_printf(MSG_DEBUG, "Interface initialization will "
1670 "be completed in a callback");
1671 return 0;
1672 }
e76da505
JD
1673
1674 if (iface->conf->ieee80211h)
1675 wpa_printf(MSG_DEBUG, "DFS support is enabled");
ad1e68e6
JM
1676 }
1677 return hostapd_setup_interface_complete(iface, 0);
0f23a5e7
JM
1678
1679fail:
1680 hostapd_set_state(iface, HAPD_IFACE_DISABLED);
1681 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
1682 if (iface->interfaces && iface->interfaces->terminate_on_error)
1683 eloop_terminate();
1684 return -1;
ad1e68e6
JM
1685}
1686
1687
6959145b
AN
1688#ifdef CONFIG_FST
1689
1690static const u8 * fst_hostapd_get_bssid_cb(void *ctx)
1691{
1692 struct hostapd_data *hapd = ctx;
1693
1694 return hapd->own_addr;
1695}
1696
1697
1698static void fst_hostapd_get_channel_info_cb(void *ctx,
1699 enum hostapd_hw_mode *hw_mode,
1700 u8 *channel)
1701{
1702 struct hostapd_data *hapd = ctx;
1703
1704 *hw_mode = ieee80211_freq_to_chan(hapd->iface->freq, channel);
1705}
1706
1707
84bcb4e7 1708static void fst_hostapd_set_ies_cb(void *ctx, const struct wpabuf *fst_ies)
6959145b
AN
1709{
1710 struct hostapd_data *hapd = ctx;
1711
1712 if (hapd->iface->fst_ies != fst_ies) {
1713 hapd->iface->fst_ies = fst_ies;
1714 if (ieee802_11_set_beacon(hapd))
1715 wpa_printf(MSG_WARNING, "FST: Cannot set beacon");
1716 }
1717}
1718
1719
1720static int fst_hostapd_send_action_cb(void *ctx, const u8 *da,
1721 struct wpabuf *buf)
1722{
1723 struct hostapd_data *hapd = ctx;
1724
1725 return hostapd_drv_send_action(hapd, hapd->iface->freq, 0, da,
1726 wpabuf_head(buf), wpabuf_len(buf));
1727}
1728
1729
a0f04da5 1730static const struct wpabuf * fst_hostapd_get_mb_ie_cb(void *ctx, const u8 *addr)
6959145b
AN
1731{
1732 struct hostapd_data *hapd = ctx;
1733 struct sta_info *sta = ap_get_sta(hapd, addr);
1734
1735 return sta ? sta->mb_ies : NULL;
1736}
1737
1738
1739static void fst_hostapd_update_mb_ie_cb(void *ctx, const u8 *addr,
1740 const u8 *buf, size_t size)
1741{
1742 struct hostapd_data *hapd = ctx;
1743 struct sta_info *sta = ap_get_sta(hapd, addr);
1744
1745 if (sta) {
1746 struct mb_ies_info info;
1747
1748 if (!mb_ies_info_by_ies(&info, buf, size)) {
1749 wpabuf_free(sta->mb_ies);
1750 sta->mb_ies = mb_ies_by_info(&info);
1751 }
1752 }
1753}
1754
1755
1756static const u8 * fst_hostapd_get_sta(struct fst_get_peer_ctx **get_ctx,
1757 Boolean mb_only)
1758{
1759 struct sta_info *s = (struct sta_info *) *get_ctx;
1760
1761 if (mb_only) {
1762 for (; s && !s->mb_ies; s = s->next)
1763 ;
1764 }
1765
1766 if (s) {
1767 *get_ctx = (struct fst_get_peer_ctx *) s->next;
1768
1769 return s->addr;
1770 }
1771
1772 *get_ctx = NULL;
1773 return NULL;
1774}
1775
1776
1777static const u8 * fst_hostapd_get_peer_first(void *ctx,
1778 struct fst_get_peer_ctx **get_ctx,
1779 Boolean mb_only)
1780{
1781 struct hostapd_data *hapd = ctx;
1782
1783 *get_ctx = (struct fst_get_peer_ctx *) hapd->sta_list;
1784
1785 return fst_hostapd_get_sta(get_ctx, mb_only);
1786}
1787
1788
1789static const u8 * fst_hostapd_get_peer_next(void *ctx,
1790 struct fst_get_peer_ctx **get_ctx,
1791 Boolean mb_only)
1792{
1793 return fst_hostapd_get_sta(get_ctx, mb_only);
1794}
1795
1796
1797void fst_hostapd_fill_iface_obj(struct hostapd_data *hapd,
1798 struct fst_wpa_obj *iface_obj)
1799{
1800 iface_obj->ctx = hapd;
1801 iface_obj->get_bssid = fst_hostapd_get_bssid_cb;
1802 iface_obj->get_channel_info = fst_hostapd_get_channel_info_cb;
1803 iface_obj->set_ies = fst_hostapd_set_ies_cb;
1804 iface_obj->send_action = fst_hostapd_send_action_cb;
1805 iface_obj->get_mb_ie = fst_hostapd_get_mb_ie_cb;
1806 iface_obj->update_mb_ie = fst_hostapd_update_mb_ie_cb;
1807 iface_obj->get_peer_first = fst_hostapd_get_peer_first;
1808 iface_obj->get_peer_next = fst_hostapd_get_peer_next;
1809}
1810
1811#endif /* CONFIG_FST */
1812
a8913881
JM
1813#ifdef CONFIG_OWE
1814
1815static int hostapd_owe_iface_iter(struct hostapd_iface *iface, void *ctx)
1816{
1817 struct hostapd_data *hapd = ctx;
1818 size_t i;
1819
1820 for (i = 0; i < iface->num_bss; i++) {
1821 struct hostapd_data *bss = iface->bss[i];
1822
1823 if (os_strcmp(hapd->conf->owe_transition_ifname,
1824 bss->conf->iface) != 0)
1825 continue;
1826
1827 wpa_printf(MSG_DEBUG,
1828 "OWE: ifname=%s found transition mode ifname=%s BSSID "
1829 MACSTR " SSID %s",
1830 hapd->conf->iface, bss->conf->iface,
1831 MAC2STR(bss->own_addr),
1832 wpa_ssid_txt(bss->conf->ssid.ssid,
1833 bss->conf->ssid.ssid_len));
1834 if (!bss->conf->ssid.ssid_set || !bss->conf->ssid.ssid_len ||
1835 is_zero_ether_addr(bss->own_addr))
1836 continue;
1837
1838 os_memcpy(hapd->conf->owe_transition_bssid, bss->own_addr,
1839 ETH_ALEN);
1840 os_memcpy(hapd->conf->owe_transition_ssid,
1841 bss->conf->ssid.ssid, bss->conf->ssid.ssid_len);
1842 hapd->conf->owe_transition_ssid_len = bss->conf->ssid.ssid_len;
1843 wpa_printf(MSG_DEBUG,
1844 "OWE: Copied transition mode information");
1845 return 1;
1846 }
1847
1848 return 0;
1849}
1850
1851
1852int hostapd_owe_trans_get_info(struct hostapd_data *hapd)
1853{
1854 if (hapd->conf->owe_transition_ssid_len > 0 &&
1855 !is_zero_ether_addr(hapd->conf->owe_transition_bssid))
1856 return 0;
1857
1858 /* Find transition mode SSID/BSSID information from a BSS operated by
1859 * this hostapd instance. */
1860 if (!hapd->iface->interfaces ||
1861 !hapd->iface->interfaces->for_each_interface)
1862 return hostapd_owe_iface_iter(hapd->iface, hapd);
1863 else
1864 return hapd->iface->interfaces->for_each_interface(
1865 hapd->iface->interfaces, hostapd_owe_iface_iter, hapd);
1866}
1867
1868
1869static int hostapd_owe_iface_iter2(struct hostapd_iface *iface, void *ctx)
1870{
1871 size_t i;
1872
1873 for (i = 0; i < iface->num_bss; i++) {
1874 struct hostapd_data *bss = iface->bss[i];
1875 int res;
1876
a8913881
JM
1877 if (!bss->conf->owe_transition_ifname[0])
1878 continue;
1879 res = hostapd_owe_trans_get_info(bss);
a8913881
JM
1880 if (res == 0)
1881 continue;
1882 wpa_printf(MSG_DEBUG,
1883 "OWE: Matching transition mode interface enabled - update beacon data for %s",
1884 bss->conf->iface);
1885 ieee802_11_set_beacon(bss);
1886 }
1887
1888 return 0;
1889}
1890
1891#endif /* CONFIG_OWE */
1892
1893
1894static void hostapd_owe_update_trans(struct hostapd_iface *iface)
1895{
1896#ifdef CONFIG_OWE
1897 /* Check whether the enabled BSS can complete OWE transition mode
1898 * configuration for any pending interface. */
1899 if (!iface->interfaces ||
1900 !iface->interfaces->for_each_interface)
1901 hostapd_owe_iface_iter2(iface, NULL);
1902 else
1903 iface->interfaces->for_each_interface(
1904 iface->interfaces, hostapd_owe_iface_iter2, NULL);
1905#endif /* CONFIG_OWE */
1906}
1907
1908
c4315e66
TM
1909static void hostapd_interface_setup_failure_handler(void *eloop_ctx,
1910 void *timeout_ctx)
1911{
1912 struct hostapd_iface *iface = eloop_ctx;
1913 struct hostapd_data *hapd;
1914
1915 if (iface->num_bss < 1 || !iface->bss || !iface->bss[0])
1916 return;
1917 hapd = iface->bss[0];
1918 if (hapd->setup_complete_cb)
1919 hapd->setup_complete_cb(hapd->setup_complete_cb_ctx);
1920}
1921
1922
053693d2
SD
1923static int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface,
1924 int err)
ad1e68e6
JM
1925{
1926 struct hostapd_data *hapd = iface->bss[0];
ad1e68e6
JM
1927 size_t j;
1928 u8 *prev_addr;
01e2231f 1929 int delay_apply_cfg = 0;
c13578c3 1930 int res_dfs_offload = 0;
ad1e68e6 1931
0f23a5e7
JM
1932 if (err)
1933 goto fail;
6fc6879b 1934
ad1e68e6 1935 wpa_printf(MSG_DEBUG, "Completing interface initialization");
5f9b4afd 1936 if (iface->freq) {
e76da505
JD
1937#ifdef NEED_AP_MLME
1938 int res;
1939#endif /* NEED_AP_MLME */
1940
bb305cbd
JM
1941 wpa_printf(MSG_DEBUG, "Mode: %s Channel: %d "
1942 "Frequency: %d MHz",
dc036d9e
JM
1943 hostapd_hw_mode_txt(iface->conf->hw_mode),
1944 iface->conf->channel, iface->freq);
6fc6879b 1945
e76da505 1946#ifdef NEED_AP_MLME
c53a9bf8
SD
1947 /* Handle DFS only if it is not offloaded to the driver */
1948 if (!(iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)) {
1949 /* Check DFS */
1950 res = hostapd_handle_dfs(iface);
1951 if (res <= 0) {
1952 if (res < 0)
1953 goto fail;
1954 return res;
1955 }
c13578c3
AK
1956 } else {
1957 /* If DFS is offloaded to the driver */
1958 res_dfs_offload = hostapd_handle_dfs_offload(iface);
1959 if (res_dfs_offload <= 0) {
1960 if (res_dfs_offload < 0)
1961 goto fail;
1962 } else {
1963 wpa_printf(MSG_DEBUG,
1964 "Proceed with AP/channel setup");
1965 /*
1966 * If this is a DFS channel, move to completing
1967 * AP setup.
1968 */
1969 if (res_dfs_offload == 1)
1970 goto dfs_offload;
1971 /* Otherwise fall through. */
1972 }
0f23a5e7 1973 }
e76da505
JD
1974#endif /* NEED_AP_MLME */
1975
01e2231f
JL
1976#ifdef CONFIG_MESH
1977 if (iface->mconf != NULL) {
1978 wpa_printf(MSG_DEBUG,
1979 "%s: Mesh configuration will be applied while joining the mesh network",
1980 iface->bss[0]->conf->iface);
1981 delay_apply_cfg = 1;
1982 }
1983#endif /* CONFIG_MESH */
1984
1985 if (!delay_apply_cfg &&
1986 hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq,
9c6d8e1d 1987 hapd->iconf->channel,
bebd91e9
AAL
1988 hapd->iconf->enable_edmg,
1989 hapd->iconf->edmg_channel,
fe0f58fa 1990 hapd->iconf->ieee80211n,
fa476336 1991 hapd->iconf->ieee80211ac,
88005ee9 1992 hapd->iconf->ieee80211ax,
fa476336 1993 hapd->iconf->secondary_channel,
c6b7ac07
JC
1994 hostapd_get_oper_chwidth(hapd->iconf),
1995 hostapd_get_oper_centr_freq_seg0_idx(
1996 hapd->iconf),
1997 hostapd_get_oper_centr_freq_seg1_idx(
1998 hapd->iconf))) {
bb305cbd
JM
1999 wpa_printf(MSG_ERROR, "Could not set channel for "
2000 "kernel driver");
0f23a5e7 2001 goto fail;
ddaa83eb
JM
2002 }
2003 }
6fc6879b 2004
5a5009dc 2005 if (iface->current_mode) {
34445d12 2006 if (hostapd_prepare_rates(iface, iface->current_mode)) {
5a5009dc
FF
2007 wpa_printf(MSG_ERROR, "Failed to prepare rates "
2008 "table.");
2009 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
2010 HOSTAPD_LEVEL_WARNING,
2011 "Failed to prepare rates table.");
0f23a5e7 2012 goto fail;
5a5009dc
FF
2013 }
2014 }
2015
bf0021ed
JM
2016 if (hapd->iconf->rts_threshold >= -1 &&
2017 hostapd_set_rts(hapd, hapd->iconf->rts_threshold) &&
2018 hapd->iconf->rts_threshold >= -1) {
bb305cbd
JM
2019 wpa_printf(MSG_ERROR, "Could not set RTS threshold for "
2020 "kernel driver");
0f23a5e7 2021 goto fail;
ddaa83eb
JM
2022 }
2023
bf0021ed
JM
2024 if (hapd->iconf->fragm_threshold >= -1 &&
2025 hostapd_set_frag(hapd, hapd->iconf->fragm_threshold) &&
2026 hapd->iconf->fragm_threshold != -1) {
bb305cbd
JM
2027 wpa_printf(MSG_ERROR, "Could not set fragmentation threshold "
2028 "for kernel driver");
0f23a5e7 2029 goto fail;
ddaa83eb 2030 }
6fc6879b 2031
ddaa83eb
JM
2032 prev_addr = hapd->own_addr;
2033
2034 for (j = 0; j < iface->num_bss; j++) {
2035 hapd = iface->bss[j];
2036 if (j)
2037 os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN);
ac1a2240 2038 if (hostapd_setup_bss(hapd, j == 0)) {
9140caf5 2039 for (;;) {
ac1a2240 2040 hapd = iface->bss[j];
438e1333 2041 hostapd_bss_deinit_no_free(hapd);
ac1a2240 2042 hostapd_free_hapd_data(hapd);
9140caf5
JM
2043 if (j == 0)
2044 break;
2045 j--;
2046 }
0f23a5e7 2047 goto fail;
ac1a2240 2048 }
902c07a7 2049 if (is_zero_ether_addr(hapd->conf->bssid))
ddaa83eb
JM
2050 prev_addr = hapd->own_addr;
2051 }
dc036d9e 2052 hapd = iface->bss[0];
ddaa83eb
JM
2053
2054 hostapd_tx_queue_params(iface);
2055
2056 ap_list_init(iface);
2057
3c4ca363
VN
2058 hostapd_set_acl(hapd);
2059
ddaa83eb
JM
2060 if (hostapd_driver_commit(hapd) < 0) {
2061 wpa_printf(MSG_ERROR, "%s: Failed to commit driver "
2062 "configuration", __func__);
0f23a5e7 2063 goto fail;
ddaa83eb
JM
2064 }
2065
86795546
VA
2066 /*
2067 * WPS UPnP module can be initialized only when the "upnp_iface" is up.
2068 * If "interface" and "upnp_iface" are the same (e.g., non-bridge
2069 * mode), the interface is up only after driver_commit, so initialize
2070 * WPS after driver_commit.
2071 */
2072 for (j = 0; j < iface->num_bss; j++) {
2073 if (hostapd_init_wps_complete(iface->bss[j]))
0f23a5e7 2074 goto fail;
86795546
VA
2075 }
2076
c13578c3
AK
2077 if ((iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
2078 !res_dfs_offload) {
2079 /*
2080 * If freq is DFS, and DFS is offloaded to the driver, then wait
2081 * for CAC to complete.
2082 */
2083 wpa_printf(MSG_DEBUG, "%s: Wait for CAC to complete", __func__);
2084 return res_dfs_offload;
2085 }
2086
2087#ifdef NEED_AP_MLME
2088dfs_offload:
2089#endif /* NEED_AP_MLME */
6959145b
AN
2090
2091#ifdef CONFIG_FST
2092 if (hapd->iconf->fst_cfg.group_id[0]) {
2093 struct fst_wpa_obj iface_obj;
2094
2095 fst_hostapd_fill_iface_obj(hapd, &iface_obj);
2096 iface->fst = fst_attach(hapd->conf->iface, hapd->own_addr,
2097 &iface_obj, &hapd->iconf->fst_cfg);
2098 if (!iface->fst) {
2099 wpa_printf(MSG_ERROR, "Could not attach to FST %s",
2100 hapd->iconf->fst_cfg.group_id);
2101 goto fail;
2102 }
2103 }
2104#endif /* CONFIG_FST */
2105
e1c5faf0 2106 hostapd_set_state(iface, HAPD_IFACE_ENABLED);
a8913881 2107 hostapd_owe_update_trans(iface);
ef721751 2108 airtime_policy_update_init(iface);
7d6d7370 2109 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_ENABLED);
c76e5d7f
JB
2110 if (hapd->setup_complete_cb)
2111 hapd->setup_complete_cb(hapd->setup_complete_cb_ctx);
2112
ad1e68e6
JM
2113 wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
2114 iface->bss[0]->conf->iface);
2b6623ab
JM
2115 if (iface->interfaces && iface->interfaces->terminate_on_error > 0)
2116 iface->interfaces->terminate_on_error--;
ad1e68e6 2117
061269b3 2118 for (j = 0; j < iface->num_bss; j++)
0998d9bd 2119 hostapd_neighbor_set_own_report(iface->bss[j]);
061269b3 2120
21db94c5 2121 return 0;
0f23a5e7
JM
2122
2123fail:
2124 wpa_printf(MSG_ERROR, "Interface initialization failed");
2125 hostapd_set_state(iface, HAPD_IFACE_DISABLED);
2126 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
6959145b
AN
2127#ifdef CONFIG_FST
2128 if (iface->fst) {
2129 fst_detach(iface->fst);
2130 iface->fst = NULL;
2131 }
2132#endif /* CONFIG_FST */
c4315e66
TM
2133
2134 if (iface->interfaces && iface->interfaces->terminate_on_error) {
0f23a5e7 2135 eloop_terminate();
c4315e66
TM
2136 } else if (hapd->setup_complete_cb) {
2137 /*
2138 * Calling hapd->setup_complete_cb directly may cause iface
2139 * deinitialization which may be accessed later by the caller.
2140 */
2141 eloop_register_timeout(0, 0,
2142 hostapd_interface_setup_failure_handler,
2143 iface, NULL);
2144 }
2145
0f23a5e7 2146 return -1;
6fc6879b
JM
2147}
2148
2149
053693d2
SD
2150/**
2151 * hostapd_setup_interface_complete - Complete interface setup
2152 *
2153 * This function is called when previous steps in the interface setup has been
2154 * completed. This can also start operations, e.g., DFS, that will require
2155 * additional processing before interface is ready to be enabled. Such
2156 * operations will call this function from eloop callbacks when finished.
2157 */
2158int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)
2159{
2160 struct hapd_interfaces *interfaces = iface->interfaces;
2161 struct hostapd_data *hapd = iface->bss[0];
2162 unsigned int i;
2163 int not_ready_in_sync_ifaces = 0;
2164
2165 if (!iface->need_to_start_in_sync)
2166 return hostapd_setup_interface_complete_sync(iface, err);
2167
2168 if (err) {
2169 wpa_printf(MSG_ERROR, "Interface initialization failed");
2170 hostapd_set_state(iface, HAPD_IFACE_DISABLED);
2171 iface->need_to_start_in_sync = 0;
2172 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
2173 if (interfaces && interfaces->terminate_on_error)
2174 eloop_terminate();
2175 return -1;
2176 }
2177
2178 if (iface->ready_to_start_in_sync) {
2179 /* Already in ready and waiting. should never happpen */
2180 return 0;
2181 }
2182
2183 for (i = 0; i < interfaces->count; i++) {
2184 if (interfaces->iface[i]->need_to_start_in_sync &&
2185 !interfaces->iface[i]->ready_to_start_in_sync)
2186 not_ready_in_sync_ifaces++;
2187 }
2188
2189 /*
2190 * Check if this is the last interface, if yes then start all the other
2191 * waiting interfaces. If not, add this interface to the waiting list.
2192 */
2193 if (not_ready_in_sync_ifaces > 1 && iface->state == HAPD_IFACE_DFS) {
2194 /*
2195 * If this interface went through CAC, do not synchronize, just
2196 * start immediately.
2197 */
2198 iface->need_to_start_in_sync = 0;
2199 wpa_printf(MSG_INFO,
2200 "%s: Finished CAC - bypass sync and start interface",
2201 iface->bss[0]->conf->iface);
2202 return hostapd_setup_interface_complete_sync(iface, err);
2203 }
2204
2205 if (not_ready_in_sync_ifaces > 1) {
2206 /* need to wait as there are other interfaces still coming up */
2207 iface->ready_to_start_in_sync = 1;
2208 wpa_printf(MSG_INFO,
2209 "%s: Interface waiting to sync with other interfaces",
2210 iface->bss[0]->conf->iface);
2211 return 0;
2212 }
2213
2214 wpa_printf(MSG_INFO,
2215 "%s: Last interface to sync - starting all interfaces",
2216 iface->bss[0]->conf->iface);
2217 iface->need_to_start_in_sync = 0;
2218 hostapd_setup_interface_complete_sync(iface, err);
2219 for (i = 0; i < interfaces->count; i++) {
2220 if (interfaces->iface[i]->need_to_start_in_sync &&
2221 interfaces->iface[i]->ready_to_start_in_sync) {
2222 hostapd_setup_interface_complete_sync(
2223 interfaces->iface[i], 0);
2224 /* Only once the interfaces are sync started */
2225 interfaces->iface[i]->need_to_start_in_sync = 0;
2226 }
2227 }
2228
2229 return 0;
2230}
2231
2232
6fc6879b 2233/**
ddaa83eb 2234 * hostapd_setup_interface - Setup of an interface
6fc6879b 2235 * @iface: Pointer to interface data.
ddaa83eb 2236 * Returns: 0 on success, -1 on failure
6fc6879b
JM
2237 *
2238 * Initializes the driver interface, validates the configuration,
2239 * and sets driver parameters based on the configuration.
ddaa83eb 2240 * Flushes old stations, sets the channel, encryption,
6fc6879b 2241 * beacons, and WDS links based on the configuration.
0dfd2c61
JM
2242 *
2243 * If interface setup requires more time, e.g., to perform HT co-ex scans, ACS,
2244 * or DFS operations, this function returns 0 before such operations have been
2245 * completed. The pending operations are registered into eloop and will be
2246 * completed from eloop callbacks. Those callbacks end up calling
2247 * hostapd_setup_interface_complete() once setup has been completed.
6fc6879b 2248 */
5c333467 2249int hostapd_setup_interface(struct hostapd_iface *iface)
6fc6879b 2250{
ddaa83eb
JM
2251 int ret;
2252
2253 ret = setup_interface(iface);
2254 if (ret) {
bee07ce8 2255 wpa_printf(MSG_ERROR, "%s: Unable to setup interface.",
6fc6879b
JM
2256 iface->bss[0]->conf->iface);
2257 return -1;
2258 }
2259
6fc6879b
JM
2260 return 0;
2261}
2262
2263
6fc6879b
JM
2264/**
2265 * hostapd_alloc_bss_data - Allocate and initialize per-BSS data
2266 * @hapd_iface: Pointer to interface data
2267 * @conf: Pointer to per-interface configuration
2268 * @bss: Pointer to per-BSS configuration for this BSS
2269 * Returns: Pointer to allocated BSS data
2270 *
2271 * This function is used to allocate per-BSS data structure. This data will be
2272 * freed after hostapd_cleanup() is called for it during interface
2273 * deinitialization.
2274 */
b6a7859d 2275struct hostapd_data *
6fc6879b
JM
2276hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,
2277 struct hostapd_config *conf,
2278 struct hostapd_bss_config *bss)
2279{
2280 struct hostapd_data *hapd;
2281
2282 hapd = os_zalloc(sizeof(*hapd));
2283 if (hapd == NULL)
2284 return NULL;
2285
d24df7c3 2286 hapd->new_assoc_sta_cb = hostapd_new_assoc_sta;
6fc6879b
JM
2287 hapd->iconf = conf;
2288 hapd->conf = bss;
2289 hapd->iface = hapd_iface;
db5e53cb
JM
2290 if (conf)
2291 hapd->driver = conf->driver;
9e7d033e 2292 hapd->ctrl_sock = -1;
56885eec 2293 dl_list_init(&hapd->ctrl_dst);
f2f8616e 2294 dl_list_init(&hapd->nr_db);
91d91abf 2295 hapd->dhcp_sock = -1;
c5fee160
MB
2296#ifdef CONFIG_IEEE80211R_AP
2297 dl_list_init(&hapd->l2_queue);
50bd8e0a 2298 dl_list_init(&hapd->l2_oui_queue);
c5fee160 2299#endif /* CONFIG_IEEE80211R_AP */
ff9f40ae
JM
2300#ifdef CONFIG_SAE
2301 dl_list_init(&hapd->sae_commit_queue);
2302#endif /* CONFIG_SAE */
6fc6879b
JM
2303
2304 return hapd;
6fc6879b
JM
2305}
2306
2307
54246f8d
JM
2308static void hostapd_bss_deinit(struct hostapd_data *hapd)
2309{
9c10be3f
JM
2310 if (!hapd)
2311 return;
54246f8d 2312 wpa_printf(MSG_DEBUG, "%s: deinit bss %s", __func__,
8fc22fdd 2313 hapd->conf ? hapd->conf->iface : "N/A");
438e1333 2314 hostapd_bss_deinit_no_free(hapd);
39c3bfcd 2315 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
f4111ff3
TB
2316#ifdef CONFIG_SQLITE
2317 if (hapd->rad_attr_db) {
2318 sqlite3_close(hapd->rad_attr_db);
2319 hapd->rad_attr_db = NULL;
2320 }
2321#endif /* CONFIG_SQLITE */
54246f8d
JM
2322 hostapd_cleanup(hapd);
2323}
2324
2325
5c333467 2326void hostapd_interface_deinit(struct hostapd_iface *iface)
5fa30f32 2327{
390e489c 2328 int j;
5fa30f32 2329
747c85f9 2330 wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
5fa30f32
JM
2331 if (iface == NULL)
2332 return;
2333
39c3bfcd
JM
2334 hostapd_set_state(iface, HAPD_IFACE_DISABLED);
2335
f0793bf1
JM
2336 eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
2337 iface->wait_channel_update = 0;
2338
6959145b
AN
2339#ifdef CONFIG_FST
2340 if (iface->fst) {
2341 fst_detach(iface->fst);
2342 iface->fst = NULL;
2343 }
2344#endif /* CONFIG_FST */
2345
1b85cad2 2346 for (j = (int) iface->num_bss - 1; j >= 0; j--) {
9c10be3f
JM
2347 if (!iface->bss)
2348 break;
54246f8d 2349 hostapd_bss_deinit(iface->bss[j]);
9c10be3f 2350 }
4a0e0115
MW
2351
2352#ifdef CONFIG_IEEE80211N
2353#ifdef NEED_AP_MLME
2354 hostapd_stop_setup_timers(iface);
2355 eloop_cancel_timeout(ap_ht2040_timeout, iface, NULL);
2356#endif /* NEED_AP_MLME */
2357#endif /* CONFIG_IEEE80211N */
f7c47833
JM
2358}
2359
2360
2361void hostapd_interface_free(struct hostapd_iface *iface)
2362{
2363 size_t j;
747c85f9
JM
2364 wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
2365 for (j = 0; j < iface->num_bss; j++) {
9c10be3f
JM
2366 if (!iface->bss)
2367 break;
747c85f9
JM
2368 wpa_printf(MSG_DEBUG, "%s: free hapd %p",
2369 __func__, iface->bss[j]);
5fa30f32 2370 os_free(iface->bss[j]);
747c85f9 2371 }
5fa30f32
JM
2372 hostapd_cleanup_iface(iface);
2373}
fa16028d
JM
2374
2375
5e993390
JM
2376struct hostapd_iface * hostapd_alloc_iface(void)
2377{
2378 struct hostapd_iface *hapd_iface;
2379
2380 hapd_iface = os_zalloc(sizeof(*hapd_iface));
2381 if (!hapd_iface)
2382 return NULL;
2383
2384 dl_list_init(&hapd_iface->sta_seen);
2385
2386 return hapd_iface;
2387}
2388
2389
66936c6a
KP
2390/**
2391 * hostapd_init - Allocate and initialize per-interface data
2392 * @config_file: Path to the configuration file
2393 * Returns: Pointer to the allocated interface data or %NULL on failure
2394 *
2395 * This function is used to allocate main data structures for per-interface
2396 * data. The allocated data buffer will be freed by calling
2397 * hostapd_cleanup_iface().
2398 */
2399struct hostapd_iface * hostapd_init(struct hapd_interfaces *interfaces,
2400 const char *config_file)
2401{
2402 struct hostapd_iface *hapd_iface = NULL;
2403 struct hostapd_config *conf = NULL;
2404 struct hostapd_data *hapd;
2405 size_t i;
2406
5e993390 2407 hapd_iface = hostapd_alloc_iface();
66936c6a
KP
2408 if (hapd_iface == NULL)
2409 goto fail;
2410
2411 hapd_iface->config_fname = os_strdup(config_file);
2412 if (hapd_iface->config_fname == NULL)
2413 goto fail;
2414
2415 conf = interfaces->config_read_cb(hapd_iface->config_fname);
2416 if (conf == NULL)
2417 goto fail;
2418 hapd_iface->conf = conf;
2419
2420 hapd_iface->num_bss = conf->num_bss;
2421 hapd_iface->bss = os_calloc(conf->num_bss,
2422 sizeof(struct hostapd_data *));
2423 if (hapd_iface->bss == NULL)
2424 goto fail;
2425
2426 for (i = 0; i < conf->num_bss; i++) {
2427 hapd = hapd_iface->bss[i] =
2428 hostapd_alloc_bss_data(hapd_iface, conf,
2429 conf->bss[i]);
2430 if (hapd == NULL)
2431 goto fail;
2432 hapd->msg_ctx = hapd;
2433 }
2434
2435 return hapd_iface;
2436
2437fail:
2438 wpa_printf(MSG_ERROR, "Failed to set up interface with %s",
2439 config_file);
2440 if (conf)
2441 hostapd_config_free(conf);
2442 if (hapd_iface) {
2443 os_free(hapd_iface->config_fname);
2444 os_free(hapd_iface->bss);
747c85f9
JM
2445 wpa_printf(MSG_DEBUG, "%s: free iface %p",
2446 __func__, hapd_iface);
66936c6a
KP
2447 os_free(hapd_iface);
2448 }
2449 return NULL;
2450}
2451
2452
2e2fff37
KP
2453static int ifname_in_use(struct hapd_interfaces *interfaces, const char *ifname)
2454{
2455 size_t i, j;
2456
2457 for (i = 0; i < interfaces->count; i++) {
2458 struct hostapd_iface *iface = interfaces->iface[i];
2459 for (j = 0; j < iface->num_bss; j++) {
2460 struct hostapd_data *hapd = iface->bss[j];
2461 if (os_strcmp(ifname, hapd->conf->iface) == 0)
2462 return 1;
2463 }
2464 }
2465
2466 return 0;
2467}
2468
2469
0dfd2c61
JM
2470/**
2471 * hostapd_interface_init_bss - Read configuration file and init BSS data
2472 *
2473 * This function is used to parse configuration file for a BSS. This BSS is
2474 * added to an existing interface sharing the same radio (if any) or a new
2475 * interface is created if this is the first interface on a radio. This
2476 * allocate memory for the BSS. No actual driver operations are started.
2477 *
2478 * This is similar to hostapd_interface_init(), but for a case where the
2479 * configuration is used to add a single BSS instead of all BSSes for a radio.
2480 */
a1fb5692
KP
2481struct hostapd_iface *
2482hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy,
2483 const char *config_fname, int debug)
2484{
2485 struct hostapd_iface *new_iface = NULL, *iface = NULL;
2486 struct hostapd_data *hapd;
2487 int k;
2488 size_t i, bss_idx;
2489
2490 if (!phy || !*phy)
2491 return NULL;
2492
2493 for (i = 0; i < interfaces->count; i++) {
2494 if (os_strcmp(interfaces->iface[i]->phy, phy) == 0) {
2495 iface = interfaces->iface[i];
2496 break;
2497 }
2498 }
2499
fee947bf 2500 wpa_printf(MSG_INFO, "Configuration file: %s (phy %s)%s",
a1fb5692
KP
2501 config_fname, phy, iface ? "" : " --> new PHY");
2502 if (iface) {
2503 struct hostapd_config *conf;
2504 struct hostapd_bss_config **tmp_conf;
2505 struct hostapd_data **tmp_bss;
2506 struct hostapd_bss_config *bss;
2e2fff37 2507 const char *ifname;
a1fb5692
KP
2508
2509 /* Add new BSS to existing iface */
2510 conf = interfaces->config_read_cb(config_fname);
2511 if (conf == NULL)
2512 return NULL;
2513 if (conf->num_bss > 1) {
2514 wpa_printf(MSG_ERROR, "Multiple BSSes specified in BSS-config");
2515 hostapd_config_free(conf);
2516 return NULL;
2517 }
2518
2e2fff37
KP
2519 ifname = conf->bss[0]->iface;
2520 if (ifname[0] != '\0' && ifname_in_use(interfaces, ifname)) {
2521 wpa_printf(MSG_ERROR,
2522 "Interface name %s already in use", ifname);
2523 hostapd_config_free(conf);
2524 return NULL;
2525 }
2526
a1fb5692
KP
2527 tmp_conf = os_realloc_array(
2528 iface->conf->bss, iface->conf->num_bss + 1,
2529 sizeof(struct hostapd_bss_config *));
2530 tmp_bss = os_realloc_array(iface->bss, iface->num_bss + 1,
2531 sizeof(struct hostapd_data *));
2532 if (tmp_bss)
2533 iface->bss = tmp_bss;
2534 if (tmp_conf) {
2535 iface->conf->bss = tmp_conf;
2536 iface->conf->last_bss = tmp_conf[0];
2537 }
2538 if (tmp_bss == NULL || tmp_conf == NULL) {
2539 hostapd_config_free(conf);
2540 return NULL;
2541 }
2542 bss = iface->conf->bss[iface->conf->num_bss] = conf->bss[0];
2543 iface->conf->num_bss++;
2544
2545 hapd = hostapd_alloc_bss_data(iface, iface->conf, bss);
2546 if (hapd == NULL) {
2547 iface->conf->num_bss--;
2548 hostapd_config_free(conf);
2549 return NULL;
2550 }
2551 iface->conf->last_bss = bss;
2552 iface->bss[iface->num_bss] = hapd;
2553 hapd->msg_ctx = hapd;
2554
2555 bss_idx = iface->num_bss++;
2556 conf->num_bss--;
2557 conf->bss[0] = NULL;
2558 hostapd_config_free(conf);
2559 } else {
2560 /* Add a new iface with the first BSS */
2561 new_iface = iface = hostapd_init(interfaces, config_fname);
2562 if (!iface)
2563 return NULL;
2564 os_strlcpy(iface->phy, phy, sizeof(iface->phy));
2565 iface->interfaces = interfaces;
2566 bss_idx = 0;
2567 }
2568
2569 for (k = 0; k < debug; k++) {
2570 if (iface->bss[bss_idx]->conf->logger_stdout_level > 0)
2571 iface->bss[bss_idx]->conf->logger_stdout_level--;
2572 }
2573
2574 if (iface->conf->bss[bss_idx]->iface[0] == '\0' &&
2575 !hostapd_drv_none(iface->bss[bss_idx])) {
2576 wpa_printf(MSG_ERROR, "Interface name not specified in %s",
2577 config_fname);
2578 if (new_iface)
2579 hostapd_interface_deinit_free(new_iface);
2580 return NULL;
2581 }
2582
2583 return iface;
2584}
2585
2586
75545652
SP
2587void hostapd_interface_deinit_free(struct hostapd_iface *iface)
2588{
2589 const struct wpa_driver_ops *driver;
2590 void *drv_priv;
747c85f9
JM
2591
2592 wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
75545652
SP
2593 if (iface == NULL)
2594 return;
747c85f9
JM
2595 wpa_printf(MSG_DEBUG, "%s: num_bss=%u conf->num_bss=%u",
2596 __func__, (unsigned int) iface->num_bss,
2597 (unsigned int) iface->conf->num_bss);
75545652
SP
2598 driver = iface->bss[0]->driver;
2599 drv_priv = iface->bss[0]->drv_priv;
2600 hostapd_interface_deinit(iface);
747c85f9
JM
2601 wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
2602 __func__, driver, drv_priv);
d92bdf96 2603 if (driver && driver->hapd_deinit && drv_priv) {
75545652 2604 driver->hapd_deinit(drv_priv);
d92bdf96
JM
2605 iface->bss[0]->drv_priv = NULL;
2606 }
75545652
SP
2607 hostapd_interface_free(iface);
2608}
2609
2610
4d1e38be
JM
2611static void hostapd_deinit_driver(const struct wpa_driver_ops *driver,
2612 void *drv_priv,
2613 struct hostapd_iface *hapd_iface)
2614{
2615 size_t j;
2616
2617 wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
2618 __func__, driver, drv_priv);
2619 if (driver && driver->hapd_deinit && drv_priv) {
2620 driver->hapd_deinit(drv_priv);
2621 for (j = 0; j < hapd_iface->num_bss; j++) {
2622 wpa_printf(MSG_DEBUG, "%s:bss[%d]->drv_priv=%p",
2623 __func__, (int) j,
2624 hapd_iface->bss[j]->drv_priv);
b9058266 2625 if (hapd_iface->bss[j]->drv_priv == drv_priv) {
4d1e38be 2626 hapd_iface->bss[j]->drv_priv = NULL;
b9058266
JM
2627 hapd_iface->extended_capa = NULL;
2628 hapd_iface->extended_capa_mask = NULL;
2629 hapd_iface->extended_capa_len = 0;
2630 }
4d1e38be
JM
2631 }
2632 }
2633}
2634
2635
75545652
SP
2636int hostapd_enable_iface(struct hostapd_iface *hapd_iface)
2637{
5d67bf15
JM
2638 size_t j;
2639
75545652
SP
2640 if (hapd_iface->bss[0]->drv_priv != NULL) {
2641 wpa_printf(MSG_ERROR, "Interface %s already enabled",
ebd79f07 2642 hapd_iface->conf->bss[0]->iface);
75545652
SP
2643 return -1;
2644 }
2645
2646 wpa_printf(MSG_DEBUG, "Enable interface %s",
ebd79f07 2647 hapd_iface->conf->bss[0]->iface);
75545652 2648
5d67bf15
JM
2649 for (j = 0; j < hapd_iface->num_bss; j++)
2650 hostapd_set_security_params(hapd_iface->conf->bss[j], 1);
08081ad8
JM
2651 if (hostapd_config_check(hapd_iface->conf, 1) < 0) {
2652 wpa_printf(MSG_INFO, "Invalid configuration - cannot enable");
2653 return -1;
2654 }
2655
75545652
SP
2656 if (hapd_iface->interfaces == NULL ||
2657 hapd_iface->interfaces->driver_init == NULL ||
71cdf6b6
JM
2658 hapd_iface->interfaces->driver_init(hapd_iface))
2659 return -1;
2660
2661 if (hostapd_setup_interface(hapd_iface)) {
4d1e38be
JM
2662 hostapd_deinit_driver(hapd_iface->bss[0]->driver,
2663 hapd_iface->bss[0]->drv_priv,
2664 hapd_iface);
75545652
SP
2665 return -1;
2666 }
71cdf6b6 2667
75545652
SP
2668 return 0;
2669}
2670
2671
2672int hostapd_reload_iface(struct hostapd_iface *hapd_iface)
2673{
2674 size_t j;
2675
2676 wpa_printf(MSG_DEBUG, "Reload interface %s",
ebd79f07 2677 hapd_iface->conf->bss[0]->iface);
6f2db2fb 2678 for (j = 0; j < hapd_iface->num_bss; j++)
5d67bf15 2679 hostapd_set_security_params(hapd_iface->conf->bss[j], 1);
08081ad8 2680 if (hostapd_config_check(hapd_iface->conf, 1) < 0) {
6f2db2fb
JM
2681 wpa_printf(MSG_ERROR, "Updated configuration is invalid");
2682 return -1;
2683 }
9f104b03
JM
2684 hostapd_clear_old(hapd_iface);
2685 for (j = 0; j < hapd_iface->num_bss; j++)
75545652 2686 hostapd_reload_bss(hapd_iface->bss[j]);
9f104b03 2687
75545652
SP
2688 return 0;
2689}
2690
2691
2692int hostapd_disable_iface(struct hostapd_iface *hapd_iface)
2693{
2694 size_t j;
75545652
SP
2695 const struct wpa_driver_ops *driver;
2696 void *drv_priv;
2697
2698 if (hapd_iface == NULL)
2699 return -1;
3fbd036e
MK
2700
2701 if (hapd_iface->bss[0]->drv_priv == NULL) {
2702 wpa_printf(MSG_INFO, "Interface %s already disabled",
2703 hapd_iface->conf->bss[0]->iface);
2704 return -1;
2705 }
2706
7d6d7370 2707 wpa_msg(hapd_iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
75545652
SP
2708 driver = hapd_iface->bss[0]->driver;
2709 drv_priv = hapd_iface->bss[0]->drv_priv;
2710
354c903f
MB
2711 hapd_iface->driver_ap_teardown =
2712 !!(hapd_iface->drv_flags &
2713 WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
2714
7b2ca5cf
S
2715#ifdef NEED_AP_MLME
2716 for (j = 0; j < hapd_iface->num_bss; j++)
2717 hostapd_cleanup_cs_params(hapd_iface->bss[j]);
2718#endif /* NEED_AP_MLME */
2719
354c903f 2720 /* same as hostapd_interface_deinit without deinitializing ctrl-iface */
75545652
SP
2721 for (j = 0; j < hapd_iface->num_bss; j++) {
2722 struct hostapd_data *hapd = hapd_iface->bss[j];
438e1333 2723 hostapd_bss_deinit_no_free(hapd);
75545652
SP
2724 hostapd_free_hapd_data(hapd);
2725 }
2726
4d1e38be 2727 hostapd_deinit_driver(driver, drv_priv, hapd_iface);
75545652
SP
2728
2729 /* From hostapd_cleanup_iface: These were initialized in
2730 * hostapd_setup_interface and hostapd_setup_interface_complete
2731 */
2732 hostapd_cleanup_iface_partial(hapd_iface);
75545652 2733
0249c125
JM
2734 wpa_printf(MSG_DEBUG, "Interface %s disabled",
2735 hapd_iface->bss[0]->conf->iface);
e1c5faf0 2736 hostapd_set_state(hapd_iface, HAPD_IFACE_DISABLED);
75545652
SP
2737 return 0;
2738}
2739
06bb8c62
SP
2740
2741static struct hostapd_iface *
2742hostapd_iface_alloc(struct hapd_interfaces *interfaces)
2743{
2744 struct hostapd_iface **iface, *hapd_iface;
2745
2746 iface = os_realloc_array(interfaces->iface, interfaces->count + 1,
2747 sizeof(struct hostapd_iface *));
2748 if (iface == NULL)
2749 return NULL;
2750 interfaces->iface = iface;
2751 hapd_iface = interfaces->iface[interfaces->count] =
5e993390 2752 hostapd_alloc_iface();
06bb8c62
SP
2753 if (hapd_iface == NULL) {
2754 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for "
2755 "the interface", __func__);
2756 return NULL;
2757 }
2758 interfaces->count++;
2759 hapd_iface->interfaces = interfaces;
2760
2761 return hapd_iface;
2762}
2763
2764
2765static struct hostapd_config *
2766hostapd_config_alloc(struct hapd_interfaces *interfaces, const char *ifname,
fab51186 2767 const char *ctrl_iface, const char *driver)
06bb8c62
SP
2768{
2769 struct hostapd_bss_config *bss;
2770 struct hostapd_config *conf;
2771
2772 /* Allocates memory for bss and conf */
2773 conf = hostapd_config_defaults();
2774 if (conf == NULL) {
2775 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for "
2776 "configuration", __func__);
3d1d4691 2777 return NULL;
06bb8c62
SP
2778 }
2779
fab51186
P
2780 if (driver) {
2781 int j;
2782
2783 for (j = 0; wpa_drivers[j]; j++) {
2784 if (os_strcmp(driver, wpa_drivers[j]->name) == 0) {
2785 conf->driver = wpa_drivers[j];
2786 goto skip;
2787 }
2788 }
2789
2790 wpa_printf(MSG_ERROR,
2791 "Invalid/unknown driver '%s' - registering the default driver",
2792 driver);
2793 }
2794
06bb8c62
SP
2795 conf->driver = wpa_drivers[0];
2796 if (conf->driver == NULL) {
2797 wpa_printf(MSG_ERROR, "No driver wrappers registered!");
2798 hostapd_config_free(conf);
2799 return NULL;
2800 }
2801
fab51186 2802skip:
ebd79f07 2803 bss = conf->last_bss = conf->bss[0];
06bb8c62
SP
2804
2805 os_strlcpy(bss->iface, ifname, sizeof(bss->iface));
2806 bss->ctrl_interface = os_strdup(ctrl_iface);
2807 if (bss->ctrl_interface == NULL) {
2808 hostapd_config_free(conf);
2809 return NULL;
2810 }
2811
2812 /* Reading configuration file skipped, will be done in SET!
2813 * From reading the configuration till the end has to be done in
2814 * SET
2815 */
2816 return conf;
2817}
2818
2819
28016592
JM
2820static int hostapd_data_alloc(struct hostapd_iface *hapd_iface,
2821 struct hostapd_config *conf)
06bb8c62
SP
2822{
2823 size_t i;
06bb8c62
SP
2824 struct hostapd_data *hapd;
2825
faebdeaa 2826 hapd_iface->bss = os_calloc(conf->num_bss,
06bb8c62
SP
2827 sizeof(struct hostapd_data *));
2828 if (hapd_iface->bss == NULL)
28016592 2829 return -1;
06bb8c62
SP
2830
2831 for (i = 0; i < conf->num_bss; i++) {
2832 hapd = hapd_iface->bss[i] =
ebd79f07 2833 hostapd_alloc_bss_data(hapd_iface, conf, conf->bss[i]);
28016592
JM
2834 if (hapd == NULL) {
2835 while (i > 0) {
2836 i--;
2837 os_free(hapd_iface->bss[i]);
2838 hapd_iface->bss[i] = NULL;
2839 }
2840 os_free(hapd_iface->bss);
2841 hapd_iface->bss = NULL;
2842 return -1;
2843 }
06bb8c62
SP
2844 hapd->msg_ctx = hapd;
2845 }
2846
28016592
JM
2847 hapd_iface->conf = conf;
2848 hapd_iface->num_bss = conf->num_bss;
06bb8c62 2849
28016592 2850 return 0;
06bb8c62
SP
2851}
2852
2853
2854int hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf)
2855{
2856 struct hostapd_config *conf = NULL;
2e2fff37
KP
2857 struct hostapd_iface *hapd_iface = NULL, *new_iface = NULL;
2858 struct hostapd_data *hapd;
06bb8c62 2859 char *ptr;
2e2fff37
KP
2860 size_t i, j;
2861 const char *conf_file = NULL, *phy_name = NULL;
2862
2863 if (os_strncmp(buf, "bss_config=", 11) == 0) {
2864 char *pos;
2865 phy_name = buf + 11;
2866 pos = os_strchr(phy_name, ':');
2867 if (!pos)
2868 return -1;
2869 *pos++ = '\0';
2870 conf_file = pos;
2871 if (!os_strlen(conf_file))
2872 return -1;
2873
2874 hapd_iface = hostapd_interface_init_bss(interfaces, phy_name,
2875 conf_file, 0);
2876 if (!hapd_iface)
2877 return -1;
2878 for (j = 0; j < interfaces->count; j++) {
2879 if (interfaces->iface[j] == hapd_iface)
2880 break;
2881 }
2882 if (j == interfaces->count) {
2883 struct hostapd_iface **tmp;
2884 tmp = os_realloc_array(interfaces->iface,
2885 interfaces->count + 1,
2886 sizeof(struct hostapd_iface *));
2887 if (!tmp) {
2888 hostapd_interface_deinit_free(hapd_iface);
2889 return -1;
2890 }
2891 interfaces->iface = tmp;
2892 interfaces->iface[interfaces->count++] = hapd_iface;
2893 new_iface = hapd_iface;
2894 }
2895
2896 if (new_iface) {
28016592 2897 if (interfaces->driver_init(hapd_iface))
2e2fff37 2898 goto fail;
71f1d1e5
JM
2899
2900 if (hostapd_setup_interface(hapd_iface)) {
71f1d1e5
JM
2901 hostapd_deinit_driver(
2902 hapd_iface->bss[0]->driver,
2903 hapd_iface->bss[0]->drv_priv,
2904 hapd_iface);
2905 goto fail;
2906 }
2e2fff37
KP
2907 } else {
2908 /* Assign new BSS with bss[0]'s driver info */
2909 hapd = hapd_iface->bss[hapd_iface->num_bss - 1];
2910 hapd->driver = hapd_iface->bss[0]->driver;
2911 hapd->drv_priv = hapd_iface->bss[0]->drv_priv;
2912 os_memcpy(hapd->own_addr, hapd_iface->bss[0]->own_addr,
2913 ETH_ALEN);
2914
ad08e141 2915 if (start_ctrl_iface_bss(hapd) < 0 ||
5e1a4565
JM
2916 (hapd_iface->state == HAPD_IFACE_ENABLED &&
2917 hostapd_setup_bss(hapd, -1))) {
c9d9ee94 2918 hostapd_cleanup(hapd);
b908c50a 2919 hapd_iface->bss[hapd_iface->num_bss - 1] = NULL;
2e2fff37
KP
2920 hapd_iface->conf->num_bss--;
2921 hapd_iface->num_bss--;
747c85f9
JM
2922 wpa_printf(MSG_DEBUG, "%s: free hapd %p %s",
2923 __func__, hapd, hapd->conf->iface);
e10422c0
JM
2924 hostapd_config_free_bss(hapd->conf);
2925 hapd->conf = NULL;
2e2fff37
KP
2926 os_free(hapd);
2927 return -1;
2928 }
2929 }
a8913881 2930 hostapd_owe_update_trans(hapd_iface);
2e2fff37
KP
2931 return 0;
2932 }
06bb8c62
SP
2933
2934 ptr = os_strchr(buf, ' ');
2935 if (ptr == NULL)
2936 return -1;
2937 *ptr++ = '\0';
2938
ed1bf011
JM
2939 if (os_strncmp(ptr, "config=", 7) == 0)
2940 conf_file = ptr + 7;
2941
06bb8c62 2942 for (i = 0; i < interfaces->count; i++) {
ebd79f07 2943 if (!os_strcmp(interfaces->iface[i]->conf->bss[0]->iface,
06bb8c62
SP
2944 buf)) {
2945 wpa_printf(MSG_INFO, "Cannot add interface - it "
2946 "already exists");
2947 return -1;
2948 }
2949 }
2950
2951 hapd_iface = hostapd_iface_alloc(interfaces);
2952 if (hapd_iface == NULL) {
2953 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
2954 "for interface", __func__);
2955 goto fail;
2956 }
28016592 2957 new_iface = hapd_iface;
06bb8c62 2958
ed1bf011
JM
2959 if (conf_file && interfaces->config_read_cb) {
2960 conf = interfaces->config_read_cb(conf_file);
2961 if (conf && conf->bss)
ebd79f07
JM
2962 os_strlcpy(conf->bss[0]->iface, buf,
2963 sizeof(conf->bss[0]->iface));
fab51186
P
2964 } else {
2965 char *driver = os_strchr(ptr, ' ');
2966
2967 if (driver)
2968 *driver++ = '\0';
2969 conf = hostapd_config_alloc(interfaces, buf, ptr, driver);
2970 }
2971
ed1bf011 2972 if (conf == NULL || conf->bss == NULL) {
06bb8c62
SP
2973 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
2974 "for configuration", __func__);
2975 goto fail;
2976 }
2977
28016592 2978 if (hostapd_data_alloc(hapd_iface, conf) < 0) {
06bb8c62
SP
2979 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
2980 "for hostapd", __func__);
2981 goto fail;
2982 }
c1c07dcb 2983 conf = NULL;
06bb8c62 2984
e4ba0315 2985 if (start_ctrl_iface(hapd_iface) < 0)
06bb8c62 2986 goto fail;
e4ba0315 2987
c1c07dcb
JM
2988 wpa_printf(MSG_INFO, "Add interface '%s'",
2989 hapd_iface->conf->bss[0]->iface);
06bb8c62
SP
2990
2991 return 0;
2992
2993fail:
2994 if (conf)
2995 hostapd_config_free(conf);
2996 if (hapd_iface) {
33b0b330 2997 if (hapd_iface->bss) {
486d2ff0
JM
2998 for (i = 0; i < hapd_iface->num_bss; i++) {
2999 hapd = hapd_iface->bss[i];
7b6e8157
JM
3000 if (!hapd)
3001 continue;
3002 if (hapd_iface->interfaces &&
486d2ff0
JM
3003 hapd_iface->interfaces->ctrl_iface_deinit)
3004 hapd_iface->interfaces->
3005 ctrl_iface_deinit(hapd);
747c85f9
JM
3006 wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)",
3007 __func__, hapd_iface->bss[i],
7b6e8157 3008 hapd->conf->iface);
71f1d1e5 3009 hostapd_cleanup(hapd);
7b6e8157
JM
3010 os_free(hapd);
3011 hapd_iface->bss[i] = NULL;
486d2ff0 3012 }
33b0b330 3013 os_free(hapd_iface->bss);
71f1d1e5 3014 hapd_iface->bss = NULL;
33b0b330 3015 }
28016592
JM
3016 if (new_iface) {
3017 interfaces->count--;
3018 interfaces->iface[interfaces->count] = NULL;
3019 }
71f1d1e5 3020 hostapd_cleanup_iface(hapd_iface);
06bb8c62
SP
3021 }
3022 return -1;
3023}
3024
3025
55920658
JM
3026static int hostapd_remove_bss(struct hostapd_iface *iface, unsigned int idx)
3027{
55920658
JM
3028 size_t i;
3029
cdf3fb1f 3030 wpa_printf(MSG_INFO, "Remove BSS '%s'", iface->conf->bss[idx]->iface);
55920658 3031
cdf3fb1f
JM
3032 /* Remove hostapd_data only if it has already been initialized */
3033 if (idx < iface->num_bss) {
3034 struct hostapd_data *hapd = iface->bss[idx];
55920658 3035
54246f8d 3036 hostapd_bss_deinit(hapd);
747c85f9
JM
3037 wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)",
3038 __func__, hapd, hapd->conf->iface);
cdf3fb1f 3039 hostapd_config_free_bss(hapd->conf);
28016592 3040 hapd->conf = NULL;
cdf3fb1f
JM
3041 os_free(hapd);
3042
3043 iface->num_bss--;
3044
3045 for (i = idx; i < iface->num_bss; i++)
3046 iface->bss[i] = iface->bss[i + 1];
3047 } else {
3048 hostapd_config_free_bss(iface->conf->bss[idx]);
3049 iface->conf->bss[idx] = NULL;
3050 }
55920658
JM
3051
3052 iface->conf->num_bss--;
cdf3fb1f 3053 for (i = idx; i < iface->conf->num_bss; i++)
55920658
JM
3054 iface->conf->bss[i] = iface->conf->bss[i + 1];
3055
3056 return 0;
3057}
3058
3059
06bb8c62
SP
3060int hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf)
3061{
3062 struct hostapd_iface *hapd_iface;
55920658 3063 size_t i, j, k = 0;
06bb8c62
SP
3064
3065 for (i = 0; i < interfaces->count; i++) {
3066 hapd_iface = interfaces->iface[i];
3067 if (hapd_iface == NULL)
3068 return -1;
2f99d907 3069 if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
06bb8c62 3070 wpa_printf(MSG_INFO, "Remove interface '%s'", buf);
354c903f
MB
3071 hapd_iface->driver_ap_teardown =
3072 !!(hapd_iface->drv_flags &
3073 WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
3074
06bb8c62
SP
3075 hostapd_interface_deinit_free(hapd_iface);
3076 k = i;
3077 while (k < (interfaces->count - 1)) {
3078 interfaces->iface[k] =
3079 interfaces->iface[k + 1];
3080 k++;
3081 }
3082 interfaces->count--;
3083 return 0;
3084 }
55920658
JM
3085
3086 for (j = 0; j < hapd_iface->conf->num_bss; j++) {
354c903f
MB
3087 if (!os_strcmp(hapd_iface->conf->bss[j]->iface, buf)) {
3088 hapd_iface->driver_ap_teardown =
3089 !(hapd_iface->drv_flags &
3090 WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
55920658 3091 return hostapd_remove_bss(hapd_iface, j);
354c903f 3092 }
55920658 3093 }
06bb8c62
SP
3094 }
3095 return -1;
3096}
3097
75545652 3098
a2de634d
JM
3099/**
3100 * hostapd_new_assoc_sta - Notify that a new station associated with the AP
3101 * @hapd: Pointer to BSS data
3102 * @sta: Pointer to the associated STA data
3103 * @reassoc: 1 to indicate this was a re-association; 0 = first association
3104 *
3105 * This function will be called whenever a station associates with the AP. It
3106 * can be called from ieee802_11.c for drivers that export MLME to hostapd and
3107 * from drv_callbacks.c based on driver events for drivers that take care of
3108 * management frames (IEEE 802.11 authentication and association) internally.
3109 */
3110void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
3111 int reassoc)
3112{
3113 if (hapd->tkip_countermeasures) {
51e2a27a
JM
3114 hostapd_drv_sta_deauth(hapd, sta->addr,
3115 WLAN_REASON_MICHAEL_MIC_FAILURE);
a2de634d
JM
3116 return;
3117 }
3118
0aef3ec8 3119 hostapd_prune_associations(hapd, sta->addr);
9e8fde21 3120 ap_sta_clear_disconnect_timeouts(hapd, sta);
a2de634d 3121
aefb53bd
JM
3122#ifdef CONFIG_P2P
3123 if (sta->p2p_ie == NULL && !sta->no_p2p_set) {
3124 sta->no_p2p_set = 1;
3125 hapd->num_sta_no_p2p++;
3126 if (hapd->num_sta_no_p2p == 1)
3127 hostapd_p2p_non_p2p_sta_connected(hapd);
3128 }
3129#endif /* CONFIG_P2P */
3130
ef721751
THJ
3131 airtime_policy_new_sta(hapd, sta);
3132
a2de634d
JM
3133 /* Start accounting here, if IEEE 802.1X and WPA are not used.
3134 * IEEE 802.1X/WPA code will start accounting after the station has
3135 * been authorized. */
95faa36a 3136 if (!hapd->conf->ieee802_1x && !hapd->conf->wpa && !hapd->conf->osen) {
113318ad 3137 ap_sta_set_authorized(hapd, sta, 1);
b3493fa1 3138 os_get_reltime(&sta->connected_time);
a2de634d 3139 accounting_sta_start(hapd, sta);
39b1572c 3140 }
a2de634d
JM
3141
3142 /* Start IEEE 802.1X authentication process for new stations */
3143 ieee802_1x_new_station(hapd, sta);
3144 if (reassoc) {
3145 if (sta->auth_alg != WLAN_AUTH_FT &&
2f1357fb
JM
3146 sta->auth_alg != WLAN_AUTH_FILS_SK &&
3147 sta->auth_alg != WLAN_AUTH_FILS_SK_PFS &&
3148 sta->auth_alg != WLAN_AUTH_FILS_PK &&
a2de634d
JM
3149 !(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)))
3150 wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH);
3151 } else
3152 wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm);
a625ff60 3153
08032c74
ST
3154 if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_WIRED) {
3155 if (eloop_cancel_timeout(ap_handle_timer, hapd, sta) > 0) {
3156 wpa_printf(MSG_DEBUG,
3157 "%s: %s: canceled wired ap_handle_timer timeout for "
3158 MACSTR,
3159 hapd->conf->iface, __func__,
3160 MAC2STR(sta->addr));
3161 }
3162 } else if (!(hapd->iface->drv_flags &
3163 WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) {
03269d55
JM
3164 wpa_printf(MSG_DEBUG,
3165 "%s: %s: reschedule ap_handle_timer timeout for "
3166 MACSTR " (%d seconds - ap_max_inactivity)",
3167 hapd->conf->iface, __func__, MAC2STR(sta->addr),
336167c8
MSS
3168 hapd->conf->ap_max_inactivity);
3169 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
3170 eloop_register_timeout(hapd->conf->ap_max_inactivity, 0,
3171 ap_handle_timer, hapd, sta);
3172 }
a93b369c 3173
3174#ifdef CONFIG_MACSEC
3175 if (hapd->conf->wpa_key_mgmt == WPA_KEY_MGMT_NONE &&
3176 hapd->conf->mka_psk_set)
3177 ieee802_1x_create_preshared_mka_hapd(hapd, sta);
3178 else
3179 ieee802_1x_alloc_kay_sm_hapd(hapd, sta);
3180#endif /* CONFIG_MACSEC */
a2de634d 3181}
e1c5faf0
JM
3182
3183
5ae6449c 3184const char * hostapd_state_text(enum hostapd_iface_state s)
e1c5faf0
JM
3185{
3186 switch (s) {
3187 case HAPD_IFACE_UNINITIALIZED:
3188 return "UNINITIALIZED";
3189 case HAPD_IFACE_DISABLED:
3190 return "DISABLED";
3191 case HAPD_IFACE_COUNTRY_UPDATE:
3192 return "COUNTRY_UPDATE";
3193 case HAPD_IFACE_ACS:
3194 return "ACS";
3195 case HAPD_IFACE_HT_SCAN:
3196 return "HT_SCAN";
3197 case HAPD_IFACE_DFS:
3198 return "DFS";
3199 case HAPD_IFACE_ENABLED:
3200 return "ENABLED";
3201 }
3202
3203 return "UNKNOWN";
3204}
3205
3206
3207void hostapd_set_state(struct hostapd_iface *iface, enum hostapd_iface_state s)
3208{
3209 wpa_printf(MSG_INFO, "%s: interface state %s->%s",
9c10be3f
JM
3210 iface->conf ? iface->conf->bss[0]->iface : "N/A",
3211 hostapd_state_text(iface->state), hostapd_state_text(s));
e1c5faf0
JM
3212 iface->state = s;
3213}
bf281c12
AO
3214
3215
4e0ab656
IP
3216int hostapd_csa_in_progress(struct hostapd_iface *iface)
3217{
3218 unsigned int i;
3219
3220 for (i = 0; i < iface->num_bss; i++)
3221 if (iface->bss[i]->csa_in_progress)
3222 return 1;
3223 return 0;
3224}
3225
3226
bf281c12
AO
3227#ifdef NEED_AP_MLME
3228
3229static void free_beacon_data(struct beacon_data *beacon)
3230{
3231 os_free(beacon->head);
3232 beacon->head = NULL;
3233 os_free(beacon->tail);
3234 beacon->tail = NULL;
3235 os_free(beacon->probe_resp);
3236 beacon->probe_resp = NULL;
3237 os_free(beacon->beacon_ies);
3238 beacon->beacon_ies = NULL;
3239 os_free(beacon->proberesp_ies);
3240 beacon->proberesp_ies = NULL;
3241 os_free(beacon->assocresp_ies);
3242 beacon->assocresp_ies = NULL;
3243}
3244
3245
6782b684 3246static int hostapd_build_beacon_data(struct hostapd_data *hapd,
bf281c12
AO
3247 struct beacon_data *beacon)
3248{
3249 struct wpabuf *beacon_extra, *proberesp_extra, *assocresp_extra;
3250 struct wpa_driver_ap_params params;
3251 int ret;
bf281c12 3252
80ed037f 3253 os_memset(beacon, 0, sizeof(*beacon));
bf281c12
AO
3254 ret = ieee802_11_build_ap_params(hapd, &params);
3255 if (ret < 0)
3256 return ret;
3257
3258 ret = hostapd_build_ap_extra_ies(hapd, &beacon_extra,
3259 &proberesp_extra,
3260 &assocresp_extra);
3261 if (ret)
3262 goto free_ap_params;
3263
3264 ret = -1;
a1f11e34 3265 beacon->head = os_memdup(params.head, params.head_len);
bf281c12
AO
3266 if (!beacon->head)
3267 goto free_ap_extra_ies;
3268
bf281c12
AO
3269 beacon->head_len = params.head_len;
3270
a1f11e34 3271 beacon->tail = os_memdup(params.tail, params.tail_len);
bf281c12
AO
3272 if (!beacon->tail)
3273 goto free_beacon;
3274
bf281c12
AO
3275 beacon->tail_len = params.tail_len;
3276
3277 if (params.proberesp != NULL) {
a1f11e34
JB
3278 beacon->probe_resp = os_memdup(params.proberesp,
3279 params.proberesp_len);
bf281c12
AO
3280 if (!beacon->probe_resp)
3281 goto free_beacon;
3282
bf281c12
AO
3283 beacon->probe_resp_len = params.proberesp_len;
3284 }
3285
3286 /* copy the extra ies */
3287 if (beacon_extra) {
a1f11e34
JB
3288 beacon->beacon_ies = os_memdup(beacon_extra->buf,
3289 wpabuf_len(beacon_extra));
bf281c12
AO
3290 if (!beacon->beacon_ies)
3291 goto free_beacon;
3292
bf281c12
AO
3293 beacon->beacon_ies_len = wpabuf_len(beacon_extra);
3294 }
3295
3296 if (proberesp_extra) {
a1f11e34
JB
3297 beacon->proberesp_ies = os_memdup(proberesp_extra->buf,
3298 wpabuf_len(proberesp_extra));
bf281c12
AO
3299 if (!beacon->proberesp_ies)
3300 goto free_beacon;
3301
bf281c12
AO
3302 beacon->proberesp_ies_len = wpabuf_len(proberesp_extra);
3303 }
3304
3305 if (assocresp_extra) {
a1f11e34
JB
3306 beacon->assocresp_ies = os_memdup(assocresp_extra->buf,
3307 wpabuf_len(assocresp_extra));
bf281c12
AO
3308 if (!beacon->assocresp_ies)
3309 goto free_beacon;
3310
bf281c12
AO
3311 beacon->assocresp_ies_len = wpabuf_len(assocresp_extra);
3312 }
3313
3314 ret = 0;
3315free_beacon:
3316 /* if the function fails, the caller should not free beacon data */
3317 if (ret)
3318 free_beacon_data(beacon);
3319
3320free_ap_extra_ies:
3321 hostapd_free_ap_extra_ies(hapd, beacon_extra, proberesp_extra,
3322 assocresp_extra);
3323free_ap_params:
3324 ieee802_11_free_ap_params(&params);
3325 return ret;
3326}
3327
3328
3329/*
982896ff
AO
3330 * TODO: This flow currently supports only changing channel and width within
3331 * the same hw_mode. Any other changes to MAC parameters or provided settings
3332 * are not supported.
bf281c12
AO
3333 */
3334static int hostapd_change_config_freq(struct hostapd_data *hapd,
3335 struct hostapd_config *conf,
3336 struct hostapd_freq_params *params,
3337 struct hostapd_freq_params *old_params)
3338{
3339 int channel;
c6b7ac07 3340 u8 seg0, seg1;
88005ee9 3341 struct hostapd_hw_modes *mode;
bf281c12
AO
3342
3343 if (!params->channel) {
3344 /* check if the new channel is supported by hw */
5841958f 3345 params->channel = hostapd_hw_get_channel(hapd, params->freq);
bf281c12
AO
3346 }
3347
5841958f
MK
3348 channel = params->channel;
3349 if (!channel)
3350 return -1;
3351
88005ee9
JC
3352 mode = hapd->iface->current_mode;
3353
bf281c12 3354 /* if a pointer to old_params is provided we save previous state */
982896ff
AO
3355 if (old_params &&
3356 hostapd_set_freq_params(old_params, conf->hw_mode,
3357 hostapd_hw_get_freq(hapd, conf->channel),
bebd91e9
AAL
3358 conf->channel, conf->enable_edmg,
3359 conf->edmg_channel, conf->ieee80211n,
88005ee9 3360 conf->ieee80211ac, conf->ieee80211ax,
982896ff 3361 conf->secondary_channel,
c6b7ac07
JC
3362 hostapd_get_oper_chwidth(conf),
3363 hostapd_get_oper_centr_freq_seg0_idx(conf),
3364 hostapd_get_oper_centr_freq_seg1_idx(conf),
88005ee9 3365 conf->vht_capab,
29d8bd1d
SE
3366 mode ? &mode->he_capab[IEEE80211_MODE_AP] :
3367 NULL))
982896ff
AO
3368 return -1;
3369
3370 switch (params->bandwidth) {
3371 case 0:
3372 case 20:
3373 case 40:
c6b7ac07 3374 hostapd_set_oper_chwidth(conf, CHANWIDTH_USE_HT);
982896ff
AO
3375 break;
3376 case 80:
3377 if (params->center_freq2)
c6b7ac07 3378 hostapd_set_oper_chwidth(conf, CHANWIDTH_80P80MHZ);
982896ff 3379 else
c6b7ac07 3380 hostapd_set_oper_chwidth(conf, CHANWIDTH_80MHZ);
982896ff
AO
3381 break;
3382 case 160:
c6b7ac07 3383 hostapd_set_oper_chwidth(conf, CHANWIDTH_160MHZ);
982896ff
AO
3384 break;
3385 default:
3386 return -1;
bf281c12
AO
3387 }
3388
3389 conf->channel = channel;
3390 conf->ieee80211n = params->ht_enabled;
3391 conf->secondary_channel = params->sec_channel_offset;
d308a44f 3392 ieee80211_freq_to_chan(params->center_freq1,
c6b7ac07 3393 &seg0);
d308a44f 3394 ieee80211_freq_to_chan(params->center_freq2,
c6b7ac07
JC
3395 &seg1);
3396 hostapd_set_oper_centr_freq_seg0_idx(conf, seg0);
3397 hostapd_set_oper_centr_freq_seg1_idx(conf, seg1);
bf281c12
AO
3398
3399 /* TODO: maybe call here hostapd_config_check here? */
3400
3401 return 0;
3402}
3403
3404
6782b684 3405static int hostapd_fill_csa_settings(struct hostapd_data *hapd,
bf281c12
AO
3406 struct csa_settings *settings)
3407{
6782b684 3408 struct hostapd_iface *iface = hapd->iface;
bf281c12
AO
3409 struct hostapd_freq_params old_freq;
3410 int ret;
f200631c 3411 u8 chan, bandwidth;
bf281c12
AO
3412
3413 os_memset(&old_freq, 0, sizeof(old_freq));
6782b684 3414 if (!iface || !iface->freq || hapd->csa_in_progress)
bf281c12
AO
3415 return -1;
3416
fa53d74c
AO
3417 switch (settings->freq_params.bandwidth) {
3418 case 80:
3419 if (settings->freq_params.center_freq2)
f200631c 3420 bandwidth = CHANWIDTH_80P80MHZ;
fa53d74c 3421 else
f200631c 3422 bandwidth = CHANWIDTH_80MHZ;
fa53d74c
AO
3423 break;
3424 case 160:
f200631c 3425 bandwidth = CHANWIDTH_160MHZ;
fa53d74c
AO
3426 break;
3427 default:
f200631c 3428 bandwidth = CHANWIDTH_USE_HT;
fa53d74c
AO
3429 break;
3430 }
3431
7d82170a
LC
3432 if (ieee80211_freq_to_channel_ext(
3433 settings->freq_params.freq,
3434 settings->freq_params.sec_channel_offset,
f200631c 3435 bandwidth,
7d82170a
LC
3436 &hapd->iface->cs_oper_class,
3437 &chan) == NUM_HOSTAPD_MODES) {
3438 wpa_printf(MSG_DEBUG,
0cd5b4ee 3439 "invalid frequency for channel switch (freq=%d, sec_channel_offset=%d, vht_enabled=%d, he_enabled=%d)",
7d82170a
LC
3440 settings->freq_params.freq,
3441 settings->freq_params.sec_channel_offset,
0cd5b4ee
JC
3442 settings->freq_params.vht_enabled,
3443 settings->freq_params.he_enabled);
7d82170a
LC
3444 return -1;
3445 }
3446
3447 settings->freq_params.channel = chan;
3448
bf281c12
AO
3449 ret = hostapd_change_config_freq(iface->bss[0], iface->conf,
3450 &settings->freq_params,
3451 &old_freq);
3452 if (ret)
3453 return ret;
3454
6782b684 3455 ret = hostapd_build_beacon_data(hapd, &settings->beacon_after);
bf281c12
AO
3456
3457 /* change back the configuration */
3458 hostapd_change_config_freq(iface->bss[0], iface->conf,
3459 &old_freq, NULL);
3460
3461 if (ret)
3462 return ret;
3463
3464 /* set channel switch parameters for csa ie */
6782b684
MK
3465 hapd->cs_freq_params = settings->freq_params;
3466 hapd->cs_count = settings->cs_count;
3467 hapd->cs_block_tx = settings->block_tx;
bf281c12 3468
6782b684 3469 ret = hostapd_build_beacon_data(hapd, &settings->beacon_csa);
bf281c12
AO
3470 if (ret) {
3471 free_beacon_data(&settings->beacon_after);
3472 return ret;
3473 }
3474
366179d2
AO
3475 settings->counter_offset_beacon[0] = hapd->cs_c_off_beacon;
3476 settings->counter_offset_presp[0] = hapd->cs_c_off_proberesp;
6315bfdb
AO
3477 settings->counter_offset_beacon[1] = hapd->cs_c_off_ecsa_beacon;
3478 settings->counter_offset_presp[1] = hapd->cs_c_off_ecsa_proberesp;
bf281c12
AO
3479
3480 return 0;
3481}
3482
3483
3484void hostapd_cleanup_cs_params(struct hostapd_data *hapd)
3485{
6782b684
MK
3486 os_memset(&hapd->cs_freq_params, 0, sizeof(hapd->cs_freq_params));
3487 hapd->cs_count = 0;
3488 hapd->cs_block_tx = 0;
3489 hapd->cs_c_off_beacon = 0;
3490 hapd->cs_c_off_proberesp = 0;
3491 hapd->csa_in_progress = 0;
6315bfdb
AO
3492 hapd->cs_c_off_ecsa_beacon = 0;
3493 hapd->cs_c_off_ecsa_proberesp = 0;
bf281c12
AO
3494}
3495
3496
bda9c085
SM
3497void hostapd_chan_switch_vht_config(struct hostapd_data *hapd, int vht_enabled)
3498{
3499 if (vht_enabled)
3500 hapd->iconf->ch_switch_vht_config |= CH_SWITCH_VHT_ENABLED;
3501 else
3502 hapd->iconf->ch_switch_vht_config |= CH_SWITCH_VHT_DISABLED;
3503
3504 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
3505 HOSTAPD_LEVEL_INFO, "CHAN_SWITCH VHT CONFIG 0x%x",
3506 hapd->iconf->ch_switch_vht_config);
3507}
3508
3509
bf281c12
AO
3510int hostapd_switch_channel(struct hostapd_data *hapd,
3511 struct csa_settings *settings)
3512{
3513 int ret;
d66873f5
AO
3514
3515 if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA)) {
3516 wpa_printf(MSG_INFO, "CSA is not supported");
3517 return -1;
3518 }
3519
6782b684 3520 ret = hostapd_fill_csa_settings(hapd, settings);
bf281c12
AO
3521 if (ret)
3522 return ret;
3523
3524 ret = hostapd_drv_switch_channel(hapd, settings);
3525 free_beacon_data(&settings->beacon_csa);
3526 free_beacon_data(&settings->beacon_after);
3527
3528 if (ret) {
3529 /* if we failed, clean cs parameters */
3530 hostapd_cleanup_cs_params(hapd);
3531 return ret;
3532 }
3533
6782b684 3534 hapd->csa_in_progress = 1;
bf281c12
AO
3535 return 0;
3536}
3537
5841958f
MK
3538
3539void
3540hostapd_switch_channel_fallback(struct hostapd_iface *iface,
3541 const struct hostapd_freq_params *freq_params)
3542{
f428332d 3543 int seg0_idx = 0, seg1_idx = 0, bw = CHANWIDTH_USE_HT;
5841958f
MK
3544
3545 wpa_printf(MSG_DEBUG, "Restarting all CSA-related BSSes");
3546
3547 if (freq_params->center_freq1)
f428332d 3548 seg0_idx = 36 + (freq_params->center_freq1 - 5180) / 5;
5841958f 3549 if (freq_params->center_freq2)
f428332d 3550 seg1_idx = 36 + (freq_params->center_freq2 - 5180) / 5;
5841958f
MK
3551
3552 switch (freq_params->bandwidth) {
3553 case 0:
3554 case 20:
3555 case 40:
f428332d 3556 bw = CHANWIDTH_USE_HT;
5841958f
MK
3557 break;
3558 case 80:
3559 if (freq_params->center_freq2)
f428332d 3560 bw = CHANWIDTH_80P80MHZ;
5841958f 3561 else
f428332d 3562 bw = CHANWIDTH_80MHZ;
5841958f
MK
3563 break;
3564 case 160:
f428332d 3565 bw = CHANWIDTH_160MHZ;
5841958f
MK
3566 break;
3567 default:
3568 wpa_printf(MSG_WARNING, "Unknown CSA bandwidth: %d",
3569 freq_params->bandwidth);
3570 break;
3571 }
3572
3573 iface->freq = freq_params->freq;
3574 iface->conf->channel = freq_params->channel;
3575 iface->conf->secondary_channel = freq_params->sec_channel_offset;
c6b7ac07
JC
3576 hostapd_set_oper_centr_freq_seg0_idx(iface->conf, seg0_idx);
3577 hostapd_set_oper_centr_freq_seg1_idx(iface->conf, seg1_idx);
3578 hostapd_set_oper_chwidth(iface->conf, bw);
5841958f
MK
3579 iface->conf->ieee80211n = freq_params->ht_enabled;
3580 iface->conf->ieee80211ac = freq_params->vht_enabled;
0cd5b4ee 3581 iface->conf->ieee80211ax = freq_params->he_enabled;
5841958f
MK
3582
3583 /*
3584 * cs_params must not be cleared earlier because the freq_params
3585 * argument may actually point to one of these.
7b2ca5cf 3586 * These params will be cleared during interface disable below.
5841958f 3587 */
5841958f
MK
3588 hostapd_disable_iface(iface);
3589 hostapd_enable_iface(iface);
3590}
3591
45e3fc72
RM
3592#endif /* NEED_AP_MLME */
3593
6959145b
AN
3594
3595struct hostapd_data * hostapd_get_iface(struct hapd_interfaces *interfaces,
3596 const char *ifname)
3597{
3598 size_t i, j;
3599
3600 for (i = 0; i < interfaces->count; i++) {
3601 struct hostapd_iface *iface = interfaces->iface[i];
3602
3603 for (j = 0; j < iface->num_bss; j++) {
3604 struct hostapd_data *hapd = iface->bss[j];
3605
3606 if (os_strcmp(ifname, hapd->conf->iface) == 0)
3607 return hapd;
3608 }
3609 }
3610
3611 return NULL;
3612}
3613
3188aaba
JM
3614
3615void hostapd_periodic_iface(struct hostapd_iface *iface)
3616{
22fd2822
JM
3617 size_t i;
3618
de744892
JM
3619 ap_list_timer(iface);
3620
22fd2822
JM
3621 for (i = 0; i < iface->num_bss; i++) {
3622 struct hostapd_data *hapd = iface->bss[i];
3623
3624 if (!hapd->started)
3625 continue;
3626
3627#ifndef CONFIG_NO_RADIUS
3628 hostapd_acl_expire(hapd);
3629#endif /* CONFIG_NO_RADIUS */
3630 }
3188aaba 3631}