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