Coverage Report

Created: 2025-04-24 06:18

/src/hostap/src/ap/ap_drv_ops.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * hostapd - Driver operations
3
 * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
4
 *
5
 * This software may be distributed under the terms of the BSD license.
6
 * See README for more details.
7
 */
8
9
#include "utils/includes.h"
10
11
#include "utils/common.h"
12
#include "common/ieee802_11_defs.h"
13
#include "common/ieee802_11_common.h"
14
#include "common/hw_features_common.h"
15
#include "wps/wps.h"
16
#include "p2p/p2p.h"
17
#include "hostapd.h"
18
#include "ieee802_11.h"
19
#include "sta_info.h"
20
#include "ap_config.h"
21
#include "p2p_hostapd.h"
22
#include "hs20.h"
23
#include "wpa_auth.h"
24
#include "hw_features.h"
25
#include "ap_drv_ops.h"
26
27
28
u32 hostapd_sta_flags_to_drv(u32 flags)
29
2.19k
{
30
2.19k
  int res = 0;
31
2.19k
  if (flags & WLAN_STA_AUTHORIZED)
32
0
    res |= WPA_STA_AUTHORIZED;
33
2.19k
  if (flags & WLAN_STA_WMM)
34
2.19k
    res |= WPA_STA_WMM;
35
2.19k
  if (flags & WLAN_STA_SHORT_PREAMBLE)
36
0
    res |= WPA_STA_SHORT_PREAMBLE;
37
2.19k
  if (flags & WLAN_STA_MFP)
38
0
    res |= WPA_STA_MFP;
39
2.19k
  if (flags & WLAN_STA_AUTH)
40
0
    res |= WPA_STA_AUTHENTICATED;
41
2.19k
  if (flags & WLAN_STA_ASSOC)
42
2.19k
    res |= WPA_STA_ASSOCIATED;
43
2.19k
  if (flags & WLAN_STA_SPP_AMSDU)
44
0
    res |= WPA_STA_SPP_AMSDU;
45
2.19k
  return res;
46
2.19k
}
47
48
49
static int add_buf(struct wpabuf **dst, const struct wpabuf *src)
50
0
{
51
0
  if (!src)
52
0
    return 0;
53
0
  if (wpabuf_resize(dst, wpabuf_len(src)) != 0)
54
0
    return -1;
55
0
  wpabuf_put_buf(*dst, src);
56
0
  return 0;
57
0
}
58
59
60
static int add_buf_data(struct wpabuf **dst, const u8 *data, size_t len)
61
0
{
62
0
  if (!data || !len)
63
0
    return 0;
64
0
  if (wpabuf_resize(dst, len) != 0)
65
0
    return -1;
66
0
  wpabuf_put_data(*dst, data, len);
67
0
  return 0;
68
0
}
69
70
71
int hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
72
             struct wpabuf **beacon_ret,
73
             struct wpabuf **proberesp_ret,
74
             struct wpabuf **assocresp_ret)
75
0
{
76
0
  struct wpabuf *beacon = NULL, *proberesp = NULL, *assocresp = NULL;
77
0
  u8 buf[200], *pos;
78
79
0
  *beacon_ret = *proberesp_ret = *assocresp_ret = NULL;
80
81
0
#ifdef NEED_AP_MLME
82
0
  pos = buf;
83
0
  pos = hostapd_eid_rm_enabled_capab(hapd, pos, sizeof(buf));
84
0
  if (add_buf_data(&assocresp, buf, pos - buf) < 0 ||
85
0
      add_buf_data(&proberesp, buf, pos - buf) < 0)
86
0
    goto fail;
87
0
#endif /* NEED_AP_MLME */
88
89
0
  pos = buf;
90
0
  pos = hostapd_eid_time_adv(hapd, pos);
91
0
  if (add_buf_data(&beacon, buf, pos - buf) < 0)
92
0
    goto fail;
93
0
  pos = hostapd_eid_time_zone(hapd, pos);
94
0
  if (add_buf_data(&proberesp, buf, pos - buf) < 0)
95
0
    goto fail;
96
97
0
  pos = buf;
98
0
  pos = hostapd_eid_ext_capab(hapd, pos, false);
99
0
  if (add_buf_data(&assocresp, buf, pos - buf) < 0)
100
0
    goto fail;
101
0
  pos = hostapd_eid_interworking(hapd, pos);
102
0
  pos = hostapd_eid_adv_proto(hapd, pos);
103
0
  pos = hostapd_eid_roaming_consortium(hapd, pos);
104
0
  if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
105
0
      add_buf_data(&proberesp, buf, pos - buf) < 0)
106
0
    goto fail;
107
108
#ifdef CONFIG_FST
109
  if (add_buf(&beacon, hapd->iface->fst_ies) < 0 ||
110
      add_buf(&proberesp, hapd->iface->fst_ies) < 0 ||
111
      add_buf(&assocresp, hapd->iface->fst_ies) < 0)
112
    goto fail;
113
#endif /* CONFIG_FST */
114
115
#ifdef CONFIG_FILS
116
  pos = hostapd_eid_fils_indic(hapd, buf, 0);
117
  if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
118
      add_buf_data(&proberesp, buf, pos - buf) < 0)
119
    goto fail;
120
#endif /* CONFIG_FILS */
121
122
0
  if (!hapd->conf->rsn_override_omit_rsnxe) {
123
0
    pos = hostapd_eid_rsnxe(hapd, buf, sizeof(buf));
124
0
    if (add_buf_data(&assocresp, buf, pos - buf) < 0)
125
0
      goto fail;
126
0
  }
127
128
0
  if (add_buf(&beacon, hapd->wps_beacon_ie) < 0 ||
129
0
      add_buf(&proberesp, hapd->wps_probe_resp_ie) < 0)
130
0
    goto fail;
131
132
#ifdef CONFIG_P2P
133
  if (add_buf(&beacon, hapd->p2p_beacon_ie) < 0 ||
134
      add_buf(&proberesp, hapd->p2p_probe_resp_ie) < 0)
135
    goto fail;
136
#endif /* CONFIG_P2P */
137
138
#ifdef CONFIG_P2P_MANAGER
139
  if (hapd->conf->p2p & P2P_MANAGE) {
140
    if (wpabuf_resize(&beacon, 100) == 0) {
141
      u8 *start, *p;
142
      start = wpabuf_put(beacon, 0);
143
      p = hostapd_eid_p2p_manage(hapd, start);
144
      wpabuf_put(beacon, p - start);
145
    }
146
147
    if (wpabuf_resize(&proberesp, 100) == 0) {
148
      u8 *start, *p;
149
      start = wpabuf_put(proberesp, 0);
150
      p = hostapd_eid_p2p_manage(hapd, start);
151
      wpabuf_put(proberesp, p - start);
152
    }
153
  }
154
#endif /* CONFIG_P2P_MANAGER */
155
156
0
#ifdef CONFIG_WPS
157
0
  if (hapd->conf->wps_state) {
158
0
    struct wpabuf *a = wps_build_assoc_resp_ie();
159
0
    add_buf(&assocresp, a);
160
0
    wpabuf_free(a);
161
0
  }
162
0
#endif /* CONFIG_WPS */
163
164
#ifdef CONFIG_P2P_MANAGER
165
  if (hapd->conf->p2p & P2P_MANAGE) {
166
    if (wpabuf_resize(&assocresp, 100) == 0) {
167
      u8 *start, *p;
168
      start = wpabuf_put(assocresp, 0);
169
      p = hostapd_eid_p2p_manage(hapd, start);
170
      wpabuf_put(assocresp, p - start);
171
    }
172
  }
173
#endif /* CONFIG_P2P_MANAGER */
174
175
#ifdef CONFIG_WIFI_DISPLAY
176
  if (hapd->p2p_group) {
177
    struct wpabuf *a;
178
    a = p2p_group_assoc_resp_ie(hapd->p2p_group, P2P_SC_SUCCESS);
179
    add_buf(&assocresp, a);
180
    wpabuf_free(a);
181
  }
182
#endif /* CONFIG_WIFI_DISPLAY */
183
184
0
#ifdef CONFIG_HS20
185
0
  pos = hostapd_eid_hs20_indication(hapd, buf);
186
0
  if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
187
0
      add_buf_data(&proberesp, buf, pos - buf) < 0)
188
0
    goto fail;
189
0
#endif /* CONFIG_HS20 */
190
191
#ifdef CONFIG_MBO
192
  if (hapd->conf->mbo_enabled ||
193
      OCE_STA_CFON_ENABLED(hapd) || OCE_AP_ENABLED(hapd)) {
194
    pos = hostapd_eid_mbo(hapd, buf, sizeof(buf));
195
    if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
196
        add_buf_data(&proberesp, buf, pos - buf) < 0 ||
197
        add_buf_data(&assocresp, buf, pos - buf) < 0)
198
      goto fail;
199
  }
200
#endif /* CONFIG_MBO */
201
202
#ifdef CONFIG_OWE
203
  pos = hostapd_eid_owe_trans(hapd, buf, sizeof(buf));
204
  if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
205
      add_buf_data(&proberesp, buf, pos - buf) < 0)
206
    goto fail;
207
#endif /* CONFIG_OWE */
208
209
0
  add_buf(&beacon, hapd->conf->vendor_elements);
210
0
  add_buf(&proberesp, hapd->conf->vendor_elements);
211
#ifdef CONFIG_TESTING_OPTIONS
212
  add_buf(&proberesp, hapd->conf->presp_elements);
213
#endif /* CONFIG_TESTING_OPTIONS */
214
0
  add_buf(&assocresp, hapd->conf->assocresp_elements);
215
216
0
  *beacon_ret = beacon;
217
0
  *proberesp_ret = proberesp;
218
0
  *assocresp_ret = assocresp;
219
220
0
  return 0;
221
222
0
fail:
223
0
  wpabuf_free(beacon);
224
0
  wpabuf_free(proberesp);
225
0
  wpabuf_free(assocresp);
226
0
  return -1;
227
0
}
228
229
230
void hostapd_free_ap_extra_ies(struct hostapd_data *hapd,
231
             struct wpabuf *beacon,
232
             struct wpabuf *proberesp,
233
             struct wpabuf *assocresp)
234
0
{
235
0
  wpabuf_free(beacon);
236
0
  wpabuf_free(proberesp);
237
0
  wpabuf_free(assocresp);
238
0
}
239
240
241
int hostapd_reset_ap_wps_ie(struct hostapd_data *hapd)
242
0
{
243
0
  if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
244
0
    return 0;
245
246
0
  return hapd->driver->set_ap_wps_ie(hapd->drv_priv, NULL, NULL, NULL);
247
0
}
248
249
250
int hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
251
0
{
252
0
  struct wpabuf *beacon, *proberesp, *assocresp;
253
0
  int ret;
254
255
0
  if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
256
0
    return 0;
257
258
0
  if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) <
259
0
      0)
260
0
    return -1;
261
262
0
  ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp,
263
0
            assocresp);
264
265
0
  hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
266
267
0
  return ret;
268
0
}
269
270
271
bool hostapd_sta_is_link_sta(struct hostapd_data *hapd,
272
           struct sta_info *sta)
273
2.19k
{
274
#ifdef CONFIG_IEEE80211BE
275
  if (ap_sta_is_mld(hapd, sta) &&
276
      sta->mld_assoc_link_id != hapd->mld_link_id)
277
    return true;
278
#endif /* CONFIG_IEEE80211BE */
279
280
2.19k
  return false;
281
2.19k
}
282
283
284
int hostapd_set_authorized(struct hostapd_data *hapd,
285
         struct sta_info *sta, int authorized)
286
0
{
287
  /*
288
   * The WPA_STA_AUTHORIZED flag is relevant only for the MLD station and
289
   * not to the link stations (as the authorization is done between the
290
   * MLD peers). Thus, do not propagate the change to the driver for the
291
   * link stations.
292
   */
293
0
  if (hostapd_sta_is_link_sta(hapd, sta)) {
294
0
    wpa_printf(MSG_DEBUG,
295
0
         "%s: Do not update link station flags (" MACSTR ")",
296
0
         __func__, MAC2STR(sta->addr));
297
0
    return 0;
298
0
  }
299
300
0
  if (authorized) {
301
0
    return hostapd_sta_set_flags(hapd, sta->addr,
302
0
               hostapd_sta_flags_to_drv(
303
0
                 sta->flags),
304
0
               WPA_STA_AUTHORIZED, ~0);
305
0
  }
306
307
0
  return hostapd_sta_set_flags(hapd, sta->addr,
308
0
             hostapd_sta_flags_to_drv(sta->flags),
309
0
             0, ~WPA_STA_AUTHORIZED);
310
0
}
311
312
313
int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta)
314
2.19k
{
315
2.19k
  int set_flags, total_flags, flags_and, flags_or;
316
2.19k
  total_flags = hostapd_sta_flags_to_drv(sta->flags);
317
2.19k
  set_flags = WPA_STA_SHORT_PREAMBLE | WPA_STA_WMM | WPA_STA_MFP |
318
2.19k
    WPA_STA_AUTHORIZED;
319
320
  /*
321
   * All the station flags other than WPA_STA_SHORT_PREAMBLE are relevant
322
   * only for the MLD station and not to the link stations (as these flags
323
   * are related to the MLD state and not the link state). As for the
324
   * WPA_STA_SHORT_PREAMBLE, since the station is an EHT station, it must
325
   * support short preamble. Thus, do not propagate the change to the
326
   * driver for the link stations.
327
   */
328
2.19k
  if (hostapd_sta_is_link_sta(hapd, sta)) {
329
0
    wpa_printf(MSG_DEBUG,
330
0
         "%s: Do not update link station flags (" MACSTR ")",
331
0
         __func__, MAC2STR(sta->addr));
332
0
    return 0;
333
0
  }
334
335
2.19k
  flags_or = total_flags & set_flags;
336
2.19k
  flags_and = total_flags | ~set_flags;
337
2.19k
  return hostapd_sta_set_flags(hapd, sta->addr, total_flags,
338
2.19k
             flags_or, flags_and);
339
2.19k
}
340
341
342
int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname,
343
            int enabled)
344
0
{
345
0
  struct wpa_bss_params params;
346
0
  os_memset(&params, 0, sizeof(params));
347
0
  params.ifname = ifname;
348
0
  params.enabled = enabled;
349
0
  if (enabled) {
350
0
    params.wpa = hapd->conf->wpa;
351
0
    params.ieee802_1x = hapd->conf->ieee802_1x;
352
0
    params.wpa_group = hapd->conf->wpa_group;
353
0
    if ((hapd->conf->wpa & (WPA_PROTO_WPA | WPA_PROTO_RSN)) ==
354
0
        (WPA_PROTO_WPA | WPA_PROTO_RSN))
355
0
      params.wpa_pairwise = hapd->conf->wpa_pairwise |
356
0
        hapd->conf->rsn_pairwise;
357
0
    else if (hapd->conf->wpa & WPA_PROTO_RSN)
358
0
      params.wpa_pairwise = hapd->conf->rsn_pairwise;
359
0
    else if (hapd->conf->wpa & WPA_PROTO_WPA)
360
0
      params.wpa_pairwise = hapd->conf->wpa_pairwise;
361
0
    params.wpa_key_mgmt = hapd->conf->wpa_key_mgmt;
362
0
    params.rsn_preauth = hapd->conf->rsn_preauth;
363
0
    params.ieee80211w = hapd->conf->ieee80211w;
364
0
  }
365
0
  return hostapd_set_ieee8021x(hapd, &params);
366
0
}
367
368
369
int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname)
370
0
{
371
0
  char force_ifname[IFNAMSIZ];
372
0
  u8 if_addr[ETH_ALEN];
373
0
  return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, hapd->own_addr,
374
0
            NULL, NULL, force_ifname, if_addr, NULL, 0);
375
0
}
376
377
378
int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname)
379
0
{
380
0
  return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname);
381
0
}
382
383
384
int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds,
385
      const u8 *addr, int aid, int val)
386
0
{
387
0
  const char *bridge = NULL;
388
389
0
  if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL)
390
0
    return -1;
391
0
  if (hapd->conf->wds_bridge[0])
392
0
    bridge = hapd->conf->wds_bridge;
393
0
  else if (hapd->conf->bridge[0])
394
0
    bridge = hapd->conf->bridge;
395
0
  return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val,
396
0
           bridge, ifname_wds);
397
0
}
398
399
400
int hostapd_add_sta_node(struct hostapd_data *hapd, const u8 *addr,
401
       u16 auth_alg)
402
0
{
403
0
  if (hapd->driver == NULL || hapd->driver->add_sta_node == NULL)
404
0
    return -EOPNOTSUPP;
405
0
  return hapd->driver->add_sta_node(hapd->drv_priv, addr, auth_alg);
406
0
}
407
408
409
int hostapd_sta_auth(struct hostapd_data *hapd, const u8 *addr,
410
         u16 seq, u16 status, const u8 *ie, size_t len)
411
0
{
412
0
  struct wpa_driver_sta_auth_params params;
413
#ifdef CONFIG_FILS
414
  struct sta_info *sta;
415
#endif /* CONFIG_FILS */
416
417
0
  if (hapd->driver == NULL || hapd->driver->sta_auth == NULL)
418
0
    return 0;
419
420
0
  os_memset(&params, 0, sizeof(params));
421
422
#ifdef CONFIG_FILS
423
  sta = ap_get_sta(hapd, addr);
424
  if (!sta) {
425
    wpa_printf(MSG_DEBUG, "Station " MACSTR
426
         " not found for sta_auth processing",
427
         MAC2STR(addr));
428
    return 0;
429
  }
430
431
  if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
432
      sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
433
      sta->auth_alg == WLAN_AUTH_FILS_PK) {
434
    params.fils_auth = 1;
435
    wpa_auth_get_fils_aead_params(sta->wpa_sm, params.fils_anonce,
436
                params.fils_snonce,
437
                params.fils_kek,
438
                &params.fils_kek_len);
439
  }
440
#endif /* CONFIG_FILS */
441
442
0
  params.own_addr = hapd->own_addr;
443
0
  params.addr = addr;
444
0
  params.seq = seq;
445
0
  params.status = status;
446
0
  params.ie = ie;
447
0
  params.len = len;
448
449
0
  return hapd->driver->sta_auth(hapd->drv_priv, &params);
450
0
}
451
452
453
int hostapd_sta_assoc(struct hostapd_data *hapd, const u8 *addr,
454
          int reassoc, u16 status, const u8 *ie, size_t len)
455
0
{
456
0
  if (hapd->driver == NULL || hapd->driver->sta_assoc == NULL)
457
0
    return 0;
458
0
  return hapd->driver->sta_assoc(hapd->drv_priv, hapd->own_addr, addr,
459
0
               reassoc, status, ie, len);
460
0
}
461
462
463
int hostapd_sta_add(struct hostapd_data *hapd,
464
        const u8 *addr, u16 aid, u16 capability,
465
        const u8 *supp_rates, size_t supp_rates_len,
466
        u16 listen_interval,
467
        const struct ieee80211_ht_capabilities *ht_capab,
468
        const struct ieee80211_vht_capabilities *vht_capab,
469
        const struct ieee80211_he_capabilities *he_capab,
470
        size_t he_capab_len,
471
        const struct ieee80211_eht_capabilities *eht_capab,
472
        size_t eht_capab_len,
473
        const struct ieee80211_he_6ghz_band_cap *he_6ghz_capab,
474
        u32 flags, u8 qosinfo, u8 vht_opmode, int supp_p2p_ps,
475
        int set, const u8 *link_addr, bool mld_link_sta,
476
        u16 eml_cap)
477
0
{
478
0
  struct hostapd_sta_add_params params;
479
480
0
  if (hapd->driver == NULL)
481
0
    return 0;
482
0
  if (hapd->driver->sta_add == NULL)
483
0
    return 0;
484
485
0
  os_memset(&params, 0, sizeof(params));
486
0
  params.addr = addr;
487
0
  params.aid = aid;
488
0
  params.capability = capability;
489
0
  params.supp_rates = supp_rates;
490
0
  params.supp_rates_len = supp_rates_len;
491
0
  params.listen_interval = listen_interval;
492
0
  params.ht_capabilities = ht_capab;
493
0
  params.vht_capabilities = vht_capab;
494
0
  params.he_capab = he_capab;
495
0
  params.he_capab_len = he_capab_len;
496
0
  params.eht_capab = eht_capab;
497
0
  params.eht_capab_len = eht_capab_len;
498
0
  params.he_6ghz_capab = he_6ghz_capab;
499
0
  params.vht_opmode_enabled = !!(flags & WLAN_STA_VHT_OPMODE_ENABLED);
500
0
  params.vht_opmode = vht_opmode;
501
0
  params.flags = hostapd_sta_flags_to_drv(flags);
502
0
  params.qosinfo = qosinfo;
503
0
  params.support_p2p_ps = supp_p2p_ps;
504
0
  params.set = set;
505
0
  params.mld_link_id = -1;
506
507
#ifdef CONFIG_IEEE80211BE
508
  /*
509
   * An AP MLD needs to always specify to what link the station needs
510
   * to be added.
511
   */
512
  if (hapd->conf->mld_ap) {
513
    params.mld_link_id = hapd->mld_link_id;
514
    params.mld_link_addr = link_addr;
515
    params.mld_link_sta = mld_link_sta;
516
    /* Copy EML capabilities of ML STA */
517
    if (link_addr)
518
      params.eml_cap = eml_cap;
519
  }
520
#endif /* CONFIG_IEEE80211BE */
521
522
0
  return hapd->driver->sta_add(hapd->drv_priv, &params);
523
0
}
524
525
526
int hostapd_add_tspec(struct hostapd_data *hapd, const u8 *addr,
527
          u8 *tspec_ie, size_t tspec_ielen)
528
0
{
529
0
  if (hapd->driver == NULL || hapd->driver->add_tspec == NULL)
530
0
    return 0;
531
0
  return hapd->driver->add_tspec(hapd->drv_priv, addr, tspec_ie,
532
0
               tspec_ielen);
533
0
}
534
535
536
int hostapd_set_privacy(struct hostapd_data *hapd, int enabled)
537
0
{
538
0
  if (hapd->driver == NULL || hapd->driver->set_privacy == NULL)
539
0
    return 0;
540
0
  return hapd->driver->set_privacy(hapd->drv_priv, enabled);
541
0
}
542
543
544
int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem,
545
           size_t elem_len)
546
0
{
547
0
  if (hapd->driver == NULL || hapd->driver->set_generic_elem == NULL)
548
0
    return 0;
549
0
  return hapd->driver->set_generic_elem(hapd->drv_priv, elem, elem_len);
550
0
}
551
552
553
int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len)
554
0
{
555
0
  if (hapd->driver == NULL || hapd->driver->hapd_get_ssid == NULL)
556
0
    return 0;
557
0
  return hapd->driver->hapd_get_ssid(hapd->drv_priv, buf, len);
558
0
}
559
560
561
int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len)
562
0
{
563
0
  if (hapd->driver == NULL || hapd->driver->hapd_set_ssid == NULL)
564
0
    return 0;
565
0
  return hapd->driver->hapd_set_ssid(hapd->drv_priv, buf, len);
566
0
}
567
568
569
int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
570
       const char *ifname, const u8 *addr, void *bss_ctx,
571
       void **drv_priv, char *force_ifname, u8 *if_addr,
572
       const char *bridge, int use_existing)
573
0
{
574
0
  if (hapd->driver == NULL || hapd->driver->if_add == NULL)
575
0
    return -1;
576
0
  return hapd->driver->if_add(hapd->drv_priv, type, ifname, addr,
577
0
            bss_ctx, drv_priv, force_ifname, if_addr,
578
0
            bridge, use_existing, 1);
579
0
}
580
581
582
#ifdef CONFIG_IEEE80211BE
583
int hostapd_if_link_remove(struct hostapd_data *hapd,
584
         enum wpa_driver_if_type type,
585
         const char *ifname, u8 link_id)
586
{
587
  if (!hapd->driver || !hapd->drv_priv || !hapd->driver->link_remove)
588
    return -1;
589
590
  return hapd->driver->link_remove(hapd->drv_priv, type, ifname,
591
           hapd->mld_link_id);
592
}
593
#endif /* CONFIG_IEEE80211BE */
594
595
596
int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
597
          const char *ifname)
598
0
{
599
0
  if (hapd->driver == NULL || hapd->drv_priv == NULL ||
600
0
      hapd->driver->if_remove == NULL)
601
0
    return -1;
602
603
#ifdef CONFIG_IEEE80211BE
604
  if (hapd->conf->mld_ap)
605
    return hostapd_if_link_remove(hapd, type, ifname,
606
                hapd->mld_link_id);
607
#endif /* CONFIG_IEEE80211BE */
608
609
0
  return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
610
0
}
611
612
613
int hostapd_set_ieee8021x(struct hostapd_data *hapd,
614
        struct wpa_bss_params *params)
615
0
{
616
0
  if (hapd->driver == NULL || hapd->driver->set_ieee8021x == NULL)
617
0
    return 0;
618
0
  return hapd->driver->set_ieee8021x(hapd->drv_priv, params);
619
0
}
620
621
622
int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
623
           const u8 *addr, int idx, int link_id, u8 *seq)
624
0
{
625
0
  if (hapd->driver == NULL || hapd->driver->get_seqnum == NULL)
626
0
    return 0;
627
0
  return hapd->driver->get_seqnum(ifname, hapd->drv_priv, addr, idx,
628
0
          link_id, seq);
629
0
}
630
631
632
int hostapd_flush(struct hostapd_data *hapd)
633
0
{
634
0
  int link_id = -1;
635
636
0
  if (hapd->driver == NULL || hapd->driver->flush == NULL)
637
0
    return 0;
638
639
#ifdef CONFIG_IEEE80211BE
640
  if (hapd->conf && hapd->conf->mld_ap)
641
    link_id = hapd->mld_link_id;
642
#endif /* CONFIG_IEEE80211BE */
643
644
0
  return hapd->driver->flush(hapd->drv_priv, link_id);
645
0
}
646
647
648
int hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode,
649
         int freq, int channel, int edmg, u8 edmg_channel,
650
         int ht_enabled, int vht_enabled,
651
         int he_enabled, bool eht_enabled,
652
         int sec_channel_offset, int oper_chwidth,
653
         int center_segment0, int center_segment1)
654
0
{
655
0
  struct hostapd_freq_params data;
656
0
  struct hostapd_hw_modes *cmode = hapd->iface->current_mode;
657
658
0
  if (hostapd_set_freq_params(&data, mode, freq, channel, edmg,
659
0
            edmg_channel, ht_enabled,
660
0
            vht_enabled, he_enabled, eht_enabled,
661
0
            sec_channel_offset, oper_chwidth,
662
0
            center_segment0, center_segment1,
663
0
            cmode ? cmode->vht_capab : 0,
664
0
            cmode ?
665
0
            &cmode->he_capab[IEEE80211_MODE_AP] : NULL,
666
0
            cmode ?
667
0
            &cmode->eht_capab[IEEE80211_MODE_AP] :
668
0
            NULL, hostapd_get_punct_bitmap(hapd)))
669
0
    return -1;
670
671
0
  if (hapd->driver == NULL)
672
0
    return 0;
673
0
  if (hapd->driver->set_freq == NULL)
674
0
    return 0;
675
676
0
  data.link_id = -1;
677
678
#ifdef CONFIG_IEEE80211BE
679
  if (hapd->conf->mld_ap) {
680
    data.link_id = hapd->mld_link_id;
681
    wpa_printf(MSG_DEBUG,
682
         "hostapd_set_freq: link_id=%d", data.link_id);
683
  }
684
#endif /* CONFIG_IEEE80211BE */
685
686
0
  return hapd->driver->set_freq(hapd->drv_priv, &data);
687
0
}
688
689
int hostapd_set_rts(struct hostapd_data *hapd, int rts)
690
0
{
691
0
  if (hapd->driver == NULL || hapd->driver->set_rts == NULL)
692
0
    return 0;
693
0
  return hapd->driver->set_rts(hapd->drv_priv, rts);
694
0
}
695
696
697
int hostapd_set_frag(struct hostapd_data *hapd, int frag)
698
0
{
699
0
  if (hapd->driver == NULL || hapd->driver->set_frag == NULL)
700
0
    return 0;
701
0
  return hapd->driver->set_frag(hapd->drv_priv, frag);
702
0
}
703
704
705
int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
706
        int total_flags, int flags_or, int flags_and)
707
2.19k
{
708
2.19k
  if (!hapd->driver || !hapd->drv_priv || !hapd->driver->sta_set_flags)
709
2.19k
    return 0;
710
0
  return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags,
711
0
             flags_or, flags_and);
712
2.19k
}
713
714
715
int hostapd_sta_set_airtime_weight(struct hostapd_data *hapd, const u8 *addr,
716
           unsigned int weight)
717
0
{
718
0
  if (!hapd->driver || !hapd->driver->sta_set_airtime_weight)
719
0
    return 0;
720
0
  return hapd->driver->sta_set_airtime_weight(hapd->drv_priv, addr,
721
0
                weight);
722
0
}
723
724
725
int hostapd_set_country(struct hostapd_data *hapd, const char *country)
726
0
{
727
0
  if (hapd->driver == NULL ||
728
0
      hapd->driver->set_country == NULL)
729
0
    return 0;
730
0
  return hapd->driver->set_country(hapd->drv_priv, country);
731
0
}
732
733
734
int hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
735
        int cw_min, int cw_max, int burst_time)
736
0
{
737
0
  int link_id = -1;
738
739
0
  if (hapd->driver == NULL || hapd->driver->set_tx_queue_params == NULL)
740
0
    return 0;
741
742
#ifdef CONFIG_IEEE80211BE
743
  if (hapd->conf->mld_ap)
744
    link_id = hapd->mld_link_id;
745
#endif /* CONFIG_IEEE80211BE */
746
747
0
  return hapd->driver->set_tx_queue_params(hapd->drv_priv, queue, aifs,
748
0
             cw_min, cw_max, burst_time,
749
0
             link_id);
750
0
}
751
752
753
struct hostapd_hw_modes *
754
hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
755
          u16 *flags, u8 *dfs_domain)
756
0
{
757
0
  if (!hapd->driver || !hapd->driver->get_hw_feature_data ||
758
0
      !hapd->drv_priv)
759
0
    return NULL;
760
0
  return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
761
0
             flags, dfs_domain);
762
0
}
763
764
765
int hostapd_driver_commit(struct hostapd_data *hapd)
766
0
{
767
0
  if (hapd->driver == NULL || hapd->driver->commit == NULL)
768
0
    return 0;
769
0
  return hapd->driver->commit(hapd->drv_priv);
770
0
}
771
772
773
int hostapd_drv_none(struct hostapd_data *hapd)
774
0
{
775
0
  return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0;
776
0
}
777
778
779
bool hostapd_drv_nl80211(struct hostapd_data *hapd)
780
0
{
781
0
  return hapd->driver && os_strcmp(hapd->driver->name, "nl80211") == 0;
782
0
}
783
784
785
int hostapd_driver_scan(struct hostapd_data *hapd,
786
      struct wpa_driver_scan_params *params)
787
0
{
788
0
  params->link_id = -1;
789
#ifdef CONFIG_IEEE80211BE
790
  if (hapd->conf->mld_ap)
791
    params->link_id = hapd->mld_link_id;
792
793
  if (!hapd->iface->scan_cb && hapd->conf->mld_ap &&
794
      hapd->iface->interfaces) {
795
    /* Other links may be waiting for scan results */
796
    unsigned int i;
797
798
    for (i = 0; i < hapd->iface->interfaces->count; i++) {
799
      struct hostapd_iface *h_iface =
800
        hapd->iface->interfaces->iface[i];
801
      struct hostapd_data *h_hapd;
802
803
      if (!h_iface || h_iface == hapd->iface ||
804
          h_iface->num_bss == 0)
805
        continue;
806
807
      h_hapd = h_iface->bss[0];
808
809
      if (hostapd_is_ml_partner(hapd, h_hapd) &&
810
          h_hapd->iface->state == HAPD_IFACE_ACS) {
811
        wpa_printf(MSG_INFO,
812
             "ACS in progress in a partner link - try to scan later");
813
        return -EBUSY;
814
      }
815
    }
816
  }
817
#endif /* CONFIG_IEEE80211BE */
818
819
0
  if (hapd->driver && hapd->driver->scan2)
820
0
    return hapd->driver->scan2(hapd->drv_priv, params);
821
0
  return -1;
822
0
}
823
824
825
struct wpa_scan_results * hostapd_driver_get_scan_results(
826
  struct hostapd_data *hapd)
827
0
{
828
0
  if (hapd->driver && hapd->driver->get_scan_results)
829
0
    return hapd->driver->get_scan_results(hapd->drv_priv, NULL);
830
0
  if (hapd->driver && hapd->driver->get_scan_results2)
831
0
    return hapd->driver->get_scan_results2(hapd->drv_priv);
832
0
  return NULL;
833
0
}
834
835
836
int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
837
         int duration)
838
0
{
839
0
  if (hapd->driver && hapd->driver->set_noa)
840
0
    return hapd->driver->set_noa(hapd->drv_priv, count, start,
841
0
               duration);
842
0
  return -1;
843
0
}
844
845
846
int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd,
847
      enum wpa_alg alg, const u8 *addr,
848
      int key_idx, int vlan_id, int set_tx,
849
      const u8 *seq, size_t seq_len,
850
      const u8 *key, size_t key_len, enum key_flag key_flag)
851
0
{
852
0
  struct wpa_driver_set_key_params params;
853
854
0
  if (hapd->driver == NULL || hapd->driver->set_key == NULL)
855
0
    return 0;
856
857
0
  os_memset(&params, 0, sizeof(params));
858
0
  params.ifname = ifname;
859
0
  params.alg = alg;
860
0
  params.addr = addr;
861
0
  params.key_idx = key_idx;
862
0
  params.set_tx = set_tx;
863
0
  params.seq = seq;
864
0
  params.seq_len = seq_len;
865
0
  params.key = key;
866
0
  params.key_len = key_len;
867
0
  params.vlan_id = vlan_id;
868
0
  params.key_flag = key_flag;
869
0
  params.link_id = -1;
870
871
#ifdef CONFIG_IEEE80211BE
872
  if (hapd->conf->mld_ap && !(key_flag & KEY_FLAG_PAIRWISE))
873
    params.link_id = hapd->mld_link_id;
874
#endif /* CONFIG_IEEE80211BE */
875
876
0
  return hapd->driver->set_key(hapd->drv_priv, &params);
877
0
}
878
879
880
int hostapd_drv_send_mlme(struct hostapd_data *hapd,
881
        const void *msg, size_t len, int noack,
882
        const u16 *csa_offs, size_t csa_offs_len,
883
        int no_encrypt)
884
0
{
885
0
  int link_id = -1;
886
887
#ifdef CONFIG_IEEE80211BE
888
  if (hapd->conf->mld_ap)
889
    link_id = hapd->mld_link_id;
890
#endif /* CONFIG_IEEE80211BE */
891
892
0
  if (!hapd->driver || !hapd->driver->send_mlme || !hapd->drv_priv)
893
0
    return 0;
894
0
  return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack, 0,
895
0
               csa_offs, csa_offs_len, no_encrypt, 0,
896
0
               link_id);
897
0
}
898
899
900
int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
901
         const u8 *addr, int reason)
902
0
{
903
0
  int link_id = -1;
904
0
  const u8 *own_addr = hapd->own_addr;
905
906
#ifdef CONFIG_IEEE80211BE
907
  if (hapd->conf->mld_ap) {
908
    struct sta_info *sta = ap_get_sta(hapd, addr);
909
910
    link_id = hapd->mld_link_id;
911
    if (ap_sta_is_mld(hapd, sta))
912
      own_addr = hapd->mld->mld_addr;
913
  }
914
#endif /* CONFIG_IEEE80211BE */
915
916
0
  if (!hapd->driver || !hapd->driver->sta_deauth || !hapd->drv_priv)
917
0
    return 0;
918
0
  return hapd->driver->sta_deauth(hapd->drv_priv, own_addr, addr,
919
0
          reason, link_id);
920
0
}
921
922
923
int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
924
           const u8 *addr, int reason)
925
0
{
926
0
  const u8 *own_addr = hapd->own_addr;
927
928
#ifdef CONFIG_IEEE80211BE
929
  if (hapd->conf->mld_ap) {
930
    struct sta_info *sta = ap_get_sta(hapd, addr);
931
932
    if (ap_sta_is_mld(hapd, sta))
933
      own_addr = hapd->mld->mld_addr;
934
  }
935
#endif /* CONFIG_IEEE80211BE */
936
937
0
  if (!hapd->driver || !hapd->driver->sta_disassoc || !hapd->drv_priv)
938
0
    return 0;
939
0
  return hapd->driver->sta_disassoc(hapd->drv_priv, own_addr, addr,
940
0
            reason);
941
0
}
942
943
944
int hostapd_drv_wnm_oper(struct hostapd_data *hapd, enum wnm_oper oper,
945
       const u8 *peer, u8 *buf, u16 *buf_len)
946
0
{
947
0
  if (hapd->driver == NULL || hapd->driver->wnm_oper == NULL)
948
0
    return -1;
949
0
  return hapd->driver->wnm_oper(hapd->drv_priv, oper, peer, buf,
950
0
              buf_len);
951
0
}
952
953
954
#ifdef CONFIG_IEEE80211BE
955
static bool hostapd_is_action_frame_link_agnostic(u8 category, u8 sub_category)
956
{
957
  /* As per IEEE P802.11be/D7.0, 35.3.14 (MLD individually addressed
958
   * Management frame delivery), between an AP MLD and a non-AP MLD, the
959
   * following individually addressed MMPDUs shall be intended for an MLD.
960
   */
961
  switch (category) {
962
  case WLAN_ACTION_BLOCK_ACK:
963
  case WLAN_ACTION_FT:
964
  case WLAN_ACTION_SA_QUERY:
965
  case WLAN_ACTION_WNM:
966
    switch (sub_category) {
967
    case WNM_BSS_TRANS_MGMT_REQ:
968
    case WNM_BSS_TRANS_MGMT_RESP:
969
    case WNM_SLEEP_MODE_REQ:
970
    case WNM_SLEEP_MODE_RESP:
971
      return true;
972
    default:
973
      return false;
974
    }
975
  case WLAN_ACTION_ROBUST_AV_STREAMING:
976
    switch (sub_category) {
977
    case ROBUST_AV_SCS_REQ:
978
    case ROBUST_AV_SCS_RESP:
979
    case ROBUST_AV_MSCS_REQ:
980
    case ROBUST_AV_MSCS_RESP:
981
      return true;
982
    default:
983
      return false;
984
    }
985
  /* TODO: Handle EHT/EPCS related action frames once the support is
986
   * added. */
987
  default:
988
    return false;
989
  }
990
}
991
#endif /* CONFIG_IEEE80211BE */
992
993
994
static int hapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
995
        unsigned int wait, const u8 *dst,
996
        const u8 *data, size_t len, bool addr3_ap,
997
        const u8 *forced_a3)
998
0
{
999
0
  const u8 *own_addr = hapd->own_addr;
1000
0
  const u8 *bssid;
1001
0
  const u8 wildcard_bssid[ETH_ALEN] = {
1002
0
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff
1003
0
  };
1004
0
  struct sta_info *sta;
1005
0
  int link_id = -1;
1006
1007
0
  if (!hapd->driver || !hapd->driver->send_action || !hapd->drv_priv)
1008
0
    return 0;
1009
0
  bssid = hapd->own_addr;
1010
0
  if (forced_a3) {
1011
0
    bssid = forced_a3;
1012
0
  } else if (!addr3_ap && !is_multicast_ether_addr(dst) &&
1013
0
       len > 0 && data[0] == WLAN_ACTION_PUBLIC) {
1014
    /*
1015
     * Public Action frames to a STA that is not a member of the BSS
1016
     * shall use wildcard BSSID value.
1017
     */
1018
0
    sta = ap_get_sta(hapd, dst);
1019
0
    if (!sta || !(sta->flags & WLAN_STA_ASSOC))
1020
0
      bssid = wildcard_bssid;
1021
0
  } else if (!addr3_ap && is_broadcast_ether_addr(dst) &&
1022
0
       len > 0 && data[0] == WLAN_ACTION_PUBLIC) {
1023
    /*
1024
     * The only current use case of Public Action frames with
1025
     * broadcast destination address is DPP PKEX. That case is
1026
     * directing all devices and not just the STAs within the BSS,
1027
     * so have to use the wildcard BSSID value.
1028
     */
1029
0
    bssid = wildcard_bssid;
1030
#ifdef CONFIG_IEEE80211BE
1031
  } else if (hapd->conf->mld_ap) {
1032
    sta = ap_get_sta(hapd, dst);
1033
1034
    if (ap_sta_is_mld(hapd, sta)) {
1035
      own_addr = hapd->mld->mld_addr;
1036
      bssid = own_addr;
1037
    }
1038
1039
    if (!hostapd_is_action_frame_link_agnostic(data[0], data[1]))
1040
      link_id = hapd->mld_link_id;
1041
#endif /* CONFIG_IEEE80211BE */
1042
0
  }
1043
1044
0
  return hapd->driver->send_action(hapd->drv_priv, freq, wait, dst,
1045
0
           own_addr, bssid, data, len, 0,
1046
0
           link_id);
1047
0
}
1048
1049
1050
int hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
1051
          unsigned int wait, const u8 *dst, const u8 *data,
1052
          size_t len)
1053
0
{
1054
0
  return hapd_drv_send_action(hapd, freq, wait, dst, data, len, false,
1055
0
            NULL);
1056
0
}
1057
1058
1059
int hostapd_drv_send_action_addr3_ap(struct hostapd_data *hapd,
1060
             unsigned int freq,
1061
             unsigned int wait, const u8 *dst,
1062
             const u8 *data, size_t len)
1063
0
{
1064
0
  return hapd_drv_send_action(hapd, freq, wait, dst, data, len, true,
1065
0
            NULL);
1066
0
}
1067
1068
1069
int hostapd_drv_send_action_forced_addr3(struct hostapd_data *hapd,
1070
           unsigned int freq,
1071
           unsigned int wait, const u8 *dst,
1072
           const u8 *a3,
1073
           const u8 *data, size_t len)
1074
0
{
1075
0
  return hapd_drv_send_action(hapd, freq, wait, dst, data, len, false,
1076
0
            a3);
1077
0
}
1078
1079
1080
int hostapd_start_dfs_cac(struct hostapd_iface *iface,
1081
        enum hostapd_hw_mode mode, int freq,
1082
        int channel, int ht_enabled, int vht_enabled,
1083
        int he_enabled, bool eht_enabled,
1084
        int sec_channel_offset, int oper_chwidth,
1085
        int center_segment0, int center_segment1,
1086
        bool radar_background)
1087
0
{
1088
0
  struct hostapd_data *hapd = iface->bss[0];
1089
0
  struct hostapd_freq_params data;
1090
0
  int res;
1091
0
  struct hostapd_hw_modes *cmode = iface->current_mode;
1092
1093
0
  if (!hapd->driver || !hapd->driver->start_dfs_cac || !cmode)
1094
0
    return 0;
1095
1096
0
  if (!iface->conf->ieee80211h) {
1097
0
    wpa_printf(MSG_ERROR, "Can't start DFS CAC, DFS functionality "
1098
0
         "is not enabled");
1099
0
    return -1;
1100
0
  }
1101
1102
0
  if (hostapd_set_freq_params(&data, mode, freq, channel, 0, 0,
1103
0
            ht_enabled,
1104
0
            vht_enabled, he_enabled, eht_enabled,
1105
0
            sec_channel_offset,
1106
0
            oper_chwidth, center_segment0,
1107
0
            center_segment1,
1108
0
            cmode->vht_capab,
1109
0
            &cmode->he_capab[IEEE80211_MODE_AP],
1110
0
            &cmode->eht_capab[IEEE80211_MODE_AP],
1111
0
            hostapd_get_punct_bitmap(hapd))) {
1112
0
    wpa_printf(MSG_ERROR, "Can't set freq params");
1113
0
    return -1;
1114
0
  }
1115
0
  data.radar_background = radar_background;
1116
1117
0
  data.link_id = -1;
1118
#ifdef CONFIG_IEEE80211BE
1119
  if (hapd->conf->mld_ap)
1120
    data.link_id = hapd->mld_link_id;
1121
#endif /* CONFIG_IEEE80211BE */
1122
1123
0
  res = hapd->driver->start_dfs_cac(hapd->drv_priv, &data);
1124
0
  if (!res) {
1125
0
    if (radar_background)
1126
0
      iface->radar_background.cac_started = 1;
1127
0
    else
1128
0
      iface->cac_started = 1;
1129
0
    os_get_reltime(&iface->dfs_cac_start);
1130
0
  }
1131
1132
0
  return res;
1133
0
}
1134
1135
1136
int hostapd_drv_set_qos_map(struct hostapd_data *hapd,
1137
          const u8 *qos_map_set, u8 qos_map_set_len)
1138
0
{
1139
0
  if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv ||
1140
0
      !(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_QOS_MAPPING))
1141
0
    return 0;
1142
0
  return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set,
1143
0
           qos_map_set_len);
1144
0
}
1145
1146
1147
void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd,
1148
              struct hostapd_hw_modes *mode,
1149
              int acs_ch_list_all, bool allow_disabled,
1150
              int **freq_list)
1151
0
{
1152
0
  int i;
1153
0
  bool is_no_ir = false;
1154
0
  bool allow_6g_acs = hostapd_config_check_bss_6g(hapd->conf) &&
1155
0
    (hapd->iface->conf->ieee80211ax ||
1156
0
     hapd->iface->conf->ieee80211be);
1157
1158
0
  for (i = 0; i < mode->num_channels; i++) {
1159
0
    struct hostapd_channel_data *chan = &mode->channels[i];
1160
1161
0
    if (!acs_ch_list_all &&
1162
0
        (hapd->iface->conf->acs_freq_list.num &&
1163
0
         !freq_range_list_includes(
1164
0
           &hapd->iface->conf->acs_freq_list,
1165
0
           chan->freq)))
1166
0
      continue;
1167
0
    if (!acs_ch_list_all &&
1168
0
        (!hapd->iface->conf->acs_freq_list_present &&
1169
0
         hapd->iface->conf->acs_ch_list.num &&
1170
0
         !freq_range_list_includes(
1171
0
           &hapd->iface->conf->acs_ch_list,
1172
0
           chan->chan)))
1173
0
      continue;
1174
0
    if (is_6ghz_freq(chan->freq) &&
1175
0
        ((hapd->iface->conf->acs_exclude_6ghz_non_psc &&
1176
0
          !is_6ghz_psc_frequency(chan->freq)) ||
1177
0
         !allow_6g_acs))
1178
0
      continue;
1179
0
    if ((!(chan->flag & HOSTAPD_CHAN_DISABLED) || allow_disabled) &&
1180
0
        !(hapd->iface->conf->acs_exclude_dfs &&
1181
0
          (chan->flag & HOSTAPD_CHAN_RADAR)) &&
1182
0
        !(chan->max_tx_power < hapd->iface->conf->min_tx_power))
1183
0
      int_array_add_unique(freq_list, chan->freq);
1184
0
    else if ((chan->flag & HOSTAPD_CHAN_NO_IR) &&
1185
0
       is_6ghz_freq(chan->freq))
1186
0
      is_no_ir = true;
1187
0
  }
1188
1189
0
  hapd->iface->is_no_ir = is_no_ir;
1190
0
}
1191
1192
1193
void hostapd_get_ext_capa(struct hostapd_iface *iface)
1194
0
{
1195
0
  struct hostapd_data *hapd = iface->bss[0];
1196
1197
0
  if (!hapd->driver || !hapd->driver->get_ext_capab)
1198
0
    return;
1199
1200
0
  hapd->driver->get_ext_capab(hapd->drv_priv, WPA_IF_AP_BSS,
1201
0
            &iface->extended_capa,
1202
0
            &iface->extended_capa_mask,
1203
0
            &iface->extended_capa_len);
1204
0
}
1205
1206
1207
void hostapd_get_mld_capa(struct hostapd_iface *iface)
1208
0
{
1209
0
  struct hostapd_data *hapd = iface->bss[0];
1210
1211
0
  if (!hapd->driver || !hapd->driver->get_mld_capab)
1212
0
    return;
1213
1214
0
  hapd->driver->get_mld_capab(hapd->drv_priv, WPA_IF_AP_BSS,
1215
0
            &iface->mld_eml_capa,
1216
0
            &iface->mld_mld_capa);
1217
0
}
1218
1219
1220
/**
1221
 * hostapd_drv_do_acs - Start automatic channel selection
1222
 * @hapd: BSS data for the device initiating ACS
1223
 * Returns: 0 on success, -1 on failure, 1 on failure due to NO_IR (AFC)
1224
 */
1225
int hostapd_drv_do_acs(struct hostapd_data *hapd)
1226
0
{
1227
0
  struct drv_acs_params params;
1228
0
  int ret, i, acs_ch_list_all = 0;
1229
0
  struct hostapd_hw_modes *mode;
1230
0
  int *freq_list = NULL;
1231
0
  enum hostapd_hw_mode selected_mode;
1232
1233
0
  if (hapd->driver == NULL || hapd->driver->do_acs == NULL)
1234
0
    return 0;
1235
1236
0
  os_memset(&params, 0, sizeof(params));
1237
0
  params.hw_mode = hapd->iface->conf->hw_mode;
1238
0
  params.link_id = -1;
1239
#ifdef CONFIG_IEEE80211BE
1240
  if (hapd->conf->mld_ap && hapd->iconf->ieee80211be &&
1241
      !hapd->conf->disable_11be)
1242
    params.link_id = hapd->mld_link_id;
1243
#endif /* CONFIG_IEEE80211BE */
1244
1245
  /*
1246
   * If no chanlist config parameter is provided, include all enabled
1247
   * channels of the selected hw_mode.
1248
   */
1249
0
  if (hapd->iface->conf->acs_freq_list_present)
1250
0
    acs_ch_list_all = !hapd->iface->conf->acs_freq_list.num;
1251
0
  else
1252
0
    acs_ch_list_all = !hapd->iface->conf->acs_ch_list.num;
1253
1254
0
  if (hapd->iface->current_mode)
1255
0
    selected_mode = hapd->iface->current_mode->mode;
1256
0
  else
1257
0
    selected_mode = HOSTAPD_MODE_IEEE80211ANY;
1258
1259
0
  for (i = 0; i < hapd->iface->num_hw_features; i++) {
1260
0
    mode = &hapd->iface->hw_features[i];
1261
0
    if (selected_mode != HOSTAPD_MODE_IEEE80211ANY &&
1262
0
        selected_mode != mode->mode)
1263
0
      continue;
1264
0
    hostapd_get_hw_mode_any_channels(hapd, mode, acs_ch_list_all,
1265
0
             false, &freq_list);
1266
0
  }
1267
1268
0
  if (!freq_list && hapd->iface->is_no_ir) {
1269
0
    wpa_printf(MSG_ERROR,
1270
0
         "NO_IR: Interface freq_list is empty. Failing do_acs.");
1271
0
    return 1;
1272
0
  }
1273
1274
0
  params.freq_list = freq_list;
1275
0
  params.edmg_enabled = hapd->iface->conf->enable_edmg;
1276
1277
0
  params.ht_enabled = !!(hapd->iface->conf->ieee80211n);
1278
0
  params.ht40_enabled = !!(hapd->iface->conf->ht_capab &
1279
0
         HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET);
1280
0
  params.vht_enabled = !!(hapd->iface->conf->ieee80211ac);
1281
0
  params.eht_enabled = !!(hapd->iface->conf->ieee80211be);
1282
0
  params.ch_width = 20;
1283
0
  if (hapd->iface->conf->ieee80211n && params.ht40_enabled)
1284
0
    params.ch_width = 40;
1285
1286
  /* Note: VHT20 is defined by combination of ht_capab & oper_chwidth
1287
   */
1288
0
  if ((hapd->iface->conf->ieee80211be ||
1289
0
       hapd->iface->conf->ieee80211ax ||
1290
0
       hapd->iface->conf->ieee80211ac) &&
1291
0
      params.ht40_enabled) {
1292
0
    enum oper_chan_width oper_chwidth;
1293
1294
0
    oper_chwidth = hostapd_get_oper_chwidth(hapd->iface->conf);
1295
0
    if (oper_chwidth == CONF_OPER_CHWIDTH_80MHZ)
1296
0
      params.ch_width = 80;
1297
0
    else if (oper_chwidth == CONF_OPER_CHWIDTH_160MHZ ||
1298
0
       oper_chwidth == CONF_OPER_CHWIDTH_80P80MHZ)
1299
0
      params.ch_width = 160;
1300
0
    else if (oper_chwidth == CONF_OPER_CHWIDTH_320MHZ)
1301
0
      params.ch_width = 320;
1302
0
  }
1303
1304
0
  if (hapd->iface->conf->op_class)
1305
0
    params.ch_width = op_class_to_bandwidth(
1306
0
      hapd->iface->conf->op_class);
1307
0
  ret = hapd->driver->do_acs(hapd->drv_priv, &params);
1308
0
  os_free(freq_list);
1309
1310
0
  return ret;
1311
0
}
1312
1313
1314
int hostapd_drv_update_dh_ie(struct hostapd_data *hapd, const u8 *peer,
1315
           u16 reason_code, const u8 *ie, size_t ielen)
1316
0
{
1317
0
  if (!hapd->driver || !hapd->driver->update_dh_ie || !hapd->drv_priv)
1318
0
    return 0;
1319
0
  return hapd->driver->update_dh_ie(hapd->drv_priv, peer, reason_code,
1320
0
            ie, ielen);
1321
0
}
1322
1323
1324
int hostapd_drv_dpp_listen(struct hostapd_data *hapd, bool enable)
1325
0
{
1326
0
  if (!hapd->driver || !hapd->driver->dpp_listen || !hapd->drv_priv)
1327
0
    return 0;
1328
0
  return hapd->driver->dpp_listen(hapd->drv_priv, enable);
1329
0
}
1330
1331
1332
#ifdef CONFIG_PASN
1333
int hostapd_drv_set_secure_ranging_ctx(struct hostapd_data *hapd,
1334
               const u8 *own_addr, const u8 *peer_addr,
1335
               u32 cipher, u8 tk_len, const u8 *tk,
1336
               u8 ltf_keyseed_len,
1337
               const u8 *ltf_keyseed, u32 action)
1338
{
1339
  struct secure_ranging_params params;
1340
1341
  if (!hapd->driver || !hapd->driver->set_secure_ranging_ctx)
1342
    return 0;
1343
1344
  os_memset(&params, 0, sizeof(params));
1345
  params.own_addr = own_addr;
1346
  params.peer_addr = peer_addr;
1347
  params.cipher = cipher;
1348
  params.tk_len = tk_len;
1349
  params.tk = tk;
1350
  params.ltf_keyseed_len = ltf_keyseed_len;
1351
  params.ltf_keyseed = ltf_keyseed;
1352
  params.action = action;
1353
1354
  return hapd->driver->set_secure_ranging_ctx(hapd->drv_priv, &params);
1355
}
1356
#endif /* CONFIG_PASN */
1357
1358
1359
struct hostapd_multi_hw_info *
1360
hostapd_get_multi_hw_info(struct hostapd_data *hapd,
1361
        unsigned int *num_multi_hws)
1362
0
{
1363
0
  if (!hapd->driver || !hapd->driver->get_multi_hw_info)
1364
0
    return NULL;
1365
1366
0
  return hapd->driver->get_multi_hw_info(hapd->drv_priv, num_multi_hws);
1367
0
}
1368
1369
1370
int hostapd_drv_add_pmkid(struct hostapd_data *hapd,
1371
        struct wpa_pmkid_params *params)
1372
0
{
1373
0
  if (!hapd->driver || !hapd->driver->add_pmkid || !hapd->drv_priv)
1374
0
    return 0;
1375
0
  return hapd->driver->add_pmkid(hapd->drv_priv, params);
1376
0
}
1377
1378
1379
int hostapd_add_pmkid(struct hostapd_data *hapd, const u8 *bssid, const u8 *pmk,
1380
          size_t pmk_len, const u8 *pmkid, int akmp)
1381
0
{
1382
0
  struct wpa_pmkid_params params;
1383
1384
0
  os_memset(&params, 0, sizeof(params));
1385
0
  params.bssid = bssid;
1386
0
  params.pmkid = pmkid;
1387
0
  params.pmk = pmk;
1388
0
  params.pmk_len = pmk_len;
1389
1390
0
  return hostapd_drv_add_pmkid(hapd, &params);
1391
0
}