Merge ~antoinelassagne/ubuntu/+source/wpa:plucky-sru-2117497 into ubuntu/+source/wpa:ubuntu/plucky

Proposed by Antoine Lassagne
Status: Needs review
Proposed branch: ~antoinelassagne/ubuntu/+source/wpa:plucky-sru-2117497
Merge into: ubuntu/+source/wpa:ubuntu/plucky
Diff against target: 123627 lines (+66346/-12714)
368 files modified
CONTRIBUTIONS (+1/-1)
README (+1/-1)
debian/changelog (+12/-0)
debian/control (+2/-1)
debian/patches/0015-Revert-Mark-authorization-completed-on-driver-indica.patch (+45/-0)
debian/patches/0019-Send-CTRL-EVENT-SIGNAL-CHANGE-message-to-control-int.patch (+5/-15)
debian/patches/Bump-DEFAULT_BSS_MAX_COUNT-to-1000.patch (+25/-0)
debian/patches/series (+2/-7)
debian/patches/upstream-fixes/0002-AP-guard-FT-SAE-code-with-CONFIG_IEEE80211R_AP.patch (+14/-10)
dev/null (+0/-36)
hostapd/Android.mk (+27/-1)
hostapd/ChangeLog (+37/-0)
hostapd/Makefile (+28/-2)
hostapd/README (+1/-1)
hostapd/android.config (+6/-0)
hostapd/config_file.c (+428/-53)
hostapd/config_file.h (+2/-5)
hostapd/ctrl_iface.c (+1020/-440)
hostapd/defconfig (+18/-3)
hostapd/hostapd.conf (+346/-10)
hostapd/hostapd.eap_user (+2/-2)
hostapd/hostapd_cli.c (+181/-36)
hostapd/main.c (+136/-6)
hs20/client/Android.mk (+10/-0)
hs20/client/est.c (+5/-32)
hs20/client/osu_client.c (+79/-36)
hs20/client/spp_client.c (+0/-1)
hs20/server/spp_server.c (+4/-1)
src/Makefile (+1/-1)
src/ap/acs.c (+471/-97)
src/ap/acs.h (+3/-0)
src/ap/airtime_policy.c (+1/-1)
src/ap/ap_config.c (+173/-32)
src/ap/ap_config.h (+214/-12)
src/ap/ap_drv_ops.c (+306/-53)
src/ap/ap_drv_ops.h (+73/-11)
src/ap/ap_list.c (+3/-3)
src/ap/ap_mlme.c (+2/-2)
src/ap/authsrv.c (+94/-0)
src/ap/beacon.c (+1020/-192)
src/ap/beacon.h (+4/-0)
src/ap/bss_load.c (+1/-1)
src/ap/comeback_token.c (+139/-0)
src/ap/comeback_token.h (+21/-0)
src/ap/ctrl_iface_ap.c (+586/-13)
src/ap/ctrl_iface_ap.h (+17/-0)
src/ap/dfs.c (+452/-156)
src/ap/dpp_hostapd.c (+1355/-62)
src/ap/dpp_hostapd.h (+5/-0)
src/ap/drv_callbacks.c (+781/-100)
src/ap/fils_hlp.c (+5/-5)
src/ap/gas_query_ap.c (+7/-3)
src/ap/gas_serv.c (+6/-5)
src/ap/gas_serv.h (+1/-1)
src/ap/hostapd.c (+1311/-130)
src/ap/hostapd.h (+163/-6)
src/ap/hw_features.c (+206/-27)
src/ap/hw_features.h (+12/-0)
src/ap/ieee802_11.c (+2426/-1604)
src/ap/ieee802_11.h (+75/-8)
src/ap/ieee802_11_auth.c (+131/-31)
src/ap/ieee802_11_auth.h (+4/-1)
src/ap/ieee802_11_eht.c (+1405/-0)
src/ap/ieee802_11_he.c (+68/-19)
src/ap/ieee802_11_ht.c (+2/-3)
src/ap/ieee802_11_shared.c (+174/-41)
src/ap/ieee802_11_vht.c (+23/-9)
src/ap/ieee802_1x.c (+187/-46)
src/ap/ieee802_1x.h (+1/-1)
src/ap/nan_usd_ap.c (+267/-0)
src/ap/nan_usd_ap.h (+46/-0)
src/ap/ndisc_snoop.c (+1/-0)
src/ap/neighbor_db.c (+59/-15)
src/ap/neighbor_db.h (+1/-0)
src/ap/pmksa_cache_auth.c (+24/-8)
src/ap/pmksa_cache_auth.h (+4/-0)
src/ap/preauth_auth.c (+2/-2)
src/ap/rrm.c (+121/-0)
src/ap/rrm.h (+2/-0)
src/ap/sta_info.c (+395/-74)
src/ap/sta_info.h (+65/-31)
src/ap/utils.c (+13/-1)
src/ap/wmm.c (+0/-7)
src/ap/wnm_ap.c (+204/-12)
src/ap/wpa_auth.c (+2012/-447)
src/ap/wpa_auth.h (+93/-10)
src/ap/wpa_auth_ft.c (+400/-215)
src/ap/wpa_auth_glue.c (+236/-33)
src/ap/wpa_auth_i.h (+42/-5)
src/ap/wpa_auth_ie.c (+81/-14)
src/ap/wpa_auth_kay.c (+9/-36)
src/ap/wps_hostapd.c (+3/-2)
src/ap/x_snoop.c (+5/-0)
src/build.rules (+1/-1)
src/common/brcm_vendor.h (+4/-4)
src/common/common_module_tests.c (+1/-1)
src/common/defs.h (+62/-5)
src/common/dpp.c (+827/-56)
src/common/dpp.h (+124/-8)
src/common/dpp_crypto.c (+201/-38)
src/common/dpp_i.h (+14/-5)
src/common/dpp_pkex.c (+37/-22)
src/common/dpp_reconfig.c (+17/-1)
src/common/dpp_tcp.c (+875/-41)
src/common/dragonfly.c (+6/-3)
src/common/gas_server.c (+61/-18)
src/common/gas_server.h (+4/-1)
src/common/hw_features_common.c (+266/-37)
src/common/hw_features_common.h (+9/-3)
src/common/ieee802_11_common.c (+895/-195)
src/common/ieee802_11_common.h (+60/-29)
src/common/ieee802_11_defs.h (+642/-80)
src/common/nan.h (+98/-0)
src/common/nan_de.c (+1395/-0)
src/common/nan_de.h (+145/-0)
src/common/ocv.c (+2/-3)
src/common/ptksa_cache.c (+70/-4)
src/common/ptksa_cache.h (+9/-38)
src/common/qca-vendor.h (+6164/-159)
src/common/sae.c (+125/-14)
src/common/sae.h (+11/-3)
src/common/version.h (+1/-1)
src/common/wpa_common.c (+760/-235)
src/common/wpa_common.h (+123/-11)
src/common/wpa_ctrl.c (+13/-3)
src/common/wpa_ctrl.h (+36/-0)
src/crypto/crypto.h (+114/-3)
src/crypto/crypto_gnutls.c (+5/-0)
src/crypto/crypto_internal.c (+5/-0)
src/crypto/crypto_libtomcrypt.c (+5/-0)
src/crypto/crypto_linux.c (+5/-0)
src/crypto/crypto_module_tests.c (+281/-0)
src/crypto/crypto_nettle.c (+5/-0)
src/crypto/crypto_none.c (+5/-0)
src/crypto/crypto_openssl.c (+2481/-141)
src/crypto/crypto_wolfssl.c (+1889/-154)
src/crypto/fips_prf_internal.c (+4/-7)
src/crypto/fips_prf_openssl.c (+15/-0)
src/crypto/sha1-pbkdf2.c (+3/-0)
src/crypto/sha256-internal.c (+0/-3)
src/crypto/sha256.c (+15/-6)
src/crypto/sha384.c (+3/-3)
src/crypto/sha512-internal.c (+0/-3)
src/crypto/sha512.c (+3/-3)
src/crypto/tls.h (+12/-6)
src/crypto/tls_gnutls.c (+1/-0)
src/crypto/tls_internal.c (+2/-9)
src/crypto/tls_none.c (+1/-0)
src/crypto/tls_openssl.c (+409/-155)
src/crypto/tls_openssl_ocsp.c (+11/-15)
src/crypto/tls_wolfssl.c (+195/-89)
src/drivers/driver.h (+900/-64)
src/drivers/driver_atheros.c (+16/-15)
src/drivers/driver_bsd.c (+9/-7)
src/drivers/driver_common.c (+44/-0)
src/drivers/driver_hostap.c (+11/-9)
src/drivers/driver_macsec_linux.c (+72/-4)
src/drivers/driver_macsec_qca.c (+2/-2)
src/drivers/driver_ndis.c (+4/-4)
src/drivers/driver_nl80211.c (+2673/-770)
src/drivers/driver_nl80211.h (+95/-18)
src/drivers/driver_nl80211_capa.c (+286/-68)
src/drivers/driver_nl80211_event.c (+1180/-111)
src/drivers/driver_nl80211_scan.c (+90/-37)
src/drivers/driver_roboswitch.c (+1/-1)
src/drivers/driver_wext.c (+6/-5)
src/drivers/driver_wired.c (+1/-1)
src/drivers/linux_ioctl.c (+10/-1)
src/drivers/ndis_events.c (+3/-2)
src/drivers/netlink.c (+4/-2)
src/drivers/nl80211_copy.h (+598/-28)
src/eap_common/eap_defs.h (+1/-1)
src/eap_common/eap_pwd_common.c (+19/-4)
src/eap_common/eap_sake_common.c (+13/-6)
src/eap_peer/eap.c (+44/-0)
src/eap_peer/eap_aka.c (+154/-44)
src/eap_peer/eap_config.h (+28/-18)
src/eap_peer/eap_fast.c (+2/-12)
src/eap_peer/eap_i.h (+9/-0)
src/eap_peer/eap_mschapv2.c (+25/-5)
src/eap_peer/eap_peap.c (+37/-3)
src/eap_peer/eap_pwd.c (+26/-7)
src/eap_peer/eap_sim.c (+158/-44)
src/eap_peer/eap_teap.c (+34/-27)
src/eap_peer/eap_tls.c (+11/-4)
src/eap_peer/eap_tls_common.c (+18/-9)
src/eap_peer/eap_tls_common.h (+5/-0)
src/eap_peer/eap_ttls.c (+29/-3)
src/eap_peer/eap_wsc.c (+12/-2)
src/eap_server/eap.h (+12/-0)
src/eap_server/eap_i.h (+7/-0)
src/eap_server/eap_server_aka.c (+117/-9)
src/eap_server/eap_server_eke.c (+1/-0)
src/eap_server/eap_server_fast.c (+2/-12)
src/eap_server/eap_server_mschapv2.c (+25/-3)
src/eap_server/eap_server_peap.c (+18/-0)
src/eap_server/eap_server_pwd.c (+26/-7)
src/eap_server/eap_server_sim.c (+127/-6)
src/eap_server/eap_server_teap.c (+36/-3)
src/eap_server/eap_server_tls.c (+9/-1)
src/eap_server/eap_server_tls_common.c (+15/-3)
src/eap_server/eap_server_ttls.c (+2/-1)
src/eap_server/eap_tls_common.h (+2/-0)
src/eapol_auth/eapol_auth_sm.c (+19/-7)
src/eapol_auth/eapol_auth_sm.h (+3/-2)
src/eapol_auth/eapol_auth_sm_i.h (+4/-0)
src/eapol_supp/eapol_supp_sm.c (+16/-1)
src/eapol_supp/eapol_supp_sm.h (+16/-2)
src/fst/fst_group.c (+8/-4)
src/fst/fst_iface.c (+1/-1)
src/fst/fst_session.c (+2/-4)
src/l2_packet/l2_packet_freebsd.c (+13/-2)
src/l2_packet/l2_packet_linux.c (+2/-2)
src/p2p/p2p.c (+80/-43)
src/p2p/p2p.h (+9/-3)
src/p2p/p2p_build.c (+13/-7)
src/p2p/p2p_dev_disc.c (+5/-5)
src/p2p/p2p_go_neg.c (+94/-27)
src/p2p/p2p_group.c (+7/-7)
src/p2p/p2p_i.h (+15/-4)
src/p2p/p2p_invitation.c (+23/-8)
src/p2p/p2p_parse.c (+24/-3)
src/p2p/p2p_pd.c (+29/-14)
src/p2p/p2p_sd.c (+15/-8)
src/p2p/p2p_utils.c (+80/-4)
src/pae/ieee802_1x_cp.c (+11/-4)
src/pae/ieee802_1x_kay.c (+58/-16)
src/pae/ieee802_1x_kay.h (+4/-1)
src/pae/ieee802_1x_secy_ops.c (+20/-0)
src/pae/ieee802_1x_secy_ops.h (+1/-0)
src/pasn/Makefile (+16/-0)
src/pasn/pasn_common.c (+232/-0)
src/pasn/pasn_common.h (+228/-0)
src/pasn/pasn_initiator.c (+1406/-0)
src/pasn/pasn_responder.c (+1032/-0)
src/radius/radius.c (+238/-59)
src/radius/radius.h (+33/-2)
src/radius/radius_client.c (+580/-209)
src/radius/radius_client.h (+26/-1)
src/radius/radius_das.c (+10/-0)
src/radius/radius_server.c (+15/-0)
src/rsn_supp/pmksa_cache.c (+231/-29)
src/rsn_supp/pmksa_cache.h (+17/-88)
src/rsn_supp/preauth.c (+11/-8)
src/rsn_supp/tdls.c (+259/-73)
src/rsn_supp/wpa.c (+1817/-373)
src/rsn_supp/wpa.h (+75/-13)
src/rsn_supp/wpa_ft.c (+189/-139)
src/rsn_supp/wpa_i.h (+54/-11)
src/rsn_supp/wpa_ie.c (+28/-8)
src/tls/libtommath.c (+0/-8)
src/tls/pkcs1.c (+4/-2)
src/tls/tlsv1_client_read.c (+2/-1)
src/tls/tlsv1_common.c (+4/-2)
src/tls/tlsv1_common.h (+2/-1)
src/tls/tlsv1_server_write.c (+1/-1)
src/utils/browser.c (+10/-0)
src/utils/common.c (+14/-1)
src/utils/common.h (+38/-0)
src/utils/crc32.c (+1/-1)
src/utils/crc32.h (+1/-1)
src/utils/http-utils.h (+1/-0)
src/utils/http_curl.c (+28/-45)
src/utils/ip_addr.c (+19/-0)
src/utils/ip_addr.h (+2/-0)
src/utils/os.h (+36/-6)
src/utils/os_unix.c (+107/-88)
src/utils/trace.c (+3/-3)
src/utils/wpa_debug.c (+9/-1)
src/utils/wpa_debug.h (+1/-0)
src/utils/wpabuf.h (+6/-0)
src/wps/ndef.c (+6/-0)
src/wps/wps.c (+3/-2)
src/wps/wps.h (+5/-0)
src/wps/wps_attr_parse.c (+12/-1)
src/wps/wps_enrollee.c (+2/-4)
src/wps/wps_er.c (+2/-2)
src/wps/wps_i.h (+1/-0)
src/wps/wps_registrar.c (+7/-8)
wpa_supplicant/Android.mk (+217/-11)
wpa_supplicant/ChangeLog (+50/-0)
wpa_supplicant/Makefile (+288/-20)
wpa_supplicant/README (+3/-1)
wpa_supplicant/README-HS20 (+32/-1)
wpa_supplicant/README-NAN-USD (+147/-0)
wpa_supplicant/README-WPS (+9/-15)
wpa_supplicant/android.config (+15/-0)
wpa_supplicant/ap.c (+266/-27)
wpa_supplicant/ap.h (+22/-2)
wpa_supplicant/bgscan.h (+1/-1)
wpa_supplicant/bgscan_learn.c (+5/-5)
wpa_supplicant/bgscan_simple.c (+61/-3)
wpa_supplicant/bss.c (+523/-40)
wpa_supplicant/bss.h (+29/-0)
wpa_supplicant/bssid_ignore.c (+15/-15)
wpa_supplicant/config.c (+409/-78)
wpa_supplicant/config.h (+127/-23)
wpa_supplicant/config_file.c (+89/-19)
wpa_supplicant/config_none.c (+2/-1)
wpa_supplicant/config_ssid.h (+110/-4)
wpa_supplicant/config_winreg.c (+2/-3)
wpa_supplicant/ctrl_iface.c (+1451/-256)
wpa_supplicant/ctrl_iface.h (+2/-0)
wpa_supplicant/ctrl_iface_unix.c (+3/-0)
wpa_supplicant/dbus/dbus_dict_helpers.c (+100/-0)
wpa_supplicant/dbus/dbus_dict_helpers.h (+9/-0)
wpa_supplicant/dbus/dbus_new.c (+141/-1)
wpa_supplicant/dbus/dbus_new.h (+24/-0)
wpa_supplicant/dbus/dbus_new_handlers.c (+660/-124)
wpa_supplicant/dbus/dbus_new_handlers.h (+7/-0)
wpa_supplicant/dbus/dbus_new_handlers_p2p.c (+73/-21)
wpa_supplicant/dbus/dbus_new_helpers.c (+193/-16)
wpa_supplicant/dbus/dbus_new_helpers.h (+5/-0)
wpa_supplicant/dbus/dbus_new_introspect.c (+1/-1)
wpa_supplicant/defconfig (+53/-0)
wpa_supplicant/doc/docbook/wpa_supplicant.sgml (+35/-13)
wpa_supplicant/dpp_supplicant.c (+1992/-192)
wpa_supplicant/dpp_supplicant.h (+5/-0)
wpa_supplicant/driver_i.h (+91/-33)
wpa_supplicant/eapol_test.c (+109/-37)
wpa_supplicant/events.c (+1464/-277)
wpa_supplicant/examples/dpp-nfc.py (+8/-2)
wpa_supplicant/gas_query.c (+36/-20)
wpa_supplicant/hs20_supplicant.c (+8/-9)
wpa_supplicant/ibss_rsn.c (+18/-14)
wpa_supplicant/ibss_rsn.h (+2/-1)
wpa_supplicant/interworking.c (+79/-45)
wpa_supplicant/main.c (+2/-0)
wpa_supplicant/mbo.c (+21/-4)
wpa_supplicant/mesh.c (+11/-5)
wpa_supplicant/mesh_mpm.c (+55/-19)
wpa_supplicant/mesh_rsn.c (+23/-4)
wpa_supplicant/nan_usd.c (+513/-0)
wpa_supplicant/nan_usd.h (+46/-0)
wpa_supplicant/notify.c (+94/-9)
wpa_supplicant/notify.h (+13/-1)
wpa_supplicant/offchannel.c (+5/-5)
wpa_supplicant/op_classes.c (+130/-20)
wpa_supplicant/p2p_supplicant.c (+310/-173)
wpa_supplicant/p2p_supplicant.h (+6/-7)
wpa_supplicant/p2p_supplicant_sd.c (+12/-2)
wpa_supplicant/pasn_supplicant.c (+489/-1219)
wpa_supplicant/preauth_test.c (+5/-3)
wpa_supplicant/robust_av.c (+296/-45)
wpa_supplicant/rrm.c (+94/-38)
wpa_supplicant/scan.c (+631/-143)
wpa_supplicant/scan.h (+21/-9)
wpa_supplicant/sme.c (+811/-137)
wpa_supplicant/sme.h (+4/-10)
wpa_supplicant/systemd/wpa_supplicant-nl80211.service.arg.in (+1/-1)
wpa_supplicant/systemd/wpa_supplicant.service.arg.in (+1/-1)
wpa_supplicant/utils/log2pcap.py (+5/-4)
wpa_supplicant/wmm_ac.c (+3/-3)
wpa_supplicant/wnm_sta.c (+312/-220)
wpa_supplicant/wnm_sta.h (+28/-2)
wpa_supplicant/wpa_cli.c (+129/-15)
wpa_supplicant/wpa_passphrase.c (+24/-1)
wpa_supplicant/wpa_priv.c (+8/-3)
wpa_supplicant/wpa_supplicant.c (+1272/-407)
wpa_supplicant/wpa_supplicant.conf (+99/-10)
wpa_supplicant/wpa_supplicant_i.h (+205/-81)
wpa_supplicant/wpa_supplicant_template.conf (+2/-0)
wpa_supplicant/wpas_glue.c (+115/-44)
wpa_supplicant/wpas_glue.h (+2/-0)
wpa_supplicant/wpas_kay.c (+16/-37)
wpa_supplicant/wpas_module_tests.c (+3/-0)
wpa_supplicant/wps_supplicant.c (+122/-44)
wpa_supplicant/wps_supplicant.h (+13/-0)
Reviewer Review Type Date Requested Status
Nick Rosbrook (community) Needs Information
git-ubuntu import Pending
Review via email: mp+493297@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Nick Rosbrook (enr0n) wrote :
review: Needs Information

Unmerged commits

5a2ab65... by Antoine Lassagne

Changelog update

827a47a... by Tobias Heider

Changelog

0f7ffd1... by Tobias Heider

Revert commit breaking authentication on brcmfmac

13c020a... by Mitchell Augustin

Bump DEFAULT_BSS_MAX_COUNT to 1000 (LP: #2117180)

e8728b7... by Antoine Lassagne

2:2.11-0ubuntu1 (patches unapplied)

Imported using git-ubuntu import.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/CONTRIBUTIONS b/CONTRIBUTIONS
2index b2064dc..6c8187c 100644
3--- a/CONTRIBUTIONS
4+++ b/CONTRIBUTIONS
5@@ -37,7 +37,7 @@ without moderation. You can subscribe to the list at this address:
6 http://lists.infradead.org/mailman/listinfo/hostap
7
8 The message should contain an inlined patch against the current
9-development branch (i.e., the master branch of
10+development branch (i.e., the main branch of
11 git://w1.fi/hostap.git). Please make sure the software you use for
12 sending the patch does not corrupt whitespace. If that cannot be fixed
13 for some reason, it is better to include an attached version of the
14diff --git a/README b/README
15index 1470c4f..8392bb3 100644
16--- a/README
17+++ b/README
18@@ -1,7 +1,7 @@
19 wpa_supplicant and hostapd
20 --------------------------
21
22-Copyright (c) 2002-2022, Jouni Malinen <j@w1.fi> and contributors
23+Copyright (c) 2002-2024, Jouni Malinen <j@w1.fi> and contributors
24 All Rights Reserved.
25
26 These programs are licensed under the BSD license (the one with
27diff --git a/debian/.gitignore b/debian/.gitignore
28deleted file mode 100644
29index 66fe32a..0000000
30--- a/debian/.gitignore
31+++ /dev/null
32@@ -1,11 +0,0 @@
33-*.debhelper
34-*.substvars
35-.debhelper/
36-debhelper-build-stamp
37-eapoltest/
38-files
39-hostapd/
40-libwpa-client-dev/
41-wpagui/
42-wpasupplicant-udeb/
43-wpasupplicant/
44diff --git a/debian/changelog b/debian/changelog
45index 6eff64f..9630d1e 100644
46--- a/debian/changelog
47+++ b/debian/changelog
48@@ -1,3 +1,15 @@
49+wpa (2:2.11-0ubuntu3~25.04.1) plucky; urgency=medium
50+
51+ * Backport of Questing's version to Plucky
52+
53+ -- Antoine Lassagne <antoine.lassagne@canonical.com> Thu, 25 Sep 2025 12:21:04 +0200
54+
55+wpa (2:2.10-24ubuntu0.1) plucky; urgency=medium
56+
57+ * Bump DEFAULT_BSS_MAX_COUNT to 1000 (LP: #2117180)
58+
59+ -- Mitchell Augustin <mitchell.augustin@canonical.com> Mon, 21 Jul 2025 18:13:31 -0500
60+
61 wpa (2:2.10-24) unstable; urgency=medium
62
63 [ Hlib Korzhynskyy ]
64diff --git a/debian/control b/debian/control
65index 803df6b..3be6d04 100644
66--- a/debian/control
67+++ b/debian/control
68@@ -1,5 +1,6 @@
69 Source: wpa
70-Maintainer: Debian wpasupplicant Maintainers <wpa@packages.debian.org>
71+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
72+XSBC-Original-Maintainer: Debian wpasupplicant Maintainers <wpa@packages.debian.org>
73 Uploaders:
74 Andrej Shadura <andrewsh@debian.org>
75 Section: net
76diff --git a/debian/patches/0015-Revert-Mark-authorization-completed-on-driver-indica.patch b/debian/patches/0015-Revert-Mark-authorization-completed-on-driver-indica.patch
77new file mode 100644
78index 0000000..09b239f
79--- /dev/null
80+++ b/debian/patches/0015-Revert-Mark-authorization-completed-on-driver-indica.patch
81@@ -0,0 +1,45 @@
82+From: Tobias Heider <me@tobhe.de>
83+Date: Mon, 1 Sep 2025 22:18:55 +0200
84+Subject: Revert "Mark authorization completed on driver indication during
85+ 4-way HS offload"
86+
87+---
88+ wpa_supplicant/events.c | 25 ++++++++-----------------
89+ 1 file changed, 8 insertions(+), 17 deletions(-)
90+
91+diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
92+index 7a6133c..56a9b81 100644
93+--- a/wpa_supplicant/events.c
94++++ b/wpa_supplicant/events.c
95+@@ -4327,23 +4327,14 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
96+ eapol_sm_notify_eap_success(wpa_s->eapol, true);
97+ } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
98+ wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
99+- if (already_authorized) {
100+- /*
101+- * We are done; the driver will take care of RSN 4-way
102+- * handshake.
103+- */
104+- wpa_supplicant_cancel_auth_timeout(wpa_s);
105+- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
106+- eapol_sm_notify_portValid(wpa_s->eapol, true);
107+- eapol_sm_notify_eap_success(wpa_s->eapol, true);
108+- } else {
109+- /* Update port, WPA_COMPLETED state from the
110+- * EVENT_PORT_AUTHORIZED handler when the driver is done
111+- * with the 4-way handshake.
112+- */
113+- wpa_msg(wpa_s, MSG_DEBUG,
114+- "ASSOC INFO: wait for driver port authorized indication");
115+- }
116++ /*
117++ * We are done; the driver will take care of RSN 4-way
118++ * handshake.
119++ */
120++ wpa_supplicant_cancel_auth_timeout(wpa_s);
121++ wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
122++ eapol_sm_notify_portValid(wpa_s->eapol, true);
123++ eapol_sm_notify_eap_success(wpa_s->eapol, true);
124+ } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X) &&
125+ wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
126+ /*
127diff --git a/debian/patches/0017-CVE-2023-52160-PEAP-client-Update-Phase-2-authentica.patch b/debian/patches/0017-CVE-2023-52160-PEAP-client-Update-Phase-2-authentica.patch
128deleted file mode 100644
129index 19abe4e..0000000
130--- a/debian/patches/0017-CVE-2023-52160-PEAP-client-Update-Phase-2-authentica.patch
131+++ /dev/null
132@@ -1,211 +0,0 @@
133-From: Jouni Malinen <j@w1.fi>
134-Date: Sat, 8 Jul 2023 19:55:32 +0300
135-Subject: CVE-2023-52160 PEAP client: Update Phase 2 authentication
136- requirements
137-
138-The previous PEAP client behavior allowed the server to skip Phase 2
139-authentication with the expectation that the server was authenticated
140-during Phase 1 through TLS server certificate validation. Various PEAP
141-specifications are not exactly clear on what the behavior on this front
142-is supposed to be and as such, this ended up being more flexible than
143-the TTLS/FAST/TEAP cases. However, this is not really ideal when
144-unfortunately common misconfiguration of PEAP is used in deployed
145-devices where the server trust root (ca_cert) is not configured or the
146-user has an easy option for allowing this validation step to be skipped.
147-
148-Change the default PEAP client behavior to be to require Phase 2
149-authentication to be successfully completed for cases where TLS session
150-resumption is not used and the client certificate has not been
151-configured. Those two exceptions are the main cases where a deployed
152-authentication server might skip Phase 2 and as such, where a more
153-strict default behavior could result in undesired interoperability
154-issues. Requiring Phase 2 authentication will end up disabling TLS
155-session resumption automatically to avoid interoperability issues.
156-
157-Allow Phase 2 authentication behavior to be configured with a new phase1
158-configuration parameter option:
159-'phase2_auth' option can be used to control Phase 2 (i.e., within TLS
160-tunnel) behavior for PEAP:
161- * 0 = do not require Phase 2 authentication
162- * 1 = require Phase 2 authentication when client certificate
163- (private_key/client_cert) is no used and TLS session resumption was
164- not used (default)
165- * 2 = require Phase 2 authentication in all cases
166-
167-Signed-off-by: Jouni Malinen <j@w1.fi>
168-origin: https://w1.fi/cgit/hostap/commit/?id=8e6485a1bcb0baffdea9e55255a81270b768439c
169-bug: https://www.top10vpn.com/research/wifi-vulnerabilities/
170-bug-debian-security: https://security-tracker.debian.org/tracker/CVE-2023-52160
171-bug-debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1064061
172----
173- src/eap_peer/eap_config.h | 8 ++++++++
174- src/eap_peer/eap_peap.c | 40 +++++++++++++++++++++++++++++++++++---
175- src/eap_peer/eap_tls_common.c | 6 ++++++
176- src/eap_peer/eap_tls_common.h | 5 +++++
177- wpa_supplicant/wpa_supplicant.conf | 7 +++++++
178- 5 files changed, 63 insertions(+), 3 deletions(-)
179-
180-diff --git a/src/eap_peer/eap_config.h b/src/eap_peer/eap_config.h
181-index 3238f74..047eec2 100644
182---- a/src/eap_peer/eap_config.h
183-+++ b/src/eap_peer/eap_config.h
184-@@ -469,6 +469,14 @@ struct eap_peer_config {
185- * 1 = use cryptobinding if server supports it
186- * 2 = require cryptobinding
187- *
188-+ * phase2_auth option can be used to control Phase 2 (i.e., within TLS
189-+ * tunnel) behavior for PEAP:
190-+ * 0 = do not require Phase 2 authentication
191-+ * 1 = require Phase 2 authentication when client certificate
192-+ * (private_key/client_cert) is no used and TLS session resumption was
193-+ * not used (default)
194-+ * 2 = require Phase 2 authentication in all cases
195-+ *
196- * EAP-WSC (WPS) uses following options: pin=Device_Password and
197- * uuid=Device_UUID
198- *
199-diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c
200-index 12e30df..6080697 100644
201---- a/src/eap_peer/eap_peap.c
202-+++ b/src/eap_peer/eap_peap.c
203-@@ -67,6 +67,7 @@ struct eap_peap_data {
204- u8 cmk[20];
205- int soh; /* Whether IF-TNCCS-SOH (Statement of Health; Microsoft NAP)
206- * is enabled. */
207-+ enum { NO_AUTH, FOR_INITIAL, ALWAYS } phase2_auth;
208- };
209-
210-
211-@@ -114,6 +115,19 @@ static void eap_peap_parse_phase1(struct eap_peap_data *data,
212- wpa_printf(MSG_DEBUG, "EAP-PEAP: Require cryptobinding");
213- }
214-
215-+ if (os_strstr(phase1, "phase2_auth=0")) {
216-+ data->phase2_auth = NO_AUTH;
217-+ wpa_printf(MSG_DEBUG,
218-+ "EAP-PEAP: Do not require Phase 2 authentication");
219-+ } else if (os_strstr(phase1, "phase2_auth=1")) {
220-+ data->phase2_auth = FOR_INITIAL;
221-+ wpa_printf(MSG_DEBUG,
222-+ "EAP-PEAP: Require Phase 2 authentication for initial connection");
223-+ } else if (os_strstr(phase1, "phase2_auth=2")) {
224-+ data->phase2_auth = ALWAYS;
225-+ wpa_printf(MSG_DEBUG,
226-+ "EAP-PEAP: Require Phase 2 authentication for all cases");
227-+ }
228- #ifdef EAP_TNC
229- if (os_strstr(phase1, "tnc=soh2")) {
230- data->soh = 2;
231-@@ -142,6 +156,7 @@ static void * eap_peap_init(struct eap_sm *sm)
232- data->force_peap_version = -1;
233- data->peap_outer_success = 2;
234- data->crypto_binding = OPTIONAL_BINDING;
235-+ data->phase2_auth = FOR_INITIAL;
236-
237- if (config && config->phase1)
238- eap_peap_parse_phase1(data, config->phase1);
239-@@ -454,6 +469,20 @@ static int eap_tlv_validate_cryptobinding(struct eap_sm *sm,
240- }
241-
242-
243-+static bool peap_phase2_sufficient(struct eap_sm *sm,
244-+ struct eap_peap_data *data)
245-+{
246-+ if ((data->phase2_auth == ALWAYS ||
247-+ (data->phase2_auth == FOR_INITIAL &&
248-+ !tls_connection_resumed(sm->ssl_ctx, data->ssl.conn) &&
249-+ !data->ssl.client_cert_conf) ||
250-+ data->phase2_eap_started) &&
251-+ !data->phase2_eap_success)
252-+ return false;
253-+ return true;
254-+}
255-+
256-+
257- /**
258- * eap_tlv_process - Process a received EAP-TLV message and generate a response
259- * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
260-@@ -568,6 +597,11 @@ static int eap_tlv_process(struct eap_sm *sm, struct eap_peap_data *data,
261- " - force failed Phase 2");
262- resp_status = EAP_TLV_RESULT_FAILURE;
263- ret->decision = DECISION_FAIL;
264-+ } else if (!peap_phase2_sufficient(sm, data)) {
265-+ wpa_printf(MSG_INFO,
266-+ "EAP-PEAP: Server indicated Phase 2 success, but sufficient Phase 2 authentication has not been completed");
267-+ resp_status = EAP_TLV_RESULT_FAILURE;
268-+ ret->decision = DECISION_FAIL;
269- } else {
270- resp_status = EAP_TLV_RESULT_SUCCESS;
271- ret->decision = DECISION_UNCOND_SUCC;
272-@@ -887,8 +921,7 @@ continue_req:
273- /* EAP-Success within TLS tunnel is used to indicate
274- * shutdown of the TLS channel. The authentication has
275- * been completed. */
276-- if (data->phase2_eap_started &&
277-- !data->phase2_eap_success) {
278-+ if (!peap_phase2_sufficient(sm, data)) {
279- wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 "
280- "Success used to indicate success, "
281- "but Phase 2 EAP was not yet "
282-@@ -1199,8 +1232,9 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
283- static bool eap_peap_has_reauth_data(struct eap_sm *sm, void *priv)
284- {
285- struct eap_peap_data *data = priv;
286-+
287- return tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
288-- data->phase2_success;
289-+ data->phase2_success && data->phase2_auth != ALWAYS;
290- }
291-
292-
293-diff --git a/src/eap_peer/eap_tls_common.c b/src/eap_peer/eap_tls_common.c
294-index c1837db..a53eeb1 100644
295---- a/src/eap_peer/eap_tls_common.c
296-+++ b/src/eap_peer/eap_tls_common.c
297-@@ -239,6 +239,12 @@ static int eap_tls_params_from_conf(struct eap_sm *sm,
298-
299- sm->ext_cert_check = !!(params->flags & TLS_CONN_EXT_CERT_CHECK);
300-
301-+ if (!phase2)
302-+ data->client_cert_conf = params->client_cert ||
303-+ params->client_cert_blob ||
304-+ params->private_key ||
305-+ params->private_key_blob;
306-+
307- return 0;
308- }
309-
310-diff --git a/src/eap_peer/eap_tls_common.h b/src/eap_peer/eap_tls_common.h
311-index 9ac0012..3348634 100644
312---- a/src/eap_peer/eap_tls_common.h
313-+++ b/src/eap_peer/eap_tls_common.h
314-@@ -79,6 +79,11 @@ struct eap_ssl_data {
315- * tls_v13 - Whether TLS v1.3 or newer is used
316- */
317- int tls_v13;
318-+
319-+ /**
320-+ * client_cert_conf: Whether client certificate has been configured
321-+ */
322-+ bool client_cert_conf;
323- };
324-
325-
326-diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
327-index 6619d6b..d63f73c 100644
328---- a/wpa_supplicant/wpa_supplicant.conf
329-+++ b/wpa_supplicant/wpa_supplicant.conf
330-@@ -1321,6 +1321,13 @@ fast_reauth=1
331- # * 0 = do not use cryptobinding (default)
332- # * 1 = use cryptobinding if server supports it
333- # * 2 = require cryptobinding
334-+# 'phase2_auth' option can be used to control Phase 2 (i.e., within TLS
335-+# tunnel) behavior for PEAP:
336-+# * 0 = do not require Phase 2 authentication
337-+# * 1 = require Phase 2 authentication when client certificate
338-+# (private_key/client_cert) is no used and TLS session resumption was
339-+# not used (default)
340-+# * 2 = require Phase 2 authentication in all cases
341- # EAP-WSC (WPS) uses following options: pin=<Device Password> or
342- # pbc=1.
343- #
344diff --git a/debian/patches/0019-Send-CTRL-EVENT-SIGNAL-CHANGE-message-to-control-int.patch b/debian/patches/0019-Send-CTRL-EVENT-SIGNAL-CHANGE-message-to-control-int.patch
345index 0cbb7dd..6a982e6 100644
346--- a/debian/patches/0019-Send-CTRL-EVENT-SIGNAL-CHANGE-message-to-control-int.patch
347+++ b/debian/patches/0019-Send-CTRL-EVENT-SIGNAL-CHANGE-message-to-control-int.patch
348@@ -24,22 +24,12 @@ diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
349 index f55e184..25b0c24 100644
350 --- a/wpa_supplicant/events.c
351 +++ b/wpa_supplicant/events.c
352-@@ -5447,12 +5447,12 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
353- data->eapol_rx.data_len);
354+@@ -6590,7 +6590,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
355+ data->eapol_rx.encrypted);
356 break;
357 case EVENT_SIGNAL_CHANGE:
358 - wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SIGNAL_CHANGE
359-- "above=%d signal=%d noise=%d txrate=%d",
360-- data->signal_change.above_threshold,
361-- data->signal_change.current_signal,
362-- data->signal_change.current_noise,
363-- data->signal_change.current_txrate);
364 + wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SIGNAL_CHANGE
365-+ "above=%d signal=%d noise=%d txrate=%d",
366-+ data->signal_change.above_threshold,
367-+ data->signal_change.current_signal,
368-+ data->signal_change.current_noise,
369-+ data->signal_change.current_txrate);
370- wpa_bss_update_level(wpa_s->current_bss,
371- data->signal_change.current_signal);
372- bgscan_notify_signal_change(
373+ "above=%d signal=%d noise=%d txrate=%lu",
374+ data->signal_change.above_threshold,
375+ data->signal_change.data.signal,
376diff --git a/debian/patches/Bump-DEFAULT_BSS_MAX_COUNT-to-1000.patch b/debian/patches/Bump-DEFAULT_BSS_MAX_COUNT-to-1000.patch
377new file mode 100644
378index 0000000..688a343
379--- /dev/null
380+++ b/debian/patches/Bump-DEFAULT_BSS_MAX_COUNT-to-1000.patch
381@@ -0,0 +1,25 @@
382+Description: Bump DEFAULT_BSS_MAX_COUNT to 1000
383+ Many congested areas have more than 200 APs in range
384+ of a typical device. When the number of APs exceeds
385+ BSS_MAX_COUNT, even nearby APs can be absent from
386+ the scanning device's AP list.
387+ This patch bumps the default to 1000 to be more in
388+ line with a realistic modern max number of APs
389+ in a given area.
390+Author: Mitchell Augustin <mitchell.augustin@canonical.com>
391+Bug-Ubuntu: https://bugs.launchpad.net/bugs/2117180
392+
393+---
394+Last-Update: 2025-07-21
395+
396+--- wpa-2.10.orig/wpa_supplicant/config.h
397++++ wpa-2.10/wpa_supplicant/config.h
398+@@ -29,7 +29,7 @@
399+ #define DEFAULT_P2P_INTRA_BSS 1
400+ #define DEFAULT_P2P_GO_MAX_INACTIVITY (5 * 60)
401+ #define DEFAULT_P2P_OPTIMIZE_LISTEN_CHAN 0
402+-#define DEFAULT_BSS_MAX_COUNT 200
403++#define DEFAULT_BSS_MAX_COUNT 1000
404+ #define DEFAULT_BSS_EXPIRATION_AGE 180
405+ #define DEFAULT_BSS_EXPIRATION_SCAN_COUNT 2
406+ #define DEFAULT_MAX_NUM_STA 128
407diff --git a/debian/patches/CVE-2022-37660.patch b/debian/patches/CVE-2022-37660.patch
408deleted file mode 100644
409index e95c20f..0000000
410--- a/debian/patches/CVE-2022-37660.patch
411+++ /dev/null
412@@ -1,122 +0,0 @@
413-[Ubuntu note: hostapd_dpp_pkex_done() in dpp_hostapd.c and
414-wpas_dpp_pkex_done() in dpp_supplicant.c were introduced in 2.11
415---Hlib Korzhynskyy]
416-
417-Backport of:
418-
419-From 15af83cf1846870873a011ed4d714732f01cd2e4 Mon Sep 17 00:00:00 2001
420-From: Jouni Malinen <quic_jouni@quicinc.com>
421-Date: Tue, 19 Jul 2022 21:23:04 +0300
422-Subject: DPP: Delete PKEX code and identifier on success completion of PKEX
423-
424-We are not supposed to reuse these without being explicitly requested to
425-perform PKEX again. There is not a strong use case for being able to
426-provision an Enrollee multiple times with PKEX, so this should have no
427-issues on the Enrollee. For a Configurator, there might be some use
428-cases that would benefit from being able to use the same code with
429-multiple Enrollee devices, e.g., for guess access with a laptop and a
430-smart phone. That case will now require a new DPP_PKEX_ADD command on
431-the Configurator after each completion of the provisioning exchange.
432-
433-Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
434----
435- src/ap/dpp_hostapd.c | 22 +++++++++++++++++++++-
436- wpa_supplicant/dpp_supplicant.c | 21 ++++++++++++++++++++-
437- 2 files changed, 41 insertions(+), 2 deletions(-)
438-
439-Index: wpa-2.10/src/ap/dpp_hostapd.c
440-===================================================================
441---- wpa-2.10.orig/src/ap/dpp_hostapd.c
442-+++ wpa-2.10/src/ap/dpp_hostapd.c
443-@@ -216,6 +216,22 @@ static void hostapd_dpp_auth_resp_retry(
444- }
445-
446-
447-+static void hostapd_dpp_pkex_clear_code(struct hostapd_data *hapd)
448-+{
449-+ if (!hapd->dpp_pkex_code && !hapd->dpp_pkex_identifier)
450-+ return;
451-+
452-+ /* Delete PKEX code and identifier on successful completion of
453-+ * PKEX. We are not supposed to reuse these without being
454-+ * explicitly requested to perform PKEX again. */
455-+ wpa_printf(MSG_DEBUG, "DPP: Delete PKEX code/identifier");
456-+ os_free(hapd->dpp_pkex_code);
457-+ hapd->dpp_pkex_code = NULL;
458-+ os_free(hapd->dpp_pkex_identifier);
459-+ hapd->dpp_pkex_identifier = NULL;
460-+}
461-+
462-+
463- void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst,
464- const u8 *data, size_t data_len, int ok)
465- {
466-@@ -1842,6 +1858,7 @@ hostapd_dpp_rx_pkex_commit_reveal_req(st
467- wpabuf_head(msg), wpabuf_len(msg));
468- wpabuf_free(msg);
469-
470-+ hostapd_dpp_pkex_clear_code(hapd);
471- bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
472- if (!bi)
473- return;
474-@@ -1873,6 +1890,7 @@ hostapd_dpp_rx_pkex_commit_reveal_resp(s
475- return;
476- }
477-
478-+ hostapd_dpp_pkex_clear_code(hapd);
479- bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
480- if (!bi)
481- return;
482-@@ -2215,7 +2233,7 @@ int hostapd_dpp_pkex_remove(struct hosta
483- return -1;
484- }
485-
486-- if ((id_val != 0 && id_val != 1) || !hapd->dpp_pkex_code)
487-+ if ((id_val != 0 && id_val != 1))
488- return -1;
489-
490- /* TODO: Support multiple PKEX entries */
491-Index: wpa-2.10/wpa_supplicant/dpp_supplicant.c
492-===================================================================
493---- wpa-2.10.orig/wpa_supplicant/dpp_supplicant.c
494-+++ wpa-2.10/wpa_supplicant/dpp_supplicant.c
495-@@ -2557,6 +2557,22 @@ static int wpas_dpp_pkex_next_channel(st
496- }
497-
498-
499-+static void wpas_dpp_pkex_clear_code(struct wpa_supplicant *wpa_s)
500-+{
501-+ if (!wpa_s->dpp_pkex_code && !wpa_s->dpp_pkex_identifier)
502-+ return;
503-+
504-+ /* Delete PKEX code and identifier on successful completion of
505-+ * PKEX. We are not supposed to reuse these without being
506-+ * explicitly requested to perform PKEX again. */
507-+ os_free(wpa_s->dpp_pkex_code);
508-+ wpa_s->dpp_pkex_code = NULL;
509-+ os_free(wpa_s->dpp_pkex_identifier);
510-+ wpa_s->dpp_pkex_identifier = NULL;
511-+
512-+}
513-+
514-+
515- static void wpas_dpp_pkex_retry_timeout(void *eloop_ctx, void *timeout_ctx)
516- {
517- struct wpa_supplicant *wpa_s = eloop_ctx;
518-@@ -2739,6 +2755,7 @@ wpas_dpp_pkex_finish(struct wpa_supplica
519- {
520- struct dpp_bootstrap_info *bi;
521-
522-+ wpas_dpp_pkex_clear_code(wpa_s);
523- bi = dpp_pkex_finish(wpa_s->dpp, wpa_s->dpp_pkex, peer, freq);
524- if (!bi)
525- return NULL;
526-@@ -3369,7 +3386,7 @@ int wpas_dpp_pkex_remove(struct wpa_supp
527- return -1;
528- }
529-
530-- if ((id_val != 0 && id_val != 1) || !wpa_s->dpp_pkex_code)
531-+ if ((id_val != 0 && id_val != 1))
532- return -1;
533-
534- /* TODO: Support multiple PKEX entries */
535diff --git a/debian/patches/series b/debian/patches/series
536index 4a7edee..96640f3 100644
537--- a/debian/patches/series
538+++ b/debian/patches/series
539@@ -7,14 +7,9 @@ systemd-add-reload-support.patch
540 manpage-replace-wheel-with-netdev.patch
541 upstream-fixes/0001-nl80211-add-extra-ies-only-if-allowed-by-driver.patch
542 upstream-fixes/0002-AP-guard-FT-SAE-code-with-CONFIG_IEEE80211R_AP.patch
543-upstream-fixes/0003-OpenSSL-Drop-security-level-to-0-with-OpenSSL-3.0-wh.patch
544 allow-legacy-renegotiation.patch
545 wpa_service_netdev.patch
546-upstream-fixes/0013-wnm-Choose-best-available-bss-not-just-first-one.patch
547-upstream-fixes/0014-wpa_supplicant-Fix-wpa_supplicant-configuration-pars.patch
548-upstream-fixes/0015-Abort-ongoing-scan.patch
549-upstream-fixes/0016-Override-ieee80211w-from-pmf-for-AP-mode-in-wpa_supp.patch
550-0017-CVE-2023-52160-PEAP-client-Update-Phase-2-authentica.patch
551-CVE-2022-37660.patch
552 CVE-2024-5290-lib_engine_trusted_path.patch
553 0019-Send-CTRL-EVENT-SIGNAL-CHANGE-message-to-control-int.patch
554+Bump-DEFAULT_BSS_MAX_COUNT-to-1000.patch
555+0015-Revert-Mark-authorization-completed-on-driver-indica.patch
556diff --git a/debian/patches/upstream-fixes/0002-AP-guard-FT-SAE-code-with-CONFIG_IEEE80211R_AP.patch b/debian/patches/upstream-fixes/0002-AP-guard-FT-SAE-code-with-CONFIG_IEEE80211R_AP.patch
557index 6509bcd..8748cf6 100644
558--- a/debian/patches/upstream-fixes/0002-AP-guard-FT-SAE-code-with-CONFIG_IEEE80211R_AP.patch
559+++ b/debian/patches/upstream-fixes/0002-AP-guard-FT-SAE-code-with-CONFIG_IEEE80211R_AP.patch
560@@ -14,11 +14,9 @@ Signed-off-by: Beniamino Galvani <bgalvani@redhat.com>
561 src/ap/wpa_auth_ie.c | 6 ++++++
562 1 file changed, 6 insertions(+)
563
564-diff --git a/src/ap/wpa_auth_ie.c b/src/ap/wpa_auth_ie.c
565-index 524922e..d63cbeb 100644
566 --- a/src/ap/wpa_auth_ie.c
567 +++ b/src/ap/wpa_auth_ie.c
568-@@ -228,11 +228,13 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
569+@@ -241,6 +241,7 @@
570 pos += RSN_SELECTOR_LEN;
571 num_suites++;
572 }
573@@ -26,31 +24,37 @@ index 524922e..d63cbeb 100644
574 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_SAE) {
575 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE);
576 pos += RSN_SELECTOR_LEN;
577+@@ -251,6 +252,7 @@
578+ pos += RSN_SELECTOR_LEN;
579 num_suites++;
580 }
581 +#endif /* CONFIG_IEEE80211R_AP */
582 #endif /* CONFIG_SAE */
583 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
584 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B);
585-@@ -670,8 +672,10 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
586- #ifdef CONFIG_SAE
587- else if (data.key_mgmt & WPA_KEY_MGMT_SAE)
588+@@ -700,10 +702,12 @@
589 selector = RSN_AUTH_KEY_MGMT_SAE;
590+ else if (data.key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY)
591+ selector = RSN_AUTH_KEY_MGMT_SAE_EXT_KEY;
592 +#ifdef CONFIG_IEEE80211R_AP
593 else if (data.key_mgmt & WPA_KEY_MGMT_FT_SAE)
594 selector = RSN_AUTH_KEY_MGMT_FT_SAE;
595+ else if (data.key_mgmt & WPA_KEY_MGMT_FT_SAE_EXT_KEY)
596+ selector = RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY;
597 +#endif /* CONFIG_IEEE80211R_AP */
598 #endif /* CONFIG_SAE */
599 else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X)
600 selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
601-@@ -778,8 +782,10 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
602- #ifdef CONFIG_SAE
603- else if (key_mgmt & WPA_KEY_MGMT_SAE)
604+@@ -820,10 +824,12 @@
605 sm->wpa_key_mgmt = WPA_KEY_MGMT_SAE;
606+ else if (key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY)
607+ sm->wpa_key_mgmt = WPA_KEY_MGMT_SAE_EXT_KEY;
608 +#ifdef CONFIG_IEEE80211R_AP
609 else if (key_mgmt & WPA_KEY_MGMT_FT_SAE)
610 sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_SAE;
611-+#endif /* CONFIG_IEEE80211R_AP */
612+ else if (key_mgmt & WPA_KEY_MGMT_FT_SAE_EXT_KEY)
613+ sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_SAE_EXT_KEY;
614++#endif /* CONFIG_IEEE80211R_AP */
615 #endif /* CONFIG_SAE */
616 else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X)
617 sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X;
618diff --git a/debian/patches/upstream-fixes/0003-OpenSSL-Drop-security-level-to-0-with-OpenSSL-3.0-wh.patch b/debian/patches/upstream-fixes/0003-OpenSSL-Drop-security-level-to-0-with-OpenSSL-3.0-wh.patch
619deleted file mode 100644
620index 18f879c..0000000
621--- a/debian/patches/upstream-fixes/0003-OpenSSL-Drop-security-level-to-0-with-OpenSSL-3.0-wh.patch
622+++ /dev/null
623@@ -1,57 +0,0 @@
624-From: Jouni Malinen <j@w1.fi>
625-Date: Sun, 22 May 2022 17:01:35 +0300
626-Subject: OpenSSL: Drop security level to 0 with OpenSSL 3.0 when using TLS 1.0/1.1
627-
628-Commit 9afb68b03976 ("OpenSSL: Allow systemwide secpolicy overrides for
629-TLS version") with commit 58bbcfa31b18 ("OpenSSL: Update security level
630-drop for TLS 1.0/1.1 with OpenSSL 3.0") allow this workaround to be
631-enabled with an explicit network configuration parameter. However, the
632-default settings are still allowing TLS 1.0 and 1.1 to be negotiated
633-just to see them fail immediately when using OpenSSL 3.0. This is not
634-exactly helpful especially when the OpenSSL error message for this
635-particular case is "internal error" which does not really say anything
636-about the reason for the error.
637-
638-It is is a bit inconvenient to update the security policy for this
639-particular issue based on the negotiated TLS version since that happens
640-in the middle of processing for the first message from the server.
641-However, this can be done by using the debug callback for printing out
642-the received TLS messages during processing.
643-
644-Drop the OpenSSL security level to 0 if that is the only option to
645-continue the TLS negotiation, i.e., when TLS 1.0/1.1 are still allowed
646-in wpa_supplicant default configuration and OpenSSL 3.0 with the
647-constraint on MD5-SHA1 use.
648-
649-Signed-off-by: Jouni Malinen <j@w1.fi>
650-
651-Bug-Debian: https://bugs.debian.org/1011121
652-Bug-Ubuntu: https://bugs.launchpad.net/bugs/1958267
653-Origin: upstream, commit:bc99366f9b960150aa2e369048bbc2218c1d414e
654----
655- src/crypto/tls_openssl.c | 9 +++++++++
656- 1 file changed, 9 insertions(+)
657-
658-diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
659-index 6602ac64f591..78621d926dab 100644
660---- a/src/crypto/tls_openssl.c
661-+++ b/src/crypto/tls_openssl.c
662-@@ -1557,6 +1557,15 @@ static void tls_msg_cb(int write_p, int version, int content_type,
663- struct tls_connection *conn = arg;
664- const u8 *pos = buf;
665-
666-+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
667-+ if ((SSL_version(ssl) == TLS1_VERSION ||
668-+ SSL_version(ssl) == TLS1_1_VERSION) &&
669-+ SSL_get_security_level(ssl) > 0) {
670-+ wpa_printf(MSG_DEBUG,
671-+ "OpenSSL: Drop security level to 0 to allow TLS 1.0/1.1 use of MD5-SHA1 signature algorithm");
672-+ SSL_set_security_level(ssl, 0);
673-+ }
674-+#endif /* OpenSSL version >= 3.0 */
675- if (write_p == 2) {
676- wpa_printf(MSG_DEBUG,
677- "OpenSSL: session ver=0x%x content_type=%d",
678---
679-2.39.0
680-
681diff --git a/debian/patches/upstream-fixes/0013-wnm-Choose-best-available-bss-not-just-first-one.patch b/debian/patches/upstream-fixes/0013-wnm-Choose-best-available-bss-not-just-first-one.patch
682deleted file mode 100644
683index d36a6e5..0000000
684--- a/debian/patches/upstream-fixes/0013-wnm-Choose-best-available-bss-not-just-first-one.patch
685+++ /dev/null
686@@ -1,117 +0,0 @@
687-From: Ben Greear <greearb@candelatech.com>
688-Date: Thu, 27 Jul 2023 09:02:11 -0700
689-Subject: wnm: Choose best available bss, not just first one.
690-
691-This should allow STA to make better choice about which
692-BSS to roam to.
693-
694-Use estimated-throughput as comparison value. Can improve
695-the est-tput measurement to improve this selection criteria
696-if wanted in the future.
697-
698-Signed-off-by: Ben Greear <greearb@candelatech.com>
699----
700- wpa_supplicant/wnm_sta.c | 55 ++++++++++++++++++++++++++++++------------------
701- 1 file changed, 34 insertions(+), 21 deletions(-)
702-
703-diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
704-index 96160dc..36cc8e4 100644
705---- a/wpa_supplicant/wnm_sta.c
706-+++ b/wpa_supplicant/wnm_sta.c
707-@@ -609,22 +609,6 @@ static void wnm_clear_acceptable(struct wpa_supplicant *wpa_s)
708- wpa_s->wnm_neighbor_report_elements[i].acceptable = 0;
709- }
710-
711--
712--static struct wpa_bss * get_first_acceptable(struct wpa_supplicant *wpa_s)
713--{
714-- unsigned int i;
715-- struct neighbor_report *nei;
716--
717-- for (i = 0; i < wpa_s->wnm_num_neighbor_report; i++) {
718-- nei = &wpa_s->wnm_neighbor_report_elements[i];
719-- if (nei->acceptable)
720-- return wpa_bss_get_bssid(wpa_s, nei->bssid);
721-- }
722--
723-- return NULL;
724--}
725--
726--
727- #ifdef CONFIG_MBO
728- static struct wpa_bss *
729- get_mbo_transition_candidate(struct wpa_supplicant *wpa_s,
730-@@ -718,6 +702,19 @@ end:
731- }
732- #endif /* CONFIG_MBO */
733-
734-+struct wpa_bss* find_best_target(struct wpa_bss* a, struct wpa_bss* b)
735-+{
736-+ if (a->est_throughput > b->est_throughput) {
737-+ wpa_printf(MSG_DEBUG, "WNM: A is best: " MACSTR " est-tput: %d B: " MACSTR " est-tput: %d",
738-+ MAC2STR(a->bssid), a->est_throughput,
739-+ MAC2STR(b->bssid), b->est_throughput);
740-+ return a;
741-+ }
742-+ wpa_printf(MSG_DEBUG, "WNM: B is best, A: " MACSTR " est-tput: %d B: " MACSTR " est-tput: %d",
743-+ MAC2STR(a->bssid), a->est_throughput,
744-+ MAC2STR(b->bssid), b->est_throughput);
745-+ return b;
746-+}
747-
748- static struct wpa_bss *
749- compare_scan_neighbor_results(struct wpa_supplicant *wpa_s, os_time_t age_secs,
750-@@ -726,6 +723,9 @@ compare_scan_neighbor_results(struct wpa_supplicant *wpa_s, os_time_t age_secs,
751- u8 i;
752- struct wpa_bss *bss = wpa_s->current_bss;
753- struct wpa_bss *target;
754-+ struct wpa_bss *best_target = bss;
755-+ struct wpa_bss *bss_in_list = NULL;
756-+ long diff;
757-
758- if (!bss)
759- return NULL;
760-@@ -812,25 +812,38 @@ compare_scan_neighbor_results(struct wpa_supplicant *wpa_s, os_time_t age_secs,
761- }
762-
763- nei->acceptable = 1;
764-+
765-+ best_target = find_best_target(target, best_target);
766-+ if (target == bss)
767-+ bss_in_list = bss;
768- }
769-
770- #ifdef CONFIG_MBO
771- if (wpa_s->wnm_mbo_trans_reason_present)
772- target = get_mbo_transition_candidate(wpa_s, reason);
773- else
774-- target = get_first_acceptable(wpa_s);
775-+ target = best_target;
776- #else /* CONFIG_MBO */
777-- target = get_first_acceptable(wpa_s);
778-+ target = best_target;
779- #endif /* CONFIG_MBO */
780-
781- if (target) {
782- wpa_printf(MSG_DEBUG,
783- "WNM: Found an acceptable preferred transition candidate BSS "
784-- MACSTR " (RSSI %d)",
785-- MAC2STR(target->bssid), target->level);
786-+ MACSTR " (RSSI %d, tput: %d bss-tput: %d)",
787-+ MAC2STR(target->bssid), target->level, target->est_throughput,
788-+ bss->est_throughput);
789- }
790-
791-- return target;
792-+ if (!bss_in_list)
793-+ return target;
794-+
795-+ diff = target->est_throughput - bss_in_list->est_throughput;
796-+ if (diff > bss_in_list->est_throughput >> 4) {
797-+ /* It is more than 100/16 percent better, so switch. */
798-+ return target;
799-+ }
800-+ return bss_in_list; /* stay with our existing bss, not enough change in est rate to switch. */
801- }
802-
803-
804diff --git a/debian/patches/upstream-fixes/0014-wpa_supplicant-Fix-wpa_supplicant-configuration-pars.patch b/debian/patches/upstream-fixes/0014-wpa_supplicant-Fix-wpa_supplicant-configuration-pars.patch
805deleted file mode 100644
806index 841d0d8..0000000
807--- a/debian/patches/upstream-fixes/0014-wpa_supplicant-Fix-wpa_supplicant-configuration-pars.patch
808+++ /dev/null
809@@ -1,28 +0,0 @@
810-From: Michael Lee <michael-cy.lee@mediatek.com>
811-Date: Thu, 27 Jul 2023 16:29:22 +0800
812-Subject: wpa_supplicant: Fix wpa_supplicant configuration parsing error
813-
814-In the original flow, after hostapd_config_tx_queue successfully
815-parses a tx_queue variable, it would not return immediately. Then it
816-would print out "unknow global field" later and set return val to -1.
817-
818-This patch returns immediately after hostapd_config_tx_queue
819-successfully parses a tx_queue variable.
820-
821-Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
822----
823- wpa_supplicant/config.c | 1 +
824- 1 file changed, 1 insertion(+)
825-
826-diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
827-index bf062b0..de08fff 100644
828---- a/wpa_supplicant/config.c
829-+++ b/wpa_supplicant/config.c
830-@@ -5397,6 +5397,7 @@ int wpa_config_process_global(struct wpa_config *config, char *pos, int line)
831- line);
832- return -1;
833- }
834-+ return ret;
835- }
836-
837- if (os_strncmp(pos, "wmm_ac_", 7) == 0) {
838diff --git a/debian/patches/upstream-fixes/0015-Abort-ongoing-scan.patch b/debian/patches/upstream-fixes/0015-Abort-ongoing-scan.patch
839deleted file mode 100644
840index 671af84..0000000
841--- a/debian/patches/upstream-fixes/0015-Abort-ongoing-scan.patch
842+++ /dev/null
843@@ -1,25 +0,0 @@
844-From: Chaitanya Tata <chaitanya.mgit@gmail.com>
845-Date: Tue, 18 Jul 2023 01:21:37 +0530
846-Subject: Abort ongoing scan
847-
848-Along with canceling queued scan, abort ongoing scan if any, this
849-ensures Wi-Fi interface is in usable state after disconnect is issued,
850-else subsequent scan after disconnect might fail with EBUSY.
851-
852-Signed-off-by: Chaitanya Tata <Chaitanya.Tata@nordicsemi.no>
853----
854- wpa_supplicant/wpa_supplicant.c | 1 +
855- 1 file changed, 1 insertion(+)
856-
857-diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
858-index d37a994..917aca4 100644
859---- a/wpa_supplicant/wpa_supplicant.c
860-+++ b/wpa_supplicant/wpa_supplicant.c
861-@@ -8181,6 +8181,7 @@ void wpas_request_disconnection(struct wpa_supplicant *wpa_s)
862- wpa_s->disconnected = 1;
863- wpa_supplicant_cancel_sched_scan(wpa_s);
864- wpa_supplicant_cancel_scan(wpa_s);
865-+ wpas_abort_ongoing_scan(wpa_s);
866- wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
867- eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
868- radio_remove_works(wpa_s, "connect", 0);
869diff --git a/debian/patches/upstream-fixes/0016-Override-ieee80211w-from-pmf-for-AP-mode-in-wpa_supp.patch b/debian/patches/upstream-fixes/0016-Override-ieee80211w-from-pmf-for-AP-mode-in-wpa_supp.patch
870deleted file mode 100644
871index 2b432d6..0000000
872--- a/debian/patches/upstream-fixes/0016-Override-ieee80211w-from-pmf-for-AP-mode-in-wpa_supp.patch
873+++ /dev/null
874@@ -1,36 +0,0 @@
875-From 5f3cdc06489ff1ec16d75c3ff41f5ac7c2f62c7c Mon Sep 17 00:00:00 2001
876-From: Chaoli Zhou <quic_zchaoli@quicinc.com>
877-Date: Thu, 8 Sep 2022 17:43:32 +0800
878-Subject: [PATCH] Override ieee80211w from pmf for AP mode in wpa_supplicant
879-
880-Since NetworkManager doesn't support setting ieee80211w to
881-wpa_supplicant and only support pmf, so override ieee80211w from pmf for
882-AP mode if ieee80211w not configurated. Do not change behavior for the
883-P2P GO cases.
884-
885-Signed-off-by: Chaoli Zhou <quic_zchaoli@quicinc.com>
886----
887- wpa_supplicant/ap.c | 6 +++++-
888- 1 file changed, 5 insertions(+), 1 deletion(-)
889-
890-diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
891-index 67f2d8ac1..653f15f54 100644
892---- a/wpa_supplicant/ap.c
893-+++ b/wpa_supplicant/ap.c
894-@@ -701,8 +701,12 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
895- bss->wpa_group_rekey = 86400;
896- }
897-
898-- if (ssid->ieee80211w != MGMT_FRAME_PROTECTION_DEFAULT)
899-+ if (ssid->ieee80211w != MGMT_FRAME_PROTECTION_DEFAULT) {
900- bss->ieee80211w = ssid->ieee80211w;
901-+ } else if (wpa_s->conf->pmf != MGMT_FRAME_PROTECTION_DEFAULT) {
902-+ if (ssid->mode == WPAS_MODE_AP)
903-+ bss->ieee80211w = wpa_s->conf->pmf;
904-+ }
905-
906- #ifdef CONFIG_OCV
907- bss->ocv = ssid->ocv;
908---
909-2.42.0
910-
911diff --git a/hostapd/Android.mk b/hostapd/Android.mk
912index bf26e41..573564d 100644
913--- a/hostapd/Android.mk
914+++ b/hostapd/Android.mk
915@@ -154,6 +154,7 @@ OBJS += src/utils/crc32.c
916 OBJS += src/common/ieee802_11_common.c
917 OBJS += src/common/wpa_common.c
918 OBJS += src/common/hw_features_common.c
919+OBJS += src/common/ptksa_cache.c
920
921 OBJS += src/eapol_auth/eapol_auth_sm.c
922
923@@ -237,6 +238,8 @@ L_CFLAGS += -DCONFIG_OCV
924 OBJS += src/common/ocv.c
925 endif
926
927+NEED_AES_UNWRAP=y
928+
929 ifdef CONFIG_IEEE80211R
930 L_CFLAGS += -DCONFIG_IEEE80211R -DCONFIG_IEEE80211R_AP
931 OBJS += src/ap/wpa_auth_ft.c
932@@ -256,6 +259,7 @@ L_CFLAGS += -DCONFIG_SAE
933 OBJS += src/common/sae.c
934 ifdef CONFIG_SAE_PK
935 L_CFLAGS += -DCONFIG_SAE_PK
936+NEED_AES_SIV=y
937 OBJS += src/common/sae_pk.c
938 endif
939 NEED_ECC=y
940@@ -294,6 +298,12 @@ ifdef CONFIG_IEEE80211AC
941 L_CFLAGS += -DCONFIG_IEEE80211AC
942 endif
943
944+ifdef CONFIG_IEEE80211BE
945+CONFIG_IEEE80211AX=y
946+L_CFLAGS += -DCONFIG_IEEE80211BE
947+OBJS += src/ap/ieee802_11_eht.c
948+endif
949+
950 ifdef CONFIG_IEEE80211AX
951 L_CFLAGS += -DCONFIG_IEEE80211AX
952 endif
953@@ -572,6 +582,12 @@ L_CFLAGS += -DCONFIG_DPP3
954 endif
955 endif
956
957+ifdef CONFIG_NAN_USD
958+OBJS += src/common/nan_de.c
959+OBJS += src/ap/nan_usd_ap.c
960+L_CFLAGS += -DCONFIG_NAN_USD
961+endif
962+
963 ifdef CONFIG_PASN
964 L_CFLAGS += -DCONFIG_PASN
965 L_CFLAGS += -DCONFIG_PTKSA_CACHE
966@@ -579,7 +595,6 @@ NEED_HMAC_SHA256_KDF=y
967 NEED_HMAC_SHA384_KDF=y
968 NEED_SHA256=y
969 NEED_SHA384=y
970-OBJS += src/common/ptksa_cache.c
971 endif
972
973 ifdef CONFIG_EAP_IKEV2
974@@ -632,6 +647,11 @@ ifdef CHAP
975 OBJS += src/eap_common/chap.c
976 endif
977
978+ifdef CONFIG_RADIUS_TLS
979+TLS_FUNCS=y
980+L_CFLAGS += -DCONFIG_RADIUS_TLS
981+endif
982+
983 ifdef TLS_FUNCS
984 NEED_DES=y
985 # Shared TLS functions (needed for EAP_TLS, EAP_PEAP, and EAP_TTLS)
986@@ -653,6 +673,7 @@ L_CFLAGS += -DCONFIG_TLSV12
987 endif
988
989 ifeq ($(CONFIG_TLS), openssl)
990+L_CFLAGS += -DCRYPTO_RSA_OAEP_SHA256
991 ifdef TLS_FUNCS
992 OBJS += src/crypto/tls_openssl.c
993 OBJS += src/crypto/tls_openssl_ocsp.c
994@@ -825,7 +846,9 @@ endif
995 ifdef NEED_AES_ENCBLOCK
996 AESOBJS += src/crypto/aes-encblock.c
997 endif
998+ifneq ($(CONFIG_TLS), openssl)
999 AESOBJS += src/crypto/aes-omac1.c
1000+endif
1001 ifdef NEED_AES_UNWRAP
1002 ifneq ($(CONFIG_TLS), openssl)
1003 NEED_AES_DEC=y
1004@@ -1026,6 +1049,9 @@ endif
1005 ifdef NEED_AP_MLME
1006 OBJS += src/ap/wmm.c
1007 OBJS += src/ap/ap_list.c
1008+OBJS += src/ap/comeback_token.c
1009+OBJS += src/pasn/pasn_responder.c
1010+OBJS += src/pasn/pasn_common.c
1011 OBJS += src/ap/ieee802_11.c
1012 OBJS += src/ap/hw_features.c
1013 OBJS += src/ap/dfs.c
1014diff --git a/hostapd/ChangeLog b/hostapd/ChangeLog
1015index 279298e..1c8240d 100644
1016--- a/hostapd/ChangeLog
1017+++ b/hostapd/ChangeLog
1018@@ -1,5 +1,42 @@
1019 ChangeLog for hostapd
1020
1021+2024-07-20 - v2.11
1022+ * Wi-Fi Easy Connect
1023+ - add support for DPP release 3
1024+ - allow Configurator parameters to be provided during config exchange
1025+ * HE/IEEE 802.11ax/Wi-Fi 6
1026+ - various fixes
1027+ * EHT/IEEE 802.11be/Wi-Fi 7
1028+ - add preliminary support
1029+ * SAE: add support for fetching the password from a RADIUS server
1030+ * support OpenSSL 3.0 API changes
1031+ * support background radar detection and CAC with some additional
1032+ drivers
1033+ * support RADIUS ACL/PSK check during 4-way handshake (wpa_psk_radius=3)
1034+ * EAP-SIM/AKA: support IMSI privacy
1035+ * improve 4-way handshake operations
1036+ - use Secure=1 in message 3 during PTK rekeying
1037+ * OCV: do not check Frequency Segment 1 Channel Number for 160 MHz cases
1038+ to avoid interoperability issues
1039+ * support new SAE AKM suites with variable length keys
1040+ * support new AKM for 802.1X/EAP with SHA384
1041+ * extend PASN support for secure ranging
1042+ * FT: Use SHA256 to derive PMKID for AKM 00-0F-AC:3 (FT-EAP)
1043+ - this is based on additional details being added in the IEEE 802.11
1044+ standard
1045+ - the new implementation is not backwards compatible
1046+ * improved ACS to cover additional channel types/bandwidths
1047+ * extended Multiple BSSID support
1048+ * fix beacon protection with FT protocol (incorrect BIGTK was provided)
1049+ * support unsynchronized service discovery (USD)
1050+ * add preliminary support for RADIUS/TLS
1051+ * add support for explicit SSID protection in 4-way handshake
1052+ (a mitigation for CVE-2023-52424; disabled by default for now, can be
1053+ enabled with ssid_protection=1)
1054+ * fix SAE H2E rejected groups validation to avoid downgrade attacks
1055+ * use stricter validation for some RADIUS messages
1056+ * a large number of other fixes, cleanup, and extensions
1057+
1058 2022-01-16 - v2.10
1059 * SAE changes
1060 - improved protection against side channel attacks
1061diff --git a/hostapd/Makefile b/hostapd/Makefile
1062index e37c13b..ca44392 100644
1063--- a/hostapd/Makefile
1064+++ b/hostapd/Makefile
1065@@ -84,6 +84,7 @@ OBJS += ../src/ap/beacon.o
1066 OBJS += ../src/ap/bss_load.o
1067 OBJS += ../src/ap/neighbor_db.o
1068 OBJS += ../src/ap/rrm.o
1069+OBJS += ../src/common/ptksa_cache.o
1070
1071 OBJS_c = hostapd_cli.o
1072 OBJS_c += ../src/common/wpa_ctrl.o
1073@@ -167,7 +168,7 @@ OBJS += ../src/eapol_auth/eapol_auth_sm.o
1074
1075
1076 ifdef CONFIG_CODE_COVERAGE
1077-CFLAGS += -O0 -fprofile-arcs -ftest-coverage
1078+CFLAGS += -O0 -fprofile-arcs -ftest-coverage -U_FORTIFY_SOURCE
1079 LIBS += -lgcov
1080 LIBS_c += -lgcov
1081 LIBS_h += -lgcov
1082@@ -276,6 +277,8 @@ CFLAGS += -DCONFIG_OCV
1083 OBJS += ../src/common/ocv.o
1084 endif
1085
1086+NEED_AES_UNWRAP=y
1087+
1088 ifdef CONFIG_IEEE80211R
1089 CFLAGS += -DCONFIG_IEEE80211R -DCONFIG_IEEE80211R_AP
1090 OBJS += ../src/ap/wpa_auth_ft.o
1091@@ -295,6 +298,7 @@ CFLAGS += -DCONFIG_SAE
1092 OBJS += ../src/common/sae.o
1093 ifdef CONFIG_SAE_PK
1094 CFLAGS += -DCONFIG_SAE_PK
1095+NEED_AES_SIV=y
1096 OBJS += ../src/common/sae_pk.o
1097 endif
1098 NEED_ECC=y
1099@@ -339,6 +343,12 @@ ifdef CONFIG_IEEE80211AC
1100 CFLAGS += -DCONFIG_IEEE80211AC
1101 endif
1102
1103+ifdef CONFIG_IEEE80211BE
1104+CONFIG_IEEE80211AX=y
1105+CFLAGS += -DCONFIG_IEEE80211BE
1106+OBJS += ../src/ap/ieee802_11_eht.o
1107+endif
1108+
1109 ifdef CONFIG_IEEE80211AX
1110 CFLAGS += -DCONFIG_IEEE80211AX
1111 OBJS += ../src/ap/ieee802_11_he.o
1112@@ -598,6 +608,12 @@ CFLAGS += -DCONFIG_DPP3
1113 endif
1114 endif
1115
1116+ifdef CONFIG_NAN_USD
1117+OBJS += ../src/common/nan_de.o
1118+OBJS += ../src/ap/nan_usd_ap.o
1119+CFLAGS += -DCONFIG_NAN_USD
1120+endif
1121+
1122 ifdef CONFIG_PASN
1123 CFLAGS += -DCONFIG_PASN
1124 CFLAGS += -DCONFIG_PTKSA_CACHE
1125@@ -605,7 +621,6 @@ NEED_HMAC_SHA256_KDF=y
1126 NEED_HMAC_SHA384_KDF=y
1127 NEED_SHA256=y
1128 NEED_SHA384=y
1129-OBJS += ../src/common/ptksa_cache.o
1130 endif
1131
1132 ifdef CONFIG_EAP_IKEV2
1133@@ -667,6 +682,11 @@ ifdef CHAP
1134 OBJS += ../src/eap_common/chap.o
1135 endif
1136
1137+ifdef CONFIG_RADIUS_TLS
1138+TLS_FUNCS=y
1139+CFLAGS += -DCONFIG_RADIUS_TLS
1140+endif
1141+
1142 ifdef TLS_FUNCS
1143 NEED_DES=y
1144 # Shared TLS functions (needed for EAP_TLS, EAP_PEAP, and EAP_TTLS)
1145@@ -708,6 +728,7 @@ endif
1146 endif
1147
1148 ifeq ($(CONFIG_TLS), openssl)
1149+CFLAGS += -DCRYPTO_RSA_OAEP_SHA256
1150 CONFIG_CRYPTO=openssl
1151 ifdef TLS_FUNCS
1152 OBJS += ../src/crypto/tls_openssl.o
1153@@ -932,11 +953,13 @@ endif
1154 ifdef NEED_AES_ENCBLOCK
1155 AESOBJS += ../src/crypto/aes-encblock.o
1156 endif
1157+ifneq ($(CONFIG_TLS), openssl)
1158 ifneq ($(CONFIG_TLS), linux)
1159 ifneq ($(CONFIG_TLS), wolfssl)
1160 AESOBJS += ../src/crypto/aes-omac1.o
1161 endif
1162 endif
1163+endif
1164 ifdef NEED_AES_UNWRAP
1165 ifneq ($(CONFIG_TLS), openssl)
1166 ifneq ($(CONFIG_TLS), linux)
1167@@ -1172,6 +1195,9 @@ endif
1168 ifdef NEED_AP_MLME
1169 OBJS += ../src/ap/wmm.o
1170 OBJS += ../src/ap/ap_list.o
1171+OBJS += ../src/ap/comeback_token.o
1172+OBJS += ../src/pasn/pasn_responder.o
1173+OBJS += ../src/pasn/pasn_common.o
1174 OBJS += ../src/ap/ieee802_11.o
1175 OBJS += ../src/ap/hw_features.o
1176 OBJS += ../src/ap/dfs.o
1177diff --git a/hostapd/README b/hostapd/README
1178index 739c964..1a0248f 100644
1179--- a/hostapd/README
1180+++ b/hostapd/README
1181@@ -2,7 +2,7 @@ hostapd - user space IEEE 802.11 AP and IEEE 802.1X/WPA/WPA2/EAP
1182 Authenticator and RADIUS authentication server
1183 ================================================================
1184
1185-Copyright (c) 2002-2022, Jouni Malinen <j@w1.fi> and contributors
1186+Copyright (c) 2002-2024, Jouni Malinen <j@w1.fi> and contributors
1187 All Rights Reserved.
1188
1189 This program is licensed under the BSD license (the one with
1190diff --git a/hostapd/android.config b/hostapd/android.config
1191index c8b3afa..522de87 100644
1192--- a/hostapd/android.config
1193+++ b/hostapd/android.config
1194@@ -121,6 +121,9 @@ CONFIG_PKCS12=y
1195 # Build IPv6 support for RADIUS operations
1196 CONFIG_IPV6=y
1197
1198+# Include support fo RADIUS/TLS into the RADIUS client
1199+#CONFIG_RADIUS_TLS=y
1200+
1201 # IEEE Std 802.11r-2008 (Fast BSS Transition)
1202 #CONFIG_IEEE80211R=y
1203
1204@@ -212,3 +215,6 @@ CONFIG_NO_RANDOM_POOL=y
1205 # release under this optional build parameter. This functionality is subject to
1206 # be completely removed in a future release.
1207 CONFIG_WEP=y
1208+
1209+# Wi-Fi Aware unsynchronized service discovery (NAN USD)
1210+#CONFIG_NAN_USD=y
1211diff --git a/hostapd/config_file.c b/hostapd/config_file.c
1212index b14728d..3fb0597 100644
1213--- a/hostapd/config_file.c
1214+++ b/hostapd/config_file.c
1215@@ -1,6 +1,6 @@
1216 /*
1217 * hostapd / Configuration file parser
1218- * Copyright (c) 2003-2018, Jouni Malinen <j@w1.fi>
1219+ * Copyright (c) 2003-2024, Jouni Malinen <j@w1.fi>
1220 *
1221 * This software may be distributed under the terms of the BSD license.
1222 * See README for more details.
1223@@ -118,52 +118,6 @@ static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss,
1224 #endif /* CONFIG_NO_VLAN */
1225
1226
1227-int hostapd_acl_comp(const void *a, const void *b)
1228-{
1229- const struct mac_acl_entry *aa = a;
1230- const struct mac_acl_entry *bb = b;
1231- return os_memcmp(aa->addr, bb->addr, sizeof(macaddr));
1232-}
1233-
1234-
1235-int hostapd_add_acl_maclist(struct mac_acl_entry **acl, int *num,
1236- int vlan_id, const u8 *addr)
1237-{
1238- struct mac_acl_entry *newacl;
1239-
1240- newacl = os_realloc_array(*acl, *num + 1, sizeof(**acl));
1241- if (!newacl) {
1242- wpa_printf(MSG_ERROR, "MAC list reallocation failed");
1243- return -1;
1244- }
1245-
1246- *acl = newacl;
1247- os_memcpy((*acl)[*num].addr, addr, ETH_ALEN);
1248- os_memset(&(*acl)[*num].vlan_id, 0, sizeof((*acl)[*num].vlan_id));
1249- (*acl)[*num].vlan_id.untagged = vlan_id;
1250- (*acl)[*num].vlan_id.notempty = !!vlan_id;
1251- (*num)++;
1252-
1253- return 0;
1254-}
1255-
1256-
1257-void hostapd_remove_acl_mac(struct mac_acl_entry **acl, int *num,
1258- const u8 *addr)
1259-{
1260- int i = 0;
1261-
1262- while (i < *num) {
1263- if (os_memcmp((*acl)[i].addr, addr, ETH_ALEN) == 0) {
1264- os_remove_in_array(*acl, *num, sizeof(**acl), i);
1265- (*num)--;
1266- } else {
1267- i++;
1268- }
1269- }
1270-}
1271-
1272-
1273 static int hostapd_config_read_maclist(const char *fname,
1274 struct mac_acl_entry **acl, int *num)
1275 {
1276@@ -713,6 +667,10 @@ static int hostapd_config_parse_key_mgmt(int line, const char *value)
1277 val |= WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
1278 #endif /* CONFIG_SHA384 */
1279 #endif /* CONFIG_IEEE80211R_AP */
1280+#ifdef CONFIG_SHA384
1281+ else if (os_strcmp(start, "WPA-EAP-SHA384") == 0)
1282+ val |= WPA_KEY_MGMT_IEEE8021X_SHA384;
1283+#endif /* CONFIG_SHA384 */
1284 else if (os_strcmp(start, "WPA-PSK-SHA256") == 0)
1285 val |= WPA_KEY_MGMT_PSK_SHA256;
1286 else if (os_strcmp(start, "WPA-EAP-SHA256") == 0)
1287@@ -720,8 +678,12 @@ static int hostapd_config_parse_key_mgmt(int line, const char *value)
1288 #ifdef CONFIG_SAE
1289 else if (os_strcmp(start, "SAE") == 0)
1290 val |= WPA_KEY_MGMT_SAE;
1291+ else if (os_strcmp(start, "SAE-EXT-KEY") == 0)
1292+ val |= WPA_KEY_MGMT_SAE_EXT_KEY;
1293 else if (os_strcmp(start, "FT-SAE") == 0)
1294 val |= WPA_KEY_MGMT_FT_SAE;
1295+ else if (os_strcmp(start, "FT-SAE-EXT-KEY") == 0)
1296+ val |= WPA_KEY_MGMT_FT_SAE_EXT_KEY;
1297 #endif /* CONFIG_SAE */
1298 #ifdef CONFIG_SUITEB
1299 else if (os_strcmp(start, "WPA-EAP-SUITE-B") == 0)
1300@@ -1058,6 +1020,78 @@ static int add_r1kh(struct hostapd_bss_config *bss, char *value)
1301
1302 return 0;
1303 }
1304+
1305+
1306+int hostapd_config_read_rxkh_file(struct hostapd_bss_config *conf,
1307+ const char *fname)
1308+{
1309+ FILE *f;
1310+ char buf[256], *pos;
1311+ int line = 0, errors = 0;
1312+
1313+ if (!fname)
1314+ return 0;
1315+
1316+ f = fopen(fname, "r");
1317+ if (!f) {
1318+ wpa_printf(MSG_ERROR, "rxkh file '%s' not found.", fname);
1319+ return -1;
1320+ }
1321+
1322+ while (fgets(buf, sizeof(buf), f)) {
1323+ line++;
1324+
1325+ if (buf[0] == '#')
1326+ continue;
1327+ pos = buf;
1328+ while (*pos != '\0') {
1329+ if (*pos == '\n') {
1330+ *pos = '\0';
1331+ break;
1332+ }
1333+ pos++;
1334+ }
1335+ if (buf[0] == '\0')
1336+ continue;
1337+
1338+ pos = os_strchr(buf, '=');
1339+ if (!pos) {
1340+ wpa_printf(MSG_ERROR, "Line %d: Invalid line '%s'",
1341+ line, buf);
1342+ errors++;
1343+ continue;
1344+ }
1345+ *pos = '\0';
1346+ pos++;
1347+
1348+ if (os_strcmp(buf, "r0kh") == 0) {
1349+ if (add_r0kh(conf, pos) < 0) {
1350+ wpa_printf(MSG_ERROR,
1351+ "Line %d: Invalid r0kh '%s'",
1352+ line, pos);
1353+ errors++;
1354+ }
1355+ } else if (os_strcmp(buf, "r1kh") == 0) {
1356+ if (add_r1kh(conf, pos) < 0) {
1357+ wpa_printf(MSG_ERROR,
1358+ "Line %d: Invalid r1kh '%s'",
1359+ line, pos);
1360+ errors++;
1361+ }
1362+ }
1363+ }
1364+
1365+ fclose(f);
1366+
1367+ if (errors) {
1368+ wpa_printf(MSG_ERROR,
1369+ "%d errors in configuring RxKHs from '%s'",
1370+ errors, fname);
1371+ return -1;
1372+ }
1373+ return 0;
1374+}
1375+
1376 #endif /* CONFIG_IEEE80211R_AP */
1377
1378
1379@@ -1644,6 +1678,8 @@ static int parse_anqp_elem(struct hostapd_bss_config *bss, char *buf, int line)
1380 return 0;
1381 }
1382
1383+#endif /* CONFIG_INTERWORKING */
1384+
1385
1386 static int parse_qos_map_set(struct hostapd_bss_config *bss,
1387 char *buf, int line)
1388@@ -1685,8 +1721,6 @@ static int parse_qos_map_set(struct hostapd_bss_config *bss,
1389 return 0;
1390 }
1391
1392-#endif /* CONFIG_INTERWORKING */
1393-
1394
1395 #ifdef CONFIG_HS20
1396 static int hs20_parse_conn_capab(struct hostapd_bss_config *bss, char *buf,
1397@@ -2197,6 +2231,7 @@ static int add_airtime_weight(struct hostapd_bss_config *bss, char *value)
1398
1399
1400 #ifdef CONFIG_SAE
1401+
1402 static int parse_sae_password(struct hostapd_bss_config *bss, const char *val)
1403 {
1404 struct sae_password_entry *pw;
1405@@ -2300,6 +2335,40 @@ fail:
1406 os_free(pw);
1407 return -1;
1408 }
1409+
1410+
1411+static int parse_sae_password_file(struct hostapd_bss_config *bss,
1412+ const char *fname)
1413+{
1414+ FILE *f;
1415+ char buf[500], *pos;
1416+ unsigned int line = 0;
1417+
1418+ f = fopen(fname, "r");
1419+ if (!f) {
1420+ wpa_printf(MSG_ERROR, "sae_password_file '%s' not found.",
1421+ fname);
1422+ return -1;
1423+ }
1424+
1425+ while (fgets(buf, sizeof(buf), f)) {
1426+ pos = os_strchr(buf, '\n');
1427+ if (pos)
1428+ *pos = '\0';
1429+ line++;
1430+ if (parse_sae_password(bss, buf)) {
1431+ wpa_printf(MSG_ERROR,
1432+ "Invalid SAE password at line %d in '%s'",
1433+ line, fname);
1434+ fclose(f);
1435+ return -1;
1436+ }
1437+ }
1438+
1439+ fclose(f);
1440+ return 0;
1441+}
1442+
1443 #endif /* CONFIG_SAE */
1444
1445
1446@@ -2349,6 +2418,24 @@ static int get_hex_config(u8 *buf, size_t max_len, int line,
1447 }
1448
1449
1450+#ifdef CONFIG_IEEE80211BE
1451+static int get_u16(const char *pos, int line, u16 *ret_val)
1452+{
1453+ char *end;
1454+ long int val = strtol(pos, &end, 0);
1455+
1456+ if (*end || val < 0 || val > 0xffff) {
1457+ wpa_printf(MSG_ERROR, "Line %d: Invalid value '%s'",
1458+ line, pos);
1459+ return -1;
1460+ }
1461+
1462+ *ret_val = val;
1463+ return 0;
1464+}
1465+#endif /* CONFIG_IEEE80211BE */
1466+
1467+
1468 static int hostapd_config_fill(struct hostapd_config *conf,
1469 struct hostapd_bss_config *bss,
1470 const char *buf, char *pos, int line)
1471@@ -2358,6 +2445,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1472 sizeof(conf->bss[0]->iface));
1473 } else if (os_strcmp(buf, "bridge") == 0) {
1474 os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));
1475+ } else if (os_strcmp(buf, "bridge_hairpin") == 0) {
1476+ bss->bridge_hairpin = atoi(pos);
1477 } else if (os_strcmp(buf, "vlan_bridge") == 0) {
1478 os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge));
1479 } else if (os_strcmp(buf, "wds_bridge") == 0) {
1480@@ -2407,7 +2496,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1481 }
1482 os_memcpy(ssid->ssid, pos, ssid->ssid_len);
1483 ssid->ssid_set = 1;
1484- ssid->short_ssid = crc32(ssid->ssid, ssid->ssid_len);
1485+ ssid->short_ssid = ieee80211_crc32(ssid->ssid, ssid->ssid_len);
1486 } else if (os_strcmp(buf, "ssid2") == 0) {
1487 struct hostapd_ssid *ssid = &bss->ssid;
1488 size_t slen;
1489@@ -2421,7 +2510,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1490 os_memcpy(ssid->ssid, str, slen);
1491 ssid->ssid_len = slen;
1492 ssid->ssid_set = 1;
1493- ssid->short_ssid = crc32(ssid->ssid, ssid->ssid_len);
1494+ ssid->short_ssid = ieee80211_crc32(ssid->ssid, ssid->ssid_len);
1495 os_free(str);
1496 } else if (os_strcmp(buf, "utf8_ssid") == 0) {
1497 bss->ssid.utf8_ssid = atoi(pos) > 0;
1498@@ -2460,6 +2549,30 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1499 bss->ap_max_inactivity = atoi(pos);
1500 } else if (os_strcmp(buf, "skip_inactivity_poll") == 0) {
1501 bss->skip_inactivity_poll = atoi(pos);
1502+ } else if (os_strcmp(buf, "bss_max_idle") == 0) {
1503+ int val = atoi(pos);
1504+
1505+ if (val < 0 || val > 2) {
1506+ wpa_printf(MSG_ERROR,
1507+ "Line %d: Invalid bss_max_idle value", line);
1508+ return 1;
1509+ }
1510+ bss->bss_max_idle = val;
1511+ } else if (os_strcmp(buf, "max_acceptable_idle_period") == 0) {
1512+ bss->max_acceptable_idle_period = atoi(pos);
1513+ } else if (os_strcmp(buf, "no_disconnect_on_group_keyerror") == 0) {
1514+ int val = atoi(pos);
1515+
1516+ if (val < 0 || val > 1) {
1517+ wpa_printf(MSG_ERROR,
1518+ "Line %d: Invalid no_disconnect_on_group_keyerror",
1519+ line);
1520+ return 1;
1521+ }
1522+ bss->no_disconnect_on_group_keyerror = val;
1523+ } else if (os_strcmp(buf, "config_id") == 0) {
1524+ os_free(bss->config_id);
1525+ bss->config_id = os_strdup(pos);
1526 } else if (os_strcmp(buf, "country_code") == 0) {
1527 if (pos[0] < 'A' || pos[0] > 'Z' ||
1528 pos[1] < 'A' || pos[1] > 'Z') {
1529@@ -2624,6 +2737,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1530 bss->eap_teap_separate_result = atoi(pos);
1531 } else if (os_strcmp(buf, "eap_teap_id") == 0) {
1532 bss->eap_teap_id = atoi(pos);
1533+ } else if (os_strcmp(buf, "eap_teap_method_sequence") == 0) {
1534+ bss->eap_teap_method_sequence = atoi(pos);
1535 #endif /* EAP_SERVER_TEAP */
1536 #ifdef EAP_SERVER_SIM
1537 } else if (os_strcmp(buf, "eap_sim_db") == 0) {
1538@@ -2635,6 +2750,11 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1539 bss->eap_sim_aka_result_ind = atoi(pos);
1540 } else if (os_strcmp(buf, "eap_sim_id") == 0) {
1541 bss->eap_sim_id = atoi(pos);
1542+ } else if (os_strcmp(buf, "imsi_privacy_key") == 0) {
1543+ os_free(bss->imsi_privacy_key);
1544+ bss->imsi_privacy_key = os_strdup(pos);
1545+ } else if (os_strcmp(buf, "eap_sim_aka_fast_reauth_limit") == 0) {
1546+ bss->eap_sim_aka_fast_reauth_limit = atoi(pos);
1547 #endif /* EAP_SERVER_SIM */
1548 #ifdef EAP_SERVER_TNC
1549 } else if (os_strcmp(buf, "tnc") == 0) {
1550@@ -2770,6 +2890,37 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1551 os_free(bss->radius->auth_server->shared_secret);
1552 bss->radius->auth_server->shared_secret = (u8 *) os_strdup(pos);
1553 bss->radius->auth_server->shared_secret_len = len;
1554+ } else if (bss->radius->auth_server &&
1555+ os_strcmp(buf, "auth_server_type") == 0) {
1556+ if (os_strcmp(pos, "UDP") == 0) {
1557+ bss->radius->auth_server->tls = false;
1558+#ifdef CONFIG_RADIUS_TLS
1559+ } else if (os_strcmp(pos, "TLS") == 0) {
1560+ bss->radius->auth_server->tls = true;
1561+#endif /* CONFIG_RADIUS_TLS */
1562+ } else {
1563+ wpa_printf(MSG_ERROR, "Line %d: unsupported RADIUS type '%s'",
1564+ line, pos);
1565+ return 1;
1566+ }
1567+#ifdef CONFIG_RADIUS_TLS
1568+ } else if (bss->radius->auth_server &&
1569+ os_strcmp(buf, "auth_server_ca_cert") == 0) {
1570+ os_free(bss->radius->auth_server->ca_cert);
1571+ bss->radius->auth_server->ca_cert = os_strdup(pos);
1572+ } else if (bss->radius->auth_server &&
1573+ os_strcmp(buf, "auth_server_client_cert") == 0) {
1574+ os_free(bss->radius->auth_server->client_cert);
1575+ bss->radius->auth_server->client_cert = os_strdup(pos);
1576+ } else if (bss->radius->auth_server &&
1577+ os_strcmp(buf, "auth_server_private_key") == 0) {
1578+ os_free(bss->radius->auth_server->private_key);
1579+ bss->radius->auth_server->private_key = os_strdup(pos);
1580+ } else if (bss->radius->auth_server &&
1581+ os_strcmp(buf, "auth_server_private_key_passwd") == 0) {
1582+ os_free(bss->radius->auth_server->private_key_passwd);
1583+ bss->radius->auth_server->private_key_passwd = os_strdup(pos);
1584+#endif /* CONFIG_RADIUS_TLS */
1585 } else if (os_strcmp(buf, "acct_server_addr") == 0) {
1586 if (hostapd_config_read_radius_addr(
1587 &bss->radius->acct_servers,
1588@@ -2804,8 +2955,42 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1589 os_free(bss->radius->acct_server->shared_secret);
1590 bss->radius->acct_server->shared_secret = (u8 *) os_strdup(pos);
1591 bss->radius->acct_server->shared_secret_len = len;
1592+ } else if (bss->radius->acct_server &&
1593+ os_strcmp(buf, "acct_server_type") == 0) {
1594+ if (os_strcmp(pos, "UDP") == 0) {
1595+ bss->radius->acct_server->tls = false;
1596+#ifdef CONFIG_RADIUS_TLS
1597+ } else if (os_strcmp(pos, "TLS") == 0) {
1598+ bss->radius->acct_server->tls = true;
1599+#endif /* CONFIG_RADIUS_TLS */
1600+ } else {
1601+ wpa_printf(MSG_ERROR, "Line %d: unsupported RADIUS type '%s'",
1602+ line, pos);
1603+ return 1;
1604+ }
1605+#ifdef CONFIG_RADIUS_TLS
1606+ } else if (bss->radius->acct_server &&
1607+ os_strcmp(buf, "acct_server_ca_cert") == 0) {
1608+ os_free(bss->radius->acct_server->ca_cert);
1609+ bss->radius->acct_server->ca_cert = os_strdup(pos);
1610+ } else if (bss->radius->acct_server &&
1611+ os_strcmp(buf, "acct_server_client_cert") == 0) {
1612+ os_free(bss->radius->acct_server->client_cert);
1613+ bss->radius->acct_server->client_cert = os_strdup(pos);
1614+ } else if (bss->radius->acct_server &&
1615+ os_strcmp(buf, "acct_server_private_key") == 0) {
1616+ os_free(bss->radius->acct_server->private_key);
1617+ bss->radius->acct_server->private_key = os_strdup(pos);
1618+ } else if (bss->radius->acct_server &&
1619+ os_strcmp(buf, "acct_server_private_key_passwd") == 0) {
1620+ os_free(bss->radius->acct_server->private_key_passwd);
1621+ bss->radius->acct_server->private_key_passwd = os_strdup(pos);
1622+#endif /* CONFIG_RADIUS_TLS */
1623 } else if (os_strcmp(buf, "radius_retry_primary_interval") == 0) {
1624 bss->radius->retry_primary_interval = atoi(pos);
1625+ } else if (os_strcmp(buf,
1626+ "radius_require_message_authenticator") == 0) {
1627+ bss->radius_require_message_authenticator = atoi(pos);
1628 } else if (os_strcmp(buf, "radius_acct_interim_interval") == 0) {
1629 bss->acct_interim_interval = atoi(pos);
1630 } else if (os_strcmp(buf, "radius_request_cui") == 0) {
1631@@ -2975,7 +3160,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1632 bss->wpa_psk_radius = atoi(pos);
1633 if (bss->wpa_psk_radius != PSK_RADIUS_IGNORED &&
1634 bss->wpa_psk_radius != PSK_RADIUS_ACCEPTED &&
1635- bss->wpa_psk_radius != PSK_RADIUS_REQUIRED) {
1636+ bss->wpa_psk_radius != PSK_RADIUS_REQUIRED &&
1637+ bss->wpa_psk_radius != PSK_RADIUS_DURING_4WAY_HS) {
1638 wpa_printf(MSG_ERROR,
1639 "Line %d: unknown wpa_psk_radius %d",
1640 line, bss->wpa_psk_radius);
1641@@ -3072,6 +3258,21 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1642 line, pos);
1643 return 1;
1644 }
1645+ } else if (os_strcmp(buf, "rxkh_file") == 0) {
1646+ os_free(bss->rxkh_file);
1647+ bss->rxkh_file = os_strdup(pos);
1648+ if (!bss->rxkh_file) {
1649+ wpa_printf(MSG_ERROR, "Line %d: allocation failed",
1650+ line);
1651+ return 1;
1652+ }
1653+ if (hostapd_config_read_rxkh_file(bss, pos)) {
1654+ wpa_printf(MSG_DEBUG,
1655+ "Line %d: failed to read rxkh_file '%s'",
1656+ line, pos);
1657+ /* Allow the file to be created later and read into
1658+ * already operating AP context. */
1659+ }
1660 } else if (os_strcmp(buf, "pmk_r1_push") == 0) {
1661 bss->pmk_r1_push = atoi(pos);
1662 } else if (os_strcmp(buf, "ft_over_ds") == 0) {
1663@@ -3139,6 +3340,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1664 line, pos);
1665 return 1;
1666 }
1667+ conf->hw_mode_set = true;
1668 } else if (os_strcmp(buf, "wps_rf_bands") == 0) {
1669 if (os_strcmp(pos, "ad") == 0)
1670 bss->wps_rf_bands = WPS_RF_60GHZ;
1671@@ -3193,6 +3395,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1672 conf->acs_freq_list_present = 1;
1673 } else if (os_strcmp(buf, "acs_exclude_6ghz_non_psc") == 0) {
1674 conf->acs_exclude_6ghz_non_psc = atoi(pos);
1675+ } else if (os_strcmp(buf, "enable_background_radar") == 0) {
1676+ conf->enable_background_radar = atoi(pos);
1677 } else if (os_strcmp(buf, "min_tx_power") == 0) {
1678 int val = atoi(pos);
1679
1680@@ -3484,6 +3688,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1681 }
1682 } else if (os_strcmp(buf, "require_ht") == 0) {
1683 conf->require_ht = atoi(pos);
1684+ } else if (os_strcmp(buf, "ht_vht_twt_responder") == 0) {
1685+ conf->ht_vht_twt_responder = atoi(pos);
1686 } else if (os_strcmp(buf, "obss_interval") == 0) {
1687 conf->obss_interval = atoi(pos);
1688 #ifdef CONFIG_IEEE80211AC
1689@@ -3511,6 +3717,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1690 #ifdef CONFIG_IEEE80211AX
1691 } else if (os_strcmp(buf, "ieee80211ax") == 0) {
1692 conf->ieee80211ax = atoi(pos);
1693+ } else if (os_strcmp(buf, "require_he") == 0) {
1694+ conf->require_he = atoi(pos);
1695 } else if (os_strcmp(buf, "he_su_beamformer") == 0) {
1696 conf->he_phy_capab.he_su_beamformer = atoi(pos);
1697 } else if (os_strcmp(buf, "he_su_beamformee") == 0) {
1698@@ -3642,6 +3850,20 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1699 line, pos);
1700 return 1;
1701 }
1702+ } else if (os_strcmp(buf, "he_6ghz_reg_pwr_type") == 0) {
1703+ conf->he_6ghz_reg_pwr_type = atoi(pos);
1704+ if (conf->he_6ghz_reg_pwr_type > HE_REG_INFO_6GHZ_AP_TYPE_MAX) {
1705+ wpa_printf(MSG_ERROR,
1706+ "Line %d: invalid he_6ghz_reg_pwr_type value",
1707+ line);
1708+ return 1;
1709+ }
1710+ } else if (os_strcmp(buf, "reg_def_cli_eirp_psd") == 0) {
1711+ conf->reg_def_cli_eirp_psd = atoi(pos);
1712+ } else if (os_strcmp(buf, "reg_sub_cli_eirp_psd") == 0) {
1713+ conf->reg_sub_cli_eirp_psd = atoi(pos);
1714+ } else if (os_strcmp(buf, "reg_def_cli_eirp") == 0) {
1715+ conf->reg_def_cli_eirp = atoi(pos);
1716 } else if (os_strcmp(buf, "he_oper_chwidth") == 0) {
1717 conf->he_oper_chwidth = atoi(pos);
1718 } else if (os_strcmp(buf, "he_oper_centr_freq_seg0_idx") == 0) {
1719@@ -3666,6 +3888,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1720 return 1;
1721 }
1722 bss->unsol_bcast_probe_resp_interval = val;
1723+ } else if (os_strcmp(buf, "mbssid") == 0) {
1724+ int mbssid = atoi(pos);
1725+ if (mbssid < 0 || mbssid > ENHANCED_MBSSID_ENABLED) {
1726+ wpa_printf(MSG_ERROR,
1727+ "Line %d: invalid mbssid (%d): '%s'.",
1728+ line, mbssid, pos);
1729+ return 1;
1730+ }
1731+ conf->mbssid = mbssid;
1732 #endif /* CONFIG_IEEE80211AX */
1733 } else if (os_strcmp(buf, "max_listen_interval") == 0) {
1734 bss->max_listen_interval = atoi(pos);
1735@@ -4053,10 +4284,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1736 bss->gas_frag_limit = val;
1737 } else if (os_strcmp(buf, "gas_comeback_delay") == 0) {
1738 bss->gas_comeback_delay = atoi(pos);
1739+#endif /* CONFIG_INTERWORKING */
1740 } else if (os_strcmp(buf, "qos_map_set") == 0) {
1741 if (parse_qos_map_set(bss, pos, line) < 0)
1742 return 1;
1743-#endif /* CONFIG_INTERWORKING */
1744 #ifdef CONFIG_RADIUS_TEST
1745 } else if (os_strcmp(buf, "dump_msk_file") == 0) {
1746 os_free(bss->dump_msk_file);
1747@@ -4297,6 +4528,23 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1748 bss->oci_freq_override_fils_assoc = atoi(pos);
1749 } else if (os_strcmp(buf, "oci_freq_override_wnm_sleep") == 0) {
1750 bss->oci_freq_override_wnm_sleep = atoi(pos);
1751+ } else if (os_strcmp(buf, "eap_skip_prot_success") == 0) {
1752+ bss->eap_skip_prot_success = atoi(pos);
1753+ } else if (os_strcmp(buf, "delay_eapol_tx") == 0) {
1754+ conf->delay_eapol_tx = atoi(pos);
1755+ } else if (os_strcmp(buf, "eapol_m1_elements") == 0) {
1756+ if (parse_wpabuf_hex(line, buf, &bss->eapol_m1_elements, pos))
1757+ return 1;
1758+ } else if (os_strcmp(buf, "eapol_m3_elements") == 0) {
1759+ if (parse_wpabuf_hex(line, buf, &bss->eapol_m3_elements, pos))
1760+ return 1;
1761+ } else if (os_strcmp(buf, "eapol_m3_no_encrypt") == 0) {
1762+ bss->eapol_m3_no_encrypt = atoi(pos);
1763+ } else if (os_strcmp(buf, "test_assoc_comeback_type") == 0) {
1764+ bss->test_assoc_comeback_type = atoi(pos);
1765+ } else if (os_strcmp(buf, "presp_elements") == 0) {
1766+ if (parse_wpabuf_hex(line, buf, &bss->presp_elements, pos))
1767+ return 1;
1768 #endif /* CONFIG_TESTING_OPTIONS */
1769 #ifdef CONFIG_SAE
1770 } else if (os_strcmp(buf, "sae_password") == 0) {
1771@@ -4305,6 +4553,13 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1772 line);
1773 return 1;
1774 }
1775+ } else if (os_strcmp(buf, "sae_password_file") == 0) {
1776+ if (parse_sae_password_file(bss, pos) < 0) {
1777+ wpa_printf(MSG_ERROR,
1778+ "Line %d: Invalid sae_password in file",
1779+ line);
1780+ return 1;
1781+ }
1782 #endif /* CONFIG_SAE */
1783 } else if (os_strcmp(buf, "vendor_elements") == 0) {
1784 if (parse_wpabuf_hex(line, buf, &bss->vendor_elements, pos))
1785@@ -4436,6 +4691,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1786 WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |
1787 WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE |
1788 WLAN_RRM_CAPS_BEACON_REPORT_TABLE;
1789+ } else if (os_strcmp(buf, "rrm_link_measurement_report") == 0) {
1790+ if (atoi(pos))
1791+ bss->radio_measurements[0] |=
1792+ WLAN_RRM_CAPS_LINK_MEASUREMENT;
1793 } else if (os_strcmp(buf, "gas_address3") == 0) {
1794 bss->gas_address3 = atoi(pos);
1795 } else if (os_strcmp(buf, "stationary_ap") == 0) {
1796@@ -4480,6 +4739,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1797 #endif /* CONFIG_FILS */
1798 } else if (os_strcmp(buf, "multicast_to_unicast") == 0) {
1799 bss->multicast_to_unicast = atoi(pos);
1800+ } else if (os_strcmp(buf, "bridge_multicast_to_unicast") == 0) {
1801+ bss->bridge_multicast_to_unicast = atoi(pos);
1802 } else if (os_strcmp(buf, "broadcast_deauth") == 0) {
1803 bss->broadcast_deauth = atoi(pos);
1804 } else if (os_strcmp(buf, "notify_mgmt_frames") == 0) {
1805@@ -4491,6 +4752,12 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1806 } else if (os_strcmp(buf, "dpp_mud_url") == 0) {
1807 os_free(bss->dpp_mud_url);
1808 bss->dpp_mud_url = os_strdup(pos);
1809+ } else if (os_strcmp(buf, "dpp_extra_conf_req_name") == 0) {
1810+ os_free(bss->dpp_extra_conf_req_name);
1811+ bss->dpp_extra_conf_req_name = os_strdup(pos);
1812+ } else if (os_strcmp(buf, "dpp_extra_conf_req_value") == 0) {
1813+ os_free(bss->dpp_extra_conf_req_value);
1814+ bss->dpp_extra_conf_req_value = os_strdup(pos);
1815 } else if (os_strcmp(buf, "dpp_connector") == 0) {
1816 os_free(bss->dpp_connector);
1817 bss->dpp_connector = os_strdup(pos);
1818@@ -4506,6 +4773,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1819 } else if (os_strcmp(buf, "dpp_controller") == 0) {
1820 if (hostapd_dpp_controller_parse(bss, pos))
1821 return 1;
1822+ } else if (os_strcmp(buf, "dpp_relay_port") == 0) {
1823+ bss->dpp_relay_port = atoi(pos);
1824 } else if (os_strcmp(buf, "dpp_configurator_connectivity") == 0) {
1825 bss->dpp_configurator_connectivity = atoi(pos);
1826 } else if (os_strcmp(buf, "dpp_pfs") == 0) {
1827@@ -4566,6 +4835,36 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1828 }
1829
1830 bss->multi_ap = val;
1831+ } else if (os_strcmp(buf, "multi_ap_profile") == 0) {
1832+ int val = atoi(pos);
1833+
1834+ if (val < MULTI_AP_PROFILE_1 || val > MULTI_AP_PROFILE_MAX) {
1835+ wpa_printf(MSG_ERROR,
1836+ "Line %d: Invalid multi_ap_profile '%s'",
1837+ line, buf);
1838+ return -1;
1839+ }
1840+ bss->multi_ap_profile = val;
1841+ } else if (os_strcmp(buf, "multi_ap_client_disallow") == 0) {
1842+ int val = atoi(pos);
1843+
1844+ if (val < 0 || val > 3) {
1845+ wpa_printf(MSG_ERROR,
1846+ "Line %d: Invalid multi_ap_client_allow '%s'",
1847+ line, buf);
1848+ return -1;
1849+ }
1850+ bss->multi_ap_client_disallow = val;
1851+ } else if (os_strcmp(buf, "multi_ap_vlanid") == 0) {
1852+ int val = atoi(pos);
1853+
1854+ if (val < 0 || val > MAX_VLAN_ID) {
1855+ wpa_printf(MSG_ERROR,
1856+ "Line %d: Invalid multi_ap_vlan_id '%s'",
1857+ line, buf);
1858+ return -1;
1859+ }
1860+ bss->multi_ap_vlanid = val;
1861 } else if (os_strcmp(buf, "rssi_reject_assoc_rssi") == 0) {
1862 conf->rssi_reject_assoc_rssi = atoi(pos);
1863 } else if (os_strcmp(buf, "rssi_reject_assoc_timeout") == 0) {
1864@@ -4641,6 +4940,16 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1865 bss->macsec_replay_protect = macsec_replay_protect;
1866 } else if (os_strcmp(buf, "macsec_replay_window") == 0) {
1867 bss->macsec_replay_window = atoi(pos);
1868+ } else if (os_strcmp(buf, "macsec_offload") == 0) {
1869+ int macsec_offload = atoi(pos);
1870+
1871+ if (macsec_offload < 0 || macsec_offload > 2) {
1872+ wpa_printf(MSG_ERROR,
1873+ "Line %d: invalid macsec_offload (%d): '%s'.",
1874+ line, macsec_offload, pos);
1875+ return 1;
1876+ }
1877+ bss->macsec_offload = macsec_offload;
1878 } else if (os_strcmp(buf, "macsec_port") == 0) {
1879 int macsec_port = atoi(pos);
1880
1881@@ -4661,6 +4970,16 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1882 return 1;
1883 }
1884 bss->mka_priority = mka_priority;
1885+ } else if (os_strcmp(buf, "macsec_csindex") == 0) {
1886+ int macsec_csindex = atoi(pos);
1887+
1888+ if (macsec_csindex < 0 || macsec_csindex > 1) {
1889+ wpa_printf(MSG_ERROR,
1890+ "Line %d: invalid macsec_csindex (%d): '%s'.",
1891+ line, macsec_csindex, pos);
1892+ return 1;
1893+ }
1894+ bss->macsec_csindex = macsec_csindex;
1895 } else if (os_strcmp(buf, "mka_cak") == 0) {
1896 size_t len = os_strlen(pos);
1897
1898@@ -4697,6 +5016,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1899 bss->disable_11ac = !!atoi(pos);
1900 } else if (os_strcmp(buf, "disable_11ax") == 0) {
1901 bss->disable_11ax = !!atoi(pos);
1902+ } else if (os_strcmp(buf, "disable_11be") == 0) {
1903+ bss->disable_11be = !!atoi(pos);
1904 #ifdef CONFIG_PASN
1905 #ifdef CONFIG_TESTING_OPTIONS
1906 } else if (os_strcmp(buf, "force_kdk_derivation") == 0) {
1907@@ -4713,6 +5034,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1908 }
1909 } else if (os_strcmp(buf, "pasn_comeback_after") == 0) {
1910 bss->pasn_comeback_after = atoi(pos);
1911+ } else if (os_strcmp(buf, "pasn_noauth") == 0) {
1912+ bss->pasn_noauth = atoi(pos);
1913 #endif /* CONFIG_PASN */
1914 } else if (os_strcmp(buf, "ext_capa_mask") == 0) {
1915 if (get_hex_config(bss->ext_capa_mask, EXT_CAPA_MAX_LEN,
1916@@ -4724,6 +5047,58 @@ static int hostapd_config_fill(struct hostapd_config *conf,
1917 return 1;
1918 } else if (os_strcmp(buf, "rnr") == 0) {
1919 bss->rnr = atoi(pos);
1920+ } else if (os_strcmp(buf, "ssid_protection") == 0) {
1921+ int val = atoi(pos);
1922+
1923+ if (val < 0 || val > 1)
1924+ return 1;
1925+ bss->ssid_protection = val;
1926+#ifdef CONFIG_IEEE80211BE
1927+ } else if (os_strcmp(buf, "ieee80211be") == 0) {
1928+ conf->ieee80211be = atoi(pos);
1929+ } else if (os_strcmp(buf, "eht_oper_chwidth") == 0) {
1930+ conf->eht_oper_chwidth = atoi(pos);
1931+ } else if (os_strcmp(buf, "eht_oper_centr_freq_seg0_idx") == 0) {
1932+ conf->eht_oper_centr_freq_seg0_idx = atoi(pos);
1933+ } else if (os_strcmp(buf, "eht_su_beamformer") == 0) {
1934+ conf->eht_phy_capab.su_beamformer = atoi(pos);
1935+ } else if (os_strcmp(buf, "eht_su_beamformee") == 0) {
1936+ conf->eht_phy_capab.su_beamformee = atoi(pos);
1937+ } else if (os_strcmp(buf, "eht_mu_beamformer") == 0) {
1938+ conf->eht_phy_capab.mu_beamformer = atoi(pos);
1939+ } else if (os_strcmp(buf, "eht_default_pe_duration") == 0) {
1940+ conf->eht_default_pe_duration = atoi(pos);
1941+ } else if (os_strcmp(buf, "punct_bitmap") == 0) {
1942+ if (get_u16(pos, line, &conf->punct_bitmap))
1943+ return 1;
1944+ } else if (os_strcmp(buf, "punct_acs_threshold") == 0) {
1945+ int val = atoi(pos);
1946+
1947+ if (val < 0 || val > 100) {
1948+ wpa_printf(MSG_ERROR,
1949+ "Line %d: punct_acs_threshold must be between 0 and 100",
1950+ line);
1951+ return 1;
1952+ }
1953+ conf->punct_acs_threshold = val;
1954+ } else if (os_strcmp(buf, "mld_ap") == 0) {
1955+ bss->mld_ap = !!atoi(pos);
1956+ } else if (os_strcmp(buf, "mld_addr") == 0) {
1957+ if (hwaddr_aton(pos, bss->mld_addr)) {
1958+ wpa_printf(MSG_ERROR, "Line %d: Invalid mld_addr",
1959+ line);
1960+ return 1;
1961+ }
1962+ } else if (os_strcmp(buf, "eht_bw320_offset") == 0) {
1963+ conf->eht_bw320_offset = atoi(pos);
1964+#ifdef CONFIG_TESTING_OPTIONS
1965+ } else if (os_strcmp(buf, "eht_oper_puncturing_override") == 0) {
1966+ if (get_u16(pos, line, &bss->eht_oper_puncturing_override))
1967+ return 1;
1968+ } else if (os_strcmp(buf, "mld_indicate_disabled") == 0) {
1969+ bss->mld_indicate_disabled = atoi(pos);
1970+#endif /* CONFIG_TESTING_OPTIONS */
1971+#endif /* CONFIG_IEEE80211BE */
1972 } else {
1973 wpa_printf(MSG_ERROR,
1974 "Line %d: unknown configuration item '%s'",
1975diff --git a/hostapd/config_file.h b/hostapd/config_file.h
1976index 9830f5a..9ef6ac8 100644
1977--- a/hostapd/config_file.h
1978+++ b/hostapd/config_file.h
1979@@ -10,13 +10,10 @@
1980 #define CONFIG_FILE_H
1981
1982 struct hostapd_config * hostapd_config_read(const char *fname);
1983+int hostapd_config_read_rxkh_file(struct hostapd_bss_config *conf,
1984+ const char *fname);
1985 int hostapd_set_iface(struct hostapd_config *conf,
1986 struct hostapd_bss_config *bss, const char *field,
1987 char *value);
1988-int hostapd_acl_comp(const void *a, const void *b);
1989-int hostapd_add_acl_maclist(struct mac_acl_entry **acl, int *num,
1990- int vlan_id, const u8 *addr);
1991-void hostapd_remove_acl_mac(struct mac_acl_entry **acl, int *num,
1992- const u8 *addr);
1993
1994 #endif /* CONFIG_FILE_H */
1995diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
1996index 86adf18..39b9ef5 100644
1997--- a/hostapd/ctrl_iface.c
1998+++ b/hostapd/ctrl_iface.c
1999@@ -38,6 +38,8 @@
2000 #endif /* CONFIG_DPP */
2001 #include "common/wpa_ctrl.h"
2002 #include "common/ptksa_cache.h"
2003+#include "common/hw_features_common.h"
2004+#include "common/nan_de.h"
2005 #include "crypto/tls.h"
2006 #include "drivers/driver.h"
2007 #include "eapol_auth/eapol_auth_sm.h"
2008@@ -62,6 +64,7 @@
2009 #include "ap/rrm.h"
2010 #include "ap/dpp_hostapd.h"
2011 #include "ap/dfs.h"
2012+#include "ap/nan_usd_ap.h"
2013 #include "wps/wps_defs.h"
2014 #include "wps/wps.h"
2015 #include "fst/fst_ctrl_iface.h"
2016@@ -772,235 +775,6 @@ static int hostapd_ctrl_iface_send_qos_map_conf(struct hostapd_data *hapd,
2017
2018 #ifdef CONFIG_WNM_AP
2019
2020-static int hostapd_ctrl_iface_disassoc_imminent(struct hostapd_data *hapd,
2021- const char *cmd)
2022-{
2023- u8 addr[ETH_ALEN];
2024- int disassoc_timer;
2025- struct sta_info *sta;
2026-
2027- if (hwaddr_aton(cmd, addr))
2028- return -1;
2029- if (cmd[17] != ' ')
2030- return -1;
2031- disassoc_timer = atoi(cmd + 17);
2032-
2033- sta = ap_get_sta(hapd, addr);
2034- if (sta == NULL) {
2035- wpa_printf(MSG_DEBUG, "Station " MACSTR
2036- " not found for disassociation imminent message",
2037- MAC2STR(addr));
2038- return -1;
2039- }
2040-
2041- return wnm_send_disassoc_imminent(hapd, sta, disassoc_timer);
2042-}
2043-
2044-
2045-static int hostapd_ctrl_iface_ess_disassoc(struct hostapd_data *hapd,
2046- const char *cmd)
2047-{
2048- u8 addr[ETH_ALEN];
2049- const char *url, *timerstr;
2050- int disassoc_timer;
2051- struct sta_info *sta;
2052-
2053- if (hwaddr_aton(cmd, addr))
2054- return -1;
2055-
2056- sta = ap_get_sta(hapd, addr);
2057- if (sta == NULL) {
2058- wpa_printf(MSG_DEBUG, "Station " MACSTR
2059- " not found for ESS disassociation imminent message",
2060- MAC2STR(addr));
2061- return -1;
2062- }
2063-
2064- timerstr = cmd + 17;
2065- if (*timerstr != ' ')
2066- return -1;
2067- timerstr++;
2068- disassoc_timer = atoi(timerstr);
2069- if (disassoc_timer < 0 || disassoc_timer > 65535)
2070- return -1;
2071-
2072- url = os_strchr(timerstr, ' ');
2073- if (url == NULL)
2074- return -1;
2075- url++;
2076-
2077- return wnm_send_ess_disassoc_imminent(hapd, sta, url, disassoc_timer);
2078-}
2079-
2080-
2081-static int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
2082- const char *cmd)
2083-{
2084- u8 addr[ETH_ALEN];
2085- const char *pos, *end;
2086- int disassoc_timer = 0;
2087- struct sta_info *sta;
2088- u8 req_mode = 0, valid_int = 0x01, dialog_token = 0x01;
2089- u8 bss_term_dur[12];
2090- char *url = NULL;
2091- int ret;
2092- u8 nei_rep[1000];
2093- int nei_len;
2094- u8 mbo[10];
2095- size_t mbo_len = 0;
2096-
2097- if (hwaddr_aton(cmd, addr)) {
2098- wpa_printf(MSG_DEBUG, "Invalid STA MAC address");
2099- return -1;
2100- }
2101-
2102- sta = ap_get_sta(hapd, addr);
2103- if (sta == NULL) {
2104- wpa_printf(MSG_DEBUG, "Station " MACSTR
2105- " not found for BSS TM Request message",
2106- MAC2STR(addr));
2107- return -1;
2108- }
2109-
2110- pos = os_strstr(cmd, " disassoc_timer=");
2111- if (pos) {
2112- pos += 16;
2113- disassoc_timer = atoi(pos);
2114- if (disassoc_timer < 0 || disassoc_timer > 65535) {
2115- wpa_printf(MSG_DEBUG, "Invalid disassoc_timer");
2116- return -1;
2117- }
2118- }
2119-
2120- pos = os_strstr(cmd, " valid_int=");
2121- if (pos) {
2122- pos += 11;
2123- valid_int = atoi(pos);
2124- }
2125-
2126- pos = os_strstr(cmd, " dialog_token=");
2127- if (pos) {
2128- pos += 14;
2129- dialog_token = atoi(pos);
2130- }
2131-
2132- pos = os_strstr(cmd, " bss_term=");
2133- if (pos) {
2134- pos += 10;
2135- req_mode |= WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED;
2136- /* TODO: TSF configurable/learnable */
2137- bss_term_dur[0] = 4; /* Subelement ID */
2138- bss_term_dur[1] = 10; /* Length */
2139- os_memset(&bss_term_dur[2], 0, 8);
2140- end = os_strchr(pos, ',');
2141- if (end == NULL) {
2142- wpa_printf(MSG_DEBUG, "Invalid bss_term data");
2143- return -1;
2144- }
2145- end++;
2146- WPA_PUT_LE16(&bss_term_dur[10], atoi(end));
2147- }
2148-
2149- nei_len = ieee802_11_parse_candidate_list(cmd, nei_rep,
2150- sizeof(nei_rep));
2151- if (nei_len < 0)
2152- return -1;
2153-
2154- pos = os_strstr(cmd, " url=");
2155- if (pos) {
2156- size_t len;
2157- pos += 5;
2158- end = os_strchr(pos, ' ');
2159- if (end)
2160- len = end - pos;
2161- else
2162- len = os_strlen(pos);
2163- url = os_malloc(len + 1);
2164- if (url == NULL)
2165- return -1;
2166- os_memcpy(url, pos, len);
2167- url[len] = '\0';
2168- req_mode |= WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT;
2169- }
2170-
2171- if (os_strstr(cmd, " pref=1"))
2172- req_mode |= WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED;
2173- if (os_strstr(cmd, " abridged=1"))
2174- req_mode |= WNM_BSS_TM_REQ_ABRIDGED;
2175- if (os_strstr(cmd, " disassoc_imminent=1"))
2176- req_mode |= WNM_BSS_TM_REQ_DISASSOC_IMMINENT;
2177-
2178-#ifdef CONFIG_MBO
2179- pos = os_strstr(cmd, "mbo=");
2180- if (pos) {
2181- unsigned int mbo_reason, cell_pref, reassoc_delay;
2182- u8 *mbo_pos = mbo;
2183-
2184- ret = sscanf(pos, "mbo=%u:%u:%u", &mbo_reason,
2185- &reassoc_delay, &cell_pref);
2186- if (ret != 3) {
2187- wpa_printf(MSG_DEBUG,
2188- "MBO requires three arguments: mbo=<reason>:<reassoc_delay>:<cell_pref>");
2189- ret = -1;
2190- goto fail;
2191- }
2192-
2193- if (mbo_reason > MBO_TRANSITION_REASON_PREMIUM_AP) {
2194- wpa_printf(MSG_DEBUG,
2195- "Invalid MBO transition reason code %u",
2196- mbo_reason);
2197- ret = -1;
2198- goto fail;
2199- }
2200-
2201- /* Valid values for Cellular preference are: 0, 1, 255 */
2202- if (cell_pref != 0 && cell_pref != 1 && cell_pref != 255) {
2203- wpa_printf(MSG_DEBUG,
2204- "Invalid MBO cellular capability %u",
2205- cell_pref);
2206- ret = -1;
2207- goto fail;
2208- }
2209-
2210- if (reassoc_delay > 65535 ||
2211- (reassoc_delay &&
2212- !(req_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT))) {
2213- wpa_printf(MSG_DEBUG,
2214- "MBO: Assoc retry delay is only valid in disassoc imminent mode");
2215- ret = -1;
2216- goto fail;
2217- }
2218-
2219- *mbo_pos++ = MBO_ATTR_ID_TRANSITION_REASON;
2220- *mbo_pos++ = 1;
2221- *mbo_pos++ = mbo_reason;
2222- *mbo_pos++ = MBO_ATTR_ID_CELL_DATA_PREF;
2223- *mbo_pos++ = 1;
2224- *mbo_pos++ = cell_pref;
2225-
2226- if (reassoc_delay) {
2227- *mbo_pos++ = MBO_ATTR_ID_ASSOC_RETRY_DELAY;
2228- *mbo_pos++ = 2;
2229- WPA_PUT_LE16(mbo_pos, reassoc_delay);
2230- mbo_pos += 2;
2231- }
2232-
2233- mbo_len = mbo_pos - mbo;
2234- }
2235-#endif /* CONFIG_MBO */
2236-
2237- ret = wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer,
2238- valid_int, bss_term_dur, dialog_token, url,
2239- nei_len ? nei_rep : NULL, nei_len,
2240- mbo_len ? mbo : NULL, mbo_len);
2241-#ifdef CONFIG_MBO
2242-fail:
2243-#endif /* CONFIG_MBO */
2244- os_free(url);
2245- return ret;
2246-}
2247-
2248-
2249 static int hostapd_ctrl_iface_coloc_intf_req(struct hostapd_data *hapd,
2250 const char *cmd)
2251 {
2252@@ -1090,6 +864,12 @@ static int hostapd_ctrl_iface_get_key_mgmt(struct hostapd_data *hapd,
2253 return pos - buf;
2254 pos += ret;
2255 }
2256+ if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_SAE_EXT_KEY) {
2257+ ret = os_snprintf(pos, end - pos, "FT-SAE-EXT-KEY ");
2258+ if (os_snprintf_error(end - pos, ret))
2259+ return pos - buf;
2260+ pos += ret;
2261+ }
2262 #endif /* CONFIG_SAE */
2263 #ifdef CONFIG_FILS
2264 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) {
2265@@ -1125,6 +905,12 @@ static int hostapd_ctrl_iface_get_key_mgmt(struct hostapd_data *hapd,
2266 return pos - buf;
2267 pos += ret;
2268 }
2269+ if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY) {
2270+ ret = os_snprintf(pos, end - pos, "SAE-EXT-KEY ");
2271+ if (os_snprintf_error(end - pos, ret))
2272+ return pos - buf;
2273+ pos += ret;
2274+ }
2275 #endif /* CONFIG_SAE */
2276 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
2277 ret = os_snprintf(pos, end - pos, "WPA-EAP-SUITE-B ");
2278@@ -1172,6 +958,14 @@ static int hostapd_ctrl_iface_get_key_mgmt(struct hostapd_data *hapd,
2279 pos += ret;
2280 }
2281 #endif /* CONFIG_DPP */
2282+#ifdef CONFIG_SHA384
2283+ if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA384) {
2284+ ret = os_snprintf(pos, end - pos, "WPA-EAP-SHA384 ");
2285+ if (os_snprintf_error(end - pos, ret))
2286+ return pos - buf;
2287+ pos += ret;
2288+ }
2289+#endif /* CONFIG_SHA384 */
2290
2291 if (pos > buf && *(pos - 1) == ' ') {
2292 *(pos - 1) = '\0';
2293@@ -1200,6 +994,14 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
2294 return pos - buf;
2295 pos += ret;
2296
2297+ if ((hapd->conf->config_id)) {
2298+ ret = os_snprintf(pos, end - pos, "config_id=%s\n",
2299+ hapd->conf->config_id);
2300+ if (os_snprintf_error(end - pos, ret))
2301+ return pos - buf;
2302+ pos += ret;
2303+ }
2304+
2305 #ifdef CONFIG_WPS
2306 ret = os_snprintf(pos, end - pos, "wps_state=%s\n",
2307 hapd->conf->wps_state == 0 ? "disabled" :
2308@@ -1362,43 +1164,6 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
2309 }
2310
2311
2312-static void hostapd_disassoc_accept_mac(struct hostapd_data *hapd)
2313-{
2314- struct sta_info *sta;
2315- struct vlan_description vlan_id;
2316-
2317- if (hapd->conf->macaddr_acl != DENY_UNLESS_ACCEPTED)
2318- return;
2319-
2320- for (sta = hapd->sta_list; sta; sta = sta->next) {
2321- if (!hostapd_maclist_found(hapd->conf->accept_mac,
2322- hapd->conf->num_accept_mac,
2323- sta->addr, &vlan_id) ||
2324- (vlan_id.notempty &&
2325- vlan_compare(&vlan_id, sta->vlan_desc)))
2326- ap_sta_disconnect(hapd, sta, sta->addr,
2327- WLAN_REASON_UNSPECIFIED);
2328- }
2329-}
2330-
2331-
2332-static void hostapd_disassoc_deny_mac(struct hostapd_data *hapd)
2333-{
2334- struct sta_info *sta;
2335- struct vlan_description vlan_id;
2336-
2337- for (sta = hapd->sta_list; sta; sta = sta->next) {
2338- if (hostapd_maclist_found(hapd->conf->deny_mac,
2339- hapd->conf->num_deny_mac, sta->addr,
2340- &vlan_id) &&
2341- (!vlan_id.notempty ||
2342- !vlan_compare(&vlan_id, sta->vlan_desc)))
2343- ap_sta_disconnect(hapd, sta, sta->addr,
2344- WLAN_REASON_UNSPECIFIED);
2345- }
2346-}
2347-
2348-
2349 static int hostapd_ctrl_iface_set_band(struct hostapd_data *hapd,
2350 const char *bands)
2351 {
2352@@ -1519,6 +1284,9 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
2353 } else if (os_strcasecmp(cmd, "dpp_configurator_params") == 0) {
2354 os_free(hapd->dpp_configurator_params);
2355 hapd->dpp_configurator_params = os_strdup(value);
2356+#ifdef CONFIG_DPP2
2357+ dpp_controller_set_params(hapd->iface->interfaces->dpp, value);
2358+#endif /* CONFIG_DPP2 */
2359 } else if (os_strcasecmp(cmd, "dpp_init_max_tries") == 0) {
2360 hapd->dpp_init_max_tries = atoi(value);
2361 } else if (os_strcasecmp(cmd, "dpp_init_retry_time") == 0) {
2362@@ -1541,6 +1309,8 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
2363 hostapd_disassoc_deny_mac(hapd);
2364 } else if (os_strcasecmp(cmd, "accept_mac_file") == 0) {
2365 hostapd_disassoc_accept_mac(hapd);
2366+ } else if (os_strcasecmp(cmd, "ssid") == 0) {
2367+ hostapd_neighbor_sync_own_report(hapd);
2368 } else if (os_strncmp(cmd, "wme_ac_", 7) == 0 ||
2369 os_strncmp(cmd, "wmm_ac_", 7) == 0) {
2370 hapd->parameter_set_count++;
2371@@ -1627,6 +1397,16 @@ static int hostapd_ctrl_iface_reload(struct hostapd_iface *iface)
2372 }
2373
2374
2375+static int hostapd_ctrl_iface_reload_bss(struct hostapd_data *bss)
2376+{
2377+ if (hostapd_reload_bss_only(bss) < 0) {
2378+ wpa_printf(MSG_ERROR, "Reloading of BSS failed");
2379+ return -1;
2380+ }
2381+ return 0;
2382+}
2383+
2384+
2385 static int hostapd_ctrl_iface_disable(struct hostapd_iface *iface)
2386 {
2387 if (hostapd_disable_iface(iface) < 0) {
2388@@ -1655,7 +1435,7 @@ hostapd_ctrl_iface_kick_mismatch_psk_sta_iter(struct hostapd_data *hapd,
2389 pmk_match = PMK_LEN == pmk_len &&
2390 os_memcmp(psk->psk, pmk, pmk_len) == 0;
2391 sta_match = psk->group == 0 &&
2392- os_memcmp(sta->addr, psk->addr, ETH_ALEN) == 0;
2393+ ether_addr_equal(sta->addr, psk->addr);
2394 bss_match = psk->group == 1;
2395
2396 if (pmk_match && (sta_match || bss_match))
2397@@ -1694,6 +1474,79 @@ static int hostapd_ctrl_iface_reload_wpa_psk(struct hostapd_data *hapd)
2398 }
2399
2400
2401+#ifdef CONFIG_IEEE80211R_AP
2402+
2403+static int hostapd_ctrl_iface_get_rxkhs(struct hostapd_data *hapd,
2404+ char *buf, size_t buflen)
2405+{
2406+ int ret, start_pos;
2407+ char *pos, *end;
2408+ struct ft_remote_r0kh *r0kh;
2409+ struct ft_remote_r1kh *r1kh;
2410+ struct hostapd_bss_config *conf = hapd->conf;
2411+
2412+ pos = buf;
2413+ end = buf + buflen;
2414+
2415+ for (r0kh = conf->r0kh_list; r0kh; r0kh=r0kh->next) {
2416+ start_pos = pos - buf;
2417+ ret = os_snprintf(pos, end - pos, "r0kh=" MACSTR " ",
2418+ MAC2STR(r0kh->addr));
2419+ if (os_snprintf_error(end - pos, ret))
2420+ return start_pos;
2421+ pos += ret;
2422+ if (r0kh->id_len + 1 >= (size_t) (end - pos))
2423+ return start_pos;
2424+ os_memcpy(pos, r0kh->id, r0kh->id_len);
2425+ pos += r0kh->id_len;
2426+ *pos++ = ' ';
2427+ pos += wpa_snprintf_hex(pos, end - pos, r0kh->key,
2428+ sizeof(r0kh->key));
2429+ ret = os_snprintf(pos, end - pos, "\n");
2430+ if (os_snprintf_error(end - pos, ret))
2431+ return start_pos;
2432+ pos += ret;
2433+ }
2434+
2435+ for (r1kh = conf->r1kh_list; r1kh; r1kh=r1kh->next) {
2436+ start_pos = pos - buf;
2437+ ret = os_snprintf(pos, end - pos, "r1kh=" MACSTR " " MACSTR " ",
2438+ MAC2STR(r1kh->addr), MAC2STR(r1kh->id));
2439+ if (os_snprintf_error(end - pos, ret))
2440+ return start_pos;
2441+ pos += ret;
2442+ pos += wpa_snprintf_hex(pos, end - pos, r1kh->key,
2443+ sizeof(r1kh->key));
2444+ ret = os_snprintf(pos, end - pos, "\n");
2445+ if (os_snprintf_error(end - pos, ret))
2446+ return start_pos;
2447+ pos += ret;
2448+ }
2449+
2450+ return pos - buf;
2451+}
2452+
2453+
2454+static int hostapd_ctrl_iface_reload_rxkhs(struct hostapd_data *hapd)
2455+{
2456+ struct hostapd_bss_config *conf = hapd->conf;
2457+ int err;
2458+
2459+ hostapd_config_clear_rxkhs(conf);
2460+
2461+ err = hostapd_config_read_rxkh_file(conf, conf->rxkh_file);
2462+ if (err < 0) {
2463+ wpa_printf(MSG_ERROR, "Reloading RxKHs failed: %d",
2464+ err);
2465+ return -1;
2466+ }
2467+
2468+ return 0;
2469+}
2470+
2471+#endif /* CONFIG_IEEE80211R_AP */
2472+
2473+
2474 #ifdef CONFIG_TESTING_OPTIONS
2475
2476 static int hostapd_ctrl_iface_radar(struct hostapd_data *hapd, char *cmd)
2477@@ -1945,7 +1798,7 @@ static int hostapd_ctrl_iface_eapol_rx(struct hostapd_data *hapd, char *cmd)
2478 return -1;
2479 }
2480
2481- ieee802_1x_receive(hapd, src, buf, len);
2482+ ieee802_1x_receive(hapd, src, buf, len, FRAME_ENCRYPTION_UNKNOWN);
2483 os_free(buf);
2484
2485 return 0;
2486@@ -2068,6 +1921,7 @@ static int hostapd_ctrl_iface_data_test_config(struct hostapd_data *hapd,
2487 int enabled = atoi(cmd);
2488 char *pos;
2489 const char *ifname;
2490+ const u8 *addr = hapd->own_addr;
2491
2492 if (!enabled) {
2493 if (hapd->l2_test) {
2494@@ -2088,7 +1942,11 @@ static int hostapd_ctrl_iface_data_test_config(struct hostapd_data *hapd,
2495 else
2496 ifname = hapd->conf->iface;
2497
2498- hapd->l2_test = l2_packet_init(ifname, hapd->own_addr,
2499+#ifdef CONFIG_IEEE80211BE
2500+ if (hapd->conf->mld_ap)
2501+ addr = hapd->mld->mld_addr;
2502+#endif /* CONFIG_IEEE80211BE */
2503+ hapd->l2_test = l2_packet_init(ifname, addr,
2504 ETHERTYPE_IP, hostapd_data_test_rx,
2505 hapd, 1);
2506 if (hapd->l2_test == NULL)
2507@@ -2225,74 +2083,6 @@ done:
2508 }
2509
2510
2511-static int hostapd_ctrl_test_alloc_fail(struct hostapd_data *hapd, char *cmd)
2512-{
2513-#ifdef WPA_TRACE_BFD
2514- char *pos;
2515-
2516- wpa_trace_fail_after = atoi(cmd);
2517- pos = os_strchr(cmd, ':');
2518- if (pos) {
2519- pos++;
2520- os_strlcpy(wpa_trace_fail_func, pos,
2521- sizeof(wpa_trace_fail_func));
2522- } else {
2523- wpa_trace_fail_after = 0;
2524- }
2525-
2526- return 0;
2527-#else /* WPA_TRACE_BFD */
2528- return -1;
2529-#endif /* WPA_TRACE_BFD */
2530-}
2531-
2532-
2533-static int hostapd_ctrl_get_alloc_fail(struct hostapd_data *hapd,
2534- char *buf, size_t buflen)
2535-{
2536-#ifdef WPA_TRACE_BFD
2537- return os_snprintf(buf, buflen, "%u:%s", wpa_trace_fail_after,
2538- wpa_trace_fail_func);
2539-#else /* WPA_TRACE_BFD */
2540- return -1;
2541-#endif /* WPA_TRACE_BFD */
2542-}
2543-
2544-
2545-static int hostapd_ctrl_test_fail(struct hostapd_data *hapd, char *cmd)
2546-{
2547-#ifdef WPA_TRACE_BFD
2548- char *pos;
2549-
2550- wpa_trace_test_fail_after = atoi(cmd);
2551- pos = os_strchr(cmd, ':');
2552- if (pos) {
2553- pos++;
2554- os_strlcpy(wpa_trace_test_fail_func, pos,
2555- sizeof(wpa_trace_test_fail_func));
2556- } else {
2557- wpa_trace_test_fail_after = 0;
2558- }
2559-
2560- return 0;
2561-#else /* WPA_TRACE_BFD */
2562- return -1;
2563-#endif /* WPA_TRACE_BFD */
2564-}
2565-
2566-
2567-static int hostapd_ctrl_get_fail(struct hostapd_data *hapd,
2568- char *buf, size_t buflen)
2569-{
2570-#ifdef WPA_TRACE_BFD
2571- return os_snprintf(buf, buflen, "%u:%s", wpa_trace_test_fail_after,
2572- wpa_trace_test_fail_func);
2573-#else /* WPA_TRACE_BFD */
2574- return -1;
2575-#endif /* WPA_TRACE_BFD */
2576-}
2577-
2578-
2579 static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)
2580 {
2581 struct sta_info *sta;
2582@@ -2664,8 +2454,46 @@ static int hostapd_ctrl_register_frame(struct hostapd_data *hapd,
2583
2584
2585 #ifdef NEED_AP_MLME
2586-static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
2587+static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params,
2588+ u16 punct_bitmap)
2589 {
2590+ u32 start_freq;
2591+
2592+ if (is_6ghz_freq(params->freq)) {
2593+ const int bw_idx[] = { 20, 40, 80, 160, 320 };
2594+ int idx, bw;
2595+
2596+ /* The 6 GHz band requires HE to be enabled. */
2597+ params->he_enabled = 1;
2598+
2599+ if (params->center_freq1) {
2600+ if (params->freq == 5935)
2601+ idx = (params->center_freq1 - 5925) / 5;
2602+ else
2603+ idx = (params->center_freq1 - 5950) / 5;
2604+
2605+ bw = center_idx_to_bw_6ghz(idx);
2606+ if (bw < 0 || bw > (int) ARRAY_SIZE(bw_idx) ||
2607+ bw_idx[bw] != params->bandwidth)
2608+ return -1;
2609+ }
2610+ } else { /* Non-6 GHz channel */
2611+ /* An EHT STA is also an HE STA as defined in
2612+ * IEEE P802.11be/D5.0, 4.3.16a. */
2613+ if (params->he_enabled || params->eht_enabled) {
2614+ params->he_enabled = 1;
2615+ /* An HE STA is also a VHT STA if operating in the 5 GHz
2616+ * band and an HE STA is also an HT STA in the 2.4 GHz
2617+ * band as defined in IEEE Std 802.11ax-2021, 4.3.15a.
2618+ * A VHT STA is an HT STA as defined in IEEE
2619+ * Std 802.11, 4.3.15. */
2620+ if (IS_5GHZ(params->freq))
2621+ params->vht_enabled = 1;
2622+
2623+ params->ht_enabled = 1;
2624+ }
2625+ }
2626+
2627 switch (params->bandwidth) {
2628 case 0:
2629 /* bandwidth not specified: use 20 MHz by default */
2630@@ -2677,11 +2505,17 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
2631
2632 if (params->center_freq2 || params->sec_channel_offset)
2633 return -1;
2634- break;
2635+
2636+ if (punct_bitmap)
2637+ return -1;
2638+ break;
2639 case 40:
2640 if (params->center_freq2 || !params->sec_channel_offset)
2641 return -1;
2642
2643+ if (punct_bitmap)
2644+ return -1;
2645+
2646 if (!params->center_freq1)
2647 break;
2648 switch (params->sec_channel_offset) {
2649@@ -2716,6 +2550,9 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
2650 return -1;
2651 }
2652
2653+ if (params->center_freq2 && punct_bitmap)
2654+ return -1;
2655+
2656 /* Adjacent and overlapped are not allowed for 80+80 */
2657 if (params->center_freq2 &&
2658 params->center_freq1 - params->center_freq2 <= 80 &&
2659@@ -2746,10 +2583,63 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
2660 return -1;
2661 }
2662 break;
2663+ case 320:
2664+ if (!params->center_freq1 || params->center_freq2 ||
2665+ !params->sec_channel_offset)
2666+ return -1;
2667+
2668+ switch (params->sec_channel_offset) {
2669+ case 1:
2670+ if (params->freq + 150 != params->center_freq1 &&
2671+ params->freq + 110 != params->center_freq1 &&
2672+ params->freq + 70 != params->center_freq1 &&
2673+ params->freq + 30 != params->center_freq1 &&
2674+ params->freq - 10 != params->center_freq1 &&
2675+ params->freq - 50 != params->center_freq1 &&
2676+ params->freq - 90 != params->center_freq1 &&
2677+ params->freq - 130 != params->center_freq1)
2678+ return -1;
2679+ break;
2680+ case -1:
2681+ if (params->freq + 130 != params->center_freq1 &&
2682+ params->freq + 90 != params->center_freq1 &&
2683+ params->freq + 50 != params->center_freq1 &&
2684+ params->freq + 10 != params->center_freq1 &&
2685+ params->freq - 30 != params->center_freq1 &&
2686+ params->freq - 70 != params->center_freq1 &&
2687+ params->freq - 110 != params->center_freq1 &&
2688+ params->freq - 150 != params->center_freq1)
2689+ return -1;
2690+ break;
2691+ }
2692+ break;
2693 default:
2694 return -1;
2695 }
2696
2697+ if (!punct_bitmap)
2698+ return 0;
2699+
2700+ if (!params->eht_enabled) {
2701+ wpa_printf(MSG_ERROR,
2702+ "Preamble puncturing supported only in EHT");
2703+ return -1;
2704+ }
2705+
2706+ if (params->freq >= 2412 && params->freq <= 2484) {
2707+ wpa_printf(MSG_ERROR,
2708+ "Preamble puncturing is not supported in 2.4 GHz");
2709+ return -1;
2710+ }
2711+
2712+ start_freq = params->center_freq1 - (params->bandwidth / 2);
2713+ if (!is_punct_bitmap_valid(params->bandwidth,
2714+ (params->freq - start_freq) / 20,
2715+ punct_bitmap)) {
2716+ wpa_printf(MSG_ERROR, "Invalid preamble puncturing bitmap");
2717+ return -1;
2718+ }
2719+
2720 return 0;
2721 }
2722 #endif /* NEED_AP_MLME */
2723@@ -2765,12 +2655,21 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
2724 unsigned int i;
2725 int bandwidth;
2726 u8 chan;
2727+ unsigned int num_err = 0;
2728+ int err = 0;
2729
2730 ret = hostapd_parse_csa_settings(pos, &settings);
2731 if (ret)
2732 return ret;
2733
2734- ret = hostapd_ctrl_check_freq_params(&settings.freq_params);
2735+ settings.link_id = -1;
2736+#ifdef CONFIG_IEEE80211BE
2737+ if (iface->num_bss && iface->bss[0]->conf->mld_ap)
2738+ settings.link_id = iface->bss[0]->mld_link_id;
2739+#endif /* CONFIG_IEEE80211BE */
2740+
2741+ ret = hostapd_ctrl_check_freq_params(&settings.freq_params,
2742+ settings.punct_bitmap);
2743 if (ret) {
2744 wpa_printf(MSG_INFO,
2745 "chanswitch: invalid frequency settings provided");
2746@@ -2790,6 +2689,9 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
2747 case 160:
2748 bandwidth = CHAN_WIDTH_160;
2749 break;
2750+ case 320:
2751+ bandwidth = CHAN_WIDTH_320;
2752+ break;
2753 default:
2754 bandwidth = CHAN_WIDTH_20;
2755 break;
2756@@ -2828,29 +2730,271 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
2757 settings.freq_params.center_freq1);
2758
2759 /* Perform CAC and switch channel */
2760+ iface->is_ch_switch_dfs = true;
2761 hostapd_switch_channel_fallback(iface, &settings.freq_params);
2762 return 0;
2763 }
2764
2765 for (i = 0; i < iface->num_bss; i++) {
2766
2767- /* Save CHAN_SWITCH VHT and HE config */
2768+ /* Save CHAN_SWITCH VHT, HE, and EHT config */
2769 hostapd_chan_switch_config(iface->bss[i],
2770 &settings.freq_params);
2771
2772- ret = hostapd_switch_channel(iface->bss[i], &settings);
2773- if (ret) {
2774- /* FIX: What do we do if CSA fails in the middle of
2775- * submitting multi-BSS CSA requests? */
2776- return ret;
2777+ err = hostapd_switch_channel(iface->bss[i], &settings);
2778+ if (err) {
2779+ ret = err;
2780+ num_err++;
2781 }
2782 }
2783
2784+ return (iface->num_bss == num_err) ? ret : 0;
2785+#else /* NEED_AP_MLME */
2786+ return -1;
2787+#endif /* NEED_AP_MLME */
2788+}
2789+
2790+
2791+#ifdef CONFIG_IEEE80211AX
2792+static int hostapd_ctrl_iface_color_change(struct hostapd_iface *iface,
2793+ const char *pos)
2794+{
2795+#ifdef NEED_AP_MLME
2796+ struct cca_settings settings;
2797+ struct hostapd_data *hapd = iface->bss[0];
2798+ int ret, color;
2799+ unsigned int i;
2800+ char *end;
2801+
2802+ os_memset(&settings, 0, sizeof(settings));
2803+
2804+ color = strtol(pos, &end, 10);
2805+ if (pos == end || color < 0 || color > 63) {
2806+ wpa_printf(MSG_ERROR, "color_change: Invalid color provided");
2807+ return -1;
2808+ }
2809+
2810+ /* Color value is expected to be [1-63]. If 0 comes, assumption is this
2811+ * is to disable the color. In this case no need to do CCA, just
2812+ * changing Beacon frames is sufficient. */
2813+ if (color == 0) {
2814+ if (iface->conf->he_op.he_bss_color_disabled) {
2815+ wpa_printf(MSG_ERROR,
2816+ "color_change: Color is already disabled");
2817+ return -1;
2818+ }
2819+
2820+ iface->conf->he_op.he_bss_color_disabled = 1;
2821+
2822+ for (i = 0; i < iface->num_bss; i++)
2823+ ieee802_11_set_beacon(iface->bss[i]);
2824+
2825+ return 0;
2826+ }
2827+
2828+ if (color == iface->conf->he_op.he_bss_color) {
2829+ if (!iface->conf->he_op.he_bss_color_disabled) {
2830+ wpa_printf(MSG_ERROR,
2831+ "color_change: Provided color is already set");
2832+ return -1;
2833+ }
2834+
2835+ iface->conf->he_op.he_bss_color_disabled = 0;
2836+
2837+ for (i = 0; i < iface->num_bss; i++)
2838+ ieee802_11_set_beacon(iface->bss[i]);
2839+
2840+ return 0;
2841+ }
2842+
2843+ if (hapd->cca_in_progress) {
2844+ wpa_printf(MSG_ERROR,
2845+ "color_change: CCA is already in progress");
2846+ return -1;
2847+ }
2848+
2849+ iface->conf->he_op.he_bss_color_disabled = 0;
2850+
2851+ for (i = 0; i < iface->num_bss; i++) {
2852+ struct hostapd_data *bss = iface->bss[i];
2853+
2854+ hostapd_cleanup_cca_params(bss);
2855+
2856+ bss->cca_color = color;
2857+ bss->cca_count = 10;
2858+
2859+ if (hostapd_fill_cca_settings(bss, &settings)) {
2860+ wpa_printf(MSG_DEBUG,
2861+ "color_change: Filling CCA settings failed for color: %d\n",
2862+ color);
2863+ hostapd_cleanup_cca_params(bss);
2864+ continue;
2865+ }
2866+
2867+ wpa_printf(MSG_DEBUG, "Setting user selected color: %d", color);
2868+ ret = hostapd_drv_switch_color(bss, &settings);
2869+ if (ret)
2870+ hostapd_cleanup_cca_params(bss);
2871+
2872+ free_beacon_data(&settings.beacon_cca);
2873+ free_beacon_data(&settings.beacon_after);
2874+ }
2875+
2876 return 0;
2877 #else /* NEED_AP_MLME */
2878 return -1;
2879 #endif /* NEED_AP_MLME */
2880 }
2881+#endif /* CONFIG_IEEE80211AX */
2882+
2883+
2884+static u8 hostapd_maxnss(struct hostapd_data *hapd, struct sta_info *sta)
2885+{
2886+ u8 *mcs_set = NULL;
2887+ u16 mcs_map;
2888+ u8 ht_rx_nss = 0;
2889+ u8 vht_rx_nss = 1;
2890+ u8 mcs;
2891+ bool ht_supported = false;
2892+ bool vht_supported = false;
2893+ int i;
2894+
2895+ if (sta->ht_capabilities && (sta->flags & WLAN_STA_HT)) {
2896+ mcs_set = sta->ht_capabilities->supported_mcs_set;
2897+ ht_supported = true;
2898+ }
2899+
2900+ if (sta->vht_capabilities && (sta->flags & WLAN_STA_VHT)) {
2901+ mcs_map = le_to_host16(
2902+ sta->vht_capabilities->vht_supported_mcs_set.rx_map);
2903+ vht_supported = true;
2904+ }
2905+
2906+ if (ht_supported && mcs_set) {
2907+ if (mcs_set[0])
2908+ ht_rx_nss++;
2909+ if (mcs_set[1])
2910+ ht_rx_nss++;
2911+ if (mcs_set[2])
2912+ ht_rx_nss++;
2913+ if (mcs_set[3])
2914+ ht_rx_nss++;
2915+ }
2916+ if (vht_supported) {
2917+ for (i = 7; i >= 0; i--) {
2918+ mcs = (mcs_map >> (2 * i)) & 0x03;
2919+ if (mcs != 0x03) {
2920+ vht_rx_nss = i + 1;
2921+ break;
2922+ }
2923+ }
2924+ }
2925+
2926+ return ht_rx_nss > vht_rx_nss ? ht_rx_nss : vht_rx_nss;
2927+}
2928+
2929+
2930+static char hostapd_ctrl_iface_notify_cw_htaction(struct hostapd_data *hapd,
2931+ const u8 *addr, u8 width)
2932+{
2933+ u8 buf[3];
2934+ char ret;
2935+
2936+ width = width >= 1 ? 1 : 0;
2937+
2938+ buf[0] = WLAN_ACTION_HT;
2939+ buf[1] = WLAN_HT_ACTION_NOTIFY_CHANWIDTH;
2940+ buf[2] = width;
2941+
2942+ ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr,
2943+ buf, sizeof(buf));
2944+ if (ret)
2945+ wpa_printf(MSG_DEBUG,
2946+ "Failed to send Notify Channel Width frame to "
2947+ MACSTR, MAC2STR(addr));
2948+
2949+ return ret;
2950+}
2951+
2952+
2953+static char hostapd_ctrl_iface_notify_cw_vhtaction(struct hostapd_data *hapd,
2954+ const u8 *addr, u8 width)
2955+{
2956+ u8 buf[3];
2957+ char ret;
2958+
2959+ buf[0] = WLAN_ACTION_VHT;
2960+ buf[1] = WLAN_VHT_ACTION_OPMODE_NOTIF;
2961+ buf[2] = width;
2962+
2963+ ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr,
2964+ buf, sizeof(buf));
2965+ if (ret)
2966+ wpa_printf(MSG_DEBUG,
2967+ "Failed to send Opeating Mode Notification frame to "
2968+ MACSTR, MAC2STR(addr));
2969+
2970+ return ret;
2971+}
2972+
2973+
2974+static char hostapd_ctrl_iface_notify_cw_change(struct hostapd_data *hapd,
2975+ const char *cmd)
2976+{
2977+ u8 cw, operating_mode = 0, nss;
2978+ struct sta_info *sta;
2979+ enum hostapd_hw_mode hw_mode;
2980+
2981+ if (is_6ghz_freq(hapd->iface->freq)) {
2982+ wpa_printf(MSG_ERROR, "20/40 BSS coex not supported in 6 GHz");
2983+ return -1;
2984+ }
2985+
2986+ cw = atoi(cmd);
2987+ hw_mode = hapd->iface->current_mode->mode;
2988+ if ((hw_mode == HOSTAPD_MODE_IEEE80211G ||
2989+ hw_mode == HOSTAPD_MODE_IEEE80211B) &&
2990+ !(cw == 0 || cw == 1)) {
2991+ wpa_printf(MSG_ERROR,
2992+ "Channel width should be either 20 MHz or 40 MHz for 2.4 GHz band");
2993+ return -1;
2994+ }
2995+
2996+ switch (cw) {
2997+ case 0:
2998+ operating_mode = 0;
2999+ break;
3000+ case 1:
3001+ operating_mode = VHT_OPMODE_CHANNEL_40MHZ;
3002+ break;
3003+ case 2:
3004+ operating_mode = VHT_OPMODE_CHANNEL_80MHZ;
3005+ break;
3006+ case 3:
3007+ operating_mode = VHT_OPMODE_CHANNEL_160MHZ;
3008+ break;
3009+ default:
3010+ wpa_printf(MSG_ERROR, "Channel width should be between 0 to 3");
3011+ return -1;
3012+ }
3013+
3014+ for (sta = hapd->sta_list; sta; sta = sta->next) {
3015+ if ((sta->flags & WLAN_STA_VHT) && sta->vht_capabilities) {
3016+ nss = hostapd_maxnss(hapd, sta) - 1;
3017+ hostapd_ctrl_iface_notify_cw_vhtaction(hapd, sta->addr,
3018+ operating_mode |
3019+ (u8) (nss << 4));
3020+ continue;
3021+ }
3022+
3023+ if ((sta->flags & (WLAN_STA_HT | WLAN_STA_VHT)) ==
3024+ WLAN_STA_HT && sta->ht_capabilities)
3025+ hostapd_ctrl_iface_notify_cw_htaction(hapd, sta->addr,
3026+ cw);
3027+ }
3028+
3029+ return 0;
3030+}
3031
3032
3033 static int hostapd_ctrl_iface_mib(struct hostapd_data *hapd, char *reply,
3034@@ -3171,6 +3315,26 @@ static int hostapd_ctrl_iface_req_beacon(struct hostapd_data *hapd,
3035 }
3036
3037
3038+static int hostapd_ctrl_iface_req_link_measurement(struct hostapd_data *hapd,
3039+ const char *cmd, char *reply,
3040+ size_t reply_size)
3041+{
3042+ u8 addr[ETH_ALEN];
3043+ int ret;
3044+
3045+ if (hwaddr_aton(cmd, addr)) {
3046+ wpa_printf(MSG_ERROR,
3047+ "CTRL: REQ_LINK_MEASUREMENT: Invalid MAC address");
3048+ return -1;
3049+ }
3050+
3051+ ret = hostapd_send_link_measurement_req(hapd, addr);
3052+ if (ret >= 0)
3053+ ret = os_snprintf(reply, reply_size, "%d", ret);
3054+ return ret;
3055+}
3056+
3057+
3058 static int hostapd_ctrl_iface_show_neighbor(struct hostapd_data *hapd,
3059 char *buf, size_t buflen)
3060 {
3061@@ -3379,80 +3543,6 @@ static int hostapd_ctrl_driver_flags2(struct hostapd_iface *iface, char *buf,
3062 }
3063
3064
3065-static int hostapd_ctrl_iface_acl_del_mac(struct mac_acl_entry **acl, int *num,
3066- const char *txtaddr)
3067-{
3068- u8 addr[ETH_ALEN];
3069- struct vlan_description vlan_id;
3070-
3071- if (!(*num))
3072- return 0;
3073-
3074- if (hwaddr_aton(txtaddr, addr))
3075- return -1;
3076-
3077- if (hostapd_maclist_found(*acl, *num, addr, &vlan_id))
3078- hostapd_remove_acl_mac(acl, num, addr);
3079-
3080- return 0;
3081-}
3082-
3083-
3084-static void hostapd_ctrl_iface_acl_clear_list(struct mac_acl_entry **acl,
3085- int *num)
3086-{
3087- while (*num)
3088- hostapd_remove_acl_mac(acl, num, (*acl)[0].addr);
3089-}
3090-
3091-
3092-static int hostapd_ctrl_iface_acl_show_mac(struct mac_acl_entry *acl, int num,
3093- char *buf, size_t buflen)
3094-{
3095- int i = 0, len = 0, ret = 0;
3096-
3097- if (!acl)
3098- return 0;
3099-
3100- while (i < num) {
3101- ret = os_snprintf(buf + len, buflen - len,
3102- MACSTR " VLAN_ID=%d\n",
3103- MAC2STR(acl[i].addr),
3104- acl[i].vlan_id.untagged);
3105- if (ret < 0 || (size_t) ret >= buflen - len)
3106- return len;
3107- i++;
3108- len += ret;
3109- }
3110- return len;
3111-}
3112-
3113-
3114-static int hostapd_ctrl_iface_acl_add_mac(struct mac_acl_entry **acl, int *num,
3115- const char *cmd)
3116-{
3117- u8 addr[ETH_ALEN];
3118- struct vlan_description vlan_id;
3119- int ret = 0, vlanid = 0;
3120- const char *pos;
3121-
3122- if (hwaddr_aton(cmd, addr))
3123- return -1;
3124-
3125- pos = os_strstr(cmd, "VLAN_ID=");
3126- if (pos)
3127- vlanid = atoi(pos + 8);
3128-
3129- if (!hostapd_maclist_found(*acl, *num, addr, &vlan_id)) {
3130- ret = hostapd_add_acl_maclist(acl, num, vlanid, addr);
3131- if (ret != -1 && *acl)
3132- qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp);
3133- }
3134-
3135- return ret < 0 ? -1 : 0;
3136-}
3137-
3138-
3139 static int hostapd_ctrl_iface_get_capability(struct hostapd_data *hapd,
3140 const char *field, char *buf,
3141 size_t buflen)
3142@@ -3500,6 +3590,395 @@ static int hostapd_ctrl_iface_driver_cmd(struct hostapd_data *hapd, char *cmd,
3143 #endif /* ANDROID */
3144
3145
3146+#ifdef CONFIG_IEEE80211BE
3147+
3148+static int hostapd_ctrl_iface_enable_mld(struct hostapd_iface *iface)
3149+{
3150+ unsigned int i;
3151+
3152+ if (!iface || !iface->bss[0]->conf->mld_ap) {
3153+ wpa_printf(MSG_ERROR,
3154+ "Trying to enable AP MLD on an interface that is not affiliated with an AP MLD");
3155+ return -1;
3156+ }
3157+
3158+ for (i = 0; i < iface->interfaces->count; ++i) {
3159+ struct hostapd_iface *h_iface = iface->interfaces->iface[i];
3160+ struct hostapd_data *h_hapd = h_iface->bss[0];
3161+
3162+ if (!hostapd_is_ml_partner(h_hapd, iface->bss[0]))
3163+ continue;
3164+
3165+ if (hostapd_enable_iface(h_iface)) {
3166+ wpa_printf(MSG_ERROR, "Enabling of AP MLD failed");
3167+ return -1;
3168+ }
3169+ }
3170+ return 0;
3171+}
3172+
3173+
3174+static void hostapd_disable_iface_bss(struct hostapd_iface *iface)
3175+{
3176+ unsigned int i;
3177+
3178+ for (i = 0; i < iface->num_bss; i++)
3179+ hostapd_bss_deinit_no_free(iface->bss[i]);
3180+}
3181+
3182+
3183+static int hostapd_ctrl_iface_disable_mld(struct hostapd_iface *iface)
3184+{
3185+ unsigned int i;
3186+
3187+ if (!iface || !iface->bss[0]->conf->mld_ap) {
3188+ wpa_printf(MSG_ERROR,
3189+ "Trying to disable AP MLD on an interface that is not affiliated with an AP MLD.");
3190+ return -1;
3191+ }
3192+
3193+ /* First, disable BSSs before stopping beaconing and doing driver
3194+ * deinit so that the broadcast Deauthentication frames go out. */
3195+
3196+ for (i = 0; i < iface->interfaces->count; ++i) {
3197+ struct hostapd_iface *h_iface = iface->interfaces->iface[i];
3198+ struct hostapd_data *h_hapd = h_iface->bss[0];
3199+
3200+ if (!hostapd_is_ml_partner(h_hapd, iface->bss[0]))
3201+ continue;
3202+
3203+ hostapd_disable_iface_bss(iface);
3204+ }
3205+
3206+ /* Then, fully disable interfaces */
3207+ for (i = 0; i < iface->interfaces->count; ++i) {
3208+ struct hostapd_iface *h_iface = iface->interfaces->iface[i];
3209+ struct hostapd_data *h_hapd = h_iface->bss[0];
3210+
3211+ if (!hostapd_is_ml_partner(h_hapd, iface->bss[0]))
3212+ continue;
3213+
3214+ if (hostapd_disable_iface(h_iface)) {
3215+ wpa_printf(MSG_ERROR, "Disabling AP MLD failed");
3216+ return -1;
3217+ }
3218+ }
3219+
3220+ return 0;
3221+}
3222+
3223+
3224+#ifdef CONFIG_TESTING_OPTIONS
3225+static int hostapd_ctrl_iface_link_remove(struct hostapd_data *hapd, char *cmd,
3226+ char *buf, size_t buflen)
3227+{
3228+ int ret;
3229+ u32 count = atoi(cmd);
3230+
3231+ if (!count)
3232+ count = 1;
3233+
3234+ ret = hostapd_link_remove(hapd, count);
3235+ if (ret == 0) {
3236+ ret = os_snprintf(buf, buflen, "%s\n", "OK");
3237+ if (os_snprintf_error(buflen, ret))
3238+ ret = -1;
3239+ else
3240+ ret = 0;
3241+ }
3242+
3243+ return ret;
3244+}
3245+#endif /* CONFIG_TESTING_OPTIONS */
3246+#endif /* CONFIG_IEEE80211BE */
3247+
3248+
3249+#ifdef CONFIG_NAN_USD
3250+
3251+static int hostapd_ctrl_nan_publish(struct hostapd_data *hapd, char *cmd,
3252+ char *buf, size_t buflen)
3253+{
3254+ char *token, *context = NULL;
3255+ int publish_id;
3256+ struct nan_publish_params params;
3257+ const char *service_name = NULL;
3258+ struct wpabuf *ssi = NULL;
3259+ int ret = -1;
3260+ enum nan_service_protocol_type srv_proto_type = 0;
3261+
3262+ os_memset(&params, 0, sizeof(params));
3263+ /* USD shall use both solicited and unsolicited transmissions */
3264+ params.unsolicited = true;
3265+ params.solicited = true;
3266+ /* USD shall require FSD without GAS */
3267+ params.fsd = true;
3268+
3269+ while ((token = str_token(cmd, " ", &context))) {
3270+ if (os_strncmp(token, "service_name=", 13) == 0) {
3271+ service_name = token + 13;
3272+ continue;
3273+ }
3274+
3275+ if (os_strncmp(token, "ttl=", 4) == 0) {
3276+ params.ttl = atoi(token + 4);
3277+ continue;
3278+ }
3279+
3280+ if (os_strncmp(token, "srv_proto_type=", 15) == 0) {
3281+ srv_proto_type = atoi(token + 15);
3282+ continue;
3283+ }
3284+
3285+ if (os_strncmp(token, "ssi=", 4) == 0) {
3286+ if (ssi)
3287+ goto fail;
3288+ ssi = wpabuf_parse_bin(token + 4);
3289+ if (!ssi)
3290+ goto fail;
3291+ continue;
3292+ }
3293+
3294+ if (os_strcmp(token, "solicited=0") == 0) {
3295+ params.solicited = false;
3296+ continue;
3297+ }
3298+
3299+ if (os_strcmp(token, "unsolicited=0") == 0) {
3300+ params.unsolicited = false;
3301+ continue;
3302+ }
3303+
3304+ if (os_strcmp(token, "fsd=0") == 0) {
3305+ params.fsd = false;
3306+ continue;
3307+ }
3308+
3309+ wpa_printf(MSG_INFO, "CTRL: Invalid NAN_PUBLISH parameter: %s",
3310+ token);
3311+ goto fail;
3312+ }
3313+
3314+ publish_id = hostapd_nan_usd_publish(hapd, service_name, srv_proto_type,
3315+ ssi, &params);
3316+ if (publish_id > 0)
3317+ ret = os_snprintf(buf, buflen, "%d", publish_id);
3318+fail:
3319+ wpabuf_free(ssi);
3320+ return ret;
3321+}
3322+
3323+
3324+static int hostapd_ctrl_nan_cancel_publish(struct hostapd_data *hapd,
3325+ char *cmd)
3326+{
3327+ char *token, *context = NULL;
3328+ int publish_id = 0;
3329+
3330+ while ((token = str_token(cmd, " ", &context))) {
3331+ if (sscanf(token, "publish_id=%i", &publish_id) == 1)
3332+ continue;
3333+ wpa_printf(MSG_INFO,
3334+ "CTRL: Invalid NAN_CANCEL_PUBLISH parameter: %s",
3335+ token);
3336+ return -1;
3337+ }
3338+
3339+ if (publish_id <= 0) {
3340+ wpa_printf(MSG_INFO,
3341+ "CTRL: Invalid or missing NAN_CANCEL_PUBLISH publish_id");
3342+ return -1;
3343+ }
3344+
3345+ hostapd_nan_usd_cancel_publish(hapd, publish_id);
3346+ return 0;
3347+}
3348+
3349+
3350+static int hostapd_ctrl_nan_update_publish(struct hostapd_data *hapd,
3351+ char *cmd)
3352+{
3353+ char *token, *context = NULL;
3354+ int publish_id = 0;
3355+ struct wpabuf *ssi = NULL;
3356+ int ret = -1;
3357+
3358+ while ((token = str_token(cmd, " ", &context))) {
3359+ if (sscanf(token, "publish_id=%i", &publish_id) == 1)
3360+ continue;
3361+ if (os_strncmp(token, "ssi=", 4) == 0) {
3362+ if (ssi)
3363+ goto fail;
3364+ ssi = wpabuf_parse_bin(token + 4);
3365+ if (!ssi)
3366+ goto fail;
3367+ continue;
3368+ }
3369+ wpa_printf(MSG_INFO,
3370+ "CTRL: Invalid NAN_UPDATE_PUBLISH parameter: %s",
3371+ token);
3372+ goto fail;
3373+ }
3374+
3375+ if (publish_id <= 0) {
3376+ wpa_printf(MSG_INFO,
3377+ "CTRL: Invalid or missing NAN_UPDATE_PUBLISH publish_id");
3378+ goto fail;
3379+ }
3380+
3381+ ret = hostapd_nan_usd_update_publish(hapd, publish_id, ssi);
3382+fail:
3383+ wpabuf_free(ssi);
3384+ return ret;
3385+}
3386+
3387+
3388+static int hostapd_ctrl_nan_subscribe(struct hostapd_data *hapd, char *cmd,
3389+ char *buf, size_t buflen)
3390+{
3391+ char *token, *context = NULL;
3392+ int subscribe_id;
3393+ struct nan_subscribe_params params;
3394+ const char *service_name = NULL;
3395+ struct wpabuf *ssi = NULL;
3396+ int ret = -1;
3397+ enum nan_service_protocol_type srv_proto_type = 0;
3398+
3399+ os_memset(&params, 0, sizeof(params));
3400+
3401+ while ((token = str_token(cmd, " ", &context))) {
3402+ if (os_strncmp(token, "service_name=", 13) == 0) {
3403+ service_name = token + 13;
3404+ continue;
3405+ }
3406+
3407+ if (os_strcmp(token, "active=1") == 0) {
3408+ params.active = true;
3409+ continue;
3410+ }
3411+
3412+ if (os_strncmp(token, "ttl=", 4) == 0) {
3413+ params.ttl = atoi(token + 4);
3414+ continue;
3415+ }
3416+
3417+ if (os_strncmp(token, "srv_proto_type=", 15) == 0) {
3418+ srv_proto_type = atoi(token + 15);
3419+ continue;
3420+ }
3421+
3422+ if (os_strncmp(token, "ssi=", 4) == 0) {
3423+ if (ssi)
3424+ goto fail;
3425+ ssi = wpabuf_parse_bin(token + 4);
3426+ if (!ssi)
3427+ goto fail;
3428+ continue;
3429+ }
3430+
3431+ wpa_printf(MSG_INFO,
3432+ "CTRL: Invalid NAN_SUBSCRIBE parameter: %s",
3433+ token);
3434+ goto fail;
3435+ }
3436+
3437+ subscribe_id = hostapd_nan_usd_subscribe(hapd, service_name,
3438+ srv_proto_type, ssi,
3439+ &params);
3440+ if (subscribe_id > 0)
3441+ ret = os_snprintf(buf, buflen, "%d", subscribe_id);
3442+fail:
3443+ wpabuf_free(ssi);
3444+ return ret;
3445+}
3446+
3447+
3448+static int hostapd_ctrl_nan_cancel_subscribe(struct hostapd_data *hapd,
3449+ char *cmd)
3450+{
3451+ char *token, *context = NULL;
3452+ int subscribe_id = 0;
3453+
3454+ while ((token = str_token(cmd, " ", &context))) {
3455+ if (sscanf(token, "subscribe_id=%i", &subscribe_id) == 1)
3456+ continue;
3457+ wpa_printf(MSG_INFO,
3458+ "CTRL: Invalid NAN_CANCEL_SUBSCRIBE parameter: %s",
3459+ token);
3460+ return -1;
3461+ }
3462+
3463+ if (subscribe_id <= 0) {
3464+ wpa_printf(MSG_INFO,
3465+ "CTRL: Invalid or missing NAN_CANCEL_SUBSCRIBE subscribe_id");
3466+ return -1;
3467+ }
3468+
3469+ hostapd_nan_usd_cancel_subscribe(hapd, subscribe_id);
3470+ return 0;
3471+}
3472+
3473+
3474+static int hostapd_ctrl_nan_transmit(struct hostapd_data *hapd, char *cmd)
3475+{
3476+ char *token, *context = NULL;
3477+ int handle = 0;
3478+ int req_instance_id = 0;
3479+ struct wpabuf *ssi = NULL;
3480+ u8 peer_addr[ETH_ALEN];
3481+ int ret = -1;
3482+
3483+ os_memset(peer_addr, 0, ETH_ALEN);
3484+
3485+ while ((token = str_token(cmd, " ", &context))) {
3486+ if (sscanf(token, "handle=%i", &handle) == 1)
3487+ continue;
3488+
3489+ if (sscanf(token, "req_instance_id=%i", &req_instance_id) == 1)
3490+ continue;
3491+
3492+ if (os_strncmp(token, "address=", 8) == 0) {
3493+ if (hwaddr_aton(token + 8, peer_addr) < 0)
3494+ return -1;
3495+ continue;
3496+ }
3497+
3498+ if (os_strncmp(token, "ssi=", 4) == 0) {
3499+ if (ssi)
3500+ goto fail;
3501+ ssi = wpabuf_parse_bin(token + 4);
3502+ if (!ssi)
3503+ goto fail;
3504+ continue;
3505+ }
3506+
3507+ wpa_printf(MSG_INFO,
3508+ "CTRL: Invalid NAN_TRANSMIT parameter: %s",
3509+ token);
3510+ goto fail;
3511+ }
3512+
3513+ if (handle <= 0) {
3514+ wpa_printf(MSG_INFO,
3515+ "CTRL: Invalid or missing NAN_TRANSMIT handle");
3516+ goto fail;
3517+ }
3518+
3519+ if (is_zero_ether_addr(peer_addr)) {
3520+ wpa_printf(MSG_INFO,
3521+ "CTRL: Invalid or missing NAN_TRANSMIT address");
3522+ goto fail;
3523+ }
3524+
3525+ ret = hostapd_nan_usd_transmit(hapd, handle, ssi, NULL, peer_addr,
3526+ req_instance_id);
3527+fail:
3528+ wpabuf_free(ssi);
3529+ return ret;
3530+}
3531+
3532+#endif /* CONFIG_NAN_USD */
3533+
3534+
3535 static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3536 char *buf, char *reply,
3537 int reply_size,
3538@@ -3517,6 +3996,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3539 } else if (os_strncmp(buf, "RELOG", 5) == 0) {
3540 if (wpa_debug_reopen_file() < 0)
3541 reply_len = -1;
3542+ } else if (os_strcmp(buf, "CLOSE_LOG") == 0) {
3543+ wpa_debug_stop_log();
3544 } else if (os_strncmp(buf, "NOTE ", 5) == 0) {
3545 wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);
3546 } else if (os_strcmp(buf, "STATUS") == 0) {
3547@@ -3682,16 +4163,30 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3548 } else if (os_strncmp(buf, "GET ", 4) == 0) {
3549 reply_len = hostapd_ctrl_iface_get(hapd, buf + 4, reply,
3550 reply_size);
3551- } else if (os_strncmp(buf, "ENABLE", 6) == 0) {
3552+ } else if (os_strcmp(buf, "ENABLE") == 0) {
3553 if (hostapd_ctrl_iface_enable(hapd->iface))
3554 reply_len = -1;
3555 } else if (os_strcmp(buf, "RELOAD_WPA_PSK") == 0) {
3556 if (hostapd_ctrl_iface_reload_wpa_psk(hapd))
3557 reply_len = -1;
3558- } else if (os_strncmp(buf, "RELOAD", 6) == 0) {
3559+#ifdef CONFIG_IEEE80211R_AP
3560+ } else if (os_strcmp(buf, "GET_RXKHS") == 0) {
3561+ reply_len = hostapd_ctrl_iface_get_rxkhs(hapd, reply,
3562+ reply_size);
3563+ } else if (os_strcmp(buf, "RELOAD_RXKHS") == 0) {
3564+ if (hostapd_ctrl_iface_reload_rxkhs(hapd))
3565+ reply_len = -1;
3566+#endif /* CONFIG_IEEE80211R_AP */
3567+ } else if (os_strcmp(buf, "RELOAD_BSS") == 0) {
3568+ if (hostapd_ctrl_iface_reload_bss(hapd))
3569+ reply_len = -1;
3570+ } else if (os_strcmp(buf, "RELOAD_CONFIG") == 0) {
3571+ if (hostapd_reload_config(hapd->iface))
3572+ reply_len = -1;
3573+ } else if (os_strcmp(buf, "RELOAD") == 0) {
3574 if (hostapd_ctrl_iface_reload(hapd->iface))
3575 reply_len = -1;
3576- } else if (os_strncmp(buf, "DISABLE", 7) == 0) {
3577+ } else if (os_strcmp(buf, "DISABLE") == 0) {
3578 if (hostapd_ctrl_iface_disable(hapd->iface))
3579 reply_len = -1;
3580 } else if (os_strcmp(buf, "UPDATE_BEACON") == 0) {
3581@@ -3727,16 +4222,15 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3582 if (hostapd_ctrl_iface_data_test_frame(hapd, buf + 16) < 0)
3583 reply_len = -1;
3584 } else if (os_strncmp(buf, "TEST_ALLOC_FAIL ", 16) == 0) {
3585- if (hostapd_ctrl_test_alloc_fail(hapd, buf + 16) < 0)
3586+ if (testing_set_fail_pattern(true, buf + 16) < 0)
3587 reply_len = -1;
3588 } else if (os_strcmp(buf, "GET_ALLOC_FAIL") == 0) {
3589- reply_len = hostapd_ctrl_get_alloc_fail(hapd, reply,
3590- reply_size);
3591+ reply_len = testing_get_fail_pattern(true, reply, reply_size);
3592 } else if (os_strncmp(buf, "TEST_FAIL ", 10) == 0) {
3593- if (hostapd_ctrl_test_fail(hapd, buf + 10) < 0)
3594+ if (testing_set_fail_pattern(false, buf + 10) < 0)
3595 reply_len = -1;
3596 } else if (os_strcmp(buf, "GET_FAIL") == 0) {
3597- reply_len = hostapd_ctrl_get_fail(hapd, reply, reply_size);
3598+ reply_len = testing_get_fail_pattern(false, reply, reply_size);
3599 } else if (os_strncmp(buf, "RESET_PN ", 9) == 0) {
3600 if (hostapd_ctrl_reset_pn(hapd, buf + 9) < 0)
3601 reply_len = -1;
3602@@ -3768,6 +4262,14 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3603 } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {
3604 if (hostapd_ctrl_iface_chan_switch(hapd->iface, buf + 12))
3605 reply_len = -1;
3606+#ifdef CONFIG_IEEE80211AX
3607+ } else if (os_strncmp(buf, "COLOR_CHANGE ", 13) == 0) {
3608+ if (hostapd_ctrl_iface_color_change(hapd->iface, buf + 13))
3609+ reply_len = -1;
3610+#endif /* CONFIG_IEEE80211AX */
3611+ } else if (os_strncmp(buf, "NOTIFY_CW_CHANGE ", 17) == 0) {
3612+ if (hostapd_ctrl_iface_notify_cw_change(hapd, buf + 17))
3613+ reply_len = -1;
3614 } else if (os_strncmp(buf, "VENDOR ", 7) == 0) {
3615 reply_len = hostapd_ctrl_iface_vendor(hapd, buf + 7, reply,
3616 reply_size);
3617@@ -3816,6 +4318,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3618 } else if (os_strncmp(buf, "REQ_BEACON ", 11) == 0) {
3619 reply_len = hostapd_ctrl_iface_req_beacon(hapd, buf + 11,
3620 reply, reply_size);
3621+ } else if (os_strncmp(buf, "REQ_LINK_MEASUREMENT ", 21) == 0) {
3622+ reply_len = hostapd_ctrl_iface_req_link_measurement(
3623+ hapd, buf + 21, reply, reply_size);
3624 } else if (os_strcmp(buf, "DRIVER_FLAGS") == 0) {
3625 reply_len = hostapd_ctrl_driver_flags(hapd->iface, reply,
3626 reply_size);
3627@@ -3828,14 +4333,15 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3628 if (os_strncmp(buf + 11, "ADD_MAC ", 8) == 0) {
3629 if (hostapd_ctrl_iface_acl_add_mac(
3630 &hapd->conf->accept_mac,
3631- &hapd->conf->num_accept_mac, buf + 19))
3632+ &hapd->conf->num_accept_mac, buf + 19) ||
3633+ hostapd_set_acl(hapd))
3634 reply_len = -1;
3635 } else if (os_strncmp((buf + 11), "DEL_MAC ", 8) == 0) {
3636- if (!hostapd_ctrl_iface_acl_del_mac(
3637+ if (hostapd_ctrl_iface_acl_del_mac(
3638 &hapd->conf->accept_mac,
3639- &hapd->conf->num_accept_mac, buf + 19))
3640- hostapd_disassoc_accept_mac(hapd);
3641- else
3642+ &hapd->conf->num_accept_mac, buf + 19) ||
3643+ hostapd_set_acl(hapd) ||
3644+ hostapd_disassoc_accept_mac(hapd))
3645 reply_len = -1;
3646 } else if (os_strcmp(buf + 11, "SHOW") == 0) {
3647 reply_len = hostapd_ctrl_iface_acl_show_mac(
3648@@ -3845,20 +4351,25 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3649 hostapd_ctrl_iface_acl_clear_list(
3650 &hapd->conf->accept_mac,
3651 &hapd->conf->num_accept_mac);
3652- hostapd_disassoc_accept_mac(hapd);
3653+ if (hostapd_set_acl(hapd) ||
3654+ hostapd_disassoc_accept_mac(hapd))
3655+ reply_len = -1;
3656+ } else {
3657+ reply_len = -1;
3658 }
3659 } else if (os_strncmp(buf, "DENY_ACL ", 9) == 0) {
3660 if (os_strncmp(buf + 9, "ADD_MAC ", 8) == 0) {
3661- if (!hostapd_ctrl_iface_acl_add_mac(
3662+ if (hostapd_ctrl_iface_acl_add_mac(
3663 &hapd->conf->deny_mac,
3664- &hapd->conf->num_deny_mac, buf + 17))
3665- hostapd_disassoc_deny_mac(hapd);
3666- else
3667+ &hapd->conf->num_deny_mac, buf + 17) ||
3668+ hostapd_set_acl(hapd) ||
3669+ hostapd_disassoc_deny_mac(hapd))
3670 reply_len = -1;
3671 } else if (os_strncmp(buf + 9, "DEL_MAC ", 8) == 0) {
3672 if (hostapd_ctrl_iface_acl_del_mac(
3673 &hapd->conf->deny_mac,
3674- &hapd->conf->num_deny_mac, buf + 17))
3675+ &hapd->conf->num_deny_mac, buf + 17) ||
3676+ hostapd_set_acl(hapd))
3677 reply_len = -1;
3678 } else if (os_strcmp(buf + 9, "SHOW") == 0) {
3679 reply_len = hostapd_ctrl_iface_acl_show_mac(
3680@@ -3868,6 +4379,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3681 hostapd_ctrl_iface_acl_clear_list(
3682 &hapd->conf->deny_mac,
3683 &hapd->conf->num_deny_mac);
3684+ if (hostapd_set_acl(hapd))
3685+ reply_len = -1;
3686+ } else {
3687+ reply_len = -1;
3688 }
3689 #ifdef CONFIG_DPP
3690 } else if (os_strncmp(buf, "DPP_QR_CODE ", 12) == 0) {
3691@@ -3959,6 +4474,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3692 if (os_snprintf_error(reply_size, reply_len))
3693 reply_len = -1;
3694 }
3695+ } else if (os_strncmp(buf, "DPP_CONFIGURATOR_SET ", 21) == 0) {
3696+ if (dpp_configurator_set(hapd->iface->interfaces->dpp,
3697+ buf + 20) < 0)
3698+ reply_len = -1;
3699 } else if (os_strncmp(buf, "DPP_CONFIGURATOR_REMOVE ", 24) == 0) {
3700 if (dpp_configurator_remove(hapd->iface->interfaces->dpp,
3701 buf + 24) < 0)
3702@@ -3997,8 +4516,41 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3703 reply_len = -1;
3704 } else if (os_strcmp(buf, "DPP_STOP_CHIRP") == 0) {
3705 hostapd_dpp_chirp_stop(hapd);
3706+ } else if (os_strncmp(buf, "DPP_RELAY_ADD_CONTROLLER ", 25) == 0) {
3707+ if (hostapd_dpp_add_controller(hapd, buf + 25) < 0)
3708+ reply_len = -1;
3709+ } else if (os_strncmp(buf, "DPP_RELAY_REMOVE_CONTROLLER ", 28) == 0) {
3710+ hostapd_dpp_remove_controller(hapd, buf + 28);
3711 #endif /* CONFIG_DPP2 */
3712+#ifdef CONFIG_DPP3
3713+ } else if (os_strcmp(buf, "DPP_PUSH_BUTTON") == 0) {
3714+ if (hostapd_dpp_push_button(hapd, NULL) < 0)
3715+ reply_len = -1;
3716+ } else if (os_strncmp(buf, "DPP_PUSH_BUTTON ", 16) == 0) {
3717+ if (hostapd_dpp_push_button(hapd, buf + 15) < 0)
3718+ reply_len = -1;
3719+#endif /* CONFIG_DPP3 */
3720 #endif /* CONFIG_DPP */
3721+#ifdef CONFIG_NAN_USD
3722+ } else if (os_strncmp(buf, "NAN_PUBLISH ", 12) == 0) {
3723+ reply_len = hostapd_ctrl_nan_publish(hapd, buf + 12, reply,
3724+ reply_size);
3725+ } else if (os_strncmp(buf, "NAN_CANCEL_PUBLISH ", 19) == 0) {
3726+ if (hostapd_ctrl_nan_cancel_publish(hapd, buf + 19) < 0)
3727+ reply_len = -1;
3728+ } else if (os_strncmp(buf, "NAN_UPDATE_PUBLISH ", 19) == 0) {
3729+ if (hostapd_ctrl_nan_update_publish(hapd, buf + 19) < 0)
3730+ reply_len = -1;
3731+ } else if (os_strncmp(buf, "NAN_SUBSCRIBE ", 14) == 0) {
3732+ reply_len = hostapd_ctrl_nan_subscribe(hapd, buf + 14, reply,
3733+ reply_size);
3734+ } else if (os_strncmp(buf, "NAN_CANCEL_SUBSCRIBE ", 21) == 0) {
3735+ if (hostapd_ctrl_nan_cancel_subscribe(hapd, buf + 21) < 0)
3736+ reply_len = -1;
3737+ } else if (os_strncmp(buf, "NAN_TRANSMIT ", 13) == 0) {
3738+ if (hostapd_ctrl_nan_transmit(hapd, buf + 13) < 0)
3739+ reply_len = -1;
3740+#endif /* CONFIG_NAN_USD */
3741 #ifdef RADIUS_SERVER
3742 } else if (os_strncmp(buf, "DAC_REQUEST ", 12) == 0) {
3743 if (radius_server_dac_request(hapd->radius_srv, buf + 12) < 0)
3744@@ -4016,6 +4568,20 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3745 reply_len = hostapd_ctrl_iface_driver_cmd(hapd, buf + 7, reply,
3746 reply_size);
3747 #endif /* ANDROID */
3748+#ifdef CONFIG_IEEE80211BE
3749+ } else if (os_strcmp(buf, "ENABLE_MLD") == 0) {
3750+ if (hostapd_ctrl_iface_enable_mld(hapd->iface))
3751+ reply_len = -1;
3752+ } else if (os_strcmp(buf, "DISABLE_MLD") == 0) {
3753+ if (hostapd_ctrl_iface_disable_mld(hapd->iface))
3754+ reply_len = -1;
3755+#ifdef CONFIG_TESTING_OPTIONS
3756+ } else if (os_strncmp(buf, "LINK_REMOVE ", 12) == 0) {
3757+ if (hostapd_ctrl_iface_link_remove(hapd, buf + 12,
3758+ reply, reply_size))
3759+ reply_len = -1;
3760+#endif /* CONFIG_TESTING_OPTIONS */
3761+#endif /* CONFIG_IEEE80211BE */
3762 } else {
3763 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
3764 reply_len = 16;
3765@@ -4506,6 +5072,20 @@ static void hostapd_ctrl_iface_flush(struct hapd_interfaces *interfaces)
3766
3767 #ifdef CONFIG_DPP
3768 dpp_global_clear(interfaces->dpp);
3769+#ifdef CONFIG_DPP3
3770+ interfaces->dpp_pb_bi = NULL;
3771+ {
3772+ int i;
3773+
3774+ for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
3775+ struct dpp_pb_info *info;
3776+
3777+ info = &interfaces->dpp_pb[i];
3778+ info->rx_time.sec = 0;
3779+ info->rx_time.usec = 0;
3780+ }
3781+ }
3782+#endif /* CONFIG_DPP3 */
3783 #endif /* CONFIG_DPP */
3784 }
3785
3786@@ -4897,7 +5477,7 @@ static void hostapd_global_ctrl_iface_receive(int sock, void *eloop_ctx,
3787 reply_len = -1;
3788 } else if (os_strncmp(buf, "INTERFACES", 10) == 0) {
3789 reply_len = hostapd_global_ctrl_iface_interfaces(
3790- interfaces, buf + 10, reply, sizeof(buffer));
3791+ interfaces, buf + 10, reply, reply_size);
3792 } else if (os_strcmp(buf, "TERMINATE") == 0) {
3793 eloop_terminate();
3794 } else {
3795diff --git a/hostapd/defconfig b/hostapd/defconfig
3796index 6b50b6c..550db69 100644
3797--- a/hostapd/defconfig
3798+++ b/hostapd/defconfig
3799@@ -141,6 +141,9 @@ CONFIG_PKCS12=y
3800 # Build IPv6 support for RADIUS operations
3801 CONFIG_IPV6=y
3802
3803+# Include support fo RADIUS/TLS into the RADIUS client
3804+#CONFIG_RADIUS_TLS=y
3805+
3806 # IEEE Std 802.11r-2008 (Fast BSS Transition)
3807 #CONFIG_IEEE80211R=y
3808
3809@@ -156,10 +159,20 @@ CONFIG_IPV6=y
3810 #CONFIG_IEEE80211AC=y
3811
3812 # IEEE 802.11ax HE support
3813+#CONFIG_IEEE80211AX=y
3814+
3815+# IEEE 802.11be EHT support
3816+# CONFIG_IEEE80211AX is mandatory for setting CONFIG_IEEE80211BE.
3817 # Note: This is experimental and work in progress. The definitions are still
3818 # subject to change and this should not be expected to interoperate with the
3819-# final IEEE 802.11ax version.
3820-#CONFIG_IEEE80211AX=y
3821+# final IEEE 802.11be version.
3822+#CONFIG_IEEE80211BE=y
3823+
3824+# Simultaneous Authentication of Equals (SAE), WPA3-Personal
3825+#CONFIG_SAE=y
3826+
3827+# SAE Public Key, WPA3-Personal
3828+#CONFIG_SAE_PK=y
3829
3830 # Remove debugging code that is printing out debug messages to stdout.
3831 # This can be used to reduce the size of the hostapd considerably if debugging
3832@@ -400,7 +413,6 @@ CONFIG_IPV6=y
3833 # Experimental implementation based on IEEE P802.11z/D2.6 and the protocol
3834 # design is still subject to change. As such, this should not yet be enabled in
3835 # production use.
3836-# This requires CONFIG_IEEE80211W=y to be enabled, too.
3837 #CONFIG_PASN=y
3838
3839 # Device Provisioning Protocol (DPP) (also known as Wi-Fi Easy Connect)
3840@@ -410,3 +422,6 @@ CONFIG_DPP2=y
3841 # DPP version 3 support (experimental and still changing; do not enable for
3842 # production use)
3843 #CONFIG_DPP3=y
3844+
3845+# Wi-Fi Aware unsynchronized service discovery (NAN USD)
3846+#CONFIG_NAN_USD=y
3847diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
3848index 3c2019f..d875d5f 100644
3849--- a/hostapd/hostapd.conf
3850+++ b/hostapd/hostapd.conf
3851@@ -225,6 +225,16 @@ channel=1
3852 # Default behavior is to include all PSC and non-PSC channels.
3853 #acs_exclude_6ghz_non_psc=1
3854
3855+# Enable background radar feature
3856+# This feature allows CAC to be run on dedicated radio RF chains while the
3857+# radio(s) are otherwise running normal AP activities on other channels.
3858+# This requires that the driver and the radio support it before feature will
3859+# actually be enabled, i.e., this parameter value is ignored with drivers that
3860+# do not advertise support for the capability.
3861+# 0: Leave disabled (default)
3862+# 1: Enable it.
3863+#enable_background_radar=1
3864+
3865 # Set minimum permitted max TX power (in dBm) for ACS and DFS channel selection.
3866 # (default 0, i.e., not constraint)
3867 #min_tx_power=20
3868@@ -512,6 +522,25 @@ wmm_ac_vo_acm=0
3869 # even if they are still in range of the AP. This can be done by setting
3870 # skip_inactivity_poll to 1 (default 0).
3871 #skip_inactivity_poll=0
3872+#
3873+# BSS max idle period management
3874+# 0 = disabled (do not advertise and manage BSS max idle period)
3875+# 1 = enabled (advertise and manage BSS max idle period; default)
3876+# 2 = enabled requiring protected frames (advertise and manage BSS max idle
3877+# period and require STAs to use protected keep-alive frames)
3878+#bss_max_idle=1
3879+#
3880+# Maximum acceptable BSS maximum idle period
3881+# If this is set to a nonzero value, the AP allows STAs to request different
3882+# maximum idle period values. This is in the units to 1000 TUs (1.024 s)
3883+#max_acceptable_idle_period=600
3884+#
3885+# Allow STA to skip group key handshake without getting disconnection when
3886+# BSS max idle period management is enabled.
3887+# 0 = disconnect STA if it does not reply to group key handshake (default)
3888+# 1 = do not disconnect STA if it does not reply to group key handshake and
3889+# if BSS max idle period management is enabled
3890+#no_disconnect_on_group_keyerror=0
3891
3892 # Disassociate stations based on excessive transmission failures or other
3893 # indications of connection loss. This depends on the driver capabilities and
3894@@ -636,6 +665,12 @@ wmm_ac_vo_acm=0
3895 # no co-existence issues with neighboring devices are found.
3896 #obss_interval=0
3897
3898+# ht_vht_twt_responder: Whether TWT responder is enabled in HT and VHT modes
3899+# 0 = disable; Disable TWT responder support in HT and VHT modes (default).
3900+# 1 = enable; Enable TWT responder support in HT and VHT modes if supported by
3901+# the driver.
3902+#ht_vht_twt_responder=0
3903+
3904 ##### IEEE 802.11ac related configuration #####################################
3905
3906 # ieee80211ac: Whether IEEE 802.11ac (VHT) is enabled
3907@@ -802,6 +837,9 @@ wmm_ac_vo_acm=0
3908 # 1 = enabled
3909 #ieee80211ax=1
3910
3911+# Require stations to support HE PHY (reject association if they do not)
3912+#require_he=1
3913+
3914 # disable_11ax: Boolean (0/1) to disable HE for a specific BSS
3915 #disable_11ax=0
3916
3917@@ -861,7 +899,7 @@ wmm_ac_vo_acm=0
3918 # he_oper_chwidth is ignored, and the channel width is derived from the
3919 # configured operating class or center frequency indexes (see
3920 # IEEE P802.11ax/D6.1 Annex E, Table E-4).
3921-#he_oper_chwidth
3922+#he_oper_chwidth (see vht_oper_chwidth)
3923 #he_oper_centr_freq_seg0_idx
3924 #he_oper_centr_freq_seg1_idx
3925
3926@@ -965,6 +1003,25 @@ wmm_ac_vo_acm=0
3927 # (default)
3928 #he_6ghz_tx_ant_pat=1
3929
3930+# 6 GHz Access Point type
3931+# This config is to set the 6 GHz Access Point type. Possible options are:
3932+# 0 = Indoor AP
3933+# 1 = Standard power AP
3934+# 2 = Very low power AP (default)
3935+# 3 = Indoor enabled AP
3936+# 4 = Indoor standard power AP
3937+# This has no impact for operation on other bands.
3938+# See IEEE P802.11-REVme/D4.0, Table E-12 (Regulatory Info subfield encoding)
3939+# for more details.
3940+#he_6ghz_reg_pwr_type=0
3941+#
3942+# 6 GHz Maximum Tx Power used in Transmit Power Envelope elements, where the
3943+# "Transmit Power Interpretation" is set to "Regulatory client EIRP PSD".
3944+# For Maximum Transmit Power Category subfield encoding set to default (0):
3945+#reg_def_cli_eirp_psd=-1
3946+# For Maximum Transmit Power Category subfield encoding set to subordinate (1):
3947+#reg_sub_cli_eirp_psd=-1
3948+
3949 # Unsolicited broadcast Probe Response transmission settings
3950 # This is for the 6 GHz band only. If the interval is set to a non-zero value,
3951 # the AP schedules unsolicited broadcast Probe Response frames to be
3952@@ -973,6 +1030,78 @@ wmm_ac_vo_acm=0
3953 # Valid range: 0..20 TUs; default is 0 (disabled)
3954 #unsol_bcast_probe_resp_interval=0
3955
3956+##### IEEE 802.11be related configuration #####################################
3957+
3958+#ieee80211be: Whether IEEE 802.11be (EHT) is enabled
3959+# 0 = disabled (default)
3960+# 1 = enabled
3961+#ieee80211be=1
3962+
3963+#disable_11be: Boolean (0/1) to disable EHT for a specific BSS
3964+#disable_11be=0
3965+
3966+#eht_su_beamformer: EHT single user beamformer support
3967+# 0 = not supported (default)
3968+# 1 = supported
3969+#eht_su_beamformer=1
3970+
3971+#eht_su_beamformee: EHT single user beamformee support
3972+# 0 = not supported (default)
3973+# 1 = supported
3974+#eht_su_beamformee=1
3975+
3976+#eht_mu_beamformer: EHT multiple user beamformer support
3977+# 0 = not supported (default)
3978+# 1 = supported
3979+#eht_mu_beamformer=1
3980+
3981+# EHT operating channel information; see matching he_* parameters for details.
3982+# The field eht_oper_centr_freq_seg0_idx field is used to indicate center
3983+# frequency of 40, 80, and 160 MHz bandwidth operation.
3984+# In the 6 GHz band, eht_oper_chwidth is ignored and the channel width is
3985+# derived from the configured operating class (IEEE P802.11be/D1.5,
3986+# Annex E.1 - Country information and operating classes).
3987+#eht_oper_chwidth (see vht_oper_chwidth)
3988+#eht_oper_centr_freq_seg0_idx
3989+
3990+#eht_default_pe_duration: The duration of PE field in EHT TB PPDU
3991+# 0 = PE field duration is the same as he_default_pe_duration (default)
3992+# 1 = PE field duration is 20 us
3993+#eht_default_pe_duration=0
3994+
3995+#eht_bw320_offset: For automatic channel selection (ACS) to indicate a preferred
3996+# 320 MHz channelization in EHT mode.
3997+# If the channel is decided or the bandwidth is not 320 MHz, this option is
3998+# meaningless.
3999+# 0 = auto-detect by hostapd
4000+# 1 = 320 MHz-1 (channel center frequency 31, 95, 159)
4001+# 2 = 320 MHz-2 (channel center frequency 63, 127, 191)
4002+#eht_bw320_offset=0
4003+
4004+# Disabled subchannel bitmap (16 bits) as per IEEE P802.11be/3.0,
4005+# Figure 9-1002c (EHT Operation Information field format). Each bit corresponds
4006+# to a 20 MHz channel, the lowest bit corresponds to the lowest frequency. A
4007+# bit set to 1 indicates that the channel is punctured (disabled). The default
4008+# value is 0 indicating that all channels are active.
4009+#punct_bitmap=0
4010+
4011+# Preamble puncturing threshold in automatic channel selection (ACS).
4012+# The value indicates the percentage of ideal channel average interference
4013+# factor above which a channel should be punctured.
4014+# Default is 0, indicates that ACS algorithm should not puncture any channel.
4015+#punct_acs_threshold=75
4016+
4017+# AP MLD - Whether this AP is a part of an AP MLD
4018+# 0 = no (no MLO)
4019+# 1 = yes (MLO)
4020+#mld_ap=0
4021+
4022+# AP MLD MAC address
4023+# The configured address will be set as the interface hardware address and used
4024+# as the AP MLD MAC address. If not set, the current interface hardware address
4025+# will be used as the AP MLD MAC address.
4026+#mld_addr=02:03:04:05:06:07
4027+
4028 ##### IEEE 802.1X-2004 related configuration ##################################
4029
4030 # Require IEEE 802.1X authorization
4031@@ -1063,6 +1192,14 @@ eapol_key_index_workaround=0
4032 # 0: No replay window, strict check (default)
4033 # 1..2^32-1: number of packets that could be misordered
4034 #
4035+# macsec_offload: IEEE 802.1X/MACsec hardware offload
4036+# This setting applies only when MACsec is in use, i.e.,
4037+# - macsec_policy is enabled
4038+# - the key server has decided to enable MACsec
4039+# 0 = MACSEC_OFFLOAD_OFF (default)
4040+# 1 = MACSEC_OFFLOAD_PHY
4041+# 2 = MACSEC_OFFLOAD_MAC
4042+#
4043 # macsec_port: IEEE 802.1X/MACsec port
4044 # Port component of the SCI
4045 # Range: 1-65534 (default: 1)
4046@@ -1070,6 +1207,10 @@ eapol_key_index_workaround=0
4047 # mka_priority (Priority of MKA Actor)
4048 # Range: 0..255 (default: 255)
4049 #
4050+# macsec_csindex: IEEE 802.1X/MACsec cipher suite
4051+# 0 = GCM-AES-128 (default)
4052+# 1 = GCM-AES-256 (default)
4053+#
4054 # mka_cak, mka_ckn, and mka_priority: IEEE 802.1X/MACsec pre-shared key mode
4055 # This allows to configure MACsec with a pre-shared key using a (CAK,CKN) pair.
4056 # In this mode, instances of hostapd can act as MACsec peers. The peer
4057@@ -1243,12 +1384,11 @@ eap_server=0
4058
4059 # dh_file: File path to DH/DSA parameters file (in PEM format)
4060 # This is an optional configuration file for setting parameters for an
4061-# ephemeral DH key exchange. In most cases, the default RSA authentication does
4062-# not use this configuration. However, it is possible setup RSA to use
4063-# ephemeral DH key exchange. In addition, ciphers with DSA keys always use
4064-# ephemeral DH keys. This can be used to achieve forward secrecy. If the file
4065-# is in DSA parameters format, it will be automatically converted into DH
4066-# params. This parameter is required if anonymous EAP-FAST is used.
4067+# ephemeral DH key exchange. If the file is in DSA parameters format, it will
4068+# be automatically converted into DH params. If the used TLS library supports
4069+# automatic DH parameter selection, that functionality will be used if this
4070+# parameter is not set. DH parameters are required if anonymous EAP-FAST is
4071+# used.
4072 # You can generate DH parameters file with OpenSSL, e.g.,
4073 # "openssl dhparam -out /etc/hostapd.dh.pem 2048"
4074 #dh_file=/etc/hostapd.dh.pem
4075@@ -1358,6 +1498,12 @@ eap_server=0
4076 # 5 = require both user and machine identity
4077 #eap_teap_id=0
4078
4079+# EAP-TEAP tunneled EAP method behavior
4080+# 0 = minimize roundtrips by merging start of the next EAP method with the
4081+# crypto-binding of the previous one.
4082+# 1 = complete crypto-binding before starting the next EAP method
4083+#eap_teap_method_sequence=0
4084+
4085 # EAP-SIM and EAP-AKA protected success/failure indication using AT_RESULT_IND
4086 # (default: 0 = disabled).
4087 #eap_sim_aka_result_ind=1
4088@@ -1367,8 +1513,25 @@ eap_server=0
4089 # 1 = use pseudonyms, but not fast reauthentication
4090 # 2 = do not use pseudonyms, but use fast reauthentication
4091 # 3 = use pseudonyms and use fast reauthentication (default)
4092+# 4 = do not use pseudonyms or fast reauthentication and allow
4093+# EAP-Response/Identity to be used without method specific identity exchange
4094+# 5 = use pseudonyms, but not fast reauthentication and allow
4095+# EAP-Response/Identity to be used without method specific identity exchange
4096+# 6 = do not use pseudonyms, but use fast reauthentication and allow
4097+# EAP-Response/Identity to be used without method specific identity exchange
4098+# 7 = use pseudonyms and use fast reauthentication and allow
4099+# EAP-Response/Identity to be used without method specific identity exchange
4100 #eap_sim_id=3
4101
4102+# IMSI privacy key (PEM encoded RSA 2048-bit private key) for decrypting
4103+# permanent identity when using EAP-SIM/AKA/AKA'.
4104+#imsi_privacy_key=imsi-privacy-key.pem
4105+
4106+# EAP-SIM and EAP-AKA fast re-authentication limit
4107+# Maximum number of fast re-authentications allowed after each full
4108+# authentication.
4109+#eap_sim_aka_fast_reauth_limit=1000
4110+
4111 # Trusted Network Connect (TNC)
4112 # If enabled, TNC validation will be required before the peer is allowed to
4113 # connect. Note: This is only used with EAP-TTLS and EAP-FAST. If any other
4114@@ -1440,6 +1603,16 @@ own_ip_addr=127.0.0.1
4115 #acct_server_port=1813
4116 #acct_server_shared_secret=secret2
4117
4118+# RADIUS/TLS instead of RADIUS/UDP
4119+#auth_server_addr=127.0.0.1
4120+#auth_server_port=2083
4121+#auth_server_type=TLS
4122+#auth_server_shared_secret=radsec
4123+#auth_server_ca_cert=<path to trusted CA certificate(s)>
4124+#auth_server_client_cert=<path to client certificate>
4125+#auth_server_private_key=<path to private key>
4126+#auth_server_private_key_passwd=<password for decrypting private key>
4127+
4128 # Retry interval for trying to return to the primary RADIUS server (in
4129 # seconds). RADIUS client code will automatically try to use the next server
4130 # when the current server is not replying to requests. If this interval is set,
4131@@ -1447,6 +1620,17 @@ own_ip_addr=127.0.0.1
4132 # currently used secondary server is still working.
4133 #radius_retry_primary_interval=600
4134
4135+# Message-Authenticator attribute requirement for non-EAP cases
4136+# hostapd requires Message-Authenticator attribute to be included in all cases
4137+# where RADIUS is used for EAP authentication. This is also required for cases
4138+# where RADIUS is used for MAC ACL (macaddr_acl=2) by default, but that case
4139+# can be configured to not require this for compatibility with RADIUS servers
4140+# that do not include the attribute. This is not recommended due to potential
4141+# security concerns, but can be used as a temporary workaround in networks where
4142+# the connection to the RADIUS server is secure.
4143+# 0 = Do not require Message-Authenticator in MAC ACL response
4144+# 1 = Require Message-Authenticator in all authentication cases (default)
4145+#radius_require_message_authenticator=1
4146
4147 # Interim accounting update interval
4148 # If this is set (larger than 0) and acct_server is configured, hostapd will
4149@@ -1651,12 +1835,19 @@ own_ip_addr=127.0.0.1
4150 #wpa_psk_file=/etc/hostapd.wpa_psk
4151
4152 # Optionally, WPA passphrase can be received from RADIUS authentication server
4153-# This requires macaddr_acl to be set to 2 (RADIUS)
4154+# This requires macaddr_acl to be set to 2 (RADIUS) for wpa_psk_radius values
4155+# 1 and 2.
4156 # 0 = disabled (default)
4157 # 1 = optional; use default passphrase/psk if RADIUS server does not include
4158 # Tunnel-Password
4159 # 2 = required; reject authentication if RADIUS server does not include
4160 # Tunnel-Password
4161+# 3 = ask RADIUS server during 4-way handshake if there is no locally
4162+# configured PSK/passphrase for the STA
4163+#
4164+# The Tunnel-Password attribute in Access-Accept can contain either the
4165+# 8..63 character ASCII passphrase or a 64 hex character encoding of the PSK.
4166+#
4167 #wpa_psk_radius=0
4168
4169 # Set of accepted key management algorithms (WPA-PSK, WPA-EAP, or both). The
4170@@ -1914,6 +2105,10 @@ own_ip_addr=127.0.0.1
4171 #sae_password=really secret|mac=ff:ff:ff:ff:ff:ff
4172 #sae_password=example secret|mac=02:03:04:05:06:07|id=pw identifier
4173 #sae_password=example secret|vlanid=3|id=pw identifier
4174+#
4175+# SAE passwords can also be read from a separate file in which each line
4176+# contains and entry in the same format as sae_password uses.
4177+#sae_password_file=/tc/hostapd.sae_passwords
4178
4179 # SAE threshold for anti-clogging mechanism (dot11RSNASAEAntiCloggingThreshold)
4180 # This parameter defines how many open SAE instances can be in progress at the
4181@@ -1924,7 +2119,7 @@ own_ip_addr=127.0.0.1
4182 # Maximum number of SAE synchronization errors (dot11RSNASAESync)
4183 # The offending SAE peer will be disconnected if more than this many
4184 # synchronization errors happen.
4185-#sae_sync=5
4186+#sae_sync=3
4187
4188 # Enabled SAE finite cyclic groups
4189 # SAE implementation are required to support group 19 (ECC group defined over a
4190@@ -2042,6 +2237,8 @@ own_ip_addr=127.0.0.1
4191 # If fils_discovery_max_interval is non-zero, the AP enables FILS Discovery
4192 # frame transmission. These values use TUs as the unit and have allowed range
4193 # of 0-10000. fils_discovery_min_interval defaults to 20.
4194+# This feature is currently supported only when ieee80211ax is enabled for
4195+# the radio and disable_11ax is not set for the BSS.
4196 #fils_discovery_min_interval=20
4197 #fils_discovery_max_interval=0
4198
4199@@ -2077,6 +2274,30 @@ own_ip_addr=127.0.0.1
4200 # (default: 10 TUs)
4201 #pasn_comeback_after=10
4202
4203+# Unauthenticated PASN activated (dot11NoAuthPASNActivated)
4204+# This indicates whether PASN without mutual authentication is allowed.
4205+# (default: 1 = activated)
4206+#pasn_noauth=1
4207+
4208+# SSID protection in 4-way handshake
4209+# The IEEE 802.11i-2004 RSN design did not provide means for protecting the
4210+# SSID in the general case. IEEE P802.11REVme/D6.0 added support for this in
4211+# 4-way handshake. This capability allows a STA to confirm that the AP has the
4212+# same understanding on which SSID is being used for an association in a
4213+# protected manner in cases where both the AP and the STA has this capability.
4214+# This can be used to mitigate CVE-2023-52424 (a.k.a. the SSID Confusion
4215+# Attack).
4216+#
4217+# Ideally, this capability would be enabled by default on the AP, but since this
4218+# is new functionality with limited testing, the default is to disable this for
4219+# now and require explicitly configuration to enable. The default behavior is
4220+# like to change once this capability has received more testing.
4221+#
4222+# 0 = SSID protection in 4-way handshake disabled (default)
4223+# 1 = SSID protection in 4-way handshake enabled
4224+#
4225+#ssid_protection=0
4226+
4227 ##### IEEE 802.11r configuration ##############################################
4228
4229 # Mobility Domain identifier (dot11FTMobilityDomainID, MDID)
4230@@ -2136,6 +2357,12 @@ own_ip_addr=127.0.0.1
4231 # list and thus will receive push notifications.
4232 #r1kh=00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff
4233
4234+# Optionally, the list of RxKHs can be read from a text file. Format is the same
4235+# as specified above. File shall contain both r0kh and r1kh. Once this variable
4236+# is set, RxKHs can be reloaded at runtime without bringing down an interface
4237+# using the RELOAD_RXKHS command.
4238+#rxkh_file=<path>
4239+
4240 # Timeout (seconds) for newly discovered R0KH/R1KH (see wildcard entries above)
4241 # Special values: 0 -> do not expire
4242 # Warning: do not cache implies no sequence number validation with wildcards
4243@@ -2390,6 +2617,23 @@ own_ip_addr=127.0.0.1
4244 #multi_ap_backhaul_wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
4245 #multi_ap_backhaul_wpa_passphrase=secret passphrase
4246
4247+# Multi-AP Profile
4248+# Indicate the supported Multi-AP profile (default: 2)
4249+# 1 = Supports Multi-AP profile 1 as defined in Wi-Fi EasyMesh specification
4250+# 2 = Supports Multi-AP profile 2 as defined in Wi-Fi EasyMesh specification
4251+#multi_ap_profile=2
4252+
4253+# Multi-AP client disallow
4254+# Used to disallow profile specific backhaul STA association
4255+# Bitmap of the disallowed Profile-X profiles
4256+# 1 = Profile-1 Backhaul STA association disallowed
4257+# 2 = Profile-2 Backhaul STA association disallowed
4258+#multi_ap_client_disallow=0
4259+
4260+# Multi-AP VLAN ID
4261+# A valid non-zero VLAN ID will be used to update Default IEEE 802.1Q Setting
4262+#multi_ap_vlanid=0
4263+
4264 # WPS UPnP interface
4265 # If set, support for external Registrars is enabled.
4266 #upnp_iface=br0
4267@@ -2453,12 +2697,24 @@ own_ip_addr=127.0.0.1
4268 # MUD URL for Enrollee's DPP Configuration Request (optional)
4269 #dpp_mud_url=https://example.com/mud
4270
4271+# JSON node name of additional data for Enrollee's DPP Configuration Request
4272+#dpp_extra_conf_req_name=org.example
4273+
4274+# JSON node data of additional data for Enrollee's DPP Configuration Request
4275+#dpp_extra_conf_req_value="abc":123
4276+
4277 #dpp_connector
4278 #dpp_netaccesskey
4279 #dpp_netaccesskey_expiry
4280 #dpp_csign
4281 #dpp_controller
4282
4283+# DPP Relay port number
4284+# TCP port to listen to for incoming connections from a Controller. This can be
4285+# used to allow Controller initiated exchanges in addition to the
4286+# Controller-as-responder cases covered by the dpp_controller parameter.
4287+#dpp_relay_port=12345
4288+
4289 # Configurator Connectivity indication
4290 # 0: no Configurator is currently connected (default)
4291 # 1: advertise that a Configurator is available
4292@@ -2726,7 +2982,12 @@ own_ip_addr=127.0.0.1
4293 # If the RADIUS server indicates that the station is not allowed to connect to
4294 # the BSS/ESS, the AP can allow the station some time to download a
4295 # notification page (URL included in the message). This parameter sets that
4296-# timeout in seconds.
4297+# timeout in seconds. If the RADIUS server provides no URL, this value is
4298+# reduced to two seconds with an additional trigger for immediate
4299+# deauthentication when the STA acknowledges reception of the deauthentication
4300+# imminent indication. Note that setting this value to 0 will prevent delivery
4301+# of the notification to the STA, so a value of at least 1 should be used here
4302+# for normal use cases.
4303 #hs20_deauth_req_timeout=60
4304
4305 # Operator Friendly Name
4306@@ -2906,6 +3167,9 @@ own_ip_addr=127.0.0.1
4307 # Enable neighbor report via radio measurements
4308 #rrm_neighbor_report=1
4309
4310+# Enable link measurement report via radio measurements
4311+#rrm_link_measurement_report=1
4312+
4313 # Enable beacon report via radio measurements
4314 #rrm_beacon_report=1
4315
4316@@ -3002,6 +3266,18 @@ own_ip_addr=127.0.0.1
4317 # Include only ECSA IE without CSA IE where possible
4318 # (channel switch operating class is needed)
4319 #ecsa_ie_only=0
4320+#
4321+# Delay EAPOL-Key messages 1/4 and 3/4 by not sending the frame until the last
4322+# attempt (wpa_pairwise_update_count). This will trigger a timeout on all
4323+# previous attempts and thus delays the frame. (testing only)
4324+#delay_eapol_tx=0
4325+#
4326+# Additional elements for Probe Response frames.
4327+# This parameter can be used to add additional element(s) to the end of the
4328+# Probe Response frames. The format for these element(s) is a hexdump of the
4329+# raw information elements (id+len+payload for one or more elements).
4330+# These elements are added after the 'vendor_elements'.
4331+#presp_elements=
4332
4333 ##### Multiple BSSID support ##################################################
4334 #
4335@@ -3045,3 +3321,63 @@ own_ip_addr=127.0.0.1
4336 #bss=wlan0_1
4337 #bssid=00:13:10:95:fe:0b
4338 # ...
4339+#
4340+# Multiple BSSID Advertisement in IEEE 802.11ax
4341+# IEEE Std 802.11ax-2021 added a feature where instead of multiple interfaces
4342+# on a common radio transmitting individual Beacon frames, those interfaces can
4343+# form a set with a common Beacon frame transmitted for all. The interface
4344+# which is brought up first is called the transmitting profile of the MBSSID
4345+# set which transmits the Beacon frames. The remaining interfaces are called
4346+# the non-transmitting profiles and these are advertised inside the Multiple
4347+# BSSID element in the Beacon and Probe Response frames from the first
4348+# interface.
4349+#
4350+# The transmitting interface is visible to all stations in the vicinity, however
4351+# the stations that do not support parsing of the Multiple BSSID element will
4352+# not be able to connect to the non-transmitting interfaces.
4353+#
4354+# Enhanced Multiple BSSID Advertisements (EMA)
4355+# When enabled, the non-transmitting interfaces are split into multiple
4356+# Beacon frames. The number of Beacon frames required to cover all the
4357+# non-transmitting profiles is called the profile periodicity.
4358+#
4359+# Refer to IEEE Std 802.11-2020 for details regarding the procedure and
4360+# required MAC address assignment.
4361+#
4362+# Following configuration is per radio.
4363+# 0 = Disabled (default)
4364+# 1 = Multiple BSSID advertisement enabled.
4365+# 2 = Enhanced multiple BSSID advertisement enabled.
4366+#mbssid=0
4367+#
4368+# The transmitting interface should be added with the 'interface' option while
4369+# the non-transmitting interfaces should be added using the 'bss' option.
4370+# Security configuration should be added separately per interface, if required.
4371+#
4372+# Example:
4373+#mbssid=2
4374+#interface=wlan2
4375+#ctrl_interface=/var/run/hostapd
4376+#wpa_passphrase=0123456789
4377+#ieee80211w=2
4378+#sae_pwe=1
4379+#auth_algs=1
4380+#wpa=2
4381+#wpa_pairwise=CCMP
4382+#ssid=<SSID-0>
4383+#bridge=br-lan
4384+#wpa_key_mgmt=SAE
4385+#bssid=00:03:7f:12:84:84
4386+#
4387+#bss=wlan2-1
4388+#ctrl_interface=/var/run/hostapd
4389+#wpa_passphrase=0123456789
4390+#ieee80211w=2
4391+#sae_pwe=1
4392+#auth_algs=1
4393+#wpa=2
4394+#wpa_pairwise=CCMP
4395+#ssid=<SSID-1>
4396+#bridge=br-lan
4397+#wpa_key_mgmt=SAE
4398+#bssid=00:03:7f:12:84:85
4399diff --git a/hostapd/hostapd.eap_user b/hostapd/hostapd.eap_user
4400index 00edc95..61ef937 100644
4401--- a/hostapd/hostapd.eap_user
4402+++ b/hostapd/hostapd.eap_user
4403@@ -52,8 +52,8 @@
4404 # Arbitrary RADIUS attributes can be added into Access-Accept packets similarly
4405 # to the way radius_auth_req_attr is used for Access-Request packet in
4406 # hostapd.conf. For EAP server, this is configured separately for each user
4407-# entry with radius_accept_attr=<value> line(s) following the main user entry
4408-# line.
4409+# entry with radius_accept_attr=<attr_id>[:<syntax:value>] line(s) following
4410+# the main user entry line.
4411
4412 # Phase 1 users
4413 "user" MD5 "password"
4414diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
4415index 2609121..eb8a383 100644
4416--- a/hostapd/hostapd_cli.c
4417+++ b/hostapd/hostapd_cli.c
4418@@ -21,7 +21,7 @@
4419
4420 static const char *const hostapd_cli_version =
4421 "hostapd_cli v" VERSION_STR "\n"
4422-"Copyright (c) 2004-2022, Jouni Malinen <j@w1.fi> and contributors";
4423+"Copyright (c) 2004-2024, Jouni Malinen <j@w1.fi> and contributors";
4424
4425 static struct wpa_ctrl *ctrl_conn;
4426 static int hostapd_cli_quit = 0;
4427@@ -252,6 +252,13 @@ static int hostapd_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
4428 }
4429
4430
4431+static int hostapd_cli_cmd_close_log(struct wpa_ctrl *ctrl, int argc,
4432+ char *argv[])
4433+{
4434+ return wpa_ctrl_command(ctrl, "CLOSE_LOG");
4435+}
4436+
4437+
4438 static int hostapd_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
4439 {
4440 if (argc > 0 && os_strcmp(argv[0], "driver") == 0)
4441@@ -307,6 +314,12 @@ static void hostapd_cli_action_process(char *msg, size_t len)
4442 }
4443
4444
4445+static void hostapd_cli_action_cb(char *msg, size_t len)
4446+{
4447+ hostapd_cli_action_process(msg, len);
4448+}
4449+
4450+
4451 static int hostapd_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
4452 {
4453 char buf[64];
4454@@ -1155,6 +1168,15 @@ static int hostapd_cli_cmd_fst(struct wpa_ctrl *ctrl, int argc, char *argv[])
4455 #endif /* CONFIG_FST */
4456
4457
4458+#ifdef CONFIG_IEEE80211AX
4459+static int hostapd_cli_cmd_color_change(struct wpa_ctrl *ctrl,
4460+ int argc, char *argv[])
4461+{
4462+ return hostapd_cli_cmd(ctrl, "COLOR_CHANGE", 1, argc, argv);
4463+}
4464+#endif /* CONFIG_IEEE80211AX */
4465+
4466+
4467 static int hostapd_cli_cmd_chan_switch(struct wpa_ctrl *ctrl,
4468 int argc, char *argv[])
4469 {
4470@@ -1169,7 +1191,7 @@ static int hostapd_cli_cmd_chan_switch(struct wpa_ctrl *ctrl,
4471 "arguments (count and freq)\n"
4472 "usage: <cs_count> <freq> [sec_channel_offset=] "
4473 "[center_freq1=] [center_freq2=] [bandwidth=] "
4474- "[blocktx] [ht|vht]\n");
4475+ "[blocktx] [ht|vht|he|eht]\n");
4476 return -1;
4477 }
4478
4479@@ -1194,34 +1216,76 @@ static int hostapd_cli_cmd_chan_switch(struct wpa_ctrl *ctrl,
4480 }
4481
4482
4483+static int hostapd_cli_cmd_notify_cw_change(struct wpa_ctrl *ctrl,
4484+ int argc, char *argv[])
4485+{
4486+ return hostapd_cli_cmd(ctrl, "NOTIFY_CW_CHANGE", 1, argc, argv);
4487+}
4488+
4489+
4490 static int hostapd_cli_cmd_enable(struct wpa_ctrl *ctrl, int argc,
4491- char *argv[])
4492+ char *argv[])
4493 {
4494 return wpa_ctrl_command(ctrl, "ENABLE");
4495 }
4496
4497
4498 static int hostapd_cli_cmd_reload(struct wpa_ctrl *ctrl, int argc,
4499- char *argv[])
4500+ char *argv[])
4501 {
4502 return wpa_ctrl_command(ctrl, "RELOAD");
4503 }
4504
4505
4506-static int hostapd_cli_cmd_disable(struct wpa_ctrl *ctrl, int argc,
4507+static int hostapd_cli_cmd_reload_bss(struct wpa_ctrl *ctrl, int argc,
4508 char *argv[])
4509 {
4510+ return wpa_ctrl_command(ctrl, "RELOAD_BSS");
4511+}
4512+
4513+
4514+static int hostapd_cli_cmd_reload_config(struct wpa_ctrl *ctrl, int argc,
4515+ char *argv[])
4516+{
4517+ return wpa_ctrl_command(ctrl, "RELOAD_CONFIG");
4518+}
4519+
4520+
4521+static int hostapd_cli_cmd_disable(struct wpa_ctrl *ctrl, int argc,
4522+ char *argv[])
4523+{
4524 return wpa_ctrl_command(ctrl, "DISABLE");
4525 }
4526
4527
4528-static int hostapd_cli_cmd_update_beacon(struct wpa_ctrl *ctrl, int argc,
4529+static int hostapd_cli_cmd_enable_mld(struct wpa_ctrl *ctrl, int argc,
4530 char *argv[])
4531 {
4532+ return wpa_ctrl_command(ctrl, "ENABLE_MLD");
4533+}
4534+
4535+
4536+static int hostapd_cli_cmd_disable_mld(struct wpa_ctrl *ctrl, int argc,
4537+ char *argv[])
4538+{
4539+ return wpa_ctrl_command(ctrl, "DISABLE_MLD");
4540+}
4541+
4542+
4543+static int hostapd_cli_cmd_update_beacon(struct wpa_ctrl *ctrl, int argc,
4544+ char *argv[])
4545+{
4546 return wpa_ctrl_command(ctrl, "UPDATE_BEACON");
4547 }
4548
4549
4550+static int hostapd_cli_cmd_stop_ap(struct wpa_ctrl *ctrl, int argc,
4551+ char *argv[])
4552+{
4553+ return wpa_ctrl_command(ctrl, "STOP_AP");
4554+}
4555+
4556+
4557 static int hostapd_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
4558 {
4559 char cmd[256];
4560@@ -1366,6 +1430,13 @@ static int hostapd_cli_cmd_driver_flags(struct wpa_ctrl *ctrl, int argc,
4561 }
4562
4563
4564+static int hostapd_cli_cmd_driver_flags2(struct wpa_ctrl *ctrl, int argc,
4565+ char *argv[])
4566+{
4567+ return wpa_ctrl_command(ctrl, "DRIVER_FLAGS2");
4568+}
4569+
4570+
4571 #ifdef CONFIG_DPP
4572
4573 static int hostapd_cli_cmd_dpp_qr_code(struct wpa_ctrl *ctrl, int argc,
4574@@ -1478,7 +1549,7 @@ static int hostapd_cli_cmd_dpp_pkex_remove(struct wpa_ctrl *ctrl, int argc,
4575 static int hostapd_cli_cmd_dpp_controller_start(struct wpa_ctrl *ctrl, int argc,
4576 char *argv[])
4577 {
4578- return hostapd_cli_cmd(ctrl, "DPP_CONTROLLER_START", 1, argc, argv);
4579+ return hostapd_cli_cmd(ctrl, "DPP_CONTROLLER_START", 0, argc, argv);
4580 }
4581
4582
4583@@ -1503,6 +1574,15 @@ static int hostapd_cli_cmd_dpp_stop_chirp(struct wpa_ctrl *ctrl, int argc,
4584 }
4585
4586 #endif /* CONFIG_DPP2 */
4587+
4588+
4589+#ifdef CONFIG_DPP3
4590+static int hostapd_cli_cmd_dpp_push_button(struct wpa_ctrl *ctrl, int argc,
4591+ char *argv[])
4592+{
4593+ return hostapd_cli_cmd(ctrl, "DPP_PUSH_BUTTON", 0, argc, argv);
4594+}
4595+#endif /* CONFIG_DPP3 */
4596 #endif /* CONFIG_DPP */
4597
4598
4599@@ -1534,6 +1614,13 @@ static int hostapd_cli_cmd_req_beacon(struct wpa_ctrl *ctrl, int argc,
4600 }
4601
4602
4603+static int hostapd_cli_cmd_req_link_measurement(struct wpa_ctrl *ctrl, int argc,
4604+ char *argv[])
4605+{
4606+ return hostapd_cli_cmd(ctrl, "REQ_LINK_MEASUREMENT", 1, argc, argv);
4607+}
4608+
4609+
4610 static int hostapd_cli_cmd_reload_wpa_psk(struct wpa_ctrl *ctrl, int argc,
4611 char *argv[])
4612 {
4613@@ -1541,6 +1628,24 @@ static int hostapd_cli_cmd_reload_wpa_psk(struct wpa_ctrl *ctrl, int argc,
4614 }
4615
4616
4617+#ifdef CONFIG_IEEE80211R_AP
4618+
4619+static int hostapd_cli_cmd_get_rxkhs(struct wpa_ctrl *ctrl, int argc,
4620+ char *argv[])
4621+{
4622+ return wpa_ctrl_command(ctrl, "GET_RXKHS");
4623+}
4624+
4625+
4626+static int hostapd_cli_cmd_reload_rxkhs(struct wpa_ctrl *ctrl, int argc,
4627+ char *argv[])
4628+{
4629+ return wpa_ctrl_command(ctrl, "RELOAD_RXKHS");
4630+}
4631+
4632+#endif /* CONFIG_IEEE80211R_AP */
4633+
4634+
4635 #ifdef ANDROID
4636 static int hostapd_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
4637 {
4638@@ -1563,6 +1668,8 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
4639 "= get MIB variables (dot1x, dot11, radius)" },
4640 { "relog", hostapd_cli_cmd_relog, NULL,
4641 "= reload/truncate debug log output file" },
4642+ { "close_log", hostapd_cli_cmd_close_log, NULL,
4643+ "= disable debug log output file" },
4644 { "status", hostapd_cli_cmd_status, NULL,
4645 "= show interface status info" },
4646 { "sta", hostapd_cli_cmd_sta, hostapd_complete_stations,
4647@@ -1648,6 +1755,13 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
4648 "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]\n"
4649 " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]\n"
4650 " = initiate channel switch announcement" },
4651+#ifdef CONFIG_IEEE80211AX
4652+ { "color_change", hostapd_cli_cmd_color_change, NULL,
4653+ "<color> = initiate BSS color change to set the specified color\n"
4654+ "Value 0 will disable the color.\n"},
4655+#endif /* CONFIG_IEEE80211AX */
4656+ { "notify_cw_change", hostapd_cli_cmd_notify_cw_change, NULL,
4657+ "<channel_width> = 0 - 20 MHz, 1 - 40 MHz, 2 - 80 MHz, 3 - 160 MHz" },
4658 { "hs20_wnm_notif", hostapd_cli_cmd_hs20_wnm_notif, NULL,
4659 "<addr> <url>\n"
4660 " = send WNM-Notification Subscription Remediation Request" },
4661@@ -1661,10 +1775,20 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
4662 "= enable hostapd on current interface" },
4663 { "reload", hostapd_cli_cmd_reload, NULL,
4664 "= reload configuration for current interface" },
4665+ { "reload_bss", hostapd_cli_cmd_reload_bss, NULL,
4666+ "= reload configuration for current BSS" },
4667+ { "reload_config", hostapd_cli_cmd_reload_config, NULL,
4668+ "= reload configuration for current interface" },
4669 { "disable", hostapd_cli_cmd_disable, NULL,
4670 "= disable hostapd on current interface" },
4671+ { "enable_mld", hostapd_cli_cmd_enable_mld, NULL,
4672+ "= enable AP MLD to which the interface is affiliated" },
4673+ { "disable_mld", hostapd_cli_cmd_disable_mld, NULL,
4674+ "= disable AP MLD to which the interface is affiliated" },
4675 { "update_beacon", hostapd_cli_cmd_update_beacon, NULL,
4676 "= update Beacon frame contents\n"},
4677+ { "stop_ap", hostapd_cli_cmd_stop_ap, NULL,
4678+ "= stop AP\n"},
4679 { "erp_flush", hostapd_cli_cmd_erp_flush, NULL,
4680 "= drop all ERP keys"},
4681 { "log_level", hostapd_cli_cmd_log_level, NULL,
4682@@ -1686,6 +1810,8 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
4683 " = send FTM range request"},
4684 { "driver_flags", hostapd_cli_cmd_driver_flags, NULL,
4685 " = show supported driver flags"},
4686+ { "driver_flags2", hostapd_cli_cmd_driver_flags2, NULL,
4687+ " = show supported driver flags2"},
4688 #ifdef CONFIG_DPP
4689 { "dpp_qr_code", hostapd_cli_cmd_dpp_qr_code, NULL,
4690 "report a scanned DPP URI from a QR Code" },
4691@@ -1729,6 +1855,10 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
4692 { "dpp_stop_chirp", hostapd_cli_cmd_dpp_stop_chirp, NULL,
4693 "= stop DPP chirp" },
4694 #endif /* CONFIG_DPP2 */
4695+#ifdef CONFIG_DPP3
4696+ { "dpp_push_button", hostapd_cli_cmd_dpp_push_button, NULL,
4697+ "= press DPP push button" },
4698+#endif /* CONFIG_DPP3 */
4699 #endif /* CONFIG_DPP */
4700 { "accept_acl", hostapd_cli_cmd_accept_macacl, NULL,
4701 "=Add/Delete/Show/Clear accept MAC ACL" },
4702@@ -1738,8 +1868,16 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
4703 "<addr> = poll a STA to check connectivity with a QoS null frame" },
4704 { "req_beacon", hostapd_cli_cmd_req_beacon, NULL,
4705 "<addr> [req_mode=] <measurement request hexdump> = send a Beacon report request to a station" },
4706+ { "req_link_measurement", hostapd_cli_cmd_req_link_measurement, NULL,
4707+ "<addr> = send a link measurement report request to a station"},
4708 { "reload_wpa_psk", hostapd_cli_cmd_reload_wpa_psk, NULL,
4709 "= reload wpa_psk_file only" },
4710+#ifdef CONFIG_IEEE80211R_AP
4711+ { "reload_rxkhs", hostapd_cli_cmd_reload_rxkhs, NULL,
4712+ "= reload R0KHs and R1KHs" },
4713+ { "get_rxkhs", hostapd_cli_cmd_get_rxkhs, NULL,
4714+ "= get R0KHs and R1KHs" },
4715+#endif /* CONFIG_IEEE80211R_AP */
4716 #ifdef ANDROID
4717 { "driver", hostapd_cli_cmd_driver, NULL,
4718 "<driver sub command> [<hex formatted data>] = send driver command data" },
4719@@ -2002,7 +2140,6 @@ static void hostapd_cli_interactive(void)
4720 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
4721 }
4722
4723- eloop_register_signal_terminate(hostapd_cli_eloop_terminate, NULL);
4724 edit_init(hostapd_cli_edit_cmd_cb, hostapd_cli_edit_eof_cb,
4725 hostapd_cli_edit_completion_cb, NULL, hfile, NULL);
4726 eloop_register_timeout(ping_interval, 0, hostapd_cli_ping, NULL, NULL);
4727@@ -2026,40 +2163,46 @@ static void hostapd_cli_cleanup(void)
4728 }
4729
4730
4731-static void hostapd_cli_action(struct wpa_ctrl *ctrl)
4732+static void hostapd_cli_action_ping(void *eloop_ctx, void *timeout_ctx)
4733 {
4734- fd_set rfds;
4735- int fd, res;
4736- struct timeval tv;
4737+ struct wpa_ctrl *ctrl = eloop_ctx;
4738 char buf[256];
4739 size_t len;
4740
4741- fd = wpa_ctrl_get_fd(ctrl);
4742+ /* verify that connection is still working */
4743+ len = sizeof(buf) - 1;
4744+ if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
4745+ hostapd_cli_action_cb) < 0 ||
4746+ len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
4747+ printf("hostapd did not reply to PING command - exiting\n");
4748+ eloop_terminate();
4749+ return;
4750+ }
4751+ eloop_register_timeout(ping_interval, 0, hostapd_cli_action_ping,
4752+ ctrl, NULL);
4753+}
4754
4755- while (!hostapd_cli_quit) {
4756- FD_ZERO(&rfds);
4757- FD_SET(fd, &rfds);
4758- tv.tv_sec = ping_interval;
4759- tv.tv_usec = 0;
4760- res = select(fd + 1, &rfds, NULL, NULL, &tv);
4761- if (res < 0 && errno != EINTR) {
4762- perror("select");
4763- break;
4764- }
4765
4766- if (FD_ISSET(fd, &rfds))
4767- hostapd_cli_recv_pending(ctrl, 0, 1);
4768- else {
4769- len = sizeof(buf) - 1;
4770- if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
4771- hostapd_cli_action_process) < 0 ||
4772- len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
4773- printf("hostapd did not reply to PING "
4774- "command - exiting\n");
4775- break;
4776- }
4777- }
4778- }
4779+static void hostapd_cli_action_receive(int sock, void *eloop_ctx,
4780+ void *sock_ctx)
4781+{
4782+ struct wpa_ctrl *ctrl = eloop_ctx;
4783+
4784+ hostapd_cli_recv_pending(ctrl, 0, 1);
4785+}
4786+
4787+
4788+static void hostapd_cli_action(struct wpa_ctrl *ctrl)
4789+{
4790+ int fd;
4791+
4792+ fd = wpa_ctrl_get_fd(ctrl);
4793+ eloop_register_timeout(ping_interval, 0, hostapd_cli_action_ping,
4794+ ctrl, NULL);
4795+ eloop_register_read_sock(fd, hostapd_cli_action_receive, ctrl, NULL);
4796+ eloop_run();
4797+ eloop_cancel_timeout(hostapd_cli_action_ping, ctrl, NULL);
4798+ eloop_unregister_read_sock(fd);
4799 }
4800
4801
4802@@ -2162,6 +2305,8 @@ int main(int argc, char *argv[])
4803 continue;
4804 }
4805
4806+ eloop_register_signal_terminate(hostapd_cli_eloop_terminate, NULL);
4807+
4808 if (action_file && !hostapd_cli_attached)
4809 return -1;
4810 if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue())
4811diff --git a/hostapd/main.c b/hostapd/main.c
4812index c9ec38d..00e02bb 100644
4813--- a/hostapd/main.c
4814+++ b/hostapd/main.c
4815@@ -15,6 +15,7 @@
4816 #include "utils/common.h"
4817 #include "utils/eloop.h"
4818 #include "utils/uuid.h"
4819+#include "crypto/crypto.h"
4820 #include "crypto/random.h"
4821 #include "crypto/tls.h"
4822 #include "common/version.h"
4823@@ -157,14 +158,50 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
4824 struct hostapd_bss_config *conf = hapd->conf;
4825 u8 *b = conf->bssid;
4826 struct wpa_driver_capa capa;
4827+#ifdef CONFIG_IEEE80211BE
4828+ struct hostapd_data *h_hapd = NULL;
4829+#endif /* CONFIG_IEEE80211BE */
4830
4831 if (hapd->driver == NULL || hapd->driver->hapd_init == NULL) {
4832 wpa_printf(MSG_ERROR, "No hostapd driver wrapper available");
4833 return -1;
4834 }
4835
4836+#ifdef CONFIG_IEEE80211BE
4837+ if (conf->mld_ap)
4838+ h_hapd = hostapd_mld_get_first_bss(hapd);
4839+
4840+ if (h_hapd) {
4841+ hapd->drv_priv = h_hapd->drv_priv;
4842+ hapd->interface_added = h_hapd->interface_added;
4843+
4844+ /*
4845+ * All interfaces participating in the AP MLD would have
4846+ * the same MLD address, which is the interface hardware
4847+ * address, while the interface address would be
4848+ * derived from the original interface address if BSSID
4849+ * is not configured, and otherwise it would be the
4850+ * configured BSSID.
4851+ */
4852+ if (is_zero_ether_addr(b)) {
4853+ os_memcpy(hapd->own_addr, h_hapd->mld->mld_addr,
4854+ ETH_ALEN);
4855+ random_mac_addr_keep_oui(hapd->own_addr);
4856+ } else {
4857+ os_memcpy(hapd->own_addr, b, ETH_ALEN);
4858+ }
4859+
4860+ hostapd_mld_add_link(hapd);
4861+ wpa_printf(MSG_DEBUG,
4862+ "Setup of non first link (%d) BSS of MLD %s",
4863+ hapd->mld_link_id, hapd->conf->iface);
4864+
4865+ goto setup_mld;
4866+ }
4867+#endif /* CONFIG_IEEE80211BE */
4868+
4869 /* Initialize the driver interface */
4870- if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5]))
4871+ if (is_zero_ether_addr(b))
4872 b = NULL;
4873
4874 os_memset(&params, 0, sizeof(params));
4875@@ -188,6 +225,19 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
4876 break;
4877 }
4878 params.bssid = b;
4879+#ifdef CONFIG_IEEE80211BE
4880+ /*
4881+ * Use the configured MLD MAC address as the interface hardware address
4882+ * if this AP is a part of an AP MLD.
4883+ */
4884+ if (hapd->conf->mld_ap) {
4885+ if (!is_zero_ether_addr(hapd->conf->mld_addr))
4886+ params.bssid = hapd->conf->mld_addr;
4887+ else
4888+ params.bssid = NULL;
4889+ }
4890+#endif /* CONFIG_IEEE80211BE */
4891+
4892 params.ifname = hapd->conf->iface;
4893 params.driver_params = hapd->iconf->driver_params;
4894 params.use_pae_group_addr = hapd->conf->use_pae_group_addr;
4895@@ -213,12 +263,36 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
4896 return -1;
4897 }
4898
4899+#ifdef CONFIG_IEEE80211BE
4900+ /*
4901+ * This is the first interface added to the AP MLD, so have the
4902+ * interface hardware address be the MLD address, while the link address
4903+ * would be derived from the original interface address if BSSID is not
4904+ * configured, and otherwise it would be the configured BSSID.
4905+ */
4906+ if (hapd->conf->mld_ap) {
4907+ os_memcpy(hapd->mld->mld_addr, hapd->own_addr, ETH_ALEN);
4908+
4909+ if (!b)
4910+ random_mac_addr_keep_oui(hapd->own_addr);
4911+ else
4912+ os_memcpy(hapd->own_addr, b, ETH_ALEN);
4913+
4914+ hostapd_mld_add_link(hapd);
4915+ wpa_printf(MSG_DEBUG, "Setup of first link (%d) BSS of MLD %s",
4916+ hapd->mld_link_id, hapd->conf->iface);
4917+ }
4918+
4919+setup_mld:
4920+#endif /* CONFIG_IEEE80211BE */
4921+
4922 if (hapd->driver->get_capa &&
4923 hapd->driver->get_capa(hapd->drv_priv, &capa) == 0) {
4924 struct wowlan_triggers *triggs;
4925
4926 iface->drv_flags = capa.flags;
4927 iface->drv_flags2 = capa.flags2;
4928+ iface->drv_rrm_flags = capa.rrm_flags;
4929 iface->probe_resp_offloads = capa.probe_resp_offloads;
4930 /*
4931 * Use default extended capa values from per-radio information
4932@@ -234,14 +308,41 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
4933 */
4934 hostapd_get_ext_capa(iface);
4935
4936+ hostapd_get_mld_capa(iface);
4937+
4938 triggs = wpa_get_wowlan_triggers(conf->wowlan_triggers, &capa);
4939 if (triggs && hapd->driver->set_wowlan) {
4940 if (hapd->driver->set_wowlan(hapd->drv_priv, triggs))
4941 wpa_printf(MSG_ERROR, "set_wowlan failed");
4942 }
4943 os_free(triggs);
4944+
4945+ iface->mbssid_max_interfaces = capa.mbssid_max_interfaces;
4946+ iface->ema_max_periodicity = capa.ema_max_periodicity;
4947 }
4948
4949+#ifdef CONFIG_IEEE80211BE
4950+ if (hapd->conf->mld_ap) {
4951+ if (!(iface->drv_flags2 & WPA_DRIVER_FLAGS2_MLO)) {
4952+ wpa_printf(MSG_INFO,
4953+ "MLD: Not supported by the driver");
4954+ return -1;
4955+ }
4956+
4957+ /* Initialize the BSS parameter change to 1 */
4958+ hapd->eht_mld_bss_param_change = 1;
4959+
4960+ wpa_printf(MSG_DEBUG,
4961+ "MLD: Set link_id=%u, mld_addr=" MACSTR
4962+ ", own_addr=" MACSTR,
4963+ hapd->mld_link_id, MAC2STR(hapd->mld->mld_addr),
4964+ MAC2STR(hapd->own_addr));
4965+
4966+ hostapd_drv_link_add(hapd, hapd->mld_link_id,
4967+ hapd->own_addr);
4968+ }
4969+#endif /* CONFIG_IEEE80211BE */
4970+
4971 return 0;
4972 }
4973
4974@@ -454,7 +555,7 @@ static void show_version(void)
4975 "hostapd v%s\n"
4976 "User space daemon for IEEE 802.11 AP management,\n"
4977 "IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"
4978- "Copyright (c) 2002-2022, Jouni Malinen <j@w1.fi> "
4979+ "Copyright (c) 2002-2024, Jouni Malinen <j@w1.fi> "
4980 "and contributors\n",
4981 VERSION_STR);
4982 }
4983@@ -465,7 +566,7 @@ static void usage(void)
4984 show_version();
4985 fprintf(stderr,
4986 "\n"
4987- "usage: hostapd [-hdBKtv] [-P <PID file>] [-e <entropy file>] "
4988+ "usage: hostapd [-hdBKtvq] [-P <PID file>] [-e <entropy file>] "
4989 "\\\n"
4990 " [-g <global ctrl_iface>] [-G <group>]\\\n"
4991 " [-i <comma-separated list of interface names>]\\\n"
4992@@ -493,7 +594,8 @@ static void usage(void)
4993 #endif /* CONFIG_DEBUG_SYSLOG */
4994 " -S start all the interfaces synchronously\n"
4995 " -t include timestamps in some debug messages\n"
4996- " -v show hostapd version\n");
4997+ " -v show hostapd version\n"
4998+ " -q show less debug messages (-qq for even less)\n");
4999
5000 exit(1);
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches