diff --git a/feeds/ipq95xx/hostapd/Makefile b/feeds/ipq95xx/hostapd/Makefile index 439fe122..d351bac3 100644 --- a/feeds/ipq95xx/hostapd/Makefile +++ b/feeds/ipq95xx/hostapd/Makefile @@ -5,13 +5,11 @@ include $(TOPDIR)/rules.mk PKG_NAME:=hostapd -PKG_RELEASE:=$(AUTORELEASE) +PKG_VERSION:=2023-02-21-ath12.3-cs -PKG_SOURCE_URL:=http://w1.fi/hostap.git -PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2021-12-13 -PKG_SOURCE_VERSION:=b26f5c0fe3 -PKG_MIRROR_HASH:=2c5b72056b6efc3a16ca912118b324371527c7ac79c4b997349d94680538a7d8 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_HASH:=639140658012286453c9f4a8d92d70efa0bbfc23d71ddea0496cf3dc90e39c80 +PKG_SOURCE_URL:=@KERNEL/software/utils/dtc PKG_MAINTAINER:=Felix Fietkau PKG_LICENSE:=BSD-3-Clause diff --git a/feeds/ipq95xx/hostapd/patches/001-wolfssl-init-RNG-with-ECC-key.patch b/feeds/ipq95xx/hostapd/patches/001-wolfssl-init-RNG-with-ECC-key.patch new file mode 100644 index 00000000..269dcaac --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/001-wolfssl-init-RNG-with-ECC-key.patch @@ -0,0 +1,43 @@ +From 21ce83b4ae2b9563175fdb4fc4312096cc399cf8 Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Wed, 5 May 2021 00:44:34 +0200 +Subject: [PATCH] wolfssl: add RNG to EC key + +Since upstream commit 6467de5a8840 ("Randomize z ordinates in +scalar mult when timing resistant") WolfSSL requires a RNG for +the EC key when built hardened which is the default. + +Set the RNG for the EC key to fix connections for OWE clients. + +Signed-off-by: David Bauer +--- + src/crypto/crypto_wolfssl.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/src/crypto/crypto_wolfssl.c ++++ b/src/crypto/crypto_wolfssl.c +@@ -1340,6 +1340,7 @@ int ecc_projective_add_point(ecc_point * + + struct crypto_ec { + ecc_key key; ++ WC_RNG rng; + mp_int a; + mp_int prime; + mp_int order; +@@ -1394,6 +1395,8 @@ struct crypto_ec * crypto_ec_init(int gr + return NULL; + + if (wc_ecc_init(&e->key) != 0 || ++ wc_InitRng(&e->rng) != 0 || ++ wc_ecc_set_rng(&e->key, &e->rng) != 0 || + wc_ecc_set_curve(&e->key, 0, curve_id) != 0 || + mp_init(&e->a) != MP_OKAY || + mp_init(&e->prime) != MP_OKAY || +@@ -1425,6 +1428,7 @@ void crypto_ec_deinit(struct crypto_ec* + mp_clear(&e->order); + mp_clear(&e->prime); + mp_clear(&e->a); ++ wc_FreeRng(&e->rng); + wc_ecc_free(&e->key); + os_free(e); + } diff --git a/feeds/ipq95xx/hostapd/patches/021-fix-sta-add-after-previous-connection.patch b/feeds/ipq95xx/hostapd/patches/021-fix-sta-add-after-previous-connection.patch new file mode 100644 index 00000000..edf599e3 --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/021-fix-sta-add-after-previous-connection.patch @@ -0,0 +1,26 @@ +--- a/src/ap/ieee802_11.c ++++ b/src/ap/ieee802_11.c +@@ -4621,6 +4621,13 @@ static int add_associated_sta(struct hos + * drivers to accept the STA parameter configuration. Since this is + * after a new FT-over-DS exchange, a new TK has been derived, so key + * reinstallation is not a concern for this case. ++ * ++ * If the STA was associated and authorized earlier, but came for a new ++ * connection (!added_unassoc + !reassoc), remove the existing STA entry ++ * so that it can be re-added. This case is rarely seen when the AP could ++ * not receive the deauth/disassoc frame from the STA. And the STA comes ++ * back with new connection within a short period or before the inactive ++ * STA entry is removed from the list. + */ + wpa_printf(MSG_DEBUG, "Add associated STA " MACSTR + " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)", +@@ -4634,7 +4641,8 @@ static int add_associated_sta(struct hos + (!(sta->flags & WLAN_STA_AUTHORIZED) || + (reassoc && sta->ft_over_ds && sta->auth_alg == WLAN_AUTH_FT) || + (!wpa_auth_sta_ft_tk_already_set(sta->wpa_sm) && +- !wpa_auth_sta_fils_tk_already_set(sta->wpa_sm)))) { ++ !wpa_auth_sta_fils_tk_already_set(sta->wpa_sm)) || ++ (!reassoc && (sta->flags & WLAN_STA_AUTHORIZED)))) { + hostapd_drv_sta_remove(hapd, sta->addr); + wpa_auth_sm_event(sta->wpa_sm, WPA_DRV_STA_REMOVED); + set = 0; diff --git a/feeds/ipq95xx/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch b/feeds/ipq95xx/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch new file mode 100644 index 00000000..a25a8ecc --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch @@ -0,0 +1,27 @@ +From: Felix Fietkau +Date: Thu, 8 Jul 2021 16:33:03 +0200 +Subject: [PATCH] hostapd: fix use of uninitialized stack variables + +When a CSA is performed on an 80 MHz channel, hostapd_change_config_freq +unconditionally calls hostapd_set_oper_centr_freq_seg0/1_idx with seg0/1 +filled by ieee80211_freq_to_chan. +However, if ieee80211_freq_to_chan fails (because the freq is 0 or invalid), +seg0/1 remains uninitialized and filled with stack garbage, causing errors +such as "hostapd: 80 MHz: center segment 1 configured" + +Signed-off-by: Felix Fietkau +--- + +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/hostapd.c +=================================================================== +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/hostapd.c ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/hostapd.c +@@ -4352,7 +4352,7 @@ static int hostapd_change_config_freq(st + struct hostapd_freq_params *old_params) + { + int channel; +- u8 seg0, seg1 = 0; ++ u8 seg0 = 0, seg1 = 0; + struct hostapd_hw_modes *mode; + + if (!params->channel) { diff --git a/feeds/ipq95xx/hostapd/patches/023-ndisc_snoop-call-dl_list_del-before-freeing-ipv6-add.patch b/feeds/ipq95xx/hostapd/patches/023-ndisc_snoop-call-dl_list_del-before-freeing-ipv6-add.patch new file mode 100644 index 00000000..9ff9b239 --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/023-ndisc_snoop-call-dl_list_del-before-freeing-ipv6-add.patch @@ -0,0 +1,19 @@ +From: Felix Fietkau +Date: Wed, 28 Jul 2021 05:43:29 +0200 +Subject: [PATCH] ndisc_snoop: call dl_list_del before freeing ipv6 addresses + +Fixes a segmentation fault on sta disconnect + +Signed-off-by: Felix Fietkau +--- + +--- a/src/ap/ndisc_snoop.c ++++ b/src/ap/ndisc_snoop.c +@@ -61,6 +61,7 @@ void sta_ip6addr_del(struct hostapd_data + dl_list_for_each_safe(ip6addr, prev, &sta->ip6addr, struct ip6addr, + list) { + hostapd_drv_br_delete_ip_neigh(hapd, 6, (u8 *) &ip6addr->addr); ++ dl_list_del(&ip6addr->list); + os_free(ip6addr); + } + } diff --git a/feeds/ipq95xx/hostapd/patches/050-build_fix.patch b/feeds/ipq95xx/hostapd/patches/050-build_fix.patch new file mode 100644 index 00000000..8680b07c --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/050-build_fix.patch @@ -0,0 +1,20 @@ +--- a/hostapd/Makefile ++++ b/hostapd/Makefile +@@ -324,6 +324,7 @@ ifdef CONFIG_FILS + CFLAGS += -DCONFIG_FILS + OBJS += ../src/ap/fils_hlp.o + NEED_SHA384=y ++NEED_HMAC_SHA384_KDF=y + NEED_AES_SIV=y + ifdef CONFIG_FILS_SK_PFS + CFLAGS += -DCONFIG_FILS_SK_PFS +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -331,6 +331,7 @@ endif + ifdef CONFIG_FILS + CFLAGS += -DCONFIG_FILS + NEED_SHA384=y ++NEED_HMAC_SHA384_KDF=y + NEED_AES_SIV=y + ifdef CONFIG_FILS_SK_PFS + CFLAGS += -DCONFIG_FILS_SK_PFS diff --git a/feeds/ipq95xx/hostapd/patches/100-daemonize_fix.patch b/feeds/ipq95xx/hostapd/patches/100-daemonize_fix.patch deleted file mode 100644 index 687bd408..00000000 --- a/feeds/ipq95xx/hostapd/patches/100-daemonize_fix.patch +++ /dev/null @@ -1,97 +0,0 @@ ---- a/src/utils/os_unix.c -+++ b/src/utils/os_unix.c -@@ -10,6 +10,7 @@ - - #include - #include -+#include - - #ifdef ANDROID - #include -@@ -188,59 +189,46 @@ int os_gmtime(os_time_t t, struct os_tm - return 0; - } - -- --#ifdef __APPLE__ --#include --static int os_daemon(int nochdir, int noclose) -+int os_daemonize(const char *pid_file) - { -- int devnull; -+ int pid = 0, i, devnull; - -- if (chdir("/") < 0) -- return -1; -+#if defined(__uClinux__) || defined(__sun__) -+ return -1; -+#else /* defined(__uClinux__) || defined(__sun__) */ - -- devnull = open("/dev/null", O_RDWR); -- if (devnull < 0) -+#ifndef __APPLE__ -+ pid = fork(); -+ if (pid < 0) - return -1; -+#endif - -- if (dup2(devnull, STDIN_FILENO) < 0) { -- close(devnull); -- return -1; -+ if (pid > 0) { -+ if (pid_file) { -+ FILE *f = fopen(pid_file, "w"); -+ if (f) { -+ fprintf(f, "%u\n", pid); -+ fclose(f); -+ } -+ } -+ _exit(0); - } - -- if (dup2(devnull, STDOUT_FILENO) < 0) { -- close(devnull); -+ if (setsid() < 0) - return -1; -- } - -- if (dup2(devnull, STDERR_FILENO) < 0) { -- close(devnull); -+ if (chdir("/") < 0) - return -1; -- } -- -- return 0; --} --#else /* __APPLE__ */ --#define os_daemon daemon --#endif /* __APPLE__ */ - -- --int os_daemonize(const char *pid_file) --{ --#if defined(__uClinux__) || defined(__sun__) -- return -1; --#else /* defined(__uClinux__) || defined(__sun__) */ -- if (os_daemon(0, 0)) { -- perror("daemon"); -+ devnull = open("/dev/null", O_RDWR); -+ if (devnull < 0) - return -1; -- } - -- if (pid_file) { -- FILE *f = fopen(pid_file, "w"); -- if (f) { -- fprintf(f, "%u\n", getpid()); -- fclose(f); -- } -- } -+ for (i = 0; i <= STDERR_FILENO; i++) -+ dup2(devnull, i); -+ -+ if (devnull > 2) -+ close(devnull); - - return -0; - #endif /* defined(__uClinux__) || defined(__sun__) */ diff --git a/feeds/ipq95xx/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch b/feeds/ipq95xx/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch new file mode 100644 index 00000000..22107944 --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch @@ -0,0 +1,8051 @@ +From e16f200dc1d2f69efc78c7c55af0d7b410a981f9 Mon Sep 17 00:00:00 2001 +From: Glenn Strauss +Date: Tue, 5 Jul 2022 02:49:50 -0400 +Subject: [PATCH 1/7] mbedtls: TLS/crypto option (initial port) + +Signed-off-by: Glenn Strauss +--- + hostapd/Makefile | 91 + + hostapd/defconfig | 15 +- + src/crypto/crypto_mbedtls.c | 4043 +++++++++++++++++ + src/crypto/tls_mbedtls.c | 3313 ++++++++++++++ + .../build/build-wpa_supplicant-mbedtls.config | 24 + + tests/hwsim/example-hostapd.config | 4 + + tests/hwsim/example-wpa_supplicant.config | 4 + + wpa_supplicant/Makefile | 74 + + wpa_supplicant/defconfig | 6 +- + 9 files changed, 7571 insertions(+), 3 deletions(-) + create mode 100644 src/crypto/crypto_mbedtls.c + create mode 100644 src/crypto/tls_mbedtls.c + create mode 100644 tests/build/build-wpa_supplicant-mbedtls.config + +--- a/hostapd/Makefile ++++ b/hostapd/Makefile +@@ -745,6 +745,40 @@ endif + CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\" + endif + ++ifeq ($(CONFIG_TLS), mbedtls) ++ifndef CONFIG_CRYPTO ++CONFIG_CRYPTO=mbedtls ++endif ++ifdef TLS_FUNCS ++OBJS += ../src/crypto/tls_mbedtls.o ++LIBS += -lmbedtls ++ifndef CONFIG_DPP ++LIBS += -lmbedx509 ++endif ++endif ++OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o ++HOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o ++SOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o ++ifdef NEED_FIPS186_2_PRF ++OBJS += ../src/crypto/fips_prf_internal.o ++SHA1OBJS += ../src/crypto/sha1-internal.o ++endif ++ifeq ($(CONFIG_CRYPTO), mbedtls) ++ifdef CONFIG_DPP ++LIBS += -lmbedx509 ++LIBS_h += -lmbedx509 ++LIBS_n += -lmbedx509 ++LIBS_s += -lmbedx509 ++endif ++LIBS += -lmbedcrypto ++LIBS_h += -lmbedcrypto ++LIBS_n += -lmbedcrypto ++LIBS_s += -lmbedcrypto ++# XXX: create a config option? ++CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 ++endif ++endif ++ + ifeq ($(CONFIG_TLS), gnutls) + ifndef CONFIG_CRYPTO + # default to libgcrypt +@@ -924,9 +958,11 @@ endif + + ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + AESOBJS += ../src/crypto/aes-wrap.o + endif + endif ++endif + ifdef NEED_AES_EAX + AESOBJS += ../src/crypto/aes-eax.o + NEED_AES_CTR=y +@@ -936,38 +972,48 @@ AESOBJS += ../src/crypto/aes-siv.o + NEED_AES_CTR=y + endif + ifdef NEED_AES_CTR ++ifneq ($(CONFIG_TLS), mbedtls) + AESOBJS += ../src/crypto/aes-ctr.o + endif ++endif + ifdef NEED_AES_ENCBLOCK ++ifneq ($(CONFIG_TLS), mbedtls) + AESOBJS += ../src/crypto/aes-encblock.o + endif ++endif + ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), linux) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + AESOBJS += ../src/crypto/aes-omac1.o + endif + endif + endif ++endif + ifdef NEED_AES_UNWRAP + ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), linux) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + NEED_AES_DEC=y + AESOBJS += ../src/crypto/aes-unwrap.o + endif + endif + endif + endif ++endif + ifdef NEED_AES_CBC + NEED_AES_DEC=y + ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), linux) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + AESOBJS += ../src/crypto/aes-cbc.o + endif + endif + endif + endif ++endif + ifdef NEED_AES_DEC + ifdef CONFIG_INTERNAL_AES + AESOBJS += ../src/crypto/aes-internal-dec.o +@@ -982,12 +1028,16 @@ ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), linux) + ifneq ($(CONFIG_TLS), gnutls) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + SHA1OBJS += ../src/crypto/sha1.o + endif + endif + endif + endif ++endif ++ifneq ($(CONFIG_TLS), mbedtls) + SHA1OBJS += ../src/crypto/sha1-prf.o ++endif + ifdef CONFIG_INTERNAL_SHA1 + SHA1OBJS += ../src/crypto/sha1-internal.o + ifdef NEED_FIPS186_2_PRF +@@ -996,16 +1046,22 @@ endif + endif + ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + SHA1OBJS += ../src/crypto/sha1-pbkdf2.o + endif + endif ++endif + ifdef NEED_T_PRF ++ifneq ($(CONFIG_TLS), mbedtls) + SHA1OBJS += ../src/crypto/sha1-tprf.o + endif ++endif + ifdef NEED_TLS_PRF ++ifneq ($(CONFIG_TLS), mbedtls) + SHA1OBJS += ../src/crypto/sha1-tlsprf.o + endif + endif ++endif + + ifdef NEED_SHA1 + OBJS += $(SHA1OBJS) +@@ -1015,11 +1071,13 @@ ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), linux) + ifneq ($(CONFIG_TLS), gnutls) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/md5.o + endif + endif + endif + endif ++endif + + ifdef NEED_MD5 + ifdef CONFIG_INTERNAL_MD5 +@@ -1058,56 +1116,81 @@ ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), linux) + ifneq ($(CONFIG_TLS), gnutls) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/sha256.o + endif + endif + endif + endif ++endif ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/sha256-prf.o ++endif + ifdef CONFIG_INTERNAL_SHA256 + OBJS += ../src/crypto/sha256-internal.o + endif + ifdef NEED_TLS_PRF_SHA256 ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/sha256-tlsprf.o + endif ++endif + ifdef NEED_TLS_PRF_SHA384 ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/sha384-tlsprf.o + endif ++endif + ifdef NEED_HMAC_SHA256_KDF ++CFLAGS += -DCONFIG_HMAC_SHA256_KDF ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/sha256-kdf.o + endif ++endif + ifdef NEED_HMAC_SHA384_KDF ++CFLAGS += -DCONFIG_HMAC_SHA384_KDF ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/sha384-kdf.o + endif ++endif + ifdef NEED_HMAC_SHA512_KDF ++CFLAGS += -DCONFIG_HMAC_SHA512_KDF ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/sha512-kdf.o + endif ++endif + ifdef NEED_SHA384 + CFLAGS += -DCONFIG_SHA384 + ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), linux) + ifneq ($(CONFIG_TLS), gnutls) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/sha384.o + endif + endif + endif + endif ++endif ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/sha384-prf.o + endif ++endif + ifdef NEED_SHA512 + CFLAGS += -DCONFIG_SHA512 + ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), linux) + ifneq ($(CONFIG_TLS), gnutls) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/sha512.o + endif + endif + endif + endif ++endif ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/sha512-prf.o + endif ++endif + + ifdef CONFIG_INTERNAL_SHA384 + CFLAGS += -DCONFIG_INTERNAL_SHA384 +@@ -1152,11 +1235,13 @@ HOBJS += $(SHA1OBJS) + ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), linux) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + HOBJS += ../src/crypto/md5.o + endif + endif + endif + endif ++endif + + ifdef CONFIG_RADIUS_SERVER + CFLAGS += -DRADIUS_SERVER +@@ -1329,7 +1414,9 @@ NOBJS += ../src/utils/trace.o + endif + + HOBJS += hlr_auc_gw.o ../src/utils/common.o ../src/utils/wpa_debug.o ../src/utils/os_$(CONFIG_OS).o ../src/utils/wpabuf.o ../src/crypto/milenage.o ++ifneq ($(CONFIG_TLS), mbedtls) + HOBJS += ../src/crypto/aes-encblock.o ++endif + ifdef CONFIG_INTERNAL_AES + HOBJS += ../src/crypto/aes-internal.o + HOBJS += ../src/crypto/aes-internal-enc.o +@@ -1352,13 +1439,17 @@ SOBJS += ../src/common/sae.o + SOBJS += ../src/common/sae_pk.o + SOBJS += ../src/common/dragonfly.o + SOBJS += $(AESOBJS) ++ifneq ($(CONFIG_TLS), mbedtls) + SOBJS += ../src/crypto/sha256-prf.o + SOBJS += ../src/crypto/sha384-prf.o + SOBJS += ../src/crypto/sha512-prf.o ++endif + SOBJS += ../src/crypto/dh_groups.o ++ifneq ($(CONFIG_TLS), mbedtls) + SOBJS += ../src/crypto/sha256-kdf.o + SOBJS += ../src/crypto/sha384-kdf.o + SOBJS += ../src/crypto/sha512-kdf.o ++endif + + _OBJS_VAR := NOBJS + include ../src/objs.mk +--- a/hostapd/defconfig ++++ b/hostapd/defconfig +@@ -6,9 +6,21 @@ + # just setting VARIABLE=n is not disabling that variable. + # + # This file is included in Makefile, so variables like CFLAGS and LIBS can also +-# be modified from here. In most cass, these lines should use += in order not ++# be modified from here. In most cases, these lines should use += in order not + # to override previous values of the variables. + ++ ++# Uncomment following two lines and fix the paths if you have installed TLS ++# libraries in a non-default location ++#CFLAGS += -I/usr/local/openssl/include ++#LIBS += -L/usr/local/openssl/lib ++ ++# Some Red Hat versions seem to include kerberos header files from OpenSSL, but ++# the kerberos files are not in the default include path. Following line can be ++# used to fix build issues on such systems (krb5.h not found). ++#CFLAGS += -I/usr/include/kerberos ++ ++ + # Driver interface for Host AP driver + CONFIG_DRIVER_HOSTAP=y + +@@ -278,6 +290,7 @@ CONFIG_IPV6=y + # openssl = OpenSSL (default) + # gnutls = GnuTLS + # internal = Internal TLSv1 implementation (experimental) ++# mbedtls = mbed TLS + # linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) + # none = Empty template + #CONFIG_TLS=openssl +--- /dev/null ++++ b/src/crypto/crypto_mbedtls.c +@@ -0,0 +1,4043 @@ ++/* ++ * crypto wrapper functions for mbed TLS ++ * ++ * SPDX-FileCopyrightText: 2022 Glenn Strauss ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#include "utils/includes.h" ++#include "utils/common.h" ++ ++#include ++#include ++#include ++#include /* mbedtls_platform_zeroize() */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef MBEDTLS_PRIVATE ++#define MBEDTLS_PRIVATE(x) x ++#endif ++ ++/* hostapd/wpa_supplicant provides forced_memzero(), ++ * but prefer mbedtls_platform_zeroize() */ ++#define forced_memzero(ptr,sz) mbedtls_platform_zeroize(ptr,sz) ++ ++#ifndef __has_attribute ++#define __has_attribute(x) 0 ++#endif ++ ++#ifndef __GNUC_PREREQ ++#define __GNUC_PREREQ(maj,min) 0 ++#endif ++ ++#ifndef __attribute_cold__ ++#if __has_attribute(cold) \ ++ || __GNUC_PREREQ(4,3) ++#define __attribute_cold__ __attribute__((__cold__)) ++#else ++#define __attribute_cold__ ++#endif ++#endif ++ ++#ifndef __attribute_noinline__ ++#if __has_attribute(noinline) \ ++ || __GNUC_PREREQ(3,1) ++#define __attribute_noinline__ __attribute__((__noinline__)) ++#else ++#define __attribute_noinline__ ++#endif ++#endif ++ ++#include "crypto.h" ++#include "aes_wrap.h" ++#include "aes.h" ++#include "md5.h" ++#include "sha1.h" ++#include "sha256.h" ++#include "sha384.h" ++#include "sha512.h" ++ ++ ++/* ++ * selective code inclusion based on preprocessor defines ++ * ++ * future: additional code could be wrapped with preprocessor checks if ++ * wpa_supplicant/Makefile and hostap/Makefile were more consistent with ++ * setting preprocessor defines for named groups of functionality ++ */ ++ ++#if defined(CONFIG_FIPS) ++#undef MBEDTLS_MD4_C /* omit md4_vector() */ ++#undef MBEDTLS_MD5_C /* omit md5_vector() hmac_md5_vector() hmac_md5() */ ++#undef MBEDTLS_DES_C /* omit des_encrypt() */ ++#undef MBEDTLS_NIST_KW_C /* omit aes_wrap() aes_unwrap() */ ++#define CRYPTO_MBEDTLS_CONFIG_FIPS ++#endif ++ ++#if !defined(CONFIG_FIPS) ++#if defined(EAP_PWD) \ ++ || defined(EAP_LEAP) || defined(EAP_LEAP_DYNAMIC) \ ++ || defined(EAP_TTLS) || defined(EAP_TTLS_DYNAMIC) \ ++ || defined(EAP_MSCHAPv2) || defined(EAP_MSCHAPv2_DYNAMIC) \ ++ || defined(EAP_SERVER_MSCHAPV2) ++#ifndef MBEDTLS_MD4_C /* (MD4 not in mbedtls 3.x) */ ++#include "md4-internal.c"/* pull in hostap local implementation */ ++#endif /* md4_vector() */ ++#else ++#undef MBEDTLS_MD4_C /* omit md4_vector() */ ++#endif ++#endif ++ ++#if !defined(CONFIG_NO_RC4) && !defined(CONFIG_NO_WPA) ++#ifndef MBEDTLS_ARC4_C /* (RC4 not in mbedtls 3.x) */ ++#include "rc4.c" /* pull in hostap local implementation */ ++#endif /* rc4_skip() */ ++#else ++#undef MBEDTLS_ARC4_C /* omit rc4_skip() */ ++#endif ++ ++#if defined(CONFIG_MACSEC) \ ++ || defined(CONFIG_NO_RADIUS) \ ++ || defined(CONFIG_IEEE80211R) \ ++ || defined(EAP_SERVER_FAST) \ ++ || defined(EAP_SERVER_TEAP) \ ++ || !defined(CONFIG_NO_WPA) ++ /* aes_wrap() aes_unwrap() */ ++#else ++#undef MBEDTLS_NIST_KW_C /* omit aes_wrap() aes_unwrap() */ ++#endif ++ ++#if !defined(CONFIG_SHA256) ++#undef MBEDTLS_SHA256_C ++#endif ++ ++#if !defined(CONFIG_SHA384) && !defined(CONFIG_SHA512) ++#undef MBEDTLS_SHA512_C ++#endif ++ ++#if defined(CONFIG_HMAC_SHA256_KDF) ++#define CRYPTO_MBEDTLS_HMAC_KDF_SHA256 ++#endif ++#if defined(CONFIG_HMAC_SHA384_KDF) ++#define CRYPTO_MBEDTLS_HMAC_KDF_SHA384 ++#endif ++#if defined(CONFIG_HMAC_SHA512_KDF) ++#define CRYPTO_MBEDTLS_HMAC_KDF_SHA512 ++#endif ++ ++#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) \ ++ || defined(EAP_TEAP) || defined(EAP_TEAP_DYNAMIC) || defined(EAP_SERVER_FAST) ++#define CRYPTO_MBEDTLS_SHA1_T_PRF ++#endif ++ ++#if defined(CONFIG_DES) ++#define CRYPTO_MBEDTLS_DES_ENCRYPT ++#endif /* des_encrypt() */ ++ ++#if !defined(CONFIG_NO_PBKDF2) ++#define CRYPTO_MBEDTLS_PBKDF2_SHA1 ++#endif /* pbkdf2_sha1() */ ++ ++#if defined(EAP_IKEV2) \ ++ || defined(EAP_IKEV2_DYNAMIC) \ ++ || defined(EAP_SERVER_IKEV2) /* CONFIG_EAP_IKEV2=y */ ++#define CRYPTO_MBEDTLS_CRYPTO_CIPHER ++#endif /* crypto_cipher_*() */ ++ ++#if defined(EAP_PWD) || defined(EAP_SERVER_PWD) /* CONFIG_EAP_PWD=y */ ++#define CRYPTO_MBEDTLS_CRYPTO_HASH ++#endif /* crypto_hash_*() */ ++ ++#if defined(EAP_PWD) || defined(EAP_SERVER_PWD) /* CONFIG_EAP_PWD=y */ \ ++ || defined(CONFIG_SAE) /* CONFIG_SAE=y */ ++#define CRYPTO_MBEDTLS_CRYPTO_BIGNUM ++#endif /* crypto_bignum_*() */ ++ ++#if defined(EAP_PWD) /* CONFIG_EAP_PWD=y */ \ ++ || defined(EAP_EKE) /* CONFIG_EAP_EKE=y */ \ ++ || defined(EAP_EKE_DYNAMIC) /* CONFIG_EAP_EKE=y */ \ ++ || defined(EAP_SERVER_EKE) /* CONFIG_EAP_EKE=y */ \ ++ || defined(EAP_IKEV2) /* CONFIG_EAP_IKEV2y */ \ ++ || defined(EAP_IKEV2_DYNAMIC)/* CONFIG_EAP_IKEV2=y */ \ ++ || defined(EAP_SERVER_IKEV2) /* CONFIG_EAP_IKEV2=y */ \ ++ || defined(CONFIG_SAE) /* CONFIG_SAE=y */ \ ++ || defined(CONFIG_WPS) /* CONFIG_WPS=y */ ++#define CRYPTO_MBEDTLS_CRYPTO_DH ++#if defined(CONFIG_WPS_NFC) ++#define CRYPTO_MBEDTLS_DH5_INIT_FIXED ++#endif /* dh5_init_fixed() */ ++#endif /* crypto_dh_*() */ ++ ++#if !defined(CONFIG_NO_WPA) /* CONFIG_NO_WPA= */ ++#define CRYPTO_MBEDTLS_CRYPTO_ECDH ++#endif /* crypto_ecdh_*() */ ++ ++#if defined(CONFIG_ECC) ++#define CRYPTO_MBEDTLS_CRYPTO_BIGNUM ++#define CRYPTO_MBEDTLS_CRYPTO_EC ++#endif /* crypto_ec_*() crypto_ec_key_*() */ ++ ++#if defined(CONFIG_DPP) /* CONFIG_DPP=y */ ++#define CRYPTO_MBEDTLS_CRYPTO_EC_DPP /* extra for DPP */ ++#define CRYPTO_MBEDTLS_CRYPTO_CSR ++#endif /* crypto_csr_*() */ ++ ++#if defined(CONFIG_DPP3) /* CONFIG_DPP3=y */ ++#define CRYPTO_MBEDTLS_CRYPTO_HPKE ++#endif ++ ++#if defined(CONFIG_DPP2) /* CONFIG_DPP2=y */ ++#define CRYPTO_MBEDTLS_CRYPTO_PKCS7 ++#endif /* crypto_pkcs7_*() */ ++ ++#if defined(EAP_SIM) || defined(EAP_SIM_DYNAMIC) || defined(EAP_SERVER_SIM) \ ++ || defined(EAP_AKA) || defined(EAP_AKA_DYNAMIC) || defined(EAP_SERVER_AKA) \ ++ || defined(CONFIG_AP) || defined(HOSTAPD) ++/* CONFIG_EAP_SIM=y CONFIG_EAP_AKA=y CONFIG_AP=y HOSTAPD */ ++#if defined(CRYPTO_RSA_OAEP_SHA256) ++#define CRYPTO_MBEDTLS_CRYPTO_RSA ++#endif ++#endif /* crypto_rsa_*() */ ++ ++ ++static int ctr_drbg_init_state; ++static mbedtls_ctr_drbg_context ctr_drbg; ++static mbedtls_entropy_context entropy; ++ ++#ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM ++#include ++static mbedtls_mpi mpi_sw_A; ++#endif ++ ++__attribute_cold__ ++__attribute_noinline__ ++static mbedtls_ctr_drbg_context * ctr_drbg_init(void) ++{ ++ mbedtls_ctr_drbg_init(&ctr_drbg); ++ mbedtls_entropy_init(&entropy); ++ if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, ++ NULL, 0)) { ++ wpa_printf(MSG_ERROR, "Init of random number generator failed"); ++ /* XXX: abort? */ ++ } ++ else ++ ctr_drbg_init_state = 1; ++ ++ return &ctr_drbg; ++} ++ ++__attribute_cold__ ++void crypto_unload(void) ++{ ++ if (ctr_drbg_init_state) { ++ mbedtls_ctr_drbg_free(&ctr_drbg); ++ mbedtls_entropy_free(&entropy); ++ #ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM ++ mbedtls_mpi_free(&mpi_sw_A); ++ #endif ++ ctr_drbg_init_state = 0; ++ } ++} ++ ++/* init ctr_drbg on first use ++ * crypto_global_init() and crypto_global_deinit() are not available here ++ * (available only when CONFIG_TLS=internal, which is not CONFIG_TLS=mbedtls) */ ++mbedtls_ctr_drbg_context * crypto_mbedtls_ctr_drbg(void); /*(not in header)*/ ++inline ++mbedtls_ctr_drbg_context * crypto_mbedtls_ctr_drbg(void) ++{ ++ return ctr_drbg_init_state ? &ctr_drbg : ctr_drbg_init(); ++} ++ ++#ifdef CRYPTO_MBEDTLS_CONFIG_FIPS ++int crypto_get_random(void *buf, size_t len) ++{ ++ return mbedtls_ctr_drbg_random(crypto_mbedtls_ctr_drbg(),buf,len) ? -1 : 0; ++} ++#endif ++ ++ ++#if 1 ++ ++/* tradeoff: slightly smaller code size here at cost of slight increase ++ * in instructions and function calls at runtime versus the expanded ++ * per-message-digest code that follows in #else (~0.5 kib .text larger) */ ++ ++__attribute_noinline__ ++static int md_vector(size_t num_elem, const u8 *addr[], const size_t *len, ++ u8 *mac, mbedtls_md_type_t md_type) ++{ ++ mbedtls_md_context_t ctx; ++ mbedtls_md_init(&ctx); ++ if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0) != 0){ ++ mbedtls_md_free(&ctx); ++ return -1; ++ } ++ mbedtls_md_starts(&ctx); ++ for (size_t i = 0; i < num_elem; ++i) ++ mbedtls_md_update(&ctx, addr[i], len[i]); ++ mbedtls_md_finish(&ctx, mac); ++ mbedtls_md_free(&ctx); ++ return 0; ++} ++ ++#ifdef MBEDTLS_SHA512_C ++int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) ++{ ++ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA512); ++} ++ ++int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) ++{ ++ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA384); ++} ++#endif ++ ++#ifdef MBEDTLS_SHA256_C ++int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) ++{ ++ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA256); ++} ++#endif ++ ++#ifdef MBEDTLS_SHA1_C ++int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) ++{ ++ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA1); ++} ++#endif ++ ++#ifdef MBEDTLS_MD5_C ++int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) ++{ ++ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_MD5); ++} ++#endif ++ ++#ifdef MBEDTLS_MD4_C ++#include ++int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) ++{ ++ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_MD4); ++} ++#endif ++ ++#else /* expanded per-message-digest functions */ ++ ++#ifdef MBEDTLS_SHA512_C ++#include ++__attribute_noinline__ ++static int sha384_512_vector(size_t num_elem, const u8 *addr[], ++ const size_t *len, u8 *mac, int is384) ++{ ++ struct mbedtls_sha512_context ctx; ++ mbedtls_sha512_init(&ctx); ++ #if MBEDTLS_VERSION_MAJOR >= 3 ++ mbedtls_sha512_starts(&ctx, is384); ++ for (size_t i = 0; i < num_elem; ++i) ++ mbedtls_sha512_update(&ctx, addr[i], len[i]); ++ mbedtls_sha512_finish(&ctx, mac); ++ #else ++ mbedtls_sha512_starts_ret(&ctx, is384); ++ for (size_t i = 0; i < num_elem; ++i) ++ mbedtls_sha512_update_ret(&ctx, addr[i], len[i]); ++ mbedtls_sha512_finish_ret(&ctx, mac); ++ #endif ++ mbedtls_sha512_free(&ctx); ++ return 0; ++} ++ ++int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) ++{ ++ return sha384_512_vector(num_elem, addr, len, mac, 0); ++} ++ ++int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) ++{ ++ return sha384_512_vector(num_elem, addr, len, mac, 1); ++} ++#endif ++ ++#ifdef MBEDTLS_SHA256_C ++#include ++int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) ++{ ++ struct mbedtls_sha256_context ctx; ++ mbedtls_sha256_init(&ctx); ++ #if MBEDTLS_VERSION_MAJOR >= 3 ++ mbedtls_sha256_starts(&ctx, 0); ++ for (size_t i = 0; i < num_elem; ++i) ++ mbedtls_sha256_update(&ctx, addr[i], len[i]); ++ mbedtls_sha256_finish(&ctx, mac); ++ #else ++ mbedtls_sha256_starts_ret(&ctx, 0); ++ for (size_t i = 0; i < num_elem; ++i) ++ mbedtls_sha256_update_ret(&ctx, addr[i], len[i]); ++ mbedtls_sha256_finish_ret(&ctx, mac); ++ #endif ++ mbedtls_sha256_free(&ctx); ++ return 0; ++} ++#endif ++ ++#ifdef MBEDTLS_SHA1_C ++#include ++int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) ++{ ++ struct mbedtls_sha1_context ctx; ++ mbedtls_sha1_init(&ctx); ++ #if MBEDTLS_VERSION_MAJOR >= 3 ++ mbedtls_sha1_starts(&ctx); ++ for (size_t i = 0; i < num_elem; ++i) ++ mbedtls_sha1_update(&ctx, addr[i], len[i]); ++ mbedtls_sha1_finish(&ctx, mac); ++ #else ++ mbedtls_sha1_starts_ret(&ctx); ++ for (size_t i = 0; i < num_elem; ++i) ++ mbedtls_sha1_update_ret(&ctx, addr[i], len[i]); ++ mbedtls_sha1_finish_ret(&ctx, mac); ++ #endif ++ mbedtls_sha1_free(&ctx); ++ return 0; ++} ++#endif ++ ++#ifdef MBEDTLS_MD5_C ++#include ++int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) ++{ ++ struct mbedtls_md5_context ctx; ++ mbedtls_md5_init(&ctx); ++ #if MBEDTLS_VERSION_MAJOR >= 3 ++ mbedtls_md5_starts(&ctx); ++ for (size_t i = 0; i < num_elem; ++i) ++ mbedtls_md5_update(&ctx, addr[i], len[i]); ++ mbedtls_md5_finish(&ctx, mac); ++ #else ++ mbedtls_md5_starts_ret(&ctx); ++ for (size_t i = 0; i < num_elem; ++i) ++ mbedtls_md5_update_ret(&ctx, addr[i], len[i]); ++ mbedtls_md5_finish_ret(&ctx, mac); ++ #endif ++ mbedtls_md5_free(&ctx); ++ return 0; ++} ++#endif ++ ++#ifdef MBEDTLS_MD4_C ++#include ++int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) ++{ ++ struct mbedtls_md4_context ctx; ++ mbedtls_md4_init(&ctx); ++ mbedtls_md4_starts_ret(&ctx); ++ for (size_t i = 0; i < num_elem; ++i) ++ mbedtls_md4_update_ret(&ctx, addr[i], len[i]); ++ mbedtls_md4_finish_ret(&ctx, mac); ++ mbedtls_md4_free(&ctx); ++ return 0; ++} ++#endif ++ ++#endif /* expanded per-message-digest functions */ ++ ++ ++__attribute_noinline__ ++static int hmac_vector(const u8 *key, size_t key_len, size_t num_elem, ++ const u8 *addr[], const size_t *len, u8 *mac, ++ mbedtls_md_type_t md_type) ++{ ++ mbedtls_md_context_t ctx; ++ mbedtls_md_init(&ctx); ++ if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1) != 0){ ++ mbedtls_md_free(&ctx); ++ return -1; ++ } ++ mbedtls_md_hmac_starts(&ctx, key, key_len); ++ for (size_t i = 0; i < num_elem; ++i) ++ mbedtls_md_hmac_update(&ctx, addr[i], len[i]); ++ mbedtls_md_hmac_finish(&ctx, mac); ++ mbedtls_md_free(&ctx); ++ return 0; ++} ++ ++#ifdef MBEDTLS_SHA512_C ++int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem, ++ const u8 *addr[], const size_t *len, u8 *mac) ++{ ++ return hmac_vector(key, key_len, num_elem, addr, len, mac, ++ MBEDTLS_MD_SHA512); ++} ++ ++int hmac_sha512(const u8 *key, size_t key_len, const u8 *data, size_t data_len, ++ u8 *mac) ++{ ++ return hmac_vector(key, key_len, 1, &data, &data_len, mac, ++ MBEDTLS_MD_SHA512); ++} ++ ++int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem, ++ const u8 *addr[], const size_t *len, u8 *mac) ++{ ++ return hmac_vector(key, key_len, num_elem, addr, len, mac, ++ MBEDTLS_MD_SHA384); ++} ++ ++int hmac_sha384(const u8 *key, size_t key_len, const u8 *data, size_t data_len, ++ u8 *mac) ++{ ++ return hmac_vector(key, key_len, 1, &data, &data_len, mac, ++ MBEDTLS_MD_SHA384); ++} ++#endif ++ ++#ifdef MBEDTLS_SHA256_C ++int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, ++ const u8 *addr[], const size_t *len, u8 *mac) ++{ ++ return hmac_vector(key, key_len, num_elem, addr, len, mac, ++ MBEDTLS_MD_SHA256); ++} ++ ++int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, size_t data_len, ++ u8 *mac) ++{ ++ return hmac_vector(key, key_len, 1, &data, &data_len, mac, ++ MBEDTLS_MD_SHA256); ++} ++#endif ++ ++#ifdef MBEDTLS_SHA1_C ++int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, ++ const u8 *addr[], const size_t *len, u8 *mac) ++{ ++ return hmac_vector(key, key_len, num_elem, addr, len, mac, ++ MBEDTLS_MD_SHA1); ++} ++ ++int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, ++ u8 *mac) ++{ ++ return hmac_vector(key, key_len, 1, &data, &data_len, mac, ++ MBEDTLS_MD_SHA1); ++} ++#endif ++ ++#ifdef MBEDTLS_MD5_C ++int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, ++ const u8 *addr[], const size_t *len, u8 *mac) ++{ ++ return hmac_vector(key, key_len, num_elem, addr, len, mac, ++ MBEDTLS_MD_MD5); ++} ++ ++int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, ++ u8 *mac) ++{ ++ return hmac_vector(key, key_len, 1, &data, &data_len, mac, ++ MBEDTLS_MD_MD5); ++} ++#endif ++ ++ ++#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA512_C) ++ ++#if defined(CRYPTO_MBEDTLS_HMAC_KDF_SHA256) \ ++ || defined(CRYPTO_MBEDTLS_HMAC_KDF_SHA384) \ ++ || defined(CRYPTO_MBEDTLS_HMAC_KDF_SHA512) ++ ++#include ++ ++/* sha256-kdf.c sha384-kdf.c sha512-kdf.c */ ++ ++/* HMAC-SHA256 KDF (RFC 5295) and HKDF-Expand(SHA256) (RFC 5869) */ ++/* HMAC-SHA384 KDF (RFC 5295) and HKDF-Expand(SHA384) (RFC 5869) */ ++/* HMAC-SHA512 KDF (RFC 5295) and HKDF-Expand(SHA512) (RFC 5869) */ ++__attribute_noinline__ ++static int hmac_kdf_expand(const u8 *prk, size_t prk_len, ++ const char *label, const u8 *info, size_t info_len, ++ u8 *okm, size_t okm_len, mbedtls_md_type_t md_type) ++{ ++ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); ++ #ifdef MBEDTLS_HKDF_C ++ if (label == NULL) /* RFC 5869 HKDF-Expand when (label == NULL) */ ++ return mbedtls_hkdf_expand(md_info, prk, prk_len, info, ++ info_len, okm, okm_len) ? -1 : 0; ++ #endif ++ ++ const size_t mac_len = mbedtls_md_get_size(md_info); ++ /* okm_len must not exceed 255 times hash len (RFC 5869 Section 2.3) */ ++ if (okm_len > ((mac_len << 8) - mac_len)) ++ return -1; ++ ++ mbedtls_md_context_t ctx; ++ mbedtls_md_init(&ctx); ++ if (mbedtls_md_setup(&ctx, md_info, 1) != 0) { ++ mbedtls_md_free(&ctx); ++ return -1; ++ } ++ mbedtls_md_hmac_starts(&ctx, prk, prk_len); ++ ++ u8 iter = 1; ++ const u8 *addr[4] = { okm, (const u8 *)label, info, &iter }; ++ size_t len[4] = { 0, label ? os_strlen(label)+1 : 0, info_len, 1 }; ++ ++ for (; okm_len >= mac_len; okm_len -= mac_len, ++iter) { ++ for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) ++ mbedtls_md_hmac_update(&ctx, addr[i], len[i]); ++ mbedtls_md_hmac_finish(&ctx, okm); ++ mbedtls_md_hmac_reset(&ctx); ++ addr[0] = okm; ++ okm += mac_len; ++ len[0] = mac_len; /*(include digest in subsequent rounds)*/ ++ } ++ ++ if (okm_len) { ++ u8 hash[MBEDTLS_MD_MAX_SIZE]; ++ for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) ++ mbedtls_md_hmac_update(&ctx, addr[i], len[i]); ++ mbedtls_md_hmac_finish(&ctx, hash); ++ os_memcpy(okm, hash, okm_len); ++ forced_memzero(hash, mac_len); ++ } ++ ++ mbedtls_md_free(&ctx); ++ return 0; ++} ++ ++#ifdef MBEDTLS_SHA512_C ++#ifdef CRYPTO_MBEDTLS_HMAC_KDF_SHA512 ++int hmac_sha512_kdf(const u8 *secret, size_t secret_len, ++ const char *label, const u8 *seed, size_t seed_len, ++ u8 *out, size_t outlen) ++{ ++ return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, ++ out, outlen, MBEDTLS_MD_SHA512); ++} ++#endif ++ ++#ifdef CRYPTO_MBEDTLS_HMAC_KDF_SHA384 ++int hmac_sha384_kdf(const u8 *secret, size_t secret_len, ++ const char *label, const u8 *seed, size_t seed_len, ++ u8 *out, size_t outlen) ++{ ++ return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, ++ out, outlen, MBEDTLS_MD_SHA384); ++} ++#endif ++#endif ++ ++#ifdef MBEDTLS_SHA256_C ++#ifdef CRYPTO_MBEDTLS_HMAC_KDF_SHA256 ++int hmac_sha256_kdf(const u8 *secret, size_t secret_len, ++ const char *label, const u8 *seed, size_t seed_len, ++ u8 *out, size_t outlen) ++{ ++ return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, ++ out, outlen, MBEDTLS_MD_SHA256); ++} ++#endif ++#endif ++ ++#endif /* CRYPTO_MBEDTLS_HMAC_KDF_* */ ++ ++ ++/* sha256-prf.c sha384-prf.c sha512-prf.c */ ++ ++/* hmac_prf_bits - IEEE Std 802.11ac-2013, 11.6.1.7.2 Key derivation function */ ++__attribute_noinline__ ++static int hmac_prf_bits(const u8 *key, size_t key_len, const char *label, ++ const u8 *data, size_t data_len, u8 *buf, ++ size_t buf_len_bits, mbedtls_md_type_t md_type) ++{ ++ mbedtls_md_context_t ctx; ++ mbedtls_md_init(&ctx); ++ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); ++ if (mbedtls_md_setup(&ctx, md_info, 1) != 0) { ++ mbedtls_md_free(&ctx); ++ return -1; ++ } ++ mbedtls_md_hmac_starts(&ctx, key, key_len); ++ ++ u16 ctr, n_le = host_to_le16(buf_len_bits); ++ const u8 * const addr[] = { (u8 *)&ctr,(u8 *)label,data,(u8 *)&n_le }; ++ const size_t len[] = { 2, os_strlen(label), data_len, 2 }; ++ const size_t mac_len = mbedtls_md_get_size(md_info); ++ size_t buf_len = (buf_len_bits + 7) / 8; ++ for (ctr = 1; buf_len >= mac_len; buf_len -= mac_len, ++ctr) { ++ #if __BYTE_ORDER == __BIG_ENDIAN ++ ctr = host_to_le16(ctr); ++ #endif ++ for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) ++ mbedtls_md_hmac_update(&ctx, addr[i], len[i]); ++ mbedtls_md_hmac_finish(&ctx, buf); ++ mbedtls_md_hmac_reset(&ctx); ++ buf += mac_len; ++ #if __BYTE_ORDER == __BIG_ENDIAN ++ ctr = le_to_host16(ctr); ++ #endif ++ } ++ ++ if (buf_len) { ++ u8 hash[MBEDTLS_MD_MAX_SIZE]; ++ #if __BYTE_ORDER == __BIG_ENDIAN ++ ctr = host_to_le16(ctr); ++ #endif ++ for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) ++ mbedtls_md_hmac_update(&ctx, addr[i], len[i]); ++ mbedtls_md_hmac_finish(&ctx, hash); ++ os_memcpy(buf, hash, buf_len); ++ buf += buf_len; ++ forced_memzero(hash, mac_len); ++ } ++ ++ /* Mask out unused bits in last octet if it does not use all the bits */ ++ if ((buf_len_bits &= 0x7)) ++ buf[-1] &= (u8)(0xff << (8 - buf_len_bits)); ++ ++ mbedtls_md_free(&ctx); ++ return 0; ++} ++ ++#ifdef MBEDTLS_SHA512_C ++int sha512_prf(const u8 *key, size_t key_len, const char *label, ++ const u8 *data, size_t data_len, u8 *buf, size_t buf_len) ++{ ++ return hmac_prf_bits(key, key_len, label, data, data_len, buf, ++ buf_len * 8, MBEDTLS_MD_SHA512); ++} ++ ++int sha384_prf(const u8 *key, size_t key_len, const char *label, ++ const u8 *data, size_t data_len, u8 *buf, size_t buf_len) ++{ ++ return hmac_prf_bits(key, key_len, label, data, data_len, buf, ++ buf_len * 8, MBEDTLS_MD_SHA384); ++} ++#endif ++ ++#ifdef MBEDTLS_SHA256_C ++int sha256_prf(const u8 *key, size_t key_len, const char *label, ++ const u8 *data, size_t data_len, u8 *buf, size_t buf_len) ++{ ++ return hmac_prf_bits(key, key_len, label, data, data_len, buf, ++ buf_len * 8, MBEDTLS_MD_SHA256); ++} ++ ++int sha256_prf_bits(const u8 *key, size_t key_len, const char *label, ++ const u8 *data, size_t data_len, u8 *buf, ++ size_t buf_len_bits) ++{ ++ return hmac_prf_bits(key, key_len, label, data, data_len, buf, ++ buf_len_bits, MBEDTLS_MD_SHA256); ++} ++#endif ++ ++#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA512_C */ ++ ++ ++#ifdef MBEDTLS_SHA1_C ++ ++/* sha1-prf.c */ ++ ++/* sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1) */ ++ ++int sha1_prf(const u8 *key, size_t key_len, const char *label, ++ const u8 *data, size_t data_len, u8 *buf, size_t buf_len) ++{ ++ /*(note: algorithm differs from hmac_prf_bits() */ ++ /*(note: smaller code size instead of expanding hmac_sha1_vector() ++ * as is done in hmac_prf_bits(); not expecting large num of loops) */ ++ u8 counter = 0; ++ const u8 *addr[] = { (u8 *)label, data, &counter }; ++ const size_t len[] = { os_strlen(label)+1, data_len, 1 }; ++ ++ for (; buf_len >= SHA1_MAC_LEN; buf_len -= SHA1_MAC_LEN, ++counter) { ++ if (hmac_sha1_vector(key, key_len, 3, addr, len, buf)) ++ return -1; ++ buf += SHA1_MAC_LEN; ++ } ++ ++ if (buf_len) { ++ u8 hash[SHA1_MAC_LEN]; ++ if (hmac_sha1_vector(key, key_len, 3, addr, len, hash)) ++ return -1; ++ os_memcpy(buf, hash, buf_len); ++ forced_memzero(hash, sizeof(hash)); ++ } ++ ++ return 0; ++} ++ ++#ifdef CRYPTO_MBEDTLS_SHA1_T_PRF ++ ++/* sha1-tprf.c */ ++ ++/* sha1_t_prf - EAP-FAST Pseudo-Random Function (T-PRF) (RFC 4851,Section 5.5)*/ ++ ++int sha1_t_prf(const u8 *key, size_t key_len, const char *label, ++ const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len) ++{ ++ /*(note: algorithm differs from hmac_prf_bits() and hmac_kdf() above)*/ ++ /*(note: smaller code size instead of expanding hmac_sha1_vector() ++ * as is done in hmac_prf_bits(); not expecting large num of loops) */ ++ u8 ctr; ++ u16 olen = host_to_be16(buf_len); ++ const u8 *addr[] = { buf, (u8 *)label, seed, (u8 *)&olen, &ctr }; ++ size_t len[] = { 0, os_strlen(label)+1, seed_len, 2, 1 }; ++ ++ for (ctr = 1; buf_len >= SHA1_MAC_LEN; buf_len -= SHA1_MAC_LEN, ++ctr) { ++ if (hmac_sha1_vector(key, key_len, 5, addr, len, buf)) ++ return -1; ++ addr[0] = buf; ++ buf += SHA1_MAC_LEN; ++ len[0] = SHA1_MAC_LEN; /*(include digest in subsequent rounds)*/ ++ } ++ ++ if (buf_len) { ++ u8 hash[SHA1_MAC_LEN]; ++ if (hmac_sha1_vector(key, key_len, 5, addr, len, hash)) ++ return -1; ++ os_memcpy(buf, hash, buf_len); ++ forced_memzero(hash, sizeof(hash)); ++ } ++ ++ return 0; ++} ++ ++#endif /* CRYPTO_MBEDTLS_SHA1_T_PRF */ ++ ++#endif /* MBEDTLS_SHA1_C */ ++ ++ ++#ifdef CRYPTO_MBEDTLS_DES_ENCRYPT ++#ifdef MBEDTLS_DES_C ++#include ++int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) ++{ ++ u8 pkey[8], next, tmp; ++ int i; ++ ++ /* Add parity bits to the key */ ++ next = 0; ++ for (i = 0; i < 7; i++) { ++ tmp = key[i]; ++ pkey[i] = (tmp >> i) | next | 1; ++ next = tmp << (7 - i); ++ } ++ pkey[i] = next | 1; ++ ++ mbedtls_des_context des; ++ mbedtls_des_init(&des); ++ int ret = mbedtls_des_setkey_enc(&des, pkey) ++ || mbedtls_des_crypt_ecb(&des, clear, cypher) ? -1 : 0; ++ mbedtls_des_free(&des); ++ return ret; ++} ++#else ++#include "des-internal.c"/* pull in hostap local implementation */ ++#endif ++#endif ++ ++ ++#ifdef CRYPTO_MBEDTLS_PBKDF2_SHA1 ++/* sha1-pbkdf2.c */ ++#include ++int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, ++ int iterations, u8 *buf, size_t buflen) ++{ ++ #if MBEDTLS_VERSION_NUMBER >= 0x03020200 /* mbedtls 3.2.2 */ ++ return mbedtls_pkcs5_pbkdf2_hmac_ext(MBEDTLS_MD_SHA1, ++ (const u8 *)passphrase, os_strlen(passphrase), ++ ssid, ssid_len, iterations, 32, buf) ? -1 : 0; ++ #else ++ const mbedtls_md_info_t *md_info; ++ md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); ++ if (md_info == NULL) ++ return -1; ++ mbedtls_md_context_t ctx; ++ mbedtls_md_init(&ctx); ++ int ret = mbedtls_md_setup(&ctx, md_info, 1) ++ || mbedtls_pkcs5_pbkdf2_hmac(&ctx, ++ (const u8 *)passphrase, os_strlen(passphrase), ++ ssid, ssid_len, iterations, 32, buf) ? -1 : 0; ++ mbedtls_md_free(&ctx); ++ return ret; ++ #endif ++} ++#endif ++ ++ ++/*#include "aes.h"*/ /* prototypes also included in "crypto.h" */ ++ ++static void *aes_crypt_init_mode(const u8 *key, size_t len, int mode) ++{ ++ mbedtls_aes_context *aes = os_malloc(sizeof(*aes)); ++ if (!aes) ++ return NULL; ++ ++ mbedtls_aes_init(aes); ++ if ((mode == MBEDTLS_AES_ENCRYPT ++ ? mbedtls_aes_setkey_enc(aes, key, len * 8) ++ : mbedtls_aes_setkey_dec(aes, key, len * 8)) == 0) ++ return aes; ++ ++ mbedtls_aes_free(aes); ++ os_free(aes); ++ return NULL; ++} ++ ++void *aes_encrypt_init(const u8 *key, size_t len) ++{ ++ return aes_crypt_init_mode(key, len, MBEDTLS_AES_ENCRYPT); ++} ++ ++int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) ++{ ++ return mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, plain, crypt); ++} ++ ++void aes_encrypt_deinit(void *ctx) ++{ ++ mbedtls_aes_free(ctx); ++ os_free(ctx); ++} ++ ++void *aes_decrypt_init(const u8 *key, size_t len) ++{ ++ return aes_crypt_init_mode(key, len, MBEDTLS_AES_DECRYPT); ++} ++ ++int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) ++{ ++ return mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_DECRYPT, crypt, plain); ++} ++ ++void aes_decrypt_deinit(void *ctx) ++{ ++ mbedtls_aes_free(ctx); ++ os_free(ctx); ++} ++ ++ ++#include "aes_wrap.h" ++ ++ ++#ifdef MBEDTLS_NIST_KW_C ++ ++#include ++ ++/* aes-wrap.c */ ++int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher) ++{ ++ mbedtls_nist_kw_context ctx; ++ mbedtls_nist_kw_init(&ctx); ++ size_t olen; ++ int ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, ++ kek, kek_len*8, 1) ++ || mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KW, plain, n*8, ++ cipher, &olen, (n+1)*8) ? -1 : 0; ++ mbedtls_nist_kw_free(&ctx); ++ return ret; ++} ++ ++/* aes-unwrap.c */ ++int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, u8 *plain) ++{ ++ mbedtls_nist_kw_context ctx; ++ mbedtls_nist_kw_init(&ctx); ++ size_t olen; ++ int ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, ++ kek, kek_len*8, 0) ++ || mbedtls_nist_kw_unwrap(&ctx, MBEDTLS_KW_MODE_KW, cipher, ++ (n+1)*8, plain, &olen, n*8) ? -1 : 0; ++ mbedtls_nist_kw_free(&ctx); ++ return ret; ++} ++ ++#else ++ ++#ifndef CRYPTO_MBEDTLS_CONFIG_FIPS ++#include "aes-wrap.c" /* pull in hostap local implementation */ ++#include "aes-unwrap.c" /* pull in hostap local implementation */ ++#endif ++ ++#endif /* MBEDTLS_NIST_KW_C */ ++ ++ ++#ifdef MBEDTLS_CMAC_C ++ ++/* aes-omac1.c */ ++ ++#include ++ ++int omac1_aes_vector( ++ const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], ++ const size_t *len, u8 *mac) ++{ ++ mbedtls_cipher_type_t cipher_type; ++ switch (key_len) { ++ case 16: cipher_type = MBEDTLS_CIPHER_AES_128_ECB; break; ++ case 24: cipher_type = MBEDTLS_CIPHER_AES_192_ECB; break; ++ case 32: cipher_type = MBEDTLS_CIPHER_AES_256_ECB; break; ++ default: return -1; ++ } ++ const mbedtls_cipher_info_t *cipher_info; ++ cipher_info = mbedtls_cipher_info_from_type(cipher_type); ++ if (cipher_info == NULL) ++ return -1; ++ ++ mbedtls_cipher_context_t ctx; ++ mbedtls_cipher_init(&ctx); ++ int ret = -1; ++ if (mbedtls_cipher_setup(&ctx, cipher_info) == 0 ++ && mbedtls_cipher_cmac_starts(&ctx, key, key_len*8) == 0) { ++ ret = 0; ++ for (size_t i = 0; i < num_elem && ret == 0; ++i) ++ ret = mbedtls_cipher_cmac_update(&ctx, addr[i], len[i]); ++ } ++ if (ret == 0) ++ ret = mbedtls_cipher_cmac_finish(&ctx, mac); ++ mbedtls_cipher_free(&ctx); ++ return ret ? -1 : 0; ++} ++ ++int omac1_aes_128_vector(const u8 *key, size_t num_elem, ++ const u8 *addr[], const size_t *len, ++ u8 *mac) ++{ ++ return omac1_aes_vector(key, 16, num_elem, addr, len, mac); ++} ++ ++int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac) ++{ ++ return omac1_aes_vector(key, 16, 1, &data, &data_len, mac); ++} ++ ++int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac) ++{ ++ return omac1_aes_vector(key, 32, 1, &data, &data_len, mac); ++} ++ ++#else ++ ++#include "aes-omac1.c" /* pull in hostap local implementation */ ++ ++#ifndef MBEDTLS_AES_BLOCK_SIZE ++#define MBEDTLS_AES_BLOCK_SIZE 16 ++#endif ++ ++#endif /* MBEDTLS_CMAC_C */ ++ ++ ++/* These interfaces can be inefficient when used in loops, as the overhead of ++ * initialization each call is large for each block input (e.g. 16 bytes) */ ++ ++ ++/* aes-encblock.c */ ++int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out) ++{ ++ mbedtls_aes_context aes; ++ mbedtls_aes_init(&aes); ++ int ret = mbedtls_aes_setkey_enc(&aes, key, 128) ++ || mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_ENCRYPT, in, out) ++ ? -1 ++ : 0; ++ mbedtls_aes_free(&aes); ++ return ret; ++} ++ ++ ++/* aes-ctr.c */ ++int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, ++ u8 *data, size_t data_len) ++{ ++ unsigned char counter[MBEDTLS_AES_BLOCK_SIZE]; ++ unsigned char stream_block[MBEDTLS_AES_BLOCK_SIZE]; ++ os_memcpy(counter, nonce, MBEDTLS_AES_BLOCK_SIZE);/*(must be writable)*/ ++ ++ mbedtls_aes_context ctx; ++ mbedtls_aes_init(&ctx); ++ size_t nc_off = 0; ++ int ret = mbedtls_aes_setkey_enc(&ctx, key, key_len*8) ++ || mbedtls_aes_crypt_ctr(&ctx, data_len, &nc_off, ++ counter, stream_block, ++ data, data) ? -1 : 0; ++ forced_memzero(stream_block, sizeof(stream_block)); ++ mbedtls_aes_free(&ctx); ++ return ret; ++} ++ ++int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, ++ u8 *data, size_t data_len) ++{ ++ return aes_ctr_encrypt(key, 16, nonce, data, data_len); ++} ++ ++ ++/* aes-cbc.c */ ++static int aes_128_cbc_oper(const u8 *key, const u8 *iv, ++ u8 *data, size_t data_len, int mode) ++{ ++ unsigned char ivec[MBEDTLS_AES_BLOCK_SIZE]; ++ os_memcpy(ivec, iv, MBEDTLS_AES_BLOCK_SIZE); /*(must be writable)*/ ++ ++ mbedtls_aes_context ctx; ++ mbedtls_aes_init(&ctx); ++ int ret = (mode == MBEDTLS_AES_ENCRYPT ++ ? mbedtls_aes_setkey_enc(&ctx, key, 128) ++ : mbedtls_aes_setkey_dec(&ctx, key, 128)) ++ || mbedtls_aes_crypt_cbc(&ctx, mode, data_len, ivec, data, data); ++ mbedtls_aes_free(&ctx); ++ return ret ? -1 : 0; ++} ++ ++int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) ++{ ++ return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_ENCRYPT); ++} ++ ++int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) ++{ ++ return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_DECRYPT); ++} ++ ++ ++/* ++ * Much of the following is documented in crypto.h as for CONFIG_TLS=internal ++ * but such comments are not accurate: ++ * ++ * "This function is only used with internal TLSv1 implementation ++ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need ++ * to implement this." ++ */ ++ ++ ++#ifdef CRYPTO_MBEDTLS_CRYPTO_CIPHER ++ ++#include ++ ++struct crypto_cipher ++{ ++ mbedtls_cipher_context_t ctx_enc; ++ mbedtls_cipher_context_t ctx_dec; ++}; ++ ++struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, ++ const u8 *iv, const u8 *key, ++ size_t key_len) ++{ ++ /* IKEv2 src/eap_common/ikev2_common.c:ikev2_{encr,decr}_encrypt() ++ * uses one of CRYPTO_CIPHER_ALG_AES or CRYPTO_CIPHER_ALG_3DES */ ++ ++ mbedtls_cipher_type_t cipher_type; ++ size_t iv_len; ++ switch (alg) { ++ #ifdef MBEDTLS_ARC4_C ++ #if 0 ++ case CRYPTO_CIPHER_ALG_RC4: ++ cipher_type = MBEDTLS_CIPHER_ARC4_128; ++ iv_len = 0; ++ break; ++ #endif ++ #endif ++ #ifdef MBEDTLS_AES_C ++ case CRYPTO_CIPHER_ALG_AES: ++ if (key_len == 16) cipher_type = MBEDTLS_CIPHER_AES_128_CTR; ++ if (key_len == 24) cipher_type = MBEDTLS_CIPHER_AES_192_CTR; ++ if (key_len == 32) cipher_type = MBEDTLS_CIPHER_AES_256_CTR; ++ iv_len = 16; ++ break; ++ #endif ++ #ifdef MBEDTLS_DES_C ++ case CRYPTO_CIPHER_ALG_3DES: ++ cipher_type = MBEDTLS_CIPHER_DES_EDE3_CBC; ++ iv_len = 8; ++ break; ++ #if 0 ++ case CRYPTO_CIPHER_ALG_DES: ++ cipher_type = MBEDTLS_CIPHER_DES_CBC; ++ iv_len = 8; ++ break; ++ #endif ++ #endif ++ default: ++ return NULL; ++ } ++ ++ const mbedtls_cipher_info_t *cipher_info; ++ cipher_info = mbedtls_cipher_info_from_type(cipher_type); ++ if (cipher_info == NULL) ++ return NULL; ++ ++ key_len *= 8; /* key_bitlen */ ++ #if 0 /*(were key_bitlen not already available)*/ ++ #if MBEDTLS_VERSION_NUMBER >= 0x03010000 /* mbedtls 3.1.0 */ ++ key_len = mbedtls_cipher_info_get_key_bitlen(cipher_info); ++ #else ++ key_len = cipher_info->MBEDTLS_PRIVATE(key_bitlen); ++ #endif ++ #endif ++ ++ #if 0 /*(were iv_len not known above, would need MBEDTLS_PRIVATE(iv_size))*/ ++ iv_len = cipher_info->MBEDTLS_PRIVATE(iv_size); ++ #endif ++ ++ struct crypto_cipher *ctx = os_malloc(sizeof(*ctx)); ++ if (!ctx) ++ return NULL; ++ ++ mbedtls_cipher_init(&ctx->ctx_enc); ++ mbedtls_cipher_init(&ctx->ctx_dec); ++ if ( mbedtls_cipher_setup(&ctx->ctx_enc,cipher_info) == 0 ++ && mbedtls_cipher_setup(&ctx->ctx_dec,cipher_info) == 0 ++ && mbedtls_cipher_setkey(&ctx->ctx_enc,key,key_len,MBEDTLS_ENCRYPT) == 0 ++ && mbedtls_cipher_setkey(&ctx->ctx_dec,key,key_len,MBEDTLS_DECRYPT) == 0 ++ && mbedtls_cipher_set_iv(&ctx->ctx_enc,iv,iv_len) == 0 ++ && mbedtls_cipher_set_iv(&ctx->ctx_dec,iv,iv_len) == 0 ++ && mbedtls_cipher_reset(&ctx->ctx_enc) == 0 ++ && mbedtls_cipher_reset(&ctx->ctx_dec) == 0) { ++ return ctx; ++ } ++ ++ mbedtls_cipher_free(&ctx->ctx_enc); ++ mbedtls_cipher_free(&ctx->ctx_dec); ++ os_free(ctx); ++ return NULL; ++} ++ ++int crypto_cipher_encrypt(struct crypto_cipher *ctx, ++ const u8 *plain, u8 *crypt, size_t len) ++{ ++ size_t olen = 0; /*(poor interface above; unknown size of u8 *crypt)*/ ++ return (mbedtls_cipher_update(&ctx->ctx_enc, plain, len, crypt, &olen) ++ || mbedtls_cipher_finish(&ctx->ctx_enc, crypt + olen, &olen)) ? -1 : 0; ++} ++ ++int crypto_cipher_decrypt(struct crypto_cipher *ctx, ++ const u8 *crypt, u8 *plain, size_t len) ++{ ++ size_t olen = 0; /*(poor interface above; unknown size of u8 *plain)*/ ++ return (mbedtls_cipher_update(&ctx->ctx_dec, crypt, len, plain, &olen) ++ || mbedtls_cipher_finish(&ctx->ctx_dec, plain + olen, &olen)) ? -1 : 0; ++} ++ ++void crypto_cipher_deinit(struct crypto_cipher *ctx) ++{ ++ mbedtls_cipher_free(&ctx->ctx_enc); ++ mbedtls_cipher_free(&ctx->ctx_dec); ++ os_free(ctx); ++} ++ ++#endif /* CRYPTO_MBEDTLS_CRYPTO_CIPHER */ ++ ++ ++#ifdef CRYPTO_MBEDTLS_CRYPTO_HASH ++ ++struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, ++ size_t key_len) ++{ ++ mbedtls_md_type_t md_type; ++ int is_hmac = 0; ++ ++ switch (alg) { ++ #ifdef MBEDTLS_MD5_C ++ case CRYPTO_HASH_ALG_MD5: ++ md_type = MBEDTLS_MD_MD5; ++ break; ++ #endif ++ #ifdef MBEDTLS_SHA1_C ++ case CRYPTO_HASH_ALG_SHA1: ++ md_type = MBEDTLS_MD_SHA1; ++ break; ++ #endif ++ #ifdef MBEDTLS_MD5_C ++ case CRYPTO_HASH_ALG_HMAC_MD5: ++ md_type = MBEDTLS_MD_MD5; ++ is_hmac = 1; ++ break; ++ #endif ++ #ifdef MBEDTLS_SHA1_C ++ case CRYPTO_HASH_ALG_HMAC_SHA1: ++ md_type = MBEDTLS_MD_SHA1; ++ is_hmac = 1; ++ break; ++ #endif ++ #ifdef MBEDTLS_SHA256_C ++ case CRYPTO_HASH_ALG_SHA256: ++ md_type = MBEDTLS_MD_SHA256; ++ break; ++ case CRYPTO_HASH_ALG_HMAC_SHA256: ++ md_type = MBEDTLS_MD_SHA256; ++ is_hmac = 1; ++ break; ++ #endif ++ #ifdef MBEDTLS_SHA512_C ++ case CRYPTO_HASH_ALG_SHA384: ++ md_type = MBEDTLS_MD_SHA384; ++ break; ++ case CRYPTO_HASH_ALG_SHA512: ++ md_type = MBEDTLS_MD_SHA512; ++ break; ++ #endif ++ default: ++ return NULL; ++ } ++ ++ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); ++ if (!md_info) ++ return NULL; ++ ++ mbedtls_md_context_t *mctx = os_malloc(sizeof(*mctx)); ++ if (mctx == NULL) ++ return NULL; ++ ++ mbedtls_md_init(mctx); ++ if (mbedtls_md_setup(mctx, md_info, is_hmac) != 0) { ++ os_free(mctx); ++ return NULL; ++ } ++ ++ if (is_hmac) ++ mbedtls_md_hmac_starts(mctx, key, key_len); ++ else ++ mbedtls_md_starts(mctx); ++ return (struct crypto_hash *)((uintptr_t)mctx | is_hmac); ++} ++ ++void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) ++{ ++ mbedtls_md_context_t *mctx = (mbedtls_md_context_t*)((uintptr_t)ctx & ~1uL); ++ #if 0 ++ /*(mbedtls_md_hmac_update() and mbedtls_md_update() ++ * make same modifications under the hood in mbedtls)*/ ++ if ((uintptr_t)ctx & 1uL) ++ mbedtls_md_hmac_update(mctx, data, len); ++ else ++ #endif ++ mbedtls_md_update(mctx, data, len); ++} ++ ++int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) ++{ ++ mbedtls_md_context_t *mctx = (mbedtls_md_context_t*)((uintptr_t)ctx & ~1uL); ++ if (mac != NULL && len != NULL) { /*(NULL if caller just freeing context)*/ ++ #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ ++ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_ctx(mctx); ++ #else ++ const mbedtls_md_info_t *md_info = mctx->MBEDTLS_PRIVATE(md_info); ++ #endif ++ size_t maclen = mbedtls_md_get_size(md_info); ++ if (*len < maclen) { ++ *len = maclen; ++ /*(note: ctx not freed; can call again with larger *len)*/ ++ return -1; ++ } ++ *len = maclen; ++ if ((uintptr_t)ctx & 1uL) ++ mbedtls_md_hmac_finish(mctx, mac); ++ else ++ mbedtls_md_finish(mctx, mac); ++ } ++ mbedtls_md_free(mctx); ++ os_free(mctx); ++ return 0; ++} ++ ++#endif /* CRYPTO_MBEDTLS_CRYPTO_HASH */ ++ ++ ++#ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM ++ ++#include ++ ++/* crypto.h bignum interfaces */ ++ ++struct crypto_bignum *crypto_bignum_init(void) ++{ ++ mbedtls_mpi *bn = os_malloc(sizeof(*bn)); ++ if (bn) ++ mbedtls_mpi_init(bn); ++ return (struct crypto_bignum *)bn; ++} ++ ++struct crypto_bignum *crypto_bignum_init_set(const u8 *buf, size_t len) ++{ ++ mbedtls_mpi *bn = os_malloc(sizeof(*bn)); ++ if (bn) { ++ mbedtls_mpi_init(bn); ++ if (mbedtls_mpi_read_binary(bn, buf, len) == 0) ++ return (struct crypto_bignum *)bn; ++ } ++ ++ os_free(bn); ++ return NULL; ++} ++ ++struct crypto_bignum *crypto_bignum_init_uint(unsigned int val) ++{ ++ #if 0 /*(hostap use of this interface passes int, not uint)*/ ++ val = host_to_be32(val); ++ return crypto_bignum_init_set((const u8 *)&val, sizeof(val)); ++ #else ++ mbedtls_mpi *bn = os_malloc(sizeof(*bn)); ++ if (bn) { ++ mbedtls_mpi_init(bn); ++ if (mbedtls_mpi_lset(bn, (int)val) == 0) ++ return (struct crypto_bignum *)bn; ++ } ++ ++ os_free(bn); ++ return NULL; ++ #endif ++} ++ ++void crypto_bignum_deinit(struct crypto_bignum *n, int clear) ++{ ++ mbedtls_mpi_free((mbedtls_mpi *)n); ++ os_free(n); ++} ++ ++int crypto_bignum_to_bin(const struct crypto_bignum *a, ++ u8 *buf, size_t buflen, size_t padlen) ++{ ++ size_t n = mbedtls_mpi_size((mbedtls_mpi *)a); ++ if (n < padlen) ++ n = padlen; ++ return n > buflen || mbedtls_mpi_write_binary((mbedtls_mpi *)a, buf, n) ++ ? -1 ++ : (int)(n); ++} ++ ++int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m) ++{ ++ /*assert(r != m);*//* r must not be same as m for mbedtls_mpi_random()*/ ++ #if MBEDTLS_VERSION_NUMBER >= 0x021B0000 /* mbedtls 2.27.0 */ ++ return mbedtls_mpi_random((mbedtls_mpi *)r, 0, (mbedtls_mpi *)m, ++ mbedtls_ctr_drbg_random, ++ crypto_mbedtls_ctr_drbg()) ? -1 : 0; ++ #else ++ /* (needed by EAP_PWD, SAE, DPP) */ ++ wpa_printf(MSG_ERROR, ++ "mbedtls 2.27.0 or later required for mbedtls_mpi_random()"); ++ return -1; ++ #endif ++} ++ ++int crypto_bignum_add(const struct crypto_bignum *a, ++ const struct crypto_bignum *b, ++ struct crypto_bignum *c) ++{ ++ return mbedtls_mpi_add_mpi((mbedtls_mpi *)c, ++ (const mbedtls_mpi *)a, ++ (const mbedtls_mpi *)b) ? -1 : 0; ++} ++ ++int crypto_bignum_mod(const struct crypto_bignum *a, ++ const struct crypto_bignum *b, ++ struct crypto_bignum *c) ++{ ++ return mbedtls_mpi_mod_mpi((mbedtls_mpi *)c, ++ (const mbedtls_mpi *)a, ++ (const mbedtls_mpi *)b) ? -1 : 0; ++} ++ ++int crypto_bignum_exptmod(const struct crypto_bignum *a, ++ const struct crypto_bignum *b, ++ const struct crypto_bignum *c, ++ struct crypto_bignum *d) ++{ ++ /* (check if input params match d; d is the result) */ ++ /* (a == d) is ok in current mbedtls implementation */ ++ if (b == d || c == d) { /*(not ok; store result in intermediate)*/ ++ mbedtls_mpi R; ++ mbedtls_mpi_init(&R); ++ int rc = mbedtls_mpi_exp_mod(&R, ++ (const mbedtls_mpi *)a, ++ (const mbedtls_mpi *)b, ++ (const mbedtls_mpi *)c, ++ NULL) ++ || mbedtls_mpi_copy((mbedtls_mpi *)d, &R) ? -1 : 0; ++ mbedtls_mpi_free(&R); ++ return rc; ++ } ++ else { ++ return mbedtls_mpi_exp_mod((mbedtls_mpi *)d, ++ (const mbedtls_mpi *)a, ++ (const mbedtls_mpi *)b, ++ (const mbedtls_mpi *)c, ++ NULL) ? -1 : 0; ++ } ++} ++ ++int crypto_bignum_inverse(const struct crypto_bignum *a, ++ const struct crypto_bignum *b, ++ struct crypto_bignum *c) ++{ ++ return mbedtls_mpi_inv_mod((mbedtls_mpi *)c, ++ (const mbedtls_mpi *)a, ++ (const mbedtls_mpi *)b) ? -1 : 0; ++} ++ ++int crypto_bignum_sub(const struct crypto_bignum *a, ++ const struct crypto_bignum *b, ++ struct crypto_bignum *c) ++{ ++ return mbedtls_mpi_sub_mpi((mbedtls_mpi *)c, ++ (const mbedtls_mpi *)a, ++ (const mbedtls_mpi *)b) ? -1 : 0; ++} ++ ++int crypto_bignum_div(const struct crypto_bignum *a, ++ const struct crypto_bignum *b, ++ struct crypto_bignum *c) ++{ ++ /*(most current use of this crypto.h interface has a == c (result), ++ * so store result in an intermediate to avoid overwritten input)*/ ++ mbedtls_mpi R; ++ mbedtls_mpi_init(&R); ++ int rc = mbedtls_mpi_div_mpi(&R, NULL, ++ (const mbedtls_mpi *)a, ++ (const mbedtls_mpi *)b) ++ || mbedtls_mpi_copy((mbedtls_mpi *)c, &R) ? -1 : 0; ++ mbedtls_mpi_free(&R); ++ return rc; ++} ++ ++int crypto_bignum_addmod(const struct crypto_bignum *a, ++ const struct crypto_bignum *b, ++ const struct crypto_bignum *c, ++ struct crypto_bignum *d) ++{ ++ return mbedtls_mpi_add_mpi((mbedtls_mpi *)d, ++ (const mbedtls_mpi *)a, ++ (const mbedtls_mpi *)b) ++ || mbedtls_mpi_mod_mpi((mbedtls_mpi *)d, ++ (mbedtls_mpi *)d, ++ (const mbedtls_mpi *)c) ? -1 : 0; ++} ++ ++int crypto_bignum_mulmod(const struct crypto_bignum *a, ++ const struct crypto_bignum *b, ++ const struct crypto_bignum *c, ++ struct crypto_bignum *d) ++{ ++ return mbedtls_mpi_mul_mpi((mbedtls_mpi *)d, ++ (const mbedtls_mpi *)a, ++ (const mbedtls_mpi *)b) ++ || mbedtls_mpi_mod_mpi((mbedtls_mpi *)d, ++ (mbedtls_mpi *)d, ++ (const mbedtls_mpi *)c) ? -1 : 0; ++} ++ ++int crypto_bignum_sqrmod(const struct crypto_bignum *a, ++ const struct crypto_bignum *b, ++ struct crypto_bignum *c) ++{ ++ #if 1 ++ return crypto_bignum_mulmod(a, a, b, c); ++ #else ++ mbedtls_mpi bn; ++ mbedtls_mpi_init(&bn); ++ if (mbedtls_mpi_lset(&bn, 2)) /* alt?: mbedtls_mpi_set_bit(&bn, 1) */ ++ return -1; ++ int ret = mbedtls_mpi_exp_mod((mbedtls_mpi *)c, ++ (const mbedtls_mpi *)a, &bn, ++ (const mbedtls_mpi *)b, NULL) ? -1 : 0; ++ mbedtls_mpi_free(&bn); ++ return ret; ++ #endif ++} ++ ++int crypto_bignum_rshift(const struct crypto_bignum *a, int n, ++ struct crypto_bignum *r) ++{ ++ return mbedtls_mpi_copy((mbedtls_mpi *)r, (const mbedtls_mpi *)a) ++ || mbedtls_mpi_shift_r((mbedtls_mpi *)r, n) ? -1 : 0; ++} ++ ++int crypto_bignum_cmp(const struct crypto_bignum *a, ++ const struct crypto_bignum *b) ++{ ++ return mbedtls_mpi_cmp_mpi((const mbedtls_mpi *)a, (const mbedtls_mpi *)b); ++} ++ ++int crypto_bignum_is_zero(const struct crypto_bignum *a) ++{ ++ /* XXX: src/common/sae.c:sswu() contains comment: ++ * "TODO: Make sure crypto_bignum_is_zero() is constant time" ++ * Note: mbedtls_mpi_cmp_int() *is not* constant time */ ++ return (mbedtls_mpi_cmp_int((const mbedtls_mpi *)a, 0) == 0); ++} ++ ++int crypto_bignum_is_one(const struct crypto_bignum *a) ++{ ++ return (mbedtls_mpi_cmp_int((const mbedtls_mpi *)a, 1) == 0); ++} ++ ++int crypto_bignum_is_odd(const struct crypto_bignum *a) ++{ ++ return mbedtls_mpi_get_bit((const mbedtls_mpi *)a, 0); ++} ++ ++#include "utils/const_time.h" ++int crypto_bignum_legendre(const struct crypto_bignum *a, ++ const struct crypto_bignum *p) ++{ ++ /* Security Note: ++ * mbedtls_mpi_exp_mod() is not documented to run in constant time, ++ * though mbedtls/library/bignum.c uses constant_time_internal.h funcs. ++ * Compare to crypto_openssl.c:crypto_bignum_legendre() ++ * which uses openssl BN_mod_exp_mont_consttime() ++ * mbedtls/library/ecp.c has further countermeasures to timing attacks, ++ * (but ecp.c funcs are not used here) */ ++ ++ mbedtls_mpi exp, tmp; ++ mbedtls_mpi_init(&exp); ++ mbedtls_mpi_init(&tmp); ++ ++ /* exp = (p-1) / 2 */ ++ int res; ++ if (mbedtls_mpi_sub_int(&exp, (const mbedtls_mpi *)p, 1) == 0 ++ && mbedtls_mpi_shift_r(&exp, 1) == 0 ++ && mbedtls_mpi_exp_mod(&tmp, (const mbedtls_mpi *)a, &exp, ++ (const mbedtls_mpi *)p, NULL) == 0) { ++ /*(modified from crypto_openssl.c:crypto_bignum_legendre())*/ ++ /* Return 1 if tmp == 1, 0 if tmp == 0, or -1 otherwise. Need ++ * to use constant time selection to avoid branches here. */ ++ unsigned int mask; ++ res = -1; ++ mask = const_time_eq((mbedtls_mpi_cmp_int(&tmp, 1) == 0), 1); ++ res = const_time_select_int(mask, 1, res); ++ mask = const_time_eq((mbedtls_mpi_cmp_int(&tmp, 0) == 0), 1); ++ res = const_time_select_int(mask, 0, res); ++ } else { ++ res = -2; ++ } ++ ++ mbedtls_mpi_free(&tmp); ++ mbedtls_mpi_free(&exp); ++ return res; ++} ++ ++#endif /* CRYPTO_MBEDTLS_CRYPTO_BIGNUM */ ++ ++ ++#ifdef CRYPTO_MBEDTLS_CRYPTO_DH ++ ++/* crypto_internal-modexp.c */ ++ ++#include ++#include ++ ++#if 0 /* crypto_dh_init() and crypto_dh_derive_secret() prefer to use mbedtls */ ++int crypto_mod_exp(const u8 *base, size_t base_len, ++ const u8 *power, size_t power_len, ++ const u8 *modulus, size_t modulus_len, ++ u8 *result, size_t *result_len) ++{ ++ mbedtls_mpi bn_base, bn_exp, bn_modulus, bn_result; ++ mbedtls_mpi_init(&bn_base); ++ mbedtls_mpi_init(&bn_exp); ++ mbedtls_mpi_init(&bn_modulus); ++ mbedtls_mpi_init(&bn_result); ++ ++ size_t len; ++ int ret = mbedtls_mpi_read_binary(&bn_base, base, base_len) ++ || mbedtls_mpi_read_binary(&bn_exp, power, power_len) ++ || mbedtls_mpi_read_binary(&bn_modulus, modulus, modulus_len) ++ || mbedtls_mpi_exp_mod(&bn_result,&bn_base,&bn_exp,&bn_modulus,NULL) ++ || (len = mbedtls_mpi_size(&bn_result)) > *result_len ++ || mbedtls_mpi_write_binary(&bn_result, result, (*result_len = len)) ++ ? -1 ++ : 0; ++ ++ mbedtls_mpi_free(&bn_base); ++ mbedtls_mpi_free(&bn_exp); ++ mbedtls_mpi_free(&bn_modulus); ++ mbedtls_mpi_free(&bn_result); ++ return ret; ++} ++#endif ++ ++static int crypto_mbedtls_dh_set_bin_pg(mbedtls_dhm_context *ctx, u8 generator, ++ const u8 *prime, size_t prime_len) ++{ ++ /*(could set these directly in MBEDTLS_PRIVATE members)*/ ++ mbedtls_mpi P, G; ++ mbedtls_mpi_init(&P); ++ mbedtls_mpi_init(&G); ++ int ret = mbedtls_mpi_lset(&G, generator) ++ || mbedtls_mpi_read_binary(&P, prime, prime_len) ++ || mbedtls_dhm_set_group(ctx, &P, &G); ++ mbedtls_mpi_free(&P); ++ mbedtls_mpi_free(&G); ++ return ret; ++} ++ ++__attribute_noinline__ ++static int crypto_mbedtls_dh_init_public(mbedtls_dhm_context *ctx, u8 generator, ++ const u8 *prime, size_t prime_len, ++ u8 *privkey, u8 *pubkey) ++{ ++ if (crypto_mbedtls_dh_set_bin_pg(ctx, generator, prime, prime_len) ++ || mbedtls_dhm_make_public(ctx, (int)prime_len, pubkey, prime_len, ++ mbedtls_ctr_drbg_random, ++ crypto_mbedtls_ctr_drbg())) ++ return -1; ++ ++ /*(enable later when upstream mbedtls interface changes require)*/ ++ #if 0 && MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ ++ mbedtls_mpi X; ++ mbedtls_mpi_init(&X); ++ int ret = mbedtls_dhm_get_value(ctx, MBEDTLS_DHM_PARAM_X, &X) ++ || mbedtls_mpi_write_binary(&X, privkey, prime_len) ? -1 : 0; ++ mbedtls_mpi_free(&X); ++ return ret; ++ #else ++ return mbedtls_mpi_write_binary(&ctx->MBEDTLS_PRIVATE(X), ++ privkey, prime_len) ? -1 : 0; ++ #endif ++} ++ ++int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey, ++ u8 *pubkey) ++{ ++ #if 0 /*(crypto_dh_init() duplicated (and identical) in crypto_*.c modules)*/ ++ size_t pubkey_len, pad; ++ ++ if (os_get_random(privkey, prime_len) < 0) ++ return -1; ++ if (os_memcmp(privkey, prime, prime_len) > 0) { ++ /* Make sure private value is smaller than prime */ ++ privkey[0] = 0; ++ } ++ ++ pubkey_len = prime_len; ++ if (crypto_mod_exp(&generator, 1, privkey, prime_len, prime, prime_len, ++ pubkey, &pubkey_len) < 0) ++ return -1; ++ if (pubkey_len < prime_len) { ++ pad = prime_len - pubkey_len; ++ os_memmove(pubkey + pad, pubkey, pubkey_len); ++ os_memset(pubkey, 0, pad); ++ } ++ ++ return 0; ++ #else ++ /* Prefer to use mbedtls to derive our public/private key, as doing so ++ * leverages mbedtls to properly format output and to perform blinding*/ ++ mbedtls_dhm_context ctx; ++ mbedtls_dhm_init(&ctx); ++ int ret = crypto_mbedtls_dh_init_public(&ctx, generator, prime, ++ prime_len, privkey, pubkey); ++ mbedtls_dhm_free(&ctx); ++ return ret; ++ #endif ++} ++ ++/*(crypto_dh_derive_secret() could be implemented using crypto.h APIs ++ * instead of being reimplemented in each crypto_*.c)*/ ++int crypto_dh_derive_secret(u8 generator, const u8 *prime, size_t prime_len, ++ const u8 *order, size_t order_len, ++ const u8 *privkey, size_t privkey_len, ++ const u8 *pubkey, size_t pubkey_len, ++ u8 *secret, size_t *len) ++{ ++ #if 0 ++ if (pubkey_len > prime_len || ++ (pubkey_len == prime_len && ++ os_memcmp(pubkey, prime, prime_len) >= 0)) ++ return -1; ++ ++ int res = 0; ++ mbedtls_mpi pub; ++ mbedtls_mpi_init(&pub); ++ if (mbedtls_mpi_read_binary(&pub, pubkey, pubkey_len) ++ || mbedtls_mpi_cmp_int(&pub, 1) <= 0) { ++ res = -1; ++ } else if (order) { ++ mbedtls_mpi p, q, tmp; ++ mbedtls_mpi_init(&p); ++ mbedtls_mpi_init(&q); ++ mbedtls_mpi_init(&tmp); ++ ++ /* verify: pubkey^q == 1 mod p */ ++ res = (mbedtls_mpi_read_binary(&p, prime, prime_len) ++ || mbedtls_mpi_read_binary(&q, order, order_len) ++ || mbedtls_mpi_exp_mod(&tmp, &pub, &q, &p, NULL) ++ || mbedtls_mpi_cmp_int(&tmp, 1) != 0); ++ ++ mbedtls_mpi_free(&p); ++ mbedtls_mpi_free(&q); ++ mbedtls_mpi_free(&tmp); ++ } ++ mbedtls_mpi_free(&pub); ++ ++ return (res == 0) ++ ? crypto_mod_exp(pubkey, pubkey_len, privkey, privkey_len, ++ prime, prime_len, secret, len) ++ : -1; ++ #else ++ /* Prefer to use mbedtls to derive DH shared secret, as doing so ++ * leverages mbedtls to validate params and to perform blinding. ++ * ++ * Attempt to reconstitute DH context to derive shared secret ++ * (due to limitations of the interface, which ought to pass context). ++ * Force provided G (our private key) into context without validation. ++ * Regenerating GX (our public key) not needed to derive shared secret. ++ */ ++ /*(older compilers might not support VLAs)*/ ++ /*unsigned char buf[2+prime_len+2+1+2+pubkey_len];*/ ++ unsigned char buf[2+MBEDTLS_MPI_MAX_SIZE+2+1+2+MBEDTLS_MPI_MAX_SIZE]; ++ unsigned char *p = buf + 2 + prime_len; ++ if (2+prime_len+2+1+2+pubkey_len > sizeof(buf)) ++ return -1; ++ WPA_PUT_BE16(buf, prime_len); /*(2-byte big-endian size of prime)*/ ++ p[0] = 0; /*(2-byte big-endian size of generator)*/ ++ p[1] = 1; ++ p[2] = generator; ++ WPA_PUT_BE16(p+3, pubkey_len); /*(2-byte big-endian size of pubkey)*/ ++ os_memcpy(p+5, pubkey, pubkey_len); ++ os_memcpy(buf+2, prime, prime_len); ++ ++ mbedtls_dhm_context ctx; ++ mbedtls_dhm_init(&ctx); ++ p = buf; ++ int ret = mbedtls_dhm_read_params(&ctx, &p, p+2+prime_len+5+pubkey_len) ++ || mbedtls_mpi_read_binary(&ctx.MBEDTLS_PRIVATE(X), ++ privkey, privkey_len) ++ || mbedtls_dhm_calc_secret(&ctx, secret, *len, len, ++ mbedtls_ctr_drbg_random, ++ crypto_mbedtls_ctr_drbg()) ? -1 : 0; ++ mbedtls_dhm_free(&ctx); ++ return ret; ++ #endif ++} ++ ++/* dh_group5.c */ ++ ++#include "dh_group5.h" ++ ++/* RFC3526_PRIME_1536[] and RFC3526_GENERATOR_1536[] from crypto_wolfssl.c */ ++ ++static const unsigned char RFC3526_PRIME_1536[] = { ++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, ++ 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, ++ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, ++ 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, ++ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, ++ 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, ++ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, ++ 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, ++ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, ++ 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, ++ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, ++ 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, ++ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, ++ 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, ++ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, ++ 0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ++}; ++ ++static const unsigned char RFC3526_GENERATOR_1536[] = { ++ 0x02 ++}; ++ ++void * dh5_init(struct wpabuf **priv, struct wpabuf **publ) ++{ ++ const unsigned char * const prime = RFC3526_PRIME_1536; ++ const size_t prime_len = sizeof(RFC3526_PRIME_1536); ++ const u8 generator = *RFC3526_GENERATOR_1536; ++ struct wpabuf *wpubl = NULL, *wpriv = NULL; ++ ++ mbedtls_dhm_context *ctx = os_malloc(sizeof(*ctx)); ++ if (ctx == NULL) ++ return NULL; ++ mbedtls_dhm_init(ctx); ++ ++ if ( (wpubl = wpabuf_alloc(prime_len)) ++ && (wpriv = wpabuf_alloc(prime_len)) ++ && crypto_mbedtls_dh_init_public(ctx, generator, prime, prime_len, ++ wpabuf_put(wpriv, prime_len), ++ wpabuf_put(wpubl, prime_len))==0) { ++ wpabuf_free(*publ); ++ wpabuf_clear_free(*priv); ++ *publ = wpubl; ++ *priv = wpriv; ++ return ctx; ++ } ++ ++ wpabuf_clear_free(wpriv); ++ wpabuf_free(wpubl); ++ mbedtls_dhm_free(ctx); ++ os_free(ctx); ++ return NULL; ++} ++ ++#ifdef CRYPTO_MBEDTLS_DH5_INIT_FIXED ++void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ) ++{ ++ const unsigned char * const prime = RFC3526_PRIME_1536; ++ const size_t prime_len = sizeof(RFC3526_PRIME_1536); ++ const u8 generator = *RFC3526_GENERATOR_1536; ++ ++ mbedtls_dhm_context *ctx = os_malloc(sizeof(*ctx)); ++ if (ctx == NULL) ++ return NULL; ++ mbedtls_dhm_init(ctx); ++ ++ if (crypto_mbedtls_dh_set_bin_pg(ctx, generator, prime, prime_len)==0 ++ #if 0 /*(ignore; not required to derive shared secret)*/ ++ && mbedtls_mpi_read_binary(&ctx->MBEDTLS_PRIVATE(GX), ++ wpabuf_head(publ),wpabuf_len(publ))==0 ++ #endif ++ && mbedtls_mpi_read_binary(&ctx->MBEDTLS_PRIVATE(X), ++ wpabuf_head(priv),wpabuf_len(priv))==0) { ++ return ctx; ++ } ++ ++ mbedtls_dhm_free(ctx); ++ os_free(ctx); ++ return NULL; ++} ++#endif ++ ++struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public, ++ const struct wpabuf *own_private) ++{ ++ /*((mbedtls_dhm_context *)ctx must already contain own_private)*/ ++ /* mbedtls 2.x: prime_len = ctx->len; */ ++ /* mbedtls 3.x: prime_len = mbedtls_dhm_get_len(ctx); */ ++ size_t olen = sizeof(RFC3526_PRIME_1536); /*(sizeof(); prime known)*/ ++ struct wpabuf *buf = wpabuf_alloc(olen); ++ if (buf == NULL) ++ return NULL; ++ if (mbedtls_dhm_read_public((mbedtls_dhm_context *)ctx, ++ wpabuf_head(peer_public), ++ wpabuf_len(peer_public)) == 0 ++ && mbedtls_dhm_calc_secret(ctx, wpabuf_mhead(buf), olen, &olen, ++ mbedtls_ctr_drbg_random, ++ crypto_mbedtls_ctr_drbg()) == 0) { ++ wpabuf_put(buf, olen); ++ return buf; ++ } ++ ++ wpabuf_free(buf); ++ return NULL; ++} ++ ++void dh5_free(void *ctx) ++{ ++ mbedtls_dhm_free(ctx); ++ os_free(ctx); ++} ++ ++#endif /* CRYPTO_MBEDTLS_CRYPTO_DH */ ++ ++ ++#if defined(CRYPTO_MBEDTLS_CRYPTO_ECDH) || defined(CRYPTO_MBEDTLS_CRYPTO_EC) ++ ++#include ++ ++#define CRYPTO_EC_pbits(e) (((mbedtls_ecp_group *)(e))->pbits) ++#define CRYPTO_EC_plen(e) ((((mbedtls_ecp_group *)(e))->pbits+7)>>3) ++#define CRYPTO_EC_P(e) (&((mbedtls_ecp_group *)(e))->P) ++#define CRYPTO_EC_N(e) (&((mbedtls_ecp_group *)(e))->N) ++#define CRYPTO_EC_A(e) (&((mbedtls_ecp_group *)(e))->A) ++#define CRYPTO_EC_B(e) (&((mbedtls_ecp_group *)(e))->B) ++#define CRYPTO_EC_G(e) (&((mbedtls_ecp_group *)(e))->G) ++ ++static mbedtls_ecp_group_id crypto_mbedtls_ecp_group_id_from_ike_id(int group) ++{ ++ /* https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml */ ++ switch (group) { ++ #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED ++ case 19: return MBEDTLS_ECP_DP_SECP256R1; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED ++ case 20: return MBEDTLS_ECP_DP_SECP384R1; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED ++ case 21: return MBEDTLS_ECP_DP_SECP521R1; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED ++ case 25: return MBEDTLS_ECP_DP_SECP192R1; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED ++ case 26: return MBEDTLS_ECP_DP_SECP224R1; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED ++ case 28: return MBEDTLS_ECP_DP_BP256R1; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED ++ case 29: return MBEDTLS_ECP_DP_BP384R1; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED ++ case 30: return MBEDTLS_ECP_DP_BP512R1; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED ++ case 31: return MBEDTLS_ECP_DP_CURVE25519; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED ++ case 32: return MBEDTLS_ECP_DP_CURVE448; ++ #endif ++ default: return MBEDTLS_ECP_DP_NONE; ++ } ++} ++ ++#ifdef CRYPTO_MBEDTLS_CRYPTO_EC ++static int crypto_mbedtls_ike_id_from_ecp_group_id(mbedtls_ecp_group_id grp_id) ++{ ++ /* https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml */ ++ /*(for crypto_ec_key_group())*/ ++ switch (grp_id) { ++ #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED ++ case MBEDTLS_ECP_DP_SECP256R1: return 19; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED ++ case MBEDTLS_ECP_DP_SECP384R1: return 20; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED ++ case MBEDTLS_ECP_DP_SECP521R1: return 21; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED ++ case MBEDTLS_ECP_DP_SECP192R1: return 25; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED ++ case MBEDTLS_ECP_DP_SECP224R1: return 26; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED ++ case MBEDTLS_ECP_DP_BP256R1: return 28; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED ++ case MBEDTLS_ECP_DP_BP384R1: return 29; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED ++ case MBEDTLS_ECP_DP_BP512R1: return 30; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED ++ case MBEDTLS_ECP_DP_CURVE25519: return 31; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED ++ case MBEDTLS_ECP_DP_CURVE448: return 32; ++ #endif ++ default: return -1; ++ } ++} ++#endif ++ ++#endif /* CRYPTO_MBEDTLS_CRYPTO_ECDH || CRYPTO_MBEDTLS_CRYPTO_EC */ ++ ++ ++#if defined(CRYPTO_MBEDTLS_CRYPTO_ECDH) || defined(CRYPTO_MBEDTLS_CRYPTO_EC_DPP) ++ ++#include ++#include ++ ++static int crypto_mbedtls_keypair_gen(int group, mbedtls_pk_context *pk) ++{ ++ mbedtls_ecp_group_id grp_id = ++ crypto_mbedtls_ecp_group_id_from_ike_id(group); ++ if (grp_id == MBEDTLS_ECP_DP_NONE) ++ return -1; ++ const mbedtls_pk_info_t *pk_info = ++ mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); ++ if (pk_info == NULL) ++ return -1; ++ return mbedtls_pk_setup(pk, pk_info) ++ || mbedtls_ecp_gen_key(grp_id, mbedtls_pk_ec(*pk), ++ mbedtls_ctr_drbg_random, ++ crypto_mbedtls_ctr_drbg()) ? -1 : 0; ++} ++ ++#endif ++ ++ ++#ifdef CRYPTO_MBEDTLS_CRYPTO_ECDH ++ ++#include ++#include ++#include ++#include ++ ++/* wrap mbedtls_ecdh_context for more future-proof direct access to components ++ * (mbedtls_ecdh_context internal implementation may change between releases) ++ * ++ * If mbedtls_pk_context -- specifically underlying mbedtls_ecp_keypair -- ++ * lifetime were guaranteed to be longer than that of mbedtls_ecdh_context, ++ * then mbedtls_pk_context or mbedtls_ecp_keypair could be stored in crypto_ecdh ++ * (or crypto_ec_key could be stored in crypto_ecdh, and crypto_ec_key could ++ * wrap mbedtls_ecp_keypair and components, to avoid MBEDTLS_PRIVATE access) */ ++struct crypto_ecdh { ++ mbedtls_ecdh_context ctx; ++ mbedtls_ecp_group grp; ++ mbedtls_ecp_point Q; ++}; ++ ++struct crypto_ecdh * crypto_ecdh_init(int group) ++{ ++ mbedtls_pk_context pk; ++ mbedtls_pk_init(&pk); ++ struct crypto_ecdh *ecdh = crypto_mbedtls_keypair_gen(group, &pk) == 0 ++ ? crypto_ecdh_init2(group, (struct crypto_ec_key *)&pk) ++ : NULL; ++ mbedtls_pk_free(&pk); ++ return ecdh; ++} ++ ++struct crypto_ecdh * crypto_ecdh_init2(int group, ++ struct crypto_ec_key *own_key) ++{ ++ mbedtls_ecp_group_id grp_id = ++ crypto_mbedtls_ecp_group_id_from_ike_id(group); ++ if (grp_id == MBEDTLS_ECP_DP_NONE) ++ return NULL; ++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)own_key); ++ struct crypto_ecdh *ecdh = os_malloc(sizeof(*ecdh)); ++ if (ecdh == NULL) ++ return NULL; ++ mbedtls_ecdh_init(&ecdh->ctx); ++ mbedtls_ecp_group_init(&ecdh->grp); ++ mbedtls_ecp_point_init(&ecdh->Q); ++ if (mbedtls_ecdh_setup(&ecdh->ctx, grp_id) == 0 ++ && mbedtls_ecdh_get_params(&ecdh->ctx,ecp_kp,MBEDTLS_ECDH_OURS) == 0) { ++ /* copy grp and Q for later use ++ * (retrieving this info later is more convoluted ++ * even if mbedtls_ecdh_make_public() is considered)*/ ++ #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ ++ mbedtls_mpi d; ++ mbedtls_mpi_init(&d); ++ if (mbedtls_ecp_export(ecp_kp, &ecdh->grp, &d, &ecdh->Q) == 0) { ++ mbedtls_mpi_free(&d); ++ return ecdh; ++ } ++ mbedtls_mpi_free(&d); ++ #else ++ if (mbedtls_ecp_group_load(&ecdh->grp, grp_id) == 0 ++ && mbedtls_ecp_copy(&ecdh->Q, &ecp_kp->MBEDTLS_PRIVATE(Q)) == 0) ++ return ecdh; ++ #endif ++ } ++ ++ mbedtls_ecp_point_free(&ecdh->Q); ++ mbedtls_ecp_group_free(&ecdh->grp); ++ mbedtls_ecdh_free(&ecdh->ctx); ++ os_free(ecdh); ++ return NULL; ++} ++ ++struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y) ++{ ++ mbedtls_ecp_group *grp = &ecdh->grp; ++ size_t len = CRYPTO_EC_plen(grp); ++ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED ++ /* len */ ++ #endif ++ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED ++ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) ++ len = inc_y ? len*2+1 : len+1; ++ #endif ++ struct wpabuf *buf = wpabuf_alloc(len); ++ if (buf == NULL) ++ return NULL; ++ inc_y = inc_y ? MBEDTLS_ECP_PF_UNCOMPRESSED : MBEDTLS_ECP_PF_COMPRESSED; ++ if (mbedtls_ecp_point_write_binary(grp, &ecdh->Q, inc_y, &len, ++ wpabuf_mhead_u8(buf), len) == 0) { ++ wpabuf_put(buf, len); ++ return buf; ++ } ++ ++ wpabuf_free(buf); ++ return NULL; ++} ++ ++#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) ++static int crypto_mbedtls_short_weierstrass_derive_y(mbedtls_ecp_group *grp, ++ mbedtls_mpi *bn, ++ int parity_bit) ++{ ++ /* y^2 = x^3 + ax + b ++ * sqrt(w) = w^((p+1)/4) mod p (for prime p where p = 3 mod 4) */ ++ mbedtls_mpi *cy2 = (mbedtls_mpi *) ++ crypto_ec_point_compute_y_sqr((struct crypto_ec *)grp, ++ (const struct crypto_bignum *)bn); /*x*/ ++ if (cy2 == NULL) ++ return -1; ++ ++ /*mbedtls_mpi_free(bn);*/ ++ /*(reuse bn to store result (y))*/ ++ ++ mbedtls_mpi exp; ++ mbedtls_mpi_init(&exp); ++ int ret = mbedtls_mpi_get_bit(&grp->P, 0) != 1 /*(p = 3 mod 4)*/ ++ || mbedtls_mpi_get_bit(&grp->P, 1) != 1 /*(p = 3 mod 4)*/ ++ || mbedtls_mpi_add_int(&exp, &grp->P, 1) ++ || mbedtls_mpi_shift_r(&exp, 2) ++ || mbedtls_mpi_exp_mod(bn, cy2, &exp, &grp->P, NULL) ++ || (mbedtls_mpi_get_bit(bn, 0) != parity_bit ++ && mbedtls_mpi_sub_mpi(bn, &grp->P, bn)); ++ mbedtls_mpi_free(&exp); ++ mbedtls_mpi_free(cy2); ++ os_free(cy2); ++ return ret; ++} ++#endif ++ ++struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y, ++ const u8 *key, size_t len) ++{ ++ if (len == 0) /*(invalid peer key)*/ ++ return NULL; ++ ++ mbedtls_ecp_group *grp = &ecdh->grp; ++ ++ #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) ++ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { ++ /* add header for mbedtls_ecdh_read_public() */ ++ u8 buf[256]; ++ if (sizeof(buf)-1 < len) ++ return NULL; ++ buf[0] = (u8)(len); ++ os_memcpy(buf+1, key, len); ++ ++ if (inc_y) { ++ if (!(len & 1)) { /*(dpp code/tests does not include tag?!?)*/ ++ if (sizeof(buf)-2 < len) ++ return NULL; ++ buf[0] = (u8)(1+len); ++ buf[1] = 0x04; ++ os_memcpy(buf+2, key, len); ++ } ++ len >>= 1; /*(repurpose len to prime_len)*/ ++ } ++ else if (key[0] == 0x02 || key[0] == 0x03) { /* (inc_y == 0) */ ++ --len; /*(repurpose len to prime_len)*/ ++ ++ /* mbedtls_ecp_point_read_binary() does not currently support ++ * MBEDTLS_ECP_PF_COMPRESSED format (buf[1] = 0x02 or 0x03) ++ * (returns MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) */ ++ ++ /* derive y, amend buf[] with y for UNCOMPRESSED format */ ++ if (sizeof(buf)-2 < len*2 || len == 0) ++ return NULL; ++ buf[0] = (u8)(1+len*2); ++ buf[1] = 0x04; ++ mbedtls_mpi bn; ++ mbedtls_mpi_init(&bn); ++ int ret = mbedtls_mpi_read_binary(&bn, key+1, len) ++ || crypto_mbedtls_short_weierstrass_derive_y(grp, &bn, ++ key[0] & 1) ++ || mbedtls_mpi_write_binary(&bn, buf+2+len, len); ++ mbedtls_mpi_free(&bn); ++ if (ret != 0) ++ return NULL; ++ } ++ ++ if (key[0] == 0) /*(repurpose len to prime_len)*/ ++ len = CRYPTO_EC_plen(grp); ++ ++ if (mbedtls_ecdh_read_public(&ecdh->ctx, buf, buf[0]+1)) ++ return NULL; ++ } ++ #endif ++ #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) ++ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { ++ if (mbedtls_ecdh_read_public(&ecdh->ctx, key, len)) ++ return NULL; ++ } ++ #endif ++ ++ struct wpabuf *buf = wpabuf_alloc(len); ++ if (buf == NULL) ++ return NULL; ++ ++ if (mbedtls_ecdh_calc_secret(&ecdh->ctx, &len, ++ wpabuf_mhead(buf), len, ++ mbedtls_ctr_drbg_random, ++ crypto_mbedtls_ctr_drbg()) == 0) { ++ wpabuf_put(buf, len); ++ return buf; ++ } ++ ++ wpabuf_clear_free(buf); ++ return NULL; ++} ++ ++void crypto_ecdh_deinit(struct crypto_ecdh *ecdh) ++{ ++ if (ecdh == NULL) ++ return; ++ mbedtls_ecp_point_free(&ecdh->Q); ++ mbedtls_ecp_group_free(&ecdh->grp); ++ mbedtls_ecdh_free(&ecdh->ctx); ++ os_free(ecdh); ++} ++ ++size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh) ++{ ++ return CRYPTO_EC_plen(&ecdh->grp); ++} ++ ++#endif /* CRYPTO_MBEDTLS_CRYPTO_ECDH */ ++ ++ ++#ifdef CRYPTO_MBEDTLS_CRYPTO_EC ++ ++#include ++ ++struct crypto_ec *crypto_ec_init(int group) ++{ ++ mbedtls_ecp_group_id grp_id = ++ crypto_mbedtls_ecp_group_id_from_ike_id(group); ++ if (grp_id == MBEDTLS_ECP_DP_NONE) ++ return NULL; ++ mbedtls_ecp_group *e = os_malloc(sizeof(*e)); ++ if (e == NULL) ++ return NULL; ++ mbedtls_ecp_group_init(e); ++ if (mbedtls_ecp_group_load(e, grp_id) == 0) ++ return (struct crypto_ec *)e; ++ ++ mbedtls_ecp_group_free(e); ++ os_free(e); ++ return NULL; ++} ++ ++void crypto_ec_deinit(struct crypto_ec *e) ++{ ++ mbedtls_ecp_group_free((mbedtls_ecp_group *)e); ++ os_free(e); ++} ++ ++size_t crypto_ec_prime_len(struct crypto_ec *e) ++{ ++ return CRYPTO_EC_plen(e); ++} ++ ++size_t crypto_ec_prime_len_bits(struct crypto_ec *e) ++{ ++ return CRYPTO_EC_pbits(e); ++} ++ ++size_t crypto_ec_order_len(struct crypto_ec *e) ++{ ++ return (mbedtls_mpi_bitlen(CRYPTO_EC_N(e)) + 7) / 8; ++} ++ ++const struct crypto_bignum *crypto_ec_get_prime(struct crypto_ec *e) ++{ ++ return (const struct crypto_bignum *)CRYPTO_EC_P(e); ++} ++ ++const struct crypto_bignum *crypto_ec_get_order(struct crypto_ec *e) ++{ ++ return (const struct crypto_bignum *)CRYPTO_EC_N(e); ++} ++ ++const struct crypto_bignum *crypto_ec_get_a(struct crypto_ec *e) ++{ ++ static const uint8_t secp256r1_a[] = ++ {0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x01, ++ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, ++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc}; ++ static const uint8_t secp384r1_a[] = ++ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, ++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, ++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, ++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, ++ 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, ++ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xfc}; ++ static const uint8_t secp521r1_a[] = ++ {0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff, ++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, ++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, ++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, ++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, ++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, ++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, ++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, ++ 0xff,0xfc}; ++ static const uint8_t secp192r1_a[] = ++ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, ++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, ++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc}; ++ static const uint8_t secp224r1_a[] = ++ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, ++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, ++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, ++ 0xff,0xff,0xff,0xfe}; ++ ++ const uint8_t *bin = NULL; ++ size_t len = 0; ++ ++ /* (mbedtls groups matching supported sswu_curve_param() IKE groups) */ ++ switch (((mbedtls_ecp_group *)e)->id) { ++ #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED ++ case MBEDTLS_ECP_DP_SECP256R1: ++ bin = secp256r1_a; ++ len = sizeof(secp256r1_a); ++ break; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED ++ case MBEDTLS_ECP_DP_SECP384R1: ++ bin = secp384r1_a; ++ len = sizeof(secp384r1_a); ++ break; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED ++ case MBEDTLS_ECP_DP_SECP521R1: ++ bin = secp521r1_a; ++ len = sizeof(secp521r1_a); ++ break; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED ++ case MBEDTLS_ECP_DP_SECP192R1: ++ bin = secp192r1_a; ++ len = sizeof(secp192r1_a); ++ break; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED ++ case MBEDTLS_ECP_DP_SECP224R1: ++ bin = secp224r1_a; ++ len = sizeof(secp224r1_a); ++ break; ++ #endif ++ #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED ++ case MBEDTLS_ECP_DP_BP256R1: ++ return (const struct crypto_bignum *)CRYPTO_EC_A(e); ++ #endif ++ #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED ++ case MBEDTLS_ECP_DP_BP384R1: ++ return (const struct crypto_bignum *)CRYPTO_EC_A(e); ++ #endif ++ #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED ++ case MBEDTLS_ECP_DP_BP512R1: ++ return (const struct crypto_bignum *)CRYPTO_EC_A(e); ++ #endif ++ #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED ++ case MBEDTLS_ECP_DP_CURVE25519: ++ return (const struct crypto_bignum *)CRYPTO_EC_A(e); ++ #endif ++ #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED ++ case MBEDTLS_ECP_DP_CURVE448: ++ return (const struct crypto_bignum *)CRYPTO_EC_A(e); ++ #endif ++ default: ++ return NULL; ++ } ++ ++ /*(note: not thread-safe; returns file-scoped static storage)*/ ++ if (mbedtls_mpi_read_binary(&mpi_sw_A, bin, len) == 0) ++ return (const struct crypto_bignum *)&mpi_sw_A; ++ return NULL; ++} ++ ++const struct crypto_bignum *crypto_ec_get_b(struct crypto_ec *e) ++{ ++ return (const struct crypto_bignum *)CRYPTO_EC_B(e); ++} ++ ++const struct crypto_ec_point * crypto_ec_get_generator(struct crypto_ec *e) ++{ ++ return (const struct crypto_ec_point *)CRYPTO_EC_G(e); ++} ++ ++struct crypto_ec_point *crypto_ec_point_init(struct crypto_ec *e) ++{ ++ mbedtls_ecp_point *p = os_malloc(sizeof(*p)); ++ if (p != NULL) ++ mbedtls_ecp_point_init(p); ++ return (struct crypto_ec_point *)p; ++} ++ ++void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear) ++{ ++ mbedtls_ecp_point_free((mbedtls_ecp_point *)p); ++ os_free(p); ++} ++ ++int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p, ++ struct crypto_bignum *x) ++{ ++ mbedtls_mpi *px = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X); ++ return mbedtls_mpi_copy((mbedtls_mpi *)x, px) ++ ? -1 ++ : 0; ++} ++ ++int crypto_ec_point_to_bin(struct crypto_ec *e, ++ const struct crypto_ec_point *point, u8 *x, u8 *y) ++{ ++ /* crypto.h documents crypto_ec_point_to_bin() output is big-endian */ ++ size_t len = CRYPTO_EC_plen(e); ++ if (x) { ++ mbedtls_mpi *px = &((mbedtls_ecp_point *)point)->MBEDTLS_PRIVATE(X); ++ if (mbedtls_mpi_write_binary(px, x, len)) ++ return -1; ++ } ++ if (y) { ++ #if 0 /*(should not be necessary; py mpi should be in initial state)*/ ++ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED ++ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) ++ == MBEDTLS_ECP_TYPE_MONTGOMERY) { ++ os_memset(y, 0, len); ++ return 0; ++ } ++ #endif ++ #endif ++ mbedtls_mpi *py = &((mbedtls_ecp_point *)point)->MBEDTLS_PRIVATE(Y); ++ if (mbedtls_mpi_write_binary(py, y, len)) ++ return -1; ++ } ++ return 0; ++} ++ ++struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e, ++ const u8 *val) ++{ ++ size_t len = CRYPTO_EC_plen(e); ++ mbedtls_ecp_point *p = os_malloc(sizeof(*p)); ++ u8 buf[1+MBEDTLS_MPI_MAX_SIZE*2]; ++ if (p == NULL) ++ return NULL; ++ mbedtls_ecp_point_init(p); ++ ++ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED ++ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) ++ == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { ++ #if 0 /* prefer alternative to MBEDTLS_PRIVATE() access */ ++ mbedtls_mpi *px = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X); ++ mbedtls_mpi *py = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y); ++ mbedtls_mpi *pz = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Z); ++ ++ if (mbedtls_mpi_read_binary(px, val, len) == 0 ++ && mbedtls_mpi_read_binary(py, val + len, len) == 0 ++ && mbedtls_mpi_lset(pz, 1) == 0) ++ return (struct crypto_ec_point *)p; ++ #else ++ buf[0] = 0x04; ++ os_memcpy(buf+1, val, len*2); ++ if (mbedtls_ecp_point_read_binary((mbedtls_ecp_group *)e, p, ++ buf, 1+len*2) == 0) ++ return (struct crypto_ec_point *)p; ++ #endif ++ } ++ #endif ++ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED ++ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) ++ == MBEDTLS_ECP_TYPE_MONTGOMERY) { ++ /* crypto.h interface documents crypto_ec_point_from_bin() ++ * val is length: prime_len * 2 and is big-endian ++ * (Short Weierstrass is assumed by hostap) ++ * Reverse to little-endian format for Montgomery */ ++ for (unsigned int i = 0; i < len; ++i) ++ buf[i] = val[len-1-i]; ++ if (mbedtls_ecp_point_read_binary((mbedtls_ecp_group *)e, p, ++ buf, len) == 0) ++ return (struct crypto_ec_point *)p; ++ } ++ #endif ++ ++ mbedtls_ecp_point_free(p); ++ os_free(p); ++ return NULL; ++} ++ ++int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a, ++ const struct crypto_ec_point *b, ++ struct crypto_ec_point *c) ++{ ++ /* mbedtls does not provide an mbedtls_ecp_point add function */ ++ mbedtls_mpi one; ++ mbedtls_mpi_init(&one); ++ int ret = mbedtls_mpi_lset(&one, 1) ++ || mbedtls_ecp_muladd( ++ (mbedtls_ecp_group *)e, (mbedtls_ecp_point *)c, ++ &one, (const mbedtls_ecp_point *)a, ++ &one, (const mbedtls_ecp_point *)b) ? -1 : 0; ++ mbedtls_mpi_free(&one); ++ return ret; ++} ++ ++int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p, ++ const struct crypto_bignum *b, ++ struct crypto_ec_point *res) ++{ ++ return mbedtls_ecp_mul( ++ (mbedtls_ecp_group *)e, (mbedtls_ecp_point *)res, ++ (const mbedtls_mpi *)b, (const mbedtls_ecp_point *)p, ++ mbedtls_ctr_drbg_random, crypto_mbedtls_ctr_drbg()) ? -1 : 0; ++} ++ ++int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p) ++{ ++ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) ++ == MBEDTLS_ECP_TYPE_MONTGOMERY) { ++ /* e.g. MBEDTLS_ECP_DP_CURVE25519 and MBEDTLS_ECP_DP_CURVE448 */ ++ wpa_printf(MSG_ERROR, ++ "%s not implemented for Montgomery curves",__func__); ++ return -1; ++ } ++ ++ /* mbedtls does not provide an mbedtls_ecp_point invert function */ ++ /* below works for Short Weierstrass; incorrect for Montgomery curves */ ++ mbedtls_mpi *py = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y); ++ return mbedtls_ecp_is_zero((mbedtls_ecp_point *)p) /*point at infinity*/ ++ || mbedtls_mpi_cmp_int(py, 0) == 0 /*point is its own inverse*/ ++ || mbedtls_mpi_sub_abs(py, CRYPTO_EC_P(e), py) == 0 ? 0 : -1; ++} ++ ++#ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED ++static int ++crypto_ec_point_y_sqr_weierstrass(mbedtls_ecp_group *e, const mbedtls_mpi *x, ++ mbedtls_mpi *y2) ++{ ++ /* MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS y^2 = x^3 + a x + b */ ++ ++ /* Short Weierstrass elliptic curve group w/o A set treated as A = -3 */ ++ /* Attempt to match mbedtls/library/ecp.c:ecp_check_pubkey_sw() behavior ++ * and elsewhere in mbedtls/library/ecp.c where if A is not set, it is ++ * treated as if A = -3. */ ++ ++ #if 0 ++ /* y^2 = x^3 + ax + b */ ++ mbedtls_mpi *A = &e->A; ++ mbedtls_mpi t, A_neg3; ++ if (&e->A.p == NULL) { ++ mbedtls_mpi_init(&A_neg3); ++ if (mbedtls_mpi_lset(&A_neg3, -3) != 0) { ++ mbedtls_mpi_free(&A_neg3); ++ return -1; ++ } ++ A = &A_neg3; ++ } ++ mbedtls_mpi_init(&t); ++ int ret = /* x^3 */ ++ mbedtls_mpi_lset(&t, 3) ++ || mbedtls_mpi_exp_mod(y2, x, &t, &e->P, NULL) ++ /* ax */ ++ || mbedtls_mpi_mul_mpi(y2, y2, A) ++ || mbedtls_mpi_mod_mpi(&t, &t, &e->P) ++ /* ax + b */ ++ || mbedtls_mpi_add_mpi(&t, &t, &e->B) ++ || mbedtls_mpi_mod_mpi(&t, &t, &e->P) ++ /* x^3 + ax + b */ ++ || mbedtls_mpi_add_mpi(&t, &t, y2) /* ax + b + x^3 */ ++ || mbedtls_mpi_mod_mpi(y2, &t, &e->P); ++ mbedtls_mpi_free(&t); ++ if (A == &A_neg3) ++ mbedtls_mpi_free(&A_neg3); ++ return ret; /* 0: success, non-zero: failure */ ++ #else ++ /* y^2 = x^3 + ax + b = (x^2 + a)x + b */ ++ return /* x^2 */ ++ mbedtls_mpi_mul_mpi(y2, x, x) ++ || mbedtls_mpi_mod_mpi(y2, y2, &e->P) ++ /* x^2 + a */ ++ || (e->A.MBEDTLS_PRIVATE(p) ++ ? mbedtls_mpi_add_mpi(y2, y2, &e->A) ++ : mbedtls_mpi_sub_int(y2, y2, 3)) ++ || mbedtls_mpi_mod_mpi(y2, y2, &e->P) ++ /* (x^2 + a)x */ ++ || mbedtls_mpi_mul_mpi(y2, y2, x) ++ || mbedtls_mpi_mod_mpi(y2, y2, &e->P) ++ /* (x^2 + a)x + b */ ++ || mbedtls_mpi_add_mpi(y2, y2, &e->B) ++ || mbedtls_mpi_mod_mpi(y2, y2, &e->P); ++ #endif ++} ++#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ ++ ++#if 0 /* not used by hostap */ ++#ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED ++static int ++crypto_ec_point_y_sqr_montgomery(mbedtls_ecp_group *e, const mbedtls_mpi *x, ++ mbedtls_mpi *y2) ++{ ++ /* XXX: !!! must be reviewed and audited for correctness !!! */ ++ ++ /* MBEDTLS_ECP_TYPE_MONTGOMERY y^2 = x^3 + a x^2 + x */ ++ ++ /* y^2 = x^3 + a x^2 + x = (x + a)x^2 + x */ ++ mbedtls_mpi x2; ++ mbedtls_mpi_init(&x2); ++ int ret = /* x^2 */ ++ mbedtls_mpi_mul_mpi(&x2, x, x) ++ || mbedtls_mpi_mod_mpi(&x2, &x2, &e->P) ++ /* x + a */ ++ || mbedtls_mpi_add_mpi(y2, x, &e->A) ++ || mbedtls_mpi_mod_mpi(y2, y2, &e->P) ++ /* (x + a)x^2 */ ++ || mbedtls_mpi_mul_mpi(y2, y2, &x2) ++ || mbedtls_mpi_mod_mpi(y2, y2, &e->P) ++ /* (x + a)x^2 + x */ ++ || mbedtls_mpi_add_mpi(y2, y2, x) ++ || mbedtls_mpi_mod_mpi(y2, y2, &e->P); ++ mbedtls_mpi_free(&x2); ++ return ret; /* 0: success, non-zero: failure */ ++} ++#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ ++#endif ++ ++struct crypto_bignum * ++crypto_ec_point_compute_y_sqr(struct crypto_ec *e, ++ const struct crypto_bignum *x) ++{ ++ mbedtls_mpi *y2 = os_malloc(sizeof(*y2)); ++ if (y2 == NULL) ++ return NULL; ++ mbedtls_mpi_init(y2); ++ ++ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED ++ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) ++ == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ++ && crypto_ec_point_y_sqr_weierstrass((mbedtls_ecp_group *)e, ++ (const mbedtls_mpi *)x, ++ y2) == 0) ++ return (struct crypto_bignum *)y2; ++ #endif ++ #if 0 /* not used by hostap */ ++ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED ++ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) ++ == MBEDTLS_ECP_TYPE_MONTGOMERY ++ && crypto_ec_point_y_sqr_montgomery((mbedtls_ecp_group *)e, ++ (const mbedtls_mpi *)x, ++ y2) == 0) ++ return (struct crypto_bignum *)y2; ++ #endif ++ #endif ++ ++ mbedtls_mpi_free(y2); ++ os_free(y2); ++ return NULL; ++} ++ ++int crypto_ec_point_is_at_infinity(struct crypto_ec *e, ++ const struct crypto_ec_point *p) ++{ ++ return mbedtls_ecp_is_zero((mbedtls_ecp_point *)p); ++} ++ ++int crypto_ec_point_is_on_curve(struct crypto_ec *e, ++ const struct crypto_ec_point *p) ++{ ++ #if 1 ++ return mbedtls_ecp_check_pubkey((const mbedtls_ecp_group *)e, ++ (const mbedtls_ecp_point *)p) == 0; ++ #else ++ /* compute y^2 mod P and compare to y^2 mod P */ ++ /*(ref: src/eap_common/eap_pwd_common.c:compute_password_element())*/ ++ const mbedtls_mpi *px = &((const mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X); ++ mbedtls_mpi *cy2 = (mbedtls_mpi *) ++ crypto_ec_point_compute_y_sqr(e, (const struct crypto_bignum *)px); ++ if (cy2 == NULL) ++ return 0; ++ ++ mbedtls_mpi y2; ++ mbedtls_mpi_init(&y2); ++ const mbedtls_mpi *py = &((const mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y); ++ int is_on_curve = mbedtls_mpi_mul_mpi(&y2, py, py) /* y^2 mod P */ ++ || mbedtls_mpi_mod_mpi(&y2, &y2, CRYPTO_EC_P(e)) ++ || mbedtls_mpi_cmp_mpi(&y2, cy2) != 0 ? 0 : 1; ++ ++ mbedtls_mpi_free(&y2); ++ mbedtls_mpi_free(cy2); ++ os_free(cy2); ++ return is_on_curve; ++ #endif ++} ++ ++int crypto_ec_point_cmp(const struct crypto_ec *e, ++ const struct crypto_ec_point *a, ++ const struct crypto_ec_point *b) ++{ ++ return mbedtls_ecp_point_cmp((const mbedtls_ecp_point *)a, ++ (const mbedtls_ecp_point *)b); ++} ++ ++#if !defined(CONFIG_NO_STDOUT_DEBUG) ++void crypto_ec_point_debug_print(const struct crypto_ec *e, ++ const struct crypto_ec_point *p, ++ const char *title) ++{ ++ u8 x[MBEDTLS_MPI_MAX_SIZE]; ++ u8 y[MBEDTLS_MPI_MAX_SIZE]; ++ size_t len = CRYPTO_EC_plen(e); ++ /* crypto_ec_point_to_bin ought to take (const struct crypto_ec *e) */ ++ struct crypto_ec *ee; ++ *(const struct crypto_ec **)&ee = e; /*(cast away const)*/ ++ if (crypto_ec_point_to_bin(ee, p, x, y) == 0) { ++ if (title) ++ wpa_printf(MSG_DEBUG, "%s", title); ++ wpa_hexdump(MSG_DEBUG, "x:", x, len); ++ wpa_hexdump(MSG_DEBUG, "y:", y, len); ++ } ++} ++#endif ++ ++ ++struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len) ++{ ++ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); ++ if (ctx == NULL) ++ return NULL; ++ mbedtls_pk_init(ctx); ++ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ ++ if (mbedtls_pk_parse_key(ctx, der, der_len, NULL, 0) == 0) ++ #else ++ if (mbedtls_pk_parse_key(ctx, der, der_len, NULL, 0, ++ mbedtls_ctr_drbg_random, ++ crypto_mbedtls_ctr_drbg()) == 0) ++ #endif ++ return (struct crypto_ec_key *)ctx; ++ ++ mbedtls_pk_free(ctx); ++ os_free(ctx); ++ return NULL; ++} ++ ++#ifdef CRYPTO_MBEDTLS_CRYPTO_HPKE ++#ifdef CONFIG_MODULE_TESTS ++/*(for crypto_module_tests.c)*/ ++struct crypto_ec_key * crypto_ec_key_set_priv(int group, ++ const u8 *raw, size_t raw_len) ++{ ++ mbedtls_ecp_group_id grp_id = ++ crypto_mbedtls_ecp_group_id_from_ike_id(group); ++ if (grp_id == MBEDTLS_ECP_DP_NONE) ++ return NULL; ++ const mbedtls_pk_info_t *pk_info = ++ mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); ++ if (pk_info == NULL) ++ return NULL; ++ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); ++ if (ctx == NULL) ++ return NULL; ++ mbedtls_pk_init(ctx); ++ if (mbedtls_pk_setup(ctx, pk_info) == 0 ++ && mbedtls_ecp_read_key(grp_id,mbedtls_pk_ec(*ctx),raw,raw_len) == 0) { ++ return (struct crypto_ec_key *)ctx; ++ } ++ ++ mbedtls_pk_free(ctx); ++ os_free(ctx); ++ return NULL; ++} ++#endif ++#endif ++ ++#include ++#include ++static int crypto_mbedtls_pk_parse_subpubkey_compressed(mbedtls_pk_context *ctx, const u8 *der, size_t der_len) ++{ ++ /* The following is modified from: ++ * mbedtls/library/pkparse.c:mbedtls_pk_parse_subpubkey() ++ * mbedtls/library/pkparse.c:pk_get_pk_alg() ++ * mbedtls/library/pkparse.c:pk_use_ecparams() ++ */ ++ mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; ++ const mbedtls_pk_info_t *pk_info; ++ int ret; ++ size_t len; ++ const unsigned char *end = der+der_len; ++ unsigned char *p; ++ *(const unsigned char **)&p = der; ++ ++ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, ++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) ++ { ++ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) ); ++ } ++ ++ end = p + len; ++ ++ /* ++ if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &alg_params ) ) != 0 ) ++ return( ret ); ++ */ ++ mbedtls_asn1_buf alg_oid, params; ++ memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) ); ++ if( ( ret = mbedtls_asn1_get_alg( &p, end, &alg_oid, ¶ms ) ) != 0 ) ++ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_ALG, ret ) ); ++ if( mbedtls_oid_get_pk_alg( &alg_oid, &pk_alg ) != 0 ) ++ return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); ++ ++ if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end, &len ) ) != 0 ) ++ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, ret ) ); ++ ++ if( p + len != end ) ++ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, ++ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) ); ++ ++ if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL ) ++ return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); ++ ++ if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 ) ++ return( ret ); ++ ++ /* assume mbedtls_pk_parse_subpubkey(&der, der+der_len, ctx) ++ * has already run with ctx initialized up to pk_get_ecpubkey(), ++ * and pk_get_ecpubkey() has returned MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ++ * ++ * mbedtls mbedtls_ecp_point_read_binary() ++ * does not handle point in COMPRESSED format ++ * ++ * (validate assumption that algorithm is EC) */ ++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*ctx); ++ if (ecp_kp == NULL) ++ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); ++ mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); ++ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); ++ mbedtls_ecp_group_id grp_id; ++ ++ ++ /* mbedtls/library/pkparse.c:pk_use_ecparams() */ ++ ++ if( params.tag == MBEDTLS_ASN1_OID ) ++ { ++ if( mbedtls_oid_get_ec_grp( ¶ms, &grp_id ) != 0 ) ++ return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE ); ++ } ++ else ++ { ++#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) ++ /*(large code block not copied from mbedtls; unsupported)*/ ++ #if 0 ++ if( ( ret = pk_group_id_from_specified( ¶ms, &grp_id ) ) != 0 ) ++ return( ret ); ++ #endif ++#endif ++ return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); ++ } ++ ++ /* ++ * grp may already be initialized; if so, make sure IDs match ++ */ ++ if( ecp_kp_grp->id != MBEDTLS_ECP_DP_NONE && ecp_kp_grp->id != grp_id ) ++ return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); ++ ++ if( ( ret = mbedtls_ecp_group_load( ecp_kp_grp, grp_id ) ) != 0 ) ++ return( ret ); ++ ++ ++ /* (validate assumption that EC point is in COMPRESSED format) */ ++ len = CRYPTO_EC_plen(ecp_kp_grp); ++ if( mbedtls_ecp_get_type(ecp_kp_grp) != MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ++ || (end - p) != 1+len ++ || (*p != 0x02 && *p != 0x03) ) ++ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); ++ ++ /* Instead of calling mbedtls/library/pkparse.c:pk_get_ecpubkey() to call ++ * mbedtls_ecp_point_read_binary(), manually parse point into ecp_kp_Q */ ++ mbedtls_mpi *X = &ecp_kp_Q->MBEDTLS_PRIVATE(X); ++ mbedtls_mpi *Y = &ecp_kp_Q->MBEDTLS_PRIVATE(Y); ++ mbedtls_mpi *Z = &ecp_kp_Q->MBEDTLS_PRIVATE(Z); ++ ret = mbedtls_mpi_lset(Z, 1); ++ if (ret != 0) ++ return( ret ); ++ ret = mbedtls_mpi_read_binary(X, p+1, len); ++ if (ret != 0) ++ return( ret ); ++ /* derive Y ++ * (similar derivation of Y in crypto_mbedtls.c:crypto_ecdh_set_peerkey())*/ ++ ret = mbedtls_mpi_copy(Y, X) /*(Y is used as input and output obj below)*/ ++ || crypto_mbedtls_short_weierstrass_derive_y(ecp_kp_grp, Y, (*p & 1)); ++ if (ret != 0) ++ return( ret ); ++ ++ return mbedtls_ecp_check_pubkey( ecp_kp_grp, ecp_kp_Q ); ++} ++ ++struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len) ++{ ++ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); ++ if (ctx == NULL) ++ return NULL; ++ mbedtls_pk_init(ctx); ++ /*int rc = mbedtls_pk_parse_subpubkey(&der, der+der_len, ctx);*/ ++ int rc = mbedtls_pk_parse_public_key(ctx, der, der_len); ++ if (rc == 0) ++ return (struct crypto_ec_key *)ctx; ++ else if (rc == MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) { ++ /* mbedtls mbedtls_ecp_point_read_binary() ++ * does not handle point in COMPRESSED format; parse internally */ ++ rc = crypto_mbedtls_pk_parse_subpubkey_compressed(ctx,der,der_len); ++ if (rc == 0) ++ return (struct crypto_ec_key *)ctx; ++ } ++ ++ mbedtls_pk_free(ctx); ++ os_free(ctx); ++ return NULL; ++} ++ ++#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP ++ ++static struct crypto_ec_key * ++crypto_ec_key_set_pub_point_for_group(mbedtls_ecp_group_id grp_id, ++ const mbedtls_ecp_point *pub, ++ const u8 *buf, size_t len) ++{ ++ const mbedtls_pk_info_t *pk_info = ++ mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); ++ if (pk_info == NULL) ++ return NULL; ++ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); ++ if (ctx == NULL) ++ return NULL; ++ mbedtls_pk_init(ctx); ++ if (mbedtls_pk_setup(ctx, pk_info) == 0) { ++ /* (Is private key generation necessary for callers?) ++ * alt: gen key then overwrite Q ++ * mbedtls_ecp_gen_key(grp_id, ecp_kp, ++ * mbedtls_ctr_drbg_random, ++ * crypto_mbedtls_ctr_drbg()) == 0 ++ */ ++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*ctx); ++ mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); ++ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); ++ mbedtls_mpi *ecp_kp_d = &ecp_kp->MBEDTLS_PRIVATE(d); ++ if (mbedtls_ecp_group_load(ecp_kp_grp, grp_id) == 0 ++ && (pub ++ ? mbedtls_ecp_copy(ecp_kp_Q, pub) == 0 ++ : mbedtls_ecp_point_read_binary(ecp_kp_grp, ecp_kp_Q, ++ buf, len) == 0) ++ && mbedtls_ecp_gen_privkey(ecp_kp_grp, ecp_kp_d, ++ mbedtls_ctr_drbg_random, ++ crypto_mbedtls_ctr_drbg()) == 0){ ++ return (struct crypto_ec_key *)ctx; ++ } ++ } ++ ++ mbedtls_pk_free(ctx); ++ os_free(ctx); ++ return NULL; ++} ++ ++struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *x, ++ const u8 *y, size_t len) ++{ ++ mbedtls_ecp_group_id grp_id = ++ crypto_mbedtls_ecp_group_id_from_ike_id(group); ++ if (grp_id == MBEDTLS_ECP_DP_NONE) ++ return NULL; ++ if (len > MBEDTLS_MPI_MAX_SIZE) ++ return NULL; ++ u8 buf[1+MBEDTLS_MPI_MAX_SIZE*2]; ++ buf[0] = 0x04; /* assume x,y for Short Weierstrass */ ++ os_memcpy(buf+1, x, len); ++ os_memcpy(buf+1+len, y, len); ++ ++ return crypto_ec_key_set_pub_point_for_group(grp_id,NULL,buf,1+len*2); ++} ++ ++struct crypto_ec_key * ++crypto_ec_key_set_pub_point(struct crypto_ec *e, ++ const struct crypto_ec_point *pub) ++{ ++ mbedtls_ecp_group_id grp_id = ((mbedtls_ecp_group *)e)->id; ++ mbedtls_ecp_point *p = (mbedtls_ecp_point *)pub; ++ return crypto_ec_key_set_pub_point_for_group(grp_id, p, NULL, 0); ++} ++ ++ ++struct crypto_ec_key * crypto_ec_key_gen(int group) ++{ ++ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); ++ if (ctx == NULL) ++ return NULL; ++ mbedtls_pk_init(ctx); ++ if (crypto_mbedtls_keypair_gen(group, ctx) == 0) ++ return (struct crypto_ec_key *)ctx; ++ mbedtls_pk_free(ctx); ++ os_free(ctx); ++ return NULL; ++} ++ ++#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ ++ ++void crypto_ec_key_deinit(struct crypto_ec_key *key) ++{ ++ mbedtls_pk_free((mbedtls_pk_context *)key); ++ os_free(key); ++} ++ ++struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key) ++{ ++ /* (similar to crypto_ec_key_get_pubkey_point(), ++ * but compressed point format and ASN.1 DER wrapping)*/ ++#ifndef MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES /*(mbedtls/library/pkwrite.h)*/ ++#define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES ( 30 + 2 * MBEDTLS_ECP_MAX_BYTES ) ++#endif ++ unsigned char buf[MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES]; ++ int len = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)key, ++ buf, sizeof(buf)); ++ if (len < 0) ++ return NULL; ++ /* Note: data is written at the end of the buffer! Use the ++ * return value to determine where you should start ++ * using the buffer */ ++ unsigned char *p = buf+sizeof(buf)-len; ++ ++ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED ++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); ++ if (ecp_kp == NULL) ++ return NULL; ++ mbedtls_ecp_group *grp = &ecp_kp->MBEDTLS_PRIVATE(grp); ++ /* Note: sae_pk.c expects pubkey point in compressed format, ++ * but mbedtls_pk_write_pubkey_der() writes uncompressed format. ++ * Manually translate format and update lengths in DER format */ ++ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { ++ unsigned char *end = buf+sizeof(buf); ++ size_t n; ++ /* SubjectPublicKeyInfo SEQUENCE */ ++ mbedtls_asn1_get_tag(&p, end, &n, ++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); ++ /* algorithm AlgorithmIdentifier */ ++ unsigned char *a = p; ++ size_t alen; ++ mbedtls_asn1_get_tag(&p, end, &alen, ++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); ++ p += alen; ++ alen = (size_t)(p - a); ++ /* subjectPublicKey BIT STRING */ ++ mbedtls_asn1_get_tag(&p, end, &n, MBEDTLS_ASN1_BIT_STRING); ++ /* rewrite into compressed point format and rebuild ASN.1 */ ++ p[1] = (buf[sizeof(buf)-1] & 1) ? 0x03 : 0x02; ++ n = 1 + 1 + (n-2)/2; ++ len = mbedtls_asn1_write_len(&p, buf, n) + (int)n; ++ len += mbedtls_asn1_write_tag(&p, buf, MBEDTLS_ASN1_BIT_STRING); ++ os_memmove(p-alen, a, alen); ++ len += alen; ++ p -= alen; ++ len += mbedtls_asn1_write_len(&p, buf, (size_t)len); ++ len += mbedtls_asn1_write_tag(&p, buf, ++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); ++ } ++ #endif ++ return wpabuf_alloc_copy(p, (size_t)len); ++} ++ ++#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP ++ ++struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key, ++ bool include_pub) ++{ ++#ifndef MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES /*(mbedtls/library/pkwrite.h)*/ ++#define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES ( 29 + 3 * MBEDTLS_ECP_MAX_BYTES ) ++#endif ++ unsigned char priv[MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES]; ++ int privlen = mbedtls_pk_write_key_der((mbedtls_pk_context *)key, ++ priv, sizeof(priv)); ++ if (privlen < 0) ++ return NULL; ++ ++ struct wpabuf *wbuf; ++ ++ /* Note: data is written at the end of the buffer! Use the ++ * return value to determine where you should start ++ * using the buffer */ ++ /* mbedtls_pk_write_key_der() includes publicKey in DER */ ++ if (include_pub) ++ wbuf = wpabuf_alloc_copy(priv+sizeof(priv)-privlen, privlen); ++ else { ++ /* calculate publicKey offset and skip from end of buffer */ ++ unsigned char *p = priv+sizeof(priv)-privlen; ++ unsigned char *end = priv+sizeof(priv); ++ size_t len; ++ /* ECPrivateKey SEQUENCE */ ++ mbedtls_asn1_get_tag(&p, end, &len, ++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); ++ /* version INTEGER */ ++ unsigned char *v = p; ++ mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER); ++ p += len; ++ /* privateKey OCTET STRING */ ++ mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); ++ p += len; ++ /* parameters ECParameters */ ++ mbedtls_asn1_get_tag(&p, end, &len, ++ MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED); ++ p += len; ++ ++ /* write new SEQUENCE header (we know that it fits in priv[]) */ ++ len = (size_t)(p - v); ++ p = v; ++ len += mbedtls_asn1_write_len(&p, priv, len); ++ len += mbedtls_asn1_write_tag(&p, priv, ++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); ++ wbuf = wpabuf_alloc_copy(p, len); ++ } ++ ++ forced_memzero(priv, sizeof(priv)); ++ return wbuf; ++} ++ ++struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key, ++ int prefix) ++{ ++ /*(similarities to crypto_ecdh_get_pubkey(), but different struct)*/ ++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); ++ if (ecp_kp == NULL) ++ return NULL; ++ mbedtls_ecp_group *grp = &ecp_kp->MBEDTLS_PRIVATE(grp); ++ size_t len = CRYPTO_EC_plen(grp); ++ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED ++ /* len */ ++ #endif ++ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED ++ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) ++ len = len*2+1; ++ #endif ++ struct wpabuf *buf = wpabuf_alloc(len); ++ if (buf == NULL) ++ return NULL; ++ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); ++ if (mbedtls_ecp_point_write_binary(grp, ecp_kp_Q, ++ MBEDTLS_ECP_PF_UNCOMPRESSED, &len, ++ wpabuf_mhead_u8(buf), len) == 0) { ++ if (!prefix) /* Remove 0x04 prefix if requested */ ++ os_memmove(wpabuf_mhead(buf),wpabuf_mhead(buf)+1,--len); ++ wpabuf_put(buf, len); ++ return buf; ++ } ++ ++ wpabuf_free(buf); ++ return NULL; ++} ++ ++struct crypto_ec_point * ++crypto_ec_key_get_public_key(struct crypto_ec_key *key) ++{ ++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); ++ if (ecp_kp == NULL) ++ return NULL; ++ mbedtls_ecp_point *p = os_malloc(sizeof(*p)); ++ if (p != NULL) { ++ /*(mbedtls_ecp_export() uses &ecp_kp->MBEDTLS_PRIVATE(grp))*/ ++ mbedtls_ecp_point_init(p); ++ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); ++ if (mbedtls_ecp_copy(p, ecp_kp_Q)) { ++ mbedtls_ecp_point_free(p); ++ os_free(p); ++ p = NULL; ++ } ++ } ++ return (struct crypto_ec_point *)p; ++} ++ ++struct crypto_bignum * ++crypto_ec_key_get_private_key(struct crypto_ec_key *key) ++{ ++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); ++ if (ecp_kp == NULL) ++ return NULL; ++ mbedtls_mpi *bn = os_malloc(sizeof(*bn)); ++ if (bn) { ++ /*(mbedtls_ecp_export() uses &ecp_kp->MBEDTLS_PRIVATE(grp))*/ ++ mbedtls_mpi_init(bn); ++ mbedtls_mpi *ecp_kp_d = &ecp_kp->MBEDTLS_PRIVATE(d); ++ if (mbedtls_mpi_copy(bn, ecp_kp_d)) { ++ mbedtls_mpi_free(bn); ++ os_free(bn); ++ bn = NULL; ++ } ++ } ++ return (struct crypto_bignum *)bn; ++} ++ ++#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ ++ ++static mbedtls_md_type_t crypto_ec_key_sign_md(size_t len) ++{ ++ /* get mbedtls_md_type_t from length of hash data to be signed */ ++ switch (len) { ++ case 64: return MBEDTLS_MD_SHA512; ++ case 48: return MBEDTLS_MD_SHA384; ++ case 32: return MBEDTLS_MD_SHA256; ++ case 20: return MBEDTLS_MD_SHA1; ++ case 16: return MBEDTLS_MD_MD5; ++ default: return MBEDTLS_MD_NONE; ++ } ++} ++ ++struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data, ++ size_t len) ++{ ++ #ifndef MBEDTLS_PK_SIGNATURE_MAX_SIZE /*(defined since mbedtls 2.20.0)*/ ++ #if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE ++ #define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN ++ #else ++ #define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE ++ #endif ++ #endif ++ size_t sig_len = MBEDTLS_PK_SIGNATURE_MAX_SIZE; ++ struct wpabuf *buf = wpabuf_alloc(sig_len); ++ if (buf == NULL) ++ return NULL; ++ if (mbedtls_pk_sign((mbedtls_pk_context *)key, ++ crypto_ec_key_sign_md(len), data, len, ++ wpabuf_mhead_u8(buf), ++ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ ++ sig_len, ++ #endif ++ &sig_len, ++ mbedtls_ctr_drbg_random, ++ crypto_mbedtls_ctr_drbg()) == 0) { ++ wpabuf_put(buf, sig_len); ++ return buf; ++ } ++ ++ wpabuf_free(buf); ++ return NULL; ++} ++ ++#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP ++struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key, ++ const u8 *data, size_t len) ++{ ++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); ++ if (ecp_kp == NULL) ++ return NULL; ++ ++ size_t sig_len = MBEDTLS_ECDSA_MAX_LEN; ++ u8 buf[MBEDTLS_ECDSA_MAX_LEN]; ++ if (mbedtls_ecdsa_write_signature(ecp_kp, crypto_ec_key_sign_md(len), ++ data, len, buf, ++ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ ++ sig_len, ++ #endif ++ &sig_len, ++ mbedtls_ctr_drbg_random, ++ crypto_mbedtls_ctr_drbg())) { ++ return NULL; ++ } ++ ++ /*(mbedtls_ecdsa_write_signature() writes signature in ASN.1)*/ ++ /* parse ASN.1 to get r and s and lengths */ ++ u8 *p = buf, *r, *s; ++ u8 *end = p + sig_len; ++ size_t rlen, slen; ++ mbedtls_asn1_get_tag(&p, end, &rlen, ++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); ++ mbedtls_asn1_get_tag(&p, end, &rlen, MBEDTLS_ASN1_INTEGER); ++ r = p; ++ p += rlen; ++ mbedtls_asn1_get_tag(&p, end, &slen, MBEDTLS_ASN1_INTEGER); ++ s = p; ++ ++ /* write raw r and s into out ++ * (including removal of leading 0 if added for ASN.1 integer) ++ * note: DPP caller expects raw r, s each padded to prime len */ ++ mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); ++ size_t plen = CRYPTO_EC_plen(ecp_kp_grp); ++ if (rlen > plen) { ++ r += (rlen - plen); ++ rlen = plen; ++ } ++ if (slen > plen) { ++ s += (slen - plen); ++ slen = plen; ++ } ++ struct wpabuf *out = wpabuf_alloc(plen*2); ++ if (out) { ++ wpabuf_put(out, plen*2); ++ p = wpabuf_mhead_u8(out); ++ os_memset(p, 0, plen*2); ++ os_memcpy(p+plen*1-rlen, r, rlen); ++ os_memcpy(p+plen*2-slen, s, slen); ++ } ++ return out; ++} ++#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ ++ ++int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data, ++ size_t len, const u8 *sig, size_t sig_len) ++{ ++ switch (mbedtls_pk_verify((mbedtls_pk_context *)key, ++ crypto_ec_key_sign_md(len), data, len, ++ sig, sig_len)) { ++ case 0: ++ /*case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:*//* XXX: allow? */ ++ return 1; ++ case MBEDTLS_ERR_ECP_VERIFY_FAILED: ++ return 0; ++ default: ++ return -1; ++ } ++} ++ ++#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP ++int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *key, ++ const u8 *data, size_t len, ++ const u8 *r, size_t r_len, ++ const u8 *s, size_t s_len) ++{ ++ /* reimplement mbedtls_ecdsa_read_signature() without encoding r and s ++ * into ASN.1 just for mbedtls_ecdsa_read_signature() to decode ASN.1 */ ++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); ++ if (ecp_kp == NULL) ++ return -1; ++ mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); ++ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); ++ ++ mbedtls_mpi mpi_r; ++ mbedtls_mpi mpi_s; ++ mbedtls_mpi_init(&mpi_r); ++ mbedtls_mpi_init(&mpi_s); ++ int ret = mbedtls_mpi_read_binary(&mpi_r, r, r_len) ++ || mbedtls_mpi_read_binary(&mpi_s, s, s_len) ? -1 : 0; ++ if (ret == 0) { ++ ret = mbedtls_ecdsa_verify(ecp_kp_grp, data, len, ++ ecp_kp_Q, &mpi_r, &mpi_s); ++ ret = ret ? ret == MBEDTLS_ERR_ECP_BAD_INPUT_DATA ? 0 : -1 : 1; ++ } ++ mbedtls_mpi_free(&mpi_r); ++ mbedtls_mpi_free(&mpi_s); ++ return ret; ++} ++#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ ++ ++int crypto_ec_key_group(struct crypto_ec_key *key) ++{ ++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); ++ if (ecp_kp == NULL) ++ return -1; ++ mbedtls_ecp_group *ecp_group = &ecp_kp->MBEDTLS_PRIVATE(grp); ++ return crypto_mbedtls_ike_id_from_ecp_group_id(ecp_group->id); ++} ++ ++#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP ++ ++int crypto_ec_key_cmp(struct crypto_ec_key *key1, struct crypto_ec_key *key2) ++{ ++#if 0 /*(DPP is passing two public keys; unable to use pk_check_pair())*/ ++ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ ++ return mbedtls_pk_check_pair((const mbedtls_pk_context *)key1, ++ (const mbedtls_pk_context *)key2) ? -1 : 0; ++ #else ++ return mbedtls_pk_check_pair((const mbedtls_pk_context *)key1, ++ (const mbedtls_pk_context *)key2, ++ mbedtls_ctr_drbg_random, ++ crypto_mbedtls_ctr_drbg()) ? -1 : 0; ++ #endif ++#else ++ mbedtls_ecp_keypair *ecp_kp1=mbedtls_pk_ec(*(mbedtls_pk_context *)key1); ++ mbedtls_ecp_keypair *ecp_kp2=mbedtls_pk_ec(*(mbedtls_pk_context *)key2); ++ if (ecp_kp1 == NULL || ecp_kp2 == NULL) ++ return -1; ++ mbedtls_ecp_group *ecp_kp1_grp = &ecp_kp1->MBEDTLS_PRIVATE(grp); ++ mbedtls_ecp_group *ecp_kp2_grp = &ecp_kp2->MBEDTLS_PRIVATE(grp); ++ mbedtls_ecp_point *ecp_kp1_Q = &ecp_kp1->MBEDTLS_PRIVATE(Q); ++ mbedtls_ecp_point *ecp_kp2_Q = &ecp_kp2->MBEDTLS_PRIVATE(Q); ++ return ecp_kp1_grp->id != ecp_kp2_grp->id ++ || mbedtls_ecp_point_cmp(ecp_kp1_Q, ecp_kp2_Q) ? -1 : 0; ++#endif ++} ++ ++void crypto_ec_key_debug_print(const struct crypto_ec_key *key, ++ const char *title) ++{ ++ /* TBD: what info is desirable here and in what human readable format?*/ ++ /*(crypto_openssl.c prints a human-readably public key and attributes)*/ ++ #if 0 ++ struct mbedtls_pk_debug_item debug_item; ++ if (mbedtls_pk_debug((const mbedtls_pk_context *)key, &debug_item)) ++ return; ++ /* ... */ ++ #endif ++ wpa_printf(MSG_DEBUG, "%s: %s not implemented", title, __func__); ++} ++ ++#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ ++ ++#endif /* CRYPTO_MBEDTLS_CRYPTO_EC */ ++ ++ ++#ifdef CRYPTO_MBEDTLS_CRYPTO_CSR ++ ++#include ++#include ++ ++struct crypto_csr * crypto_csr_init(void) ++{ ++ mbedtls_x509write_csr *csr = os_malloc(sizeof(*csr)); ++ if (csr != NULL) ++ mbedtls_x509write_csr_init(csr); ++ return (struct crypto_csr *)csr; ++} ++ ++struct crypto_csr * crypto_csr_verify(const struct wpabuf *req) ++{ ++ /* future: look for alternatives to MBEDTLS_PRIVATE() access */ ++ ++ /* sole caller src/common/dpp_crypto.c:dpp_validate_csr() ++ * uses (mbedtls_x509_csr *) to obtain CSR_ATTR_CHALLENGE_PASSWORD ++ * so allocate different object (mbedtls_x509_csr *) and special-case ++ * object when used in crypto_csr_get_attribute() and when free()d in ++ * crypto_csr_deinit(). */ ++ ++ mbedtls_x509_csr *csr = os_malloc(sizeof(*csr)); ++ if (csr == NULL) ++ return NULL; ++ mbedtls_x509_csr_init(csr); ++ const mbedtls_md_info_t *md_info; ++ unsigned char digest[MBEDTLS_MD_MAX_SIZE]; ++ if (mbedtls_x509_csr_parse_der(csr,wpabuf_head(req),wpabuf_len(req))==0 ++ && (md_info=mbedtls_md_info_from_type(csr->MBEDTLS_PRIVATE(sig_md))) ++ != NULL ++ && mbedtls_md(md_info, csr->cri.p, csr->cri.len, digest) == 0) { ++ switch (mbedtls_pk_verify(&csr->pk,csr->MBEDTLS_PRIVATE(sig_md), ++ digest, mbedtls_md_get_size(md_info), ++ csr->MBEDTLS_PRIVATE(sig).p, ++ csr->MBEDTLS_PRIVATE(sig).len)) { ++ case 0: ++ /*case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:*//* XXX: allow? */ ++ return (struct crypto_csr *)((uintptr_t)csr | 1uL); ++ default: ++ break; ++ } ++ } ++ ++ mbedtls_x509_csr_free(csr); ++ os_free(csr); ++ return NULL; ++} ++ ++void crypto_csr_deinit(struct crypto_csr *csr) ++{ ++ if ((uintptr_t)csr & 1uL) { ++ csr = (struct crypto_csr *)((uintptr_t)csr & ~1uL); ++ mbedtls_x509_csr_free((mbedtls_x509_csr *)csr); ++ } ++ else ++ mbedtls_x509write_csr_free((mbedtls_x509write_csr *)csr); ++ os_free(csr); ++} ++ ++int crypto_csr_set_ec_public_key(struct crypto_csr *csr, ++ struct crypto_ec_key *key) ++{ ++ mbedtls_x509write_csr_set_key((mbedtls_x509write_csr *)csr, ++ (mbedtls_pk_context *)key); ++ return 0; ++} ++ ++int crypto_csr_set_name(struct crypto_csr *csr, enum crypto_csr_name type, ++ const char *name) ++{ ++ /* specialized for src/common/dpp_crypto.c */ ++ ++ /* sole caller src/common/dpp_crypto.c:dpp_build_csr() ++ * calls this function only once, using type == CSR_NAME_CN ++ * (If called more than once, this code would need to append ++ * components to the subject name, which we could do by ++ * appending to (mbedtls_x509write_csr *) private member ++ * mbedtls_asn1_named_data *MBEDTLS_PRIVATE(subject)) */ ++ ++ const char *label; ++ switch (type) { ++ case CSR_NAME_CN: label = "CN="; break; ++ case CSR_NAME_SN: label = "SN="; break; ++ case CSR_NAME_C: label = "C="; break; ++ case CSR_NAME_O: label = "O="; break; ++ case CSR_NAME_OU: label = "OU="; break; ++ default: return -1; ++ } ++ ++ size_t len = strlen(name); ++ struct wpabuf *buf = wpabuf_alloc(3+len+1); ++ if (buf == NULL) ++ return -1; ++ wpabuf_put_data(buf, label, strlen(label)); ++ wpabuf_put_data(buf, name, len+1); /*(include trailing '\0')*/ ++ /* Note: 'name' provided is set as given and should be backslash-escaped ++ * by caller when necessary, e.g. literal ',' which are not separating ++ * components should be backslash-escaped */ ++ ++ int ret = ++ mbedtls_x509write_csr_set_subject_name((mbedtls_x509write_csr *)csr, ++ wpabuf_head(buf)) ? -1 : 0; ++ wpabuf_free(buf); ++ return ret; ++} ++ ++/* OBJ_pkcs9_challengePassword 1 2 840 113549 1 9 7 */ ++static const char OBJ_pkcs9_challengePassword[] = MBEDTLS_OID_PKCS9 "\x07"; ++ ++int crypto_csr_set_attribute(struct crypto_csr *csr, enum crypto_csr_attr attr, ++ int attr_type, const u8 *value, size_t len) ++{ ++ /* specialized for src/common/dpp_crypto.c */ ++ /* sole caller src/common/dpp_crypto.c:dpp_build_csr() passes ++ * attr == CSR_ATTR_CHALLENGE_PASSWORD ++ * attr_type == ASN1_TAG_UTF8STRING */ ++ ++ const char *oid; ++ size_t oid_len; ++ switch (attr) { ++ case CSR_ATTR_CHALLENGE_PASSWORD: ++ oid = OBJ_pkcs9_challengePassword; ++ oid_len = sizeof(OBJ_pkcs9_challengePassword)-1; ++ break; ++ default: ++ return -1; ++ } ++ ++ #if 0 /*(incorrect; sets an extension, not an attribute)*/ ++ return mbedtls_x509write_csr_set_extension((mbedtls_x509write_csr *)csr, ++ oid, oid_len, ++ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ ++ 0, /*(critical flag)*/ ++ #endif ++ value, len) ? -1 : 0; ++ #else ++ (void)oid; ++ (void)oid_len; ++ #endif ++ ++ /* mbedtls does not currently provide way to set an attribute in a CSR: ++ * https://github.com/Mbed-TLS/mbedtls/issues/4886 */ ++ wpa_printf(MSG_ERROR, ++ "mbedtls does not currently support setting challengePassword " ++ "attribute in CSR"); ++ return -1; ++} ++ ++const u8 * mbedtls_x509_csr_attr_oid_value(mbedtls_x509_csr *csr, ++ const char *oid, size_t oid_len, ++ size_t *vlen, int *vtype) ++{ ++ /* Note: mbedtls_x509_csr_parse_der() has parsed and validated CSR, ++ * so validation checks are not repeated here ++ * ++ * It would be nicer if (mbedtls_x509_csr *) had an mbedtls_x509_buf of ++ * Attributes (or at least a pointer) since mbedtls_x509_csr_parse_der() ++ * already parsed the rest of CertificationRequestInfo, some of which is ++ * repeated here to step to Attributes. Since csr->subject_raw.p points ++ * into csr->cri.p, which points into csr->raw.p, step over version and ++ * subject of CertificationRequestInfo (SEQUENCE) */ ++ unsigned char *p = csr->subject_raw.p + csr->subject_raw.len; ++ unsigned char *end = csr->cri.p + csr->cri.len, *ext; ++ size_t len; ++ ++ /* step over SubjectPublicKeyInfo */ ++ mbedtls_asn1_get_tag(&p, end, &len, ++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); ++ p += len; ++ ++ /* Attributes ++ * { ATTRIBUTE:IOSet } ::= SET OF { SEQUENCE { OID, value } } ++ */ ++ if (mbedtls_asn1_get_tag(&p, end, &len, ++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) { ++ return NULL; ++ } ++ while (p < end) { ++ if (mbedtls_asn1_get_tag(&p, end, &len, ++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) { ++ return NULL; ++ } ++ ext = p; ++ p += len; ++ ++ if (mbedtls_asn1_get_tag(&ext,end,&len,MBEDTLS_ASN1_OID) != 0) ++ return NULL; ++ if (oid_len != len || 0 != memcmp(ext, oid, oid_len)) ++ continue; ++ ++ /* found oid; return value */ ++ *vtype = *ext++; /* tag */ ++ return (mbedtls_asn1_get_len(&ext,end,vlen) == 0) ? ext : NULL; ++ } ++ ++ return NULL; ++} ++ ++const u8 * crypto_csr_get_attribute(struct crypto_csr *csr, ++ enum crypto_csr_attr attr, ++ size_t *len, int *type) ++{ ++ /* specialized for src/common/dpp_crypto.c */ ++ /* sole caller src/common/dpp_crypto.c:dpp_build_csr() passes ++ * attr == CSR_ATTR_CHALLENGE_PASSWORD */ ++ ++ const char *oid; ++ size_t oid_len; ++ switch (attr) { ++ case CSR_ATTR_CHALLENGE_PASSWORD: ++ oid = OBJ_pkcs9_challengePassword; ++ oid_len = sizeof(OBJ_pkcs9_challengePassword)-1; ++ break; ++ default: ++ return NULL; ++ } ++ ++ /* see crypto_csr_verify(); expecting (mbedtls_x509_csr *) tagged |=1 */ ++ if (!((uintptr_t)csr & 1uL)) ++ return NULL; ++ csr = (struct crypto_csr *)((uintptr_t)csr & ~1uL); ++ ++ return mbedtls_x509_csr_attr_oid_value((mbedtls_x509_csr *)csr, ++ oid, oid_len, len, type); ++} ++ ++struct wpabuf * crypto_csr_sign(struct crypto_csr *csr, ++ struct crypto_ec_key *key, ++ enum crypto_hash_alg algo) ++{ ++ mbedtls_md_type_t sig_md; ++ switch (algo) { ++ #ifdef MBEDTLS_SHA256_C ++ case CRYPTO_HASH_ALG_SHA256: sig_md = MBEDTLS_MD_SHA256; break; ++ #endif ++ #ifdef MBEDTLS_SHA512_C ++ case CRYPTO_HASH_ALG_SHA384: sig_md = MBEDTLS_MD_SHA384; break; ++ case CRYPTO_HASH_ALG_SHA512: sig_md = MBEDTLS_MD_SHA512; break; ++ #endif ++ default: ++ return NULL; ++ } ++ mbedtls_x509write_csr_set_md_alg((mbedtls_x509write_csr *)csr, sig_md); ++ ++ #if 0 ++ unsigned char key_usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE ++ | MBEDTLS_X509_KU_KEY_CERT_SIGN; ++ if (mbedtls_x509write_csr_set_key_usage((mbedtls_x509write_csr *)csr, ++ key_usage)) ++ return NULL; ++ #endif ++ ++ #if 0 ++ unsigned char ns_cert_type = MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT ++ | MBEDTLS_X509_NS_CERT_TYPE_EMAIL; ++ if (mbedtls_x509write_csr_set_ns_cert_type((mbedtls_x509write_csr *)csr, ++ ns_cert_type)) ++ return NULL; ++ #endif ++ ++ #if 0 ++ /* mbedtls does not currently provide way to set an attribute in a CSR: ++ * https://github.com/Mbed-TLS/mbedtls/issues/4886 ++ * XXX: hwsim dpp_enterprise test fails due to this limitation. ++ * ++ * Current usage of this function is solely by dpp_build_csr(), ++ * so as a kludge, might consider custom (struct crypto_csr *) ++ * containing (mbedtls_x509write_csr *) and a list of attributes ++ * (i.e. challengePassword). Might have to totally reimplement ++ * mbedtls_x509write_csr_der(); underlying x509write_csr_der_internal() ++ * handles signing the CSR. (This is more work that appending an ++ * Attributes section to end of CSR and adjusting ASN.1 length of CSR.) ++ */ ++ #endif ++ ++ unsigned char buf[4096]; /* XXX: large enough? too large? */ ++ int len = mbedtls_x509write_csr_der((mbedtls_x509write_csr *)csr, ++ buf, sizeof(buf), ++ mbedtls_ctr_drbg_random, ++ crypto_mbedtls_ctr_drbg()); ++ if (len < 0) ++ return NULL; ++ /* Note: data is written at the end of the buffer! Use the ++ * return value to determine where you should start ++ * using the buffer */ ++ return wpabuf_alloc_copy(buf+sizeof(buf)-len, (size_t)len); ++} ++ ++#endif /* CRYPTO_MBEDTLS_CRYPTO_CSR */ ++ ++ ++#ifdef CRYPTO_MBEDTLS_CRYPTO_PKCS7 ++ ++#if 0 ++#include /* PKCS7 is not currently supported in mbedtls */ ++#include ++#endif ++ ++struct wpabuf * crypto_pkcs7_get_certificates(const struct wpabuf *pkcs7) ++{ ++ /* PKCS7 is not currently supported in mbedtls */ ++ return NULL; ++ ++#if 0 ++ /* https://github.com/naynajain/mbedtls-1 branch: development-pkcs7 ++ * (??? potential future contribution to mbedtls ???) */ ++ ++ /* Note: PKCS7 signature *is not* verified by this function. ++ * The function interface does not provide for passing a certificate */ ++ ++ mbedtls_pkcs7 mpkcs7; ++ mbedtls_pkcs7_init(&mpkcs7); ++ int pkcs7_type = mbedtls_pkcs7_parse_der(wpabuf_head(pkcs7), ++ wpabuf_len(pkcs7), ++ &mpkcs7); ++ wpabuf *buf = NULL; ++ do { ++ if (pkcs7_type < 0) ++ break; ++ ++ /* src/common/dpp.c:dpp_parse_cred_dot1x() interested in certs ++ * for wpa_supplicant/dpp_supplicant.c:wpas_dpp_add_network() ++ * (? are adding certificate headers and footers desired ?) */ ++ ++ /* development-pkcs7 branch does not currently provide ++ * additional interfaces to retrieve the parsed data */ ++ ++ mbedtls_x509_crt *certs = ++ &mpkcs7.MBEDTLS_PRIVATE(signed_data).MBEDTLS_PRIVATE(certs); ++ int ncerts = ++ mpkcs7.MBEDTLS_PRIVATE(signed_data).MBEDTLS_PRIVATE(no_of_certs); ++ ++ /* allocate buffer for PEM (base64-encoded DER) ++ * plus header, footer, newlines, and some extra */ ++ buf = wpabuf_alloc((wpabuf_len(pkcs7)+2)/3*4 + ncerts*64); ++ if (buf == NULL) ++ break; ++ ++ #define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" ++ #define PEM_END_CRT "-----END CERTIFICATE-----\n" ++ size_t olen; ++ for (int i = 0; i < ncerts; ++i) { ++ int ret = mbedtls_pem_write_buffer( ++ PEM_BEGIN_CRT, PEM_END_CRT, ++ certs[i].raw.p, certs[i].raw.len, ++ wpabuf_mhead(buf, 0), wpabuf_tailroom(buf), ++ &olen)); ++ if (ret == 0) ++ wpabuf_put(buf, olen); ++ } else { ++ if (ret == MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) ++ ret = wpabuf_resize( ++ &buf,olen-wpabuf_tailroom(buf)); ++ if (ret == 0) { ++ --i;/*(adjust loop iterator for retry)*/ ++ continue; ++ } ++ wpabuf_free(buf); ++ buf = NULL; ++ break; ++ } ++ } ++ } while (0); ++ ++ mbedtls_pkcs7_free(&mpkcs7); ++ return buf; ++#endif ++} ++ ++#endif /* CRYPTO_MBEDTLS_CRYPTO_PKCS7 */ ++ ++ ++#ifdef MBEDTLS_ARC4_C ++#include ++int rc4_skip(const u8 *key, size_t keylen, size_t skip, ++ u8 *data, size_t data_len) ++{ ++ mbedtls_arc4_context ctx; ++ mbedtls_arc4_init(&ctx); ++ mbedtls_arc4_setup(&ctx, key, keylen); ++ ++ if (skip) { ++ /*(prefer [16] on ancient hardware with smaller cache lines)*/ ++ unsigned char skip_buf[64]; /*('skip' is generally small)*/ ++ /*os_memset(skip_buf, 0, sizeof(skip_buf));*/ /*(necessary?)*/ ++ size_t len; ++ do { ++ len = skip > sizeof(skip_buf) ? sizeof(skip_buf) : skip; ++ mbedtls_arc4_crypt(&ctx, len, skip_buf, skip_buf); ++ } while ((skip -= len)); ++ } ++ ++ int ret = mbedtls_arc4_crypt(&ctx, data_len, data, data); ++ mbedtls_arc4_free(&ctx); ++ return ret; ++} ++#endif ++ ++ ++/* duplicated in tls_mbedtls.c:tls_mbedtls_readfile()*/ ++__attribute_noinline__ ++static int crypto_mbedtls_readfile(const char *path, u8 **buf, size_t *n) ++{ ++ #if 0 /* #ifdef MBEDTLS_FS_IO */ ++ /*(includes +1 for '\0' needed by mbedtls PEM parsing funcs)*/ ++ if (mbedtls_pk_load_file(path, (unsigned char **)buf, n) != 0) { ++ wpa_printf(MSG_ERROR, "error: mbedtls_pk_load_file %s", path); ++ return -1; ++ } ++ #else ++ /*(use os_readfile() so that we can use os_free() ++ *(if we use mbedtls_pk_load_file() above, macros prevent calling free() ++ * directly #if defined(OS_REJECT_C_LIB_FUNCTIONS) and calling os_free() ++ * on buf aborts in tests if buf not allocated via os_malloc())*/ ++ *buf = (u8 *)os_readfile(path, n); ++ if (!*buf) { ++ wpa_printf(MSG_ERROR, "error: os_readfile %s", path); ++ return -1; ++ } ++ u8 *buf0 = os_realloc(*buf, *n+1); ++ if (!buf0) { ++ bin_clear_free(*buf, *n); ++ *buf = NULL; ++ return -1; ++ } ++ buf0[(*n)++] = '\0'; ++ *buf = buf0; ++ #endif ++ return 0; ++} ++ ++ ++#ifdef CRYPTO_MBEDTLS_CRYPTO_RSA ++#ifdef MBEDTLS_RSA_C ++ ++#include ++#include ++ ++struct crypto_rsa_key * crypto_rsa_key_read(const char *file, bool private_key) ++{ ++ /* mbedtls_pk_parse_keyfile() and mbedtls_pk_parse_public_keyfile() ++ * require #ifdef MBEDTLS_FS_IO in mbedtls library. Prefer to use ++ * crypto_mbedtls_readfile(), which wraps os_readfile() */ ++ u8 *data; ++ size_t len; ++ if (crypto_mbedtls_readfile(file, &data, &len) != 0) ++ return NULL; ++ ++ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); ++ if (ctx == NULL) { ++ bin_clear_free(data, len); ++ return NULL; ++ } ++ mbedtls_pk_init(ctx); ++ ++ int rc; ++ rc = (private_key ++ ? mbedtls_pk_parse_key(ctx, data, len, NULL, 0 ++ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ ++ ,mbedtls_ctr_drbg_random, ++ crypto_mbedtls_ctr_drbg() ++ #endif ++ ) ++ : mbedtls_pk_parse_public_key(ctx, data, len)) == 0 ++ && mbedtls_pk_can_do(ctx, MBEDTLS_PK_RSA); ++ ++ bin_clear_free(data, len); ++ ++ if (rc) { ++ /* use MBEDTLS_RSA_PKCS_V21 padding for RSAES-OAEP */ ++ /* use MBEDTLS_MD_SHA256 for these hostap interfaces */ ++ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ ++ /*(no return value in mbedtls 2.x)*/ ++ mbedtls_rsa_set_padding(mbedtls_pk_rsa(*ctx), ++ MBEDTLS_RSA_PKCS_V21, ++ MBEDTLS_MD_SHA256); ++ #else ++ if (mbedtls_rsa_set_padding(mbedtls_pk_rsa(*ctx), ++ MBEDTLS_RSA_PKCS_V21, ++ MBEDTLS_MD_SHA256) == 0) ++ #endif ++ return (struct crypto_rsa_key *)ctx; ++ } ++ ++ mbedtls_pk_free(ctx); ++ os_free(ctx); ++ return NULL; ++} ++ ++struct wpabuf * crypto_rsa_oaep_sha256_encrypt(struct crypto_rsa_key *key, ++ const struct wpabuf *in) ++{ ++ mbedtls_rsa_context *pk_rsa = mbedtls_pk_rsa(*(mbedtls_pk_context*)key); ++ size_t olen = mbedtls_rsa_get_len(pk_rsa); ++ struct wpabuf *buf = wpabuf_alloc(olen); ++ if (buf == NULL) ++ return NULL; ++ ++ /* mbedtls_pk_encrypt() takes a few more hops to get to same func */ ++ if (mbedtls_rsa_rsaes_oaep_encrypt(pk_rsa, ++ mbedtls_ctr_drbg_random, ++ crypto_mbedtls_ctr_drbg(), ++ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ ++ MBEDTLS_RSA_PRIVATE, ++ #endif ++ NULL, 0, ++ wpabuf_len(in), wpabuf_head(in), ++ wpabuf_put(buf, olen)) == 0) { ++ return buf; ++ } ++ ++ wpabuf_clear_free(buf); ++ return NULL; ++} ++ ++struct wpabuf * crypto_rsa_oaep_sha256_decrypt(struct crypto_rsa_key *key, ++ const struct wpabuf *in) ++{ ++ mbedtls_rsa_context *pk_rsa = mbedtls_pk_rsa(*(mbedtls_pk_context*)key); ++ size_t olen = mbedtls_rsa_get_len(pk_rsa); ++ struct wpabuf *buf = wpabuf_alloc(olen); ++ if (buf == NULL) ++ return NULL; ++ ++ /* mbedtls_pk_decrypt() takes a few more hops to get to same func */ ++ if (mbedtls_rsa_rsaes_oaep_decrypt(pk_rsa, ++ mbedtls_ctr_drbg_random, ++ crypto_mbedtls_ctr_drbg(), ++ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ ++ MBEDTLS_RSA_PUBLIC, ++ #endif ++ NULL, 0, &olen, wpabuf_head(in), ++ wpabuf_mhead(buf), olen) == 0) { ++ wpabuf_put(buf, olen); ++ return buf; ++ } ++ ++ wpabuf_clear_free(buf); ++ return NULL; ++} ++ ++void crypto_rsa_key_free(struct crypto_rsa_key *key) ++{ ++ mbedtls_pk_free((mbedtls_pk_context *)key); ++ os_free(key); ++} ++ ++#endif /* MBEDTLS_RSA_C */ ++#endif /* CRYPTO_MBEDTLS_CRYPTO_RSA */ ++ ++#ifdef CRYPTO_MBEDTLS_CRYPTO_HPKE ++ ++struct wpabuf * hpke_base_seal(enum hpke_kem_id kem_id, ++ enum hpke_kdf_id kdf_id, ++ enum hpke_aead_id aead_id, ++ struct crypto_ec_key *peer_pub, ++ const u8 *info, size_t info_len, ++ const u8 *aad, size_t aad_len, ++ const u8 *pt, size_t pt_len) ++{ ++ /* not yet implemented */ ++ return NULL; ++} ++ ++struct wpabuf * hpke_base_open(enum hpke_kem_id kem_id, ++ enum hpke_kdf_id kdf_id, ++ enum hpke_aead_id aead_id, ++ struct crypto_ec_key *own_priv, ++ const u8 *info, size_t info_len, ++ const u8 *aad, size_t aad_len, ++ const u8 *enc_ct, size_t enc_ct_len) ++{ ++ /* not yet implemented */ ++ return NULL; ++} ++ ++#endif +--- /dev/null ++++ b/src/crypto/tls_mbedtls.c +@@ -0,0 +1,3313 @@ ++/* ++ * SSL/TLS interface functions for mbed TLS ++ * ++ * SPDX-FileCopyrightText: 2022 Glenn Strauss ++ * SPDX-License-Identifier: BSD-3-Clause ++ * ++ * This software may be distributed under the terms of the BSD license. ++ * See README for more details. ++ * ++ * template: src/crypto/tls_none.c ++ * reference: src/crypto/tls_*.c ++ * ++ * Known Limitations: ++ * - no TLSv1.3 (not available in mbedtls 2.x; experimental in mbedtls 3.x) ++ * - no OCSP (not yet available in mbedtls) ++ * - mbedtls does not support all certificate encodings used by hwsim tests ++ * PCKS#5 v1.5 ++ * PCKS#12 ++ * DH DSA ++ * - EAP-FAST, EAP-TEAP session ticket support not implemented in tls_mbedtls.c ++ * - mbedtls does not currently provide way to set an attribute in a CSR ++ * https://github.com/Mbed-TLS/mbedtls/issues/4886 ++ * so tests/hwsim dpp_enterprise tests fail ++ * - DPP2 not supported ++ * PKCS#7 parsing is not supported in mbedtls ++ * See crypto_mbedtls.c:crypto_pkcs7_get_certificates() comments ++ * - DPP3 not supported ++ * hpke_base_seal() and hpke_base_seal() not implemented in crypto_mbedtls.c ++ * ++ * Status: ++ * - code written to be compatible with mbedtls 2.x and mbedtls 3.x ++ * (currently requires mbedtls >= 2.27.0 for mbedtls_mpi_random()) ++ * (currently requires mbedtls >= 2.18.0 for mbedtls_ssl_tls_prf()) ++ * - builds with tests/build/build-wpa_supplicant-mbedtls.config ++ * - passes all tests/ crypto module tests (incomplete coverage) ++ * ($ cd tests; make clean; make -j 4 run-tests CONFIG_TLS=mbedtls) ++ * - passes almost all tests/hwsim tests ++ * (hwsim tests skipped for missing features) ++ * ++ * RFE: ++ * - EAP-FAST, EAP-TEAP session ticket support not implemented in tls_mbedtls.c ++ * - client/server session resumption, and/or save client session ticket ++ */ ++ ++#include "includes.h" ++#include "common.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include /* mbedtls_calloc() mbedtls_free() */ ++#include /* mbedtls_platform_zeroize() */ ++#include ++#include ++#include ++#include ++ ++#if MBEDTLS_VERSION_NUMBER >= 0x02040000 /* mbedtls 2.4.0 */ ++#include ++#else ++#include ++#endif ++ ++#ifndef MBEDTLS_PRIVATE ++#define MBEDTLS_PRIVATE(x) x ++#endif ++ ++#if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */ ++#define mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl) \ ++ ((ssl)->MBEDTLS_PRIVATE(session) \ ++ ?(ssl)->MBEDTLS_PRIVATE(session)->MBEDTLS_PRIVATE(ciphersuite) \ ++ : 0) ++#define mbedtls_ssl_ciphersuite_get_name(info) \ ++ (info)->MBEDTLS_PRIVATE(name) ++#endif ++ ++#include "crypto.h" /* sha256_vector() */ ++#include "tls.h" ++ ++#ifndef SHA256_DIGEST_LENGTH ++#define SHA256_DIGEST_LENGTH 32 ++#endif ++ ++#ifndef MBEDTLS_EXPKEY_FIXED_SECRET_LEN ++#define MBEDTLS_EXPKEY_FIXED_SECRET_LEN 48 ++#endif ++ ++#ifndef MBEDTLS_EXPKEY_RAND_LEN ++#define MBEDTLS_EXPKEY_RAND_LEN 32 ++#endif ++ ++#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ ++static mbedtls_ssl_export_keys_t tls_connection_export_keys_cb; ++#elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ ++static mbedtls_ssl_export_keys_ext_t tls_connection_export_keys_cb; ++#else /*(not implemented; return error)*/ ++#define mbedtls_ssl_tls_prf(a,b,c,d,e,f,g,h) (-1) ++typedef mbedtls_tls_prf_types int; ++#endif ++ ++ ++/* hostapd/wpa_supplicant provides forced_memzero(), ++ * but prefer mbedtls_platform_zeroize() */ ++#define forced_memzero(ptr,sz) mbedtls_platform_zeroize(ptr,sz) ++ ++ ++#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) \ ++ || defined(EAP_TEAP) || defined(EAP_SERVER_TEAP) ++#ifdef MBEDTLS_SSL_SESSION_TICKETS ++#ifdef MBEDTLS_SSL_TICKET_C ++#define TLS_MBEDTLS_SESSION_TICKETS ++#if defined(EAP_TEAP) || defined(EAP_SERVER_TEAP) ++#define TLS_MBEDTLS_EAP_TEAP ++#endif ++#if !defined(CONFIG_FIPS) /* EAP-FAST keys cannot be exported in FIPS mode */ ++#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) ++#define TLS_MBEDTLS_EAP_FAST ++#endif ++#endif ++#endif ++#endif ++#endif ++ ++ ++struct tls_conf { ++ mbedtls_ssl_config conf; ++ ++ unsigned int verify_peer:1; ++ unsigned int verify_depth0_only:1; ++ unsigned int check_crl:2; /*(needs :2 bits for 0, 1, 2)*/ ++ unsigned int check_crl_strict:1; /*(needs :1 bit for 0, 1)*/ ++ unsigned int ca_cert_probe:1; ++ unsigned int has_ca_cert:1; ++ unsigned int has_client_cert:1; ++ unsigned int has_private_key:1; ++ unsigned int suiteb128:1; ++ unsigned int suiteb192:1; ++ mbedtls_x509_crl *crl; ++ mbedtls_x509_crt ca_cert; ++ mbedtls_x509_crt client_cert; ++ mbedtls_pk_context private_key; ++ ++ uint32_t refcnt; ++ ++ unsigned int flags; ++ char *subject_match; ++ char *altsubject_match; ++ char *suffix_match; ++ char *domain_match; ++ char *check_cert_subject; ++ u8 ca_cert_hash[SHA256_DIGEST_LENGTH]; ++ ++ int *ciphersuites; /* list of ciphersuite ids for mbedtls_ssl_config */ ++#if MBEDTLS_VERSION_NUMBER < 0x03010000 /* mbedtls 3.1.0 */ ++ mbedtls_ecp_group_id *curves; ++#else ++ uint16_t *curves; /* list of curve ids for mbedtls_ssl_config */ ++#endif ++}; ++ ++ ++struct tls_global { ++ struct tls_conf *tls_conf; ++ char *ocsp_stapling_response; ++ mbedtls_ctr_drbg_context *ctr_drbg; /*(see crypto_mbedtls.c)*/ ++ #ifdef MBEDTLS_SSL_SESSION_TICKETS ++ mbedtls_ssl_ticket_context ticket_ctx; ++ #endif ++ char *ca_cert_file; ++ struct os_reltime crl_reload_previous; ++ unsigned int crl_reload_interval; ++ uint32_t refcnt; ++ struct tls_config init_conf; ++}; ++ ++static struct tls_global tls_ctx_global; ++ ++ ++struct tls_connection { ++ struct tls_conf *tls_conf; ++ struct wpabuf *push_buf; ++ struct wpabuf *pull_buf; ++ size_t pull_buf_offset; ++ ++ unsigned int established:1; ++ unsigned int resumed:1; ++ unsigned int verify_peer:1; ++ unsigned int is_server:1; ++ ++ mbedtls_ssl_context ssl; ++ ++ mbedtls_tls_prf_types tls_prf_type; ++ size_t expkey_keyblock_size; ++ size_t expkey_secret_len; ++ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ ++ unsigned char expkey_secret[MBEDTLS_EXPKEY_FIXED_SECRET_LEN]; ++ #else ++ unsigned char expkey_secret[MBEDTLS_MD_MAX_SIZE]; ++ #endif ++ unsigned char expkey_randbytes[MBEDTLS_EXPKEY_RAND_LEN*2]; ++ ++ int read_alerts, write_alerts, failed; ++ ++ #ifdef TLS_MBEDTLS_SESSION_TICKETS ++ tls_session_ticket_cb session_ticket_cb; ++ void *session_ticket_cb_ctx; ++ unsigned char *clienthello_session_ticket; ++ size_t clienthello_session_ticket_len; ++ #endif ++ char *peer_subject; /* peer subject info for authenticated peer */ ++ struct wpabuf *success_data; ++}; ++ ++ ++#ifndef __has_attribute ++#define __has_attribute(x) 0 ++#endif ++ ++#ifndef __GNUC_PREREQ ++#define __GNUC_PREREQ(maj,min) 0 ++#endif ++ ++#ifndef __attribute_cold__ ++#if __has_attribute(cold) \ ++ || __GNUC_PREREQ(4,3) ++#define __attribute_cold__ __attribute__((__cold__)) ++#else ++#define __attribute_cold__ ++#endif ++#endif ++ ++#ifndef __attribute_noinline__ ++#if __has_attribute(noinline) \ ++ || __GNUC_PREREQ(3,1) ++#define __attribute_noinline__ __attribute__((__noinline__)) ++#else ++#define __attribute_noinline__ ++#endif ++#endif ++ ++ ++__attribute_cold__ ++__attribute_noinline__ ++static void emsg(int level, const char * const msg) ++{ ++ wpa_printf(level, "MTLS: %s", msg); ++} ++ ++ ++__attribute_cold__ ++__attribute_noinline__ ++static void emsgrc(int level, const char * const msg, int rc) ++{ ++ #ifdef MBEDTLS_ERROR_C ++ /* error logging convenience function that decodes mbedtls result codes */ ++ char buf[256]; ++ mbedtls_strerror(rc, buf, sizeof(buf)); ++ wpa_printf(level, "MTLS: %s: %s (-0x%04x)", msg, buf, -rc); ++ #else ++ wpa_printf(level, "MTLS: %s: (-0x%04x)", msg, -rc); ++ #endif ++} ++ ++ ++#define elog(rc, msg) emsgrc(MSG_ERROR, (msg), (rc)) ++#define ilog(rc, msg) emsgrc(MSG_INFO, (msg), (rc)) ++ ++ ++struct tls_conf * tls_conf_init(void *tls_ctx) ++{ ++ struct tls_conf *tls_conf = os_zalloc(sizeof(*tls_conf)); ++ if (tls_conf == NULL) ++ return NULL; ++ tls_conf->refcnt = 1; ++ ++ mbedtls_ssl_config_init(&tls_conf->conf); ++ mbedtls_ssl_conf_rng(&tls_conf->conf, ++ mbedtls_ctr_drbg_random, tls_ctx_global.ctr_drbg); ++ mbedtls_x509_crt_init(&tls_conf->ca_cert); ++ mbedtls_x509_crt_init(&tls_conf->client_cert); ++ mbedtls_pk_init(&tls_conf->private_key); ++ ++ return tls_conf; ++} ++ ++ ++void tls_conf_deinit(struct tls_conf *tls_conf) ++{ ++ if (tls_conf == NULL || --tls_conf->refcnt != 0) ++ return; ++ ++ mbedtls_x509_crt_free(&tls_conf->ca_cert); ++ mbedtls_x509_crt_free(&tls_conf->client_cert); ++ if (tls_conf->crl) { ++ mbedtls_x509_crl_free(tls_conf->crl); ++ os_free(tls_conf->crl); ++ } ++ mbedtls_pk_free(&tls_conf->private_key); ++ mbedtls_ssl_config_free(&tls_conf->conf); ++ os_free(tls_conf->curves); ++ os_free(tls_conf->ciphersuites); ++ os_free(tls_conf->subject_match); ++ os_free(tls_conf->altsubject_match); ++ os_free(tls_conf->suffix_match); ++ os_free(tls_conf->domain_match); ++ os_free(tls_conf->check_cert_subject); ++ os_free(tls_conf); ++} ++ ++ ++mbedtls_ctr_drbg_context * crypto_mbedtls_ctr_drbg(void); /*(not in header)*/ ++ ++__attribute_cold__ ++void * tls_init(const struct tls_config *conf) ++{ ++ /* RFE: review struct tls_config *conf (different from tls_conf) */ ++ ++ if (++tls_ctx_global.refcnt > 1) ++ return &tls_ctx_global; ++ ++ tls_ctx_global.ctr_drbg = crypto_mbedtls_ctr_drbg(); ++ #ifdef MBEDTLS_SSL_SESSION_TICKETS ++ mbedtls_ssl_ticket_init(&tls_ctx_global.ticket_ctx); ++ mbedtls_ssl_ticket_setup(&tls_ctx_global.ticket_ctx, ++ mbedtls_ctr_drbg_random, ++ tls_ctx_global.ctr_drbg, ++ MBEDTLS_CIPHER_AES_256_GCM, ++ 43200); /* ticket timeout: 12 hours */ ++ #endif ++ /* copy struct for future use */ ++ tls_ctx_global.init_conf = *conf; ++ if (conf->openssl_ciphers) ++ tls_ctx_global.init_conf.openssl_ciphers = ++ os_strdup(conf->openssl_ciphers); ++ ++ tls_ctx_global.crl_reload_interval = conf->crl_reload_interval; ++ os_get_reltime(&tls_ctx_global.crl_reload_previous); ++ ++ return &tls_ctx_global; ++} ++ ++ ++__attribute_cold__ ++void tls_deinit(void *tls_ctx) ++{ ++ if (tls_ctx == NULL || --tls_ctx_global.refcnt != 0) ++ return; ++ ++ tls_conf_deinit(tls_ctx_global.tls_conf); ++ os_free(tls_ctx_global.ca_cert_file); ++ os_free(tls_ctx_global.ocsp_stapling_response); ++ char *openssl_ciphers; /*(allocated in tls_init())*/ ++ *(const char **)&openssl_ciphers = ++ tls_ctx_global.init_conf.openssl_ciphers; ++ os_free(openssl_ciphers); ++ #ifdef MBEDTLS_SSL_SESSION_TICKETS ++ mbedtls_ssl_ticket_free(&tls_ctx_global.ticket_ctx); ++ #endif ++ os_memset(&tls_ctx_global, 0, sizeof(tls_ctx_global)); ++} ++ ++ ++int tls_get_errors(void *tls_ctx) ++{ ++ return 0; ++} ++ ++ ++static void tls_connection_deinit_expkey(struct tls_connection *conn) ++{ ++ conn->tls_prf_type = 0; /* MBEDTLS_SSL_TLS_PRF_NONE; */ ++ conn->expkey_keyblock_size = 0; ++ conn->expkey_secret_len = 0; ++ forced_memzero(conn->expkey_secret, sizeof(conn->expkey_secret)); ++ forced_memzero(conn->expkey_randbytes, sizeof(conn->expkey_randbytes)); ++} ++ ++ ++#ifdef TLS_MBEDTLS_SESSION_TICKETS ++void tls_connection_deinit_clienthello_session_ticket(struct tls_connection *conn) ++{ ++ if (conn->clienthello_session_ticket) { ++ mbedtls_platform_zeroize(conn->clienthello_session_ticket, ++ conn->clienthello_session_ticket_len); ++ mbedtls_free(conn->clienthello_session_ticket); ++ conn->clienthello_session_ticket = NULL; ++ conn->clienthello_session_ticket_len = 0; ++ } ++} ++#endif ++ ++ ++void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn) ++{ ++ if (conn == NULL) ++ return; ++ ++ #if 0 /*(good intention, but never sent since we destroy self below)*/ ++ if (conn->established) ++ mbedtls_ssl_close_notify(&conn->ssl); ++ #endif ++ ++ if (conn->tls_prf_type) ++ tls_connection_deinit_expkey(conn); ++ ++ #ifdef TLS_MBEDTLS_SESSION_TICKETS ++ if (conn->clienthello_session_ticket) ++ tls_connection_deinit_clienthello_session_ticket(conn); ++ #endif ++ ++ os_free(conn->peer_subject); ++ wpabuf_free(conn->success_data); ++ wpabuf_free(conn->push_buf); ++ wpabuf_free(conn->pull_buf); ++ mbedtls_ssl_free(&conn->ssl); ++ tls_conf_deinit(conn->tls_conf); ++ os_free(conn); ++} ++ ++ ++static void tls_mbedtls_refresh_crl(void); ++static int tls_mbedtls_ssl_setup(struct tls_connection *conn); ++ ++struct tls_connection * tls_connection_init(void *tls_ctx) ++{ ++ struct tls_connection *conn = os_zalloc(sizeof(*conn)); ++ if (conn == NULL) ++ return NULL; ++ ++ mbedtls_ssl_init(&conn->ssl); ++ ++ conn->tls_conf = tls_ctx_global.tls_conf; /*(inherit global conf, if set)*/ ++ if (conn->tls_conf) { ++ ++conn->tls_conf->refcnt; ++ /* check for CRL refresh if inheriting from global config */ ++ tls_mbedtls_refresh_crl(); ++ ++ conn->verify_peer = conn->tls_conf->verify_peer; ++ if (tls_mbedtls_ssl_setup(conn) != 0) { ++ tls_connection_deinit(&tls_ctx_global, conn); ++ return NULL; ++ } ++ } ++ ++ return conn; ++} ++ ++ ++int tls_connection_established(void *tls_ctx, struct tls_connection *conn) ++{ ++ return conn ? conn->established : 0; ++} ++ ++ ++__attribute_noinline__ ++char * tls_mbedtls_peer_serial_num(const mbedtls_x509_crt *crt, char *serial_num, size_t len) ++{ ++ /* mbedtls_x509_serial_gets() inefficiently formats to hex separated by ++ * colons, so generate the hex serial number here. The func ++ * wpa_snprintf_hex_uppercase() is similarly inefficient. */ ++ size_t i = 0; /* skip leading 0's per Distinguished Encoding Rules (DER) */ ++ while (i < crt->serial.len && crt->serial.p[i] == 0) ++i; ++ if (i == crt->serial.len) --i; ++ ++ const unsigned char *s = crt->serial.p + i; ++ const size_t e = (crt->serial.len - i) * 2; ++ if (e >= len) ++ return NULL; ++ #if 0 ++ wpa_snprintf_hex_uppercase(serial_num, len, s, crt->serial.len-i); ++ #else ++ for (i = 0; i < e; i+=2, ++s) { ++ serial_num[i+0] = "0123456789ABCDEF"[(*s >> 4)]; ++ serial_num[i+1] = "0123456789ABCDEF"[(*s & 0xF)]; ++ } ++ serial_num[e] = '\0'; ++ #endif ++ return serial_num; ++} ++ ++ ++char * tls_connection_peer_serial_num(void *tls_ctx, ++ struct tls_connection *conn) ++{ ++ const mbedtls_x509_crt *crt = mbedtls_ssl_get_peer_cert(&conn->ssl); ++ if (crt == NULL) ++ return NULL; ++ size_t len = crt->serial.len * 2 + 1; ++ char *serial_num = os_malloc(len); ++ if (!serial_num) ++ return NULL; ++ return tls_mbedtls_peer_serial_num(crt, serial_num, len); ++} ++ ++ ++static void tls_pull_buf_reset(struct tls_connection *conn); ++ ++int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn) ++{ ++ /* Note: this function called from eap_peer_tls_reauth_init() ++ * for session resumption, not for connection shutdown */ ++ ++ if (conn == NULL) ++ return -1; ++ ++ tls_pull_buf_reset(conn); ++ wpabuf_free(conn->push_buf); ++ conn->push_buf = NULL; ++ conn->established = 0; ++ conn->resumed = 0; ++ if (conn->tls_prf_type) ++ tls_connection_deinit_expkey(conn); ++ ++ /* RFE: prepare for session resumption? (see doc in crypto/tls.h) */ ++ ++ return mbedtls_ssl_session_reset(&conn->ssl); ++} ++ ++ ++static int tls_wpabuf_resize_put_data(struct wpabuf **buf, ++ const unsigned char *data, size_t dlen) ++{ ++ if (wpabuf_resize(buf, dlen) < 0) ++ return 0; ++ wpabuf_put_data(*buf, data, dlen); ++ return 1; ++} ++ ++ ++static int tls_pull_buf_append(struct tls_connection *conn, ++ const struct wpabuf *in_data) ++{ ++ /*(interface does not lend itself to move semantics)*/ ++ return tls_wpabuf_resize_put_data(&conn->pull_buf, ++ wpabuf_head(in_data), ++ wpabuf_len(in_data)); ++} ++ ++ ++static void tls_pull_buf_reset(struct tls_connection *conn) ++{ ++ /*(future: might consider reusing conn->pull_buf)*/ ++ wpabuf_free(conn->pull_buf); ++ conn->pull_buf = NULL; ++ conn->pull_buf_offset = 0; ++} ++ ++ ++__attribute_cold__ ++static void tls_pull_buf_discard(struct tls_connection *conn, const char *func) ++{ ++ size_t discard = wpabuf_len(conn->pull_buf) - conn->pull_buf_offset; ++ if (discard) ++ wpa_printf(MSG_DEBUG, ++ "%s - %zu bytes remaining in pull_buf; discarding", ++ func, discard); ++ tls_pull_buf_reset(conn); ++} ++ ++ ++static int tls_pull_func(void *ptr, unsigned char *buf, size_t len) ++{ ++ struct tls_connection *conn = (struct tls_connection *) ptr; ++ if (conn->pull_buf == NULL) ++ return MBEDTLS_ERR_SSL_WANT_READ; ++ const size_t dlen = wpabuf_len(conn->pull_buf) - conn->pull_buf_offset; ++ if (dlen == 0) ++ return MBEDTLS_ERR_SSL_WANT_READ; ++ ++ if (len > dlen) ++ len = dlen; ++ os_memcpy(buf, wpabuf_head(conn->pull_buf)+conn->pull_buf_offset, len); ++ ++ if (len == dlen) { ++ tls_pull_buf_reset(conn); ++ /*wpa_printf(MSG_DEBUG, "%s - emptied pull_buf", __func__);*/ ++ } ++ else { ++ conn->pull_buf_offset += len; ++ /*wpa_printf(MSG_DEBUG, "%s - %zu bytes remaining in pull_buf", ++ __func__, dlen - len);*/ ++ } ++ return (int)len; ++} ++ ++ ++static int tls_push_func(void *ptr, const unsigned char *buf, size_t len) ++{ ++ struct tls_connection *conn = (struct tls_connection *) ptr; ++ return tls_wpabuf_resize_put_data(&conn->push_buf, buf, len) ++ ? (int)len ++ : MBEDTLS_ERR_SSL_ALLOC_FAILED; ++} ++ ++ ++static int ++tls_mbedtls_verify_cb (void *arg, mbedtls_x509_crt *crt, int depth, uint32_t *flags); ++ ++ ++static int tls_mbedtls_ssl_setup(struct tls_connection *conn) ++{ ++ #if 0 ++ /* mbedtls_ssl_setup() must be called only once */ ++ /* If this func might be called multiple times (e.g. via set_params), ++ * then we should set a flag in conn that ssl was initialized */ ++ if (conn->ssl_is_init) { ++ mbedtls_ssl_free(&conn->ssl); ++ mbedtls_ssl_init(&conn->ssl); ++ } ++ #endif ++ ++ int ret = mbedtls_ssl_setup(&conn->ssl, &conn->tls_conf->conf); ++ if (ret != 0) { ++ elog(ret, "mbedtls_ssl_setup"); ++ return -1; ++ } ++ ++ mbedtls_ssl_set_bio(&conn->ssl, conn, tls_push_func, tls_pull_func, NULL); ++ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ ++ mbedtls_ssl_set_export_keys_cb( ++ &conn->ssl, tls_connection_export_keys_cb, conn); ++ #elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ ++ mbedtls_ssl_conf_export_keys_ext_cb( ++ &conn->tls_conf->conf, tls_connection_export_keys_cb, conn); ++ #endif ++ if (conn->verify_peer) ++ mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn); ++ ++ return 0; ++} ++ ++ ++static int tls_mbedtls_data_is_pem(const u8 *data) ++{ ++ return (NULL != os_strstr((char *)data, "-----")); ++} ++ ++ ++static void tls_mbedtls_set_allowed_tls_vers(struct tls_conf *tls_conf, ++ mbedtls_ssl_config *conf) ++{ ++ #if !defined(MBEDTLS_SSL_PROTO_TLS1_3) ++ tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_3; ++ #endif ++ ++ /* unconditionally require TLSv1.2+ for TLS_CONN_SUITEB */ ++ if (tls_conf->flags & TLS_CONN_SUITEB) { ++ tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_0; ++ tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_1; ++ } ++ ++ const unsigned int flags = tls_conf->flags; ++ ++ /* attempt to map flags to min and max TLS protocol version */ ++ ++ int min = (flags & TLS_CONN_DISABLE_TLSv1_0) ++ ? (flags & TLS_CONN_DISABLE_TLSv1_1) ++ ? (flags & TLS_CONN_DISABLE_TLSv1_2) ++ ? (flags & TLS_CONN_DISABLE_TLSv1_3) ++ ? 4 ++ : 3 ++ : 2 ++ : 1 ++ : 0; ++ ++ int max = (flags & TLS_CONN_DISABLE_TLSv1_3) ++ ? (flags & TLS_CONN_DISABLE_TLSv1_2) ++ ? (flags & TLS_CONN_DISABLE_TLSv1_1) ++ ? (flags & TLS_CONN_DISABLE_TLSv1_0) ++ ? -1 ++ : 0 ++ : 1 ++ : 2 ++ : 3; ++ ++ if ((flags & TLS_CONN_ENABLE_TLSv1_2) && min > 2) min = 2; ++ if ((flags & TLS_CONN_ENABLE_TLSv1_1) && min > 1) min = 1; ++ if ((flags & TLS_CONN_ENABLE_TLSv1_0) && min > 0) min = 0; ++ if (max < min) { ++ emsg(MSG_ERROR, "invalid tls_disable_tlsv* params; ignoring"); ++ return; ++ } ++ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ ++ /* mbed TLS 3.0.0 removes support for protocols < TLSv1.2 */ ++ if (min < 2 || max < 2) { ++ emsg(MSG_ERROR, "invalid tls_disable_tlsv* params; ignoring"); ++ if (min < 2) min = 2; ++ if (max < 2) max = 2; ++ } ++ #endif ++ ++ #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ ++ /* MBEDTLS_SSL_VERSION_TLS1_2 = 0x0303 *//*!< (D)TLS 1.2 */ ++ /* MBEDTLS_SSL_VERSION_TLS1_3 = 0x0304 *//*!< (D)TLS 1.3 */ ++ min = (min == 2) ? MBEDTLS_SSL_VERSION_TLS1_2 : MBEDTLS_SSL_VERSION_TLS1_3; ++ max = (max == 2) ? MBEDTLS_SSL_VERSION_TLS1_2 : MBEDTLS_SSL_VERSION_TLS1_3; ++ mbedtls_ssl_conf_min_tls_version(conf, min); ++ mbedtls_ssl_conf_max_tls_version(conf, max); ++ #else ++ #ifndef MBEDTLS_SSL_MINOR_VERSION_4 ++ if (min == 3) min = 2; ++ if (max == 3) max = 2; ++ #endif ++ /* MBEDTLS_SSL_MINOR_VERSION_0 0 *//*!< SSL v3.0 */ ++ /* MBEDTLS_SSL_MINOR_VERSION_1 1 *//*!< TLS v1.0 */ ++ /* MBEDTLS_SSL_MINOR_VERSION_2 2 *//*!< TLS v1.1 */ ++ /* MBEDTLS_SSL_MINOR_VERSION_3 3 *//*!< TLS v1.2 */ ++ /* MBEDTLS_SSL_MINOR_VERSION_4 4 *//*!< TLS v1.3 */ ++ mbedtls_ssl_conf_min_version(conf, MBEDTLS_SSL_MAJOR_VERSION_3, min+1); ++ mbedtls_ssl_conf_max_version(conf, MBEDTLS_SSL_MAJOR_VERSION_3, max+1); ++ #endif ++} ++ ++ ++__attribute_noinline__ ++static int tls_mbedtls_readfile(const char *path, u8 **buf, size_t *n); ++ ++ ++static int ++tls_mbedtls_set_dhparams(struct tls_conf *tls_conf, const char *dh_file) ++{ ++ size_t len; ++ u8 *data; ++ if (tls_mbedtls_readfile(dh_file, &data, &len)) ++ return 0; ++ ++ /* parse only if DH parameters if in PEM format */ ++ if (tls_mbedtls_data_is_pem(data) ++ && NULL == os_strstr((char *)data, "-----BEGIN DH PARAMETERS-----")) { ++ if (os_strstr((char *)data, "-----BEGIN DSA PARAMETERS-----")) ++ wpa_printf(MSG_WARNING, "DSA parameters not handled (%s)", dh_file); ++ else ++ wpa_printf(MSG_WARNING, "unexpected DH param content (%s)",dh_file); ++ forced_memzero(data, len); ++ os_free(data); ++ return 0; ++ } ++ ++ /* mbedtls_dhm_parse_dhm() expects "-----BEGIN DH PARAMETERS-----" if PEM */ ++ mbedtls_dhm_context dhm; ++ mbedtls_dhm_init(&dhm); ++ int rc = mbedtls_dhm_parse_dhm(&dhm, data, len); ++ if (0 == rc) ++ rc = mbedtls_ssl_conf_dh_param_ctx(&tls_conf->conf, &dhm); ++ if (0 != rc) ++ elog(rc, dh_file); ++ mbedtls_dhm_free(&dhm); ++ ++ forced_memzero(data, len); ++ os_free(data); ++ return (0 == rc); ++} ++ ++ ++/* reference: lighttpd src/mod_mbedtls.c:mod_mbedtls_ssl_append_curve() ++ * (same author: gstrauss@gluelogic.com; same license: BSD-3-Clause) */ ++#if MBEDTLS_VERSION_NUMBER < 0x03010000 /* mbedtls 3.1.0 */ ++static int ++tls_mbedtls_append_curve (mbedtls_ecp_group_id *ids, int nids, int idsz, const mbedtls_ecp_group_id id) ++{ ++ if (1 >= idsz - (nids + 1)) { ++ emsg(MSG_ERROR, "error: too many curves during list expand"); ++ return -1; ++ } ++ ids[++nids] = id; ++ return nids; ++} ++ ++ ++static int ++tls_mbedtls_set_curves(struct tls_conf *tls_conf, const char *curvelist) ++{ ++ mbedtls_ecp_group_id ids[512]; ++ int nids = -1; ++ const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1); ++ const mbedtls_ecp_curve_info * const curve_info = mbedtls_ecp_curve_list(); ++ ++ for (const char *e = curvelist-1; e; ) { ++ const char * const n = e+1; ++ e = os_strchr(n, ':'); ++ size_t len = e ? (size_t)(e - n) : os_strlen(n); ++ mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE; ++ switch (len) { ++ case 5: ++ if (0 == os_memcmp("P-521", n, 5)) ++ grp_id = MBEDTLS_ECP_DP_SECP521R1; ++ else if (0 == os_memcmp("P-384", n, 5)) ++ grp_id = MBEDTLS_ECP_DP_SECP384R1; ++ else if (0 == os_memcmp("P-256", n, 5)) ++ grp_id = MBEDTLS_ECP_DP_SECP256R1; ++ break; ++ case 6: ++ if (0 == os_memcmp("BP-521", n, 6)) ++ grp_id = MBEDTLS_ECP_DP_BP512R1; ++ else if (0 == os_memcmp("BP-384", n, 6)) ++ grp_id = MBEDTLS_ECP_DP_BP384R1; ++ else if (0 == os_memcmp("BP-256", n, 6)) ++ grp_id = MBEDTLS_ECP_DP_BP256R1; ++ break; ++ default: ++ break; ++ } ++ if (grp_id != MBEDTLS_ECP_DP_NONE) { ++ nids = tls_mbedtls_append_curve(ids, nids, idsz, grp_id); ++ if (-1 == nids) return 0; ++ continue; ++ } ++ /* similar to mbedtls_ecp_curve_info_from_name() */ ++ const mbedtls_ecp_curve_info *info; ++ for (info = curve_info; info->grp_id != MBEDTLS_ECP_DP_NONE; ++info) { ++ if (0 == os_strncmp(info->name, n, len) && info->name[len] == '\0') ++ break; ++ } ++ if (info->grp_id == MBEDTLS_ECP_DP_NONE) { ++ wpa_printf(MSG_ERROR, "MTLS: unrecognized curve: %.*s",(int)len,n); ++ return 0; ++ } ++ ++ nids = tls_mbedtls_append_curve(ids, nids, idsz, info->grp_id); ++ if (-1 == nids) return 0; ++ } ++ ++ /* mod_openssl configures "prime256v1" if curve list not specified, ++ * but mbedtls provides a list of supported curves if not explicitly set */ ++ if (-1 == nids) return 1; /* empty list; no-op */ ++ ++ ids[++nids] = MBEDTLS_ECP_DP_NONE; /* terminate list */ ++ ++nids; ++ ++ /* curves list must be persistent for lifetime of mbedtls_ssl_config */ ++ tls_conf->curves = os_malloc(nids * sizeof(mbedtls_ecp_group_id)); ++ if (tls_conf->curves == NULL) ++ return 0; ++ os_memcpy(tls_conf->curves, ids, nids * sizeof(mbedtls_ecp_group_id)); ++ ++ mbedtls_ssl_conf_curves(&tls_conf->conf, tls_conf->curves); ++ return 1; ++} ++#else ++static int ++tls_mbedtls_append_curve (uint16_t *ids, int nids, int idsz, const uint16_t id) ++{ ++ if (1 >= idsz - (nids + 1)) { ++ emsg(MSG_ERROR, "error: too many curves during list expand"); ++ return -1; ++ } ++ ids[++nids] = id; ++ return nids; ++} ++ ++ ++static int ++tls_mbedtls_set_curves(struct tls_conf *tls_conf, const char *curvelist) ++{ ++ /* TLS Supported Groups (renamed from "EC Named Curve Registry") ++ * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 ++ */ ++ uint16_t ids[512]; ++ int nids = -1; ++ const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1); ++ const mbedtls_ecp_curve_info * const curve_info = mbedtls_ecp_curve_list(); ++ ++ for (const char *e = curvelist-1; e; ) { ++ const char * const n = e+1; ++ e = os_strchr(n, ':'); ++ size_t len = e ? (size_t)(e - n) : os_strlen(n); ++ uint16_t tls_id = 0; ++ switch (len) { ++ case 5: ++ if (0 == os_memcmp("P-521", n, 5)) ++ tls_id = 25; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP521R1 */ ++ else if (0 == os_memcmp("P-384", n, 5)) ++ tls_id = 24; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP384R1 */ ++ else if (0 == os_memcmp("P-256", n, 5)) ++ tls_id = 23; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP256R1 */ ++ break; ++ case 6: ++ if (0 == os_memcmp("BP-521", n, 6)) ++ tls_id = 28; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP512R1 */ ++ else if (0 == os_memcmp("BP-384", n, 6)) ++ tls_id = 27; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP384R1 */ ++ else if (0 == os_memcmp("BP-256", n, 6)) ++ tls_id = 26; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP256R1 */ ++ break; ++ default: ++ break; ++ } ++ if (tls_id != 0) { ++ nids = tls_mbedtls_append_curve(ids, nids, idsz, tls_id); ++ if (-1 == nids) return 0; ++ continue; ++ } ++ /* similar to mbedtls_ecp_curve_info_from_name() */ ++ const mbedtls_ecp_curve_info *info; ++ for (info = curve_info; info->tls_id != 0; ++info) { ++ if (0 == os_strncmp(info->name, n, len) && info->name[len] == '\0') ++ break; ++ } ++ if (info->tls_id == 0) { ++ wpa_printf(MSG_ERROR, "MTLS: unrecognized curve: %.*s",(int)len,n); ++ return 0; ++ } ++ ++ nids = tls_mbedtls_append_curve(ids, nids, idsz, info->tls_id); ++ if (-1 == nids) return 0; ++ } ++ ++ /* mod_openssl configures "prime256v1" if curve list not specified, ++ * but mbedtls provides a list of supported curves if not explicitly set */ ++ if (-1 == nids) return 1; /* empty list; no-op */ ++ ++ ids[++nids] = 0; /* terminate list */ ++ ++nids; ++ ++ /* curves list must be persistent for lifetime of mbedtls_ssl_config */ ++ tls_conf->curves = os_malloc(nids * sizeof(uint16_t)); ++ if (tls_conf->curves == NULL) ++ return 0; ++ os_memcpy(tls_conf->curves, ids, nids * sizeof(uint16_t)); ++ ++ mbedtls_ssl_conf_groups(&tls_conf->conf, tls_conf->curves); ++ return 1; ++} ++#endif /* MBEDTLS_VERSION_NUMBER >= 0x03010000 */ /* mbedtls 3.1.0 */ ++ ++ ++/* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */ ++static const int suite_AES_256_ephemeral[] = { ++ /* All AES-256 ephemeral suites */ ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, ++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, ++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, ++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8 ++}; ++ ++/* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */ ++static const int suite_AES_128_ephemeral[] = { ++ /* All AES-128 ephemeral suites */ ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, ++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, ++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, ++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8 ++}; ++ ++/* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */ ++/* HIGH cipher list (mapped from openssl list to mbedtls) */ ++static const int suite_HIGH[] = { ++ MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, ++ MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, ++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, ++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, ++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, ++ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, ++ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, ++ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384, ++ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384, ++ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, ++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, ++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, ++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, ++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, ++ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, ++ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, ++ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256, ++ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256, ++ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256, ++ MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, ++ MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, ++ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, ++ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, ++ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, ++ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, ++ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, ++ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, ++ MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, ++ MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, ++ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, ++ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384, ++ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, ++ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, ++ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, ++ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, ++ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, ++ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, ++ MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, ++ MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, ++ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, ++ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256, ++ MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, ++ MBEDTLS_TLS_RSA_WITH_AES_256_CCM, ++ MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, ++ MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, ++ MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, ++ MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, ++ MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, ++ MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384, ++ MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, ++ MBEDTLS_TLS_RSA_WITH_AES_128_CCM, ++ MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, ++ MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, ++ MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, ++ MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, ++ MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, ++ MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256, ++ MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, ++ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, ++ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, ++ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, ++ MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, ++ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, ++ MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, ++ MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, ++ MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, ++ MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, ++ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, ++ MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, ++ MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, ++ MBEDTLS_TLS_PSK_WITH_AES_256_CCM, ++ MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, ++ MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, ++ MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, ++ MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, ++ MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384, ++ MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, ++ MBEDTLS_TLS_PSK_WITH_AES_128_CCM, ++ MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, ++ MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, ++ MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, ++ MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, ++ MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 ++}; ++ ++ ++__attribute_noinline__ ++static int ++tls_mbedtls_append_ciphersuite (int *ids, int nids, int idsz, const int *x, int xsz) ++{ ++ if (xsz >= idsz - (nids + 1)) { ++ emsg(MSG_ERROR, "error: too many ciphers during list expand"); ++ return -1; ++ } ++ ++ for (int i = 0; i < xsz; ++i) ++ ids[++nids] = x[i]; ++ ++ return nids; ++} ++ ++ ++static int ++tls_mbedtls_translate_ciphername(int id, char *buf, size_t buflen) ++{ ++ const mbedtls_ssl_ciphersuite_t *info = ++ mbedtls_ssl_ciphersuite_from_id(id); ++ if (info == NULL) ++ return 0; ++ const char *name = mbedtls_ssl_ciphersuite_get_name(info); ++ const size_t len = os_strlen(name); ++ if (len == 7 && 0 == os_memcmp(name, "unknown", 7)) ++ return 0; ++ if (len >= buflen) ++ return 0; ++ os_strlcpy(buf, name, buflen); ++ ++ /* attempt to translate mbedtls string to openssl string ++ * (some heuristics; incomplete) */ ++ size_t i = 0, j = 0; ++ if (buf[0] == 'T') { ++ if (os_strncmp(buf, "TLS1-3-", 7) == 0) { ++ buf[3] = '-'; ++ j = 4; /* remove "1-3" from "TLS1-3-" prefix */ ++ i = 7; ++ } ++ else if (os_strncmp(buf, "TLS-", 4) == 0) ++ i = 4; /* remove "TLS-" prefix */ ++ } ++ for (; buf[i]; ++i) { ++ if (buf[i] == '-') { ++ if (i >= 3) { ++ if (0 == os_memcmp(buf+i-3, "AES", 3)) ++ continue; /* "AES-" -> "AES" */ ++ } ++ if (i >= 4) { ++ if (0 == os_memcmp(buf+i-4, "WITH", 4)) { ++ j -= 4; /* remove "WITH-" */ ++ continue; ++ } ++ } ++ } ++ buf[j++] = buf[i]; ++ } ++ buf[j] = '\0'; ++ ++ return j; ++} ++ ++ ++__attribute_noinline__ ++static int ++tls_mbedtls_set_ciphersuites(struct tls_conf *tls_conf, int *ids, int nids) ++{ ++ /* ciphersuites list must be persistent for lifetime of mbedtls_ssl_config*/ ++ os_free(tls_conf->ciphersuites); ++ tls_conf->ciphersuites = os_malloc(nids * sizeof(int)); ++ if (tls_conf->ciphersuites == NULL) ++ return 0; ++ os_memcpy(tls_conf->ciphersuites, ids, nids * sizeof(int)); ++ mbedtls_ssl_conf_ciphersuites(&tls_conf->conf, tls_conf->ciphersuites); ++ return 1; ++} ++ ++ ++static int ++tls_mbedtls_set_ciphers(struct tls_conf *tls_conf, const char *ciphers) ++{ ++ char buf[64]; ++ int ids[512]; ++ int nids = -1; ++ const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1); ++ const char *next; ++ size_t blen, clen; ++ do { ++ next = os_strchr(ciphers, ':'); ++ clen = next ? (size_t)(next - ciphers) : os_strlen(ciphers); ++ if (!clen) ++ continue; ++ ++ /* special-case a select set of openssl group names for hwsim tests */ ++ /* (review; remove excess code if tests are not run for non-OpenSSL?) */ ++ if (clen == 9 && os_memcmp(ciphers, "SUITEB192", 9) == 0) { ++ static int ssl_preset_suiteb192_ciphersuites[] = { ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, ++ 0 ++ }; ++ return tls_mbedtls_set_ciphersuites(tls_conf, ++ ssl_preset_suiteb192_ciphersuites, ++ 2); ++ } ++ if (clen == 9 && os_memcmp(ciphers, "SUITEB128", 9) == 0) { ++ static int ssl_preset_suiteb128_ciphersuites[] = { ++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, ++ 0 ++ }; ++ return tls_mbedtls_set_ciphersuites(tls_conf, ++ ssl_preset_suiteb128_ciphersuites, ++ 2); ++ } ++ if (clen == 7 && os_memcmp(ciphers, "DEFAULT", 7) == 0) ++ continue; ++ if (clen == 6 && os_memcmp(ciphers, "AES128", 6) == 0) { ++ nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, ++ suite_AES_128_ephemeral, ++ (int)ARRAY_SIZE(suite_AES_128_ephemeral)); ++ if (nids == -1) ++ return 0; ++ continue; ++ } ++ if (clen == 6 && os_memcmp(ciphers, "AES256", 6) == 0) { ++ nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, ++ suite_AES_256_ephemeral, ++ (int)ARRAY_SIZE(suite_AES_256_ephemeral)); ++ if (nids == -1) ++ return 0; ++ continue; ++ } ++ if (clen == 4 && os_memcmp(ciphers, "HIGH", 4) == 0) { ++ nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, suite_HIGH, ++ (int)ARRAY_SIZE(suite_HIGH)); ++ if (nids == -1) ++ return 0; ++ continue; ++ } ++ /* ignore anonymous cipher group names (?not supported by mbedtls?) */ ++ if (clen == 4 && os_memcmp(ciphers, "!ADH", 4) == 0) ++ continue; ++ if (clen == 6 && os_memcmp(ciphers, "-aECDH", 6) == 0) ++ continue; ++ if (clen == 7 && os_memcmp(ciphers, "-aECDSA", 7) == 0) ++ continue; ++ ++ /* attempt to match mbedtls cipher names ++ * nb: does not support openssl group names or list manipulation syntax ++ * (alt: could copy almost 1200 lines (!!!) of lighttpd mod_mbedtls.c ++ * mod_mbedtls_ssl_conf_ciphersuites() to translate strings) ++ * note: not efficient to rewrite list for each ciphers entry, ++ * but this code is expected to run only at startup ++ */ ++ const int *list = mbedtls_ssl_list_ciphersuites(); ++ for (; *list; ++list) { ++ blen = tls_mbedtls_translate_ciphername(*list,buf,sizeof(buf)); ++ if (!blen) ++ continue; ++ ++ /* matching heuristics additional to translate_ciphername above */ ++ if (blen == clen+4) { ++ char *cbc = os_strstr(buf, "CBC-"); ++ if (cbc) { ++ os_memmove(cbc, cbc+4, blen-(cbc+4-buf)+1); /*(w/ '\0')*/ ++ blen -= 4; ++ } ++ } ++ if (blen >= clen && os_memcmp(ciphers, buf, clen) == 0 ++ && (blen == clen ++ || (blen == clen+7 && os_memcmp(buf+clen, "-SHA256", 7)))) { ++ if (1 >= idsz - (nids + 1)) { ++ emsg(MSG_ERROR, ++ "error: too many ciphers during list expand"); ++ return 0; ++ } ++ ids[++nids] = *list; ++ break; ++ } ++ } ++ if (*list == 0) { ++ wpa_printf(MSG_ERROR, ++ "MTLS: unrecognized cipher: %.*s", (int)clen, ciphers); ++ return 0; ++ } ++ } while ((ciphers = next ? next+1 : NULL)); ++ ++ if (-1 == nids) return 1; /* empty list; no-op */ ++ ++ ids[++nids] = 0; /* terminate list */ ++ ++nids; ++ ++ return tls_mbedtls_set_ciphersuites(tls_conf, ids, nids); ++} ++ ++ ++__attribute_noinline__ ++static int tls_mbedtls_set_item(char **config_item, const char *item) ++{ ++ os_free(*config_item); ++ *config_item = NULL; ++ return item ? (*config_item = os_strdup(item)) != NULL : 1; ++} ++ ++ ++static int tls_connection_set_subject_match(struct tls_conf *tls_conf, ++ const struct tls_connection_params *params) ++{ ++ int rc = 1; ++ rc &= tls_mbedtls_set_item(&tls_conf->subject_match, ++ params->subject_match); ++ rc &= tls_mbedtls_set_item(&tls_conf->altsubject_match, ++ params->altsubject_match); ++ rc &= tls_mbedtls_set_item(&tls_conf->suffix_match, ++ params->suffix_match); ++ rc &= tls_mbedtls_set_item(&tls_conf->domain_match, ++ params->domain_match); ++ rc &= tls_mbedtls_set_item(&tls_conf->check_cert_subject, ++ params->check_cert_subject); ++ return rc; ++} ++ ++ ++/* duplicated in crypto_mbedtls.c:crypto_mbedtls_readfile()*/ ++__attribute_noinline__ ++static int tls_mbedtls_readfile(const char *path, u8 **buf, size_t *n) ++{ ++ #if 0 /* #ifdef MBEDTLS_FS_IO */ ++ /*(includes +1 for '\0' needed by mbedtls PEM parsing funcs)*/ ++ if (mbedtls_pk_load_file(path, (unsigned char **)buf, n) != 0) { ++ wpa_printf(MSG_ERROR, "error: mbedtls_pk_load_file %s", path); ++ return -1; ++ } ++ #else ++ /*(use os_readfile() so that we can use os_free() ++ *(if we use mbedtls_pk_load_file() above, macros prevent calling free() ++ * directly #if defined(OS_REJECT_C_LIB_FUNCTIONS) and calling os_free() ++ * on buf aborts in tests if buf not allocated via os_malloc())*/ ++ *buf = (u8 *)os_readfile(path, n); ++ if (!*buf) { ++ wpa_printf(MSG_ERROR, "error: os_readfile %s", path); ++ return -1; ++ } ++ u8 *buf0 = os_realloc(*buf, *n+1); ++ if (!buf0) { ++ bin_clear_free(*buf, *n); ++ *buf = NULL; ++ return -1; ++ } ++ buf0[(*n)++] = '\0'; ++ *buf = buf0; ++ #endif ++ return 0; ++} ++ ++ ++static int tls_mbedtls_set_crl(struct tls_conf *tls_conf, const u8 *data, size_t len) ++{ ++ /* do not use mbedtls_x509_crl_parse() on PEM unless it contains CRL */ ++ if (len && data[len-1] == '\0' ++ && NULL == os_strstr((const char *)data,"-----BEGIN X509 CRL-----") ++ && tls_mbedtls_data_is_pem(data)) ++ return 0; ++ ++ mbedtls_x509_crl crl; ++ mbedtls_x509_crl_init(&crl); ++ int rc = mbedtls_x509_crl_parse(&crl, data, len); ++ if (rc < 0) { ++ mbedtls_x509_crl_free(&crl); ++ return rc == MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ? 0 : rc; ++ } ++ ++ mbedtls_x509_crl *crl_new = os_malloc(sizeof(crl)); ++ if (crl_new == NULL) { ++ mbedtls_x509_crl_free(&crl); ++ return MBEDTLS_ERR_X509_ALLOC_FAILED; ++ } ++ os_memcpy(crl_new, &crl, sizeof(crl)); ++ ++ mbedtls_x509_crl *crl_old = tls_conf->crl; ++ tls_conf->crl = crl_new; ++ if (crl_old) { ++ mbedtls_x509_crl_free(crl_old); ++ os_free(crl_old); ++ } ++ return 0; ++} ++ ++ ++static int tls_mbedtls_set_ca(struct tls_conf *tls_conf, u8 *data, size_t len) ++{ ++ /* load crt struct onto stack and then copy into tls_conf in ++ * order to preserve existing tls_conf value if error occurs ++ * ++ * hostapd is not threaded, or else should allocate memory and swap in ++ * pointer reduce race condition. (If threaded, would also need to ++ * keep reference count of use to avoid freeing while still in use.) */ ++ ++ mbedtls_x509_crt crt; ++ mbedtls_x509_crt_init(&crt); ++ int rc = mbedtls_x509_crt_parse(&crt, data, len); ++ if (rc < 0) { ++ mbedtls_x509_crt_free(&crt); ++ return rc; ++ } ++ ++ mbedtls_x509_crt_free(&tls_conf->ca_cert); ++ os_memcpy(&tls_conf->ca_cert, &crt, sizeof(crt)); ++ return 0; ++} ++ ++ ++static int tls_mbedtls_set_ca_and_crl(struct tls_conf *tls_conf, const char *ca_cert_file) ++{ ++ size_t len; ++ u8 *data; ++ if (tls_mbedtls_readfile(ca_cert_file, &data, &len)) ++ return -1; ++ ++ int rc; ++ if (0 == (rc = tls_mbedtls_set_ca(tls_conf, data, len)) ++ && (!tls_mbedtls_data_is_pem(data) /*skip parse for CRL if not PEM*/ ++ || 0 == (rc = tls_mbedtls_set_crl(tls_conf, data, len)))) { ++ mbedtls_ssl_conf_ca_chain(&tls_conf->conf, ++ &tls_conf->ca_cert, ++ tls_conf->crl); ++ } ++ else { ++ elog(rc, __func__); ++ emsg(MSG_ERROR, ca_cert_file); ++ } ++ ++ forced_memzero(data, len); ++ os_free(data); ++ return rc; ++} ++ ++ ++static void tls_mbedtls_refresh_crl(void) ++{ ++ /* check for CRL refresh ++ * continue even if error occurs; continue with previous cert, CRL */ ++ unsigned int crl_reload_interval = tls_ctx_global.crl_reload_interval; ++ const char *ca_cert_file = tls_ctx_global.ca_cert_file; ++ if (!crl_reload_interval || !ca_cert_file) ++ return; ++ ++ struct os_reltime *previous = &tls_ctx_global.crl_reload_previous; ++ struct os_reltime now; ++ if (os_get_reltime(&now) != 0 ++ || !os_reltime_expired(&now, previous, crl_reload_interval)) ++ return; ++ ++ /* Note: modifying global state is not thread-safe ++ * if in use by existing connections ++ * ++ * src/utils/os.h does not provide a portable stat() ++ * or else it would be a good idea to check mtime and size, ++ * and avoid reloading if file has not changed */ ++ ++ if (tls_mbedtls_set_ca_and_crl(tls_ctx_global.tls_conf, ca_cert_file) == 0) ++ *previous = now; ++} ++ ++ ++static int tls_mbedtls_set_ca_cert(struct tls_conf *tls_conf, ++ const struct tls_connection_params *params) ++{ ++ if (params->ca_cert) { ++ if (os_strncmp(params->ca_cert, "probe://", 8) == 0) { ++ tls_conf->ca_cert_probe = 1; ++ tls_conf->has_ca_cert = 1; ++ return 0; ++ } ++ ++ if (os_strncmp(params->ca_cert, "hash://", 7) == 0) { ++ const char *pos = params->ca_cert + 7; ++ if (os_strncmp(pos, "server/sha256/", 14) != 0) { ++ emsg(MSG_ERROR, "unsupported ca_cert hash value"); ++ return -1; ++ } ++ pos += 14; ++ if (os_strlen(pos) != SHA256_DIGEST_LENGTH*2) { ++ emsg(MSG_ERROR, "unexpected ca_cert hash length"); ++ return -1; ++ } ++ if (hexstr2bin(pos, tls_conf->ca_cert_hash, ++ SHA256_DIGEST_LENGTH) < 0) { ++ emsg(MSG_ERROR, "invalid ca_cert hash value"); ++ return -1; ++ } ++ emsg(MSG_DEBUG, "checking only server certificate match"); ++ tls_conf->verify_depth0_only = 1; ++ tls_conf->has_ca_cert = 1; ++ return 0; ++ } ++ ++ if (tls_mbedtls_set_ca_and_crl(tls_conf, params->ca_cert) != 0) ++ return -1; ++ } ++ if (params->ca_cert_blob) { ++ size_t len = params->ca_cert_blob_len; ++ int is_pem = tls_mbedtls_data_is_pem(params->ca_cert_blob); ++ if (len && params->ca_cert_blob[len-1] != '\0' && is_pem) ++ ++len; /*(include '\0' in len for PEM)*/ ++ int ret = mbedtls_x509_crt_parse(&tls_conf->ca_cert, ++ params->ca_cert_blob, len); ++ if (ret != 0) { ++ elog(ret, "mbedtls_x509_crt_parse"); ++ return -1; ++ } ++ if (is_pem) { /*(ca_cert_blob in DER format contains ca cert only)*/ ++ ret = tls_mbedtls_set_crl(tls_conf, params->ca_cert_blob, len); ++ if (ret != 0) { ++ elog(ret, "mbedtls_x509_crl_parse"); ++ return -1; ++ } ++ } ++ } ++ ++ if (mbedtls_x509_time_is_future(&tls_conf->ca_cert.valid_from) ++ || mbedtls_x509_time_is_past(&tls_conf->ca_cert.valid_to)) { ++ emsg(MSG_WARNING, "ca_cert expired or not yet valid"); ++ if (params->ca_cert) ++ emsg(MSG_WARNING, params->ca_cert); ++ } ++ ++ tls_conf->has_ca_cert = 1; ++ return 0; ++} ++ ++ ++static int tls_mbedtls_set_certs(struct tls_conf *tls_conf, ++ const struct tls_connection_params *params) ++{ ++ int ret; ++ ++ if (params->ca_cert || params->ca_cert_blob) { ++ if (tls_mbedtls_set_ca_cert(tls_conf, params) != 0) ++ return -1; ++ } ++ else if (params->ca_path) { ++ emsg(MSG_INFO, "ca_path support not implemented"); ++ return -1; ++ } ++ ++ if (!tls_conf->has_ca_cert) ++ mbedtls_ssl_conf_authmode(&tls_conf->conf, MBEDTLS_SSL_VERIFY_NONE); ++ else { ++ /* Initial setting: REQUIRED for client, OPTIONAL for server ++ * (see also tls_connection_set_verify()) */ ++ tls_conf->verify_peer = (tls_ctx_global.tls_conf == NULL); ++ int authmode = tls_conf->verify_peer ++ ? MBEDTLS_SSL_VERIFY_REQUIRED ++ : MBEDTLS_SSL_VERIFY_OPTIONAL; ++ mbedtls_ssl_conf_authmode(&tls_conf->conf, authmode); ++ mbedtls_ssl_conf_ca_chain(&tls_conf->conf, ++ &tls_conf->ca_cert, ++ tls_conf->crl); ++ ++ if (!tls_connection_set_subject_match(tls_conf, params)) ++ return -1; ++ } ++ ++ if (params->client_cert2) /*(yes, server_cert2 in msg below)*/ ++ emsg(MSG_INFO, "server_cert2 support not implemented"); ++ ++ if (params->client_cert) { ++ size_t len; ++ u8 *data; ++ if (tls_mbedtls_readfile(params->client_cert, &data, &len)) ++ return -1; ++ ret = mbedtls_x509_crt_parse(&tls_conf->client_cert, data, len); ++ forced_memzero(data, len); ++ os_free(data); ++ } ++ if (params->client_cert_blob) { ++ size_t len = params->client_cert_blob_len; ++ if (len && params->client_cert_blob[len-1] != '\0' ++ && tls_mbedtls_data_is_pem(params->client_cert_blob)) ++ ++len; /*(include '\0' in len for PEM)*/ ++ ret = mbedtls_x509_crt_parse(&tls_conf->client_cert, ++ params->client_cert_blob, len); ++ } ++ if (params->client_cert || params->client_cert_blob) { ++ if (ret < 0) { ++ elog(ret, "mbedtls_x509_crt_parse"); ++ if (params->client_cert) ++ emsg(MSG_ERROR, params->client_cert); ++ return -1; ++ } ++ if (mbedtls_x509_time_is_future(&tls_conf->client_cert.valid_from) ++ || mbedtls_x509_time_is_past(&tls_conf->client_cert.valid_to)) { ++ emsg(MSG_WARNING, "cert expired or not yet valid"); ++ if (params->client_cert) ++ emsg(MSG_WARNING, params->client_cert); ++ } ++ tls_conf->has_client_cert = 1; ++ } ++ ++ if (params->private_key || params->private_key_blob) { ++ size_t len = params->private_key_blob_len; ++ u8 *data; ++ *(const u8 **)&data = params->private_key_blob; ++ if (len && data[len-1] != '\0' && tls_mbedtls_data_is_pem(data)) ++ ++len; /*(include '\0' in len for PEM)*/ ++ if (params->private_key ++ && tls_mbedtls_readfile(params->private_key, &data, &len)) { ++ return -1; ++ } ++ const char *pwd = params->private_key_passwd; ++ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ ++ ret = mbedtls_pk_parse_key(&tls_conf->private_key, ++ data, len, ++ (const unsigned char *)pwd, ++ pwd ? os_strlen(pwd) : 0, ++ mbedtls_ctr_drbg_random, ++ tls_ctx_global.ctr_drbg); ++ #else ++ ret = mbedtls_pk_parse_key(&tls_conf->private_key, ++ data, len, ++ (const unsigned char *)pwd, ++ pwd ? os_strlen(pwd) : 0); ++ #endif ++ if (params->private_key) { ++ forced_memzero(data, len); ++ os_free(data); ++ } ++ if (ret < 0) { ++ elog(ret, "mbedtls_pk_parse_key"); ++ return -1; ++ } ++ tls_conf->has_private_key = 1; ++ } ++ ++ if (tls_conf->has_client_cert && tls_conf->has_private_key) { ++ ret = mbedtls_ssl_conf_own_cert( ++ &tls_conf->conf, &tls_conf->client_cert, &tls_conf->private_key); ++ if (ret < 0) { ++ elog(ret, "mbedtls_ssl_conf_own_cert"); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++ ++/* mbedtls_x509_crt_profile_suiteb plus rsa_min_bitlen 2048 */ ++/* (reference: see also mbedtls_x509_crt_profile_next) */ ++/* ??? should permit SHA-512, too, and additional curves ??? */ ++static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb128 = ++{ ++ /* Only SHA-256 and 384 */ ++ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | ++ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), ++ /* Only ECDSA */ ++ MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) | ++ MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ), ++#if defined(MBEDTLS_ECP_C) ++ /* Only NIST P-256 and P-384 */ ++ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | ++ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), ++#else ++ 0, ++#endif ++ 2048, ++}; ++ ++ ++/* stricter than mbedtls_x509_crt_profile_suiteb */ ++/* (reference: see also mbedtls_x509_crt_profile_next) */ ++/* ??? should permit SHA-512, too, and additional curves ??? */ ++static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb192 = ++{ ++ /* Only SHA-384 */ ++ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), ++ /* Only ECDSA */ ++ MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) | ++ MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ), ++#if defined(MBEDTLS_ECP_C) ++ /* Only NIST P-384 */ ++ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), ++#else ++ 0, ++#endif ++ 3072, ++}; ++ ++ ++/* stricter than mbedtls_x509_crt_profile_suiteb except allow any PK alg */ ++/* (reference: see also mbedtls_x509_crt_profile_next) */ ++/* ??? should permit SHA-512, too, and additional curves ??? */ ++static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb192_anypk = ++{ ++ /* Only SHA-384 */ ++ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), ++ 0xFFFFFFF, /* Any PK alg */ ++#if defined(MBEDTLS_ECP_C) ++ /* Only NIST P-384 */ ++ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), ++#else ++ 0, ++#endif ++ 3072, ++}; ++ ++ ++static int tls_mbedtls_set_params(struct tls_conf *tls_conf, ++ const struct tls_connection_params *params) ++{ ++ tls_conf->flags = params->flags; ++ ++ if (tls_conf->flags & TLS_CONN_REQUIRE_OCSP_ALL) { ++ emsg(MSG_INFO, "ocsp=3 not supported"); ++ return -1; ++ } ++ ++ if (tls_conf->flags & TLS_CONN_REQUIRE_OCSP) { ++ emsg(MSG_INFO, "ocsp not supported"); ++ return -1; ++ } ++ ++ int suiteb128 = 0; ++ int suiteb192 = 0; ++ if (params->openssl_ciphers) { ++ if (os_strcmp(params->openssl_ciphers, "SUITEB192") == 0) { ++ suiteb192 = 1; ++ tls_conf->flags |= TLS_CONN_SUITEB; ++ } ++ if (os_strcmp(params->openssl_ciphers, "SUITEB128") == 0) { ++ suiteb128 = 1; ++ tls_conf->flags |= TLS_CONN_SUITEB; ++ } ++ } ++ ++ int ret = mbedtls_ssl_config_defaults( ++ &tls_conf->conf, tls_ctx_global.tls_conf ? MBEDTLS_SSL_IS_SERVER ++ : MBEDTLS_SSL_IS_CLIENT, ++ MBEDTLS_SSL_TRANSPORT_STREAM, ++ (tls_conf->flags & TLS_CONN_SUITEB) ? MBEDTLS_SSL_PRESET_SUITEB ++ : MBEDTLS_SSL_PRESET_DEFAULT); ++ if (ret != 0) { ++ elog(ret, "mbedtls_ssl_config_defaults"); ++ return -1; ++ } ++ ++ if (suiteb128) { ++ mbedtls_ssl_conf_cert_profile(&tls_conf->conf, ++ &tls_mbedtls_crt_profile_suiteb128); ++ mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 2048); ++ } ++ else if (suiteb192) { ++ mbedtls_ssl_conf_cert_profile(&tls_conf->conf, ++ &tls_mbedtls_crt_profile_suiteb192); ++ mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 3072); ++ } ++ else if (tls_conf->flags & TLS_CONN_SUITEB) { ++ /* treat as suiteb192 while allowing any PK algorithm */ ++ mbedtls_ssl_conf_cert_profile(&tls_conf->conf, ++ &tls_mbedtls_crt_profile_suiteb192_anypk); ++ mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 3072); ++ } ++ ++ tls_mbedtls_set_allowed_tls_vers(tls_conf, &tls_conf->conf); ++ ret = tls_mbedtls_set_certs(tls_conf, params); ++ if (ret != 0) ++ return -1; ++ ++ if (params->dh_file ++ && !tls_mbedtls_set_dhparams(tls_conf, params->dh_file)) { ++ return -1; ++ } ++ ++ if (params->openssl_ecdh_curves ++ && !tls_mbedtls_set_curves(tls_conf, params->openssl_ecdh_curves)) { ++ return -1; ++ } ++ ++ if (params->openssl_ciphers) { ++ if (!tls_mbedtls_set_ciphers(tls_conf, params->openssl_ciphers)) ++ return -1; ++ } ++ else if (tls_conf->flags & TLS_CONN_SUITEB) { ++ /* special-case a select set of ciphers for hwsim tests */ ++ if (!tls_mbedtls_set_ciphers(tls_conf, ++ (tls_conf->flags & TLS_CONN_SUITEB_NO_ECDH) ++ ? "DHE-RSA-AES256-GCM-SHA384" ++ : "ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384")) ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ ++int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, ++ const struct tls_connection_params *params) ++{ ++ if (conn == NULL || params == NULL) ++ return -1; ++ ++ tls_conf_deinit(conn->tls_conf); ++ struct tls_conf *tls_conf = conn->tls_conf = tls_conf_init(tls_ctx); ++ if (tls_conf == NULL) ++ return -1; ++ ++ if (tls_ctx_global.tls_conf) { ++ tls_conf->check_crl = tls_ctx_global.tls_conf->check_crl; ++ tls_conf->check_crl_strict = tls_ctx_global.tls_conf->check_crl_strict; ++ /*(tls_openssl.c inherits check_cert_subject from global conf)*/ ++ if (tls_ctx_global.tls_conf->check_cert_subject) { ++ tls_conf->check_cert_subject = ++ os_strdup(tls_ctx_global.tls_conf->check_cert_subject); ++ if (tls_conf->check_cert_subject == NULL) ++ return -1; ++ } ++ } ++ ++ if (tls_mbedtls_set_params(tls_conf, params) != 0) ++ return -1; ++ conn->verify_peer = tls_conf->verify_peer; ++ ++ return tls_mbedtls_ssl_setup(conn); ++} ++ ++ ++#ifdef TLS_MBEDTLS_SESSION_TICKETS ++ ++static int tls_mbedtls_clienthello_session_ticket_prep (struct tls_connection *conn, ++ const u8 *data, size_t len) ++{ ++ if (conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET) ++ return -1; ++ if (conn->clienthello_session_ticket) ++ tls_connection_deinit_clienthello_session_ticket(conn); ++ if (len) { ++ conn->clienthello_session_ticket = mbedtls_calloc(1, len); ++ if (conn->clienthello_session_ticket == NULL) ++ return -1; ++ conn->clienthello_session_ticket_len = len; ++ os_memcpy(conn->clienthello_session_ticket, data, len); ++ } ++ return 0; ++} ++ ++ ++static void tls_mbedtls_clienthello_session_ticket_set (struct tls_connection *conn) ++{ ++ mbedtls_ssl_session *sess = conn->ssl.MBEDTLS_PRIVATE(session_negotiate); ++ if (sess->MBEDTLS_PRIVATE(ticket)) { ++ mbedtls_platform_zeroize(sess->MBEDTLS_PRIVATE(ticket), ++ sess->MBEDTLS_PRIVATE(ticket_len)); ++ mbedtls_free(sess->MBEDTLS_PRIVATE(ticket)); ++ } ++ sess->MBEDTLS_PRIVATE(ticket) = conn->clienthello_session_ticket; ++ sess->MBEDTLS_PRIVATE(ticket_len) = conn->clienthello_session_ticket_len; ++ sess->MBEDTLS_PRIVATE(ticket_lifetime) = 86400;/* XXX: can hint be 0? */ ++ ++ conn->clienthello_session_ticket = NULL; ++ conn->clienthello_session_ticket_len = 0; ++} ++ ++ ++static int tls_mbedtls_ssl_ticket_write(void *p_ticket, ++ const mbedtls_ssl_session *session, ++ unsigned char *start, ++ const unsigned char *end, ++ size_t *tlen, ++ uint32_t *lifetime) ++{ ++ struct tls_connection *conn = p_ticket; ++ if (conn && conn->session_ticket_cb) { ++ /* see tls_mbedtls_clienthello_session_ticket_prep() */ ++ /* see tls_mbedtls_clienthello_session_ticket_set() */ ++ return 0; ++ } ++ ++ return mbedtls_ssl_ticket_write(&tls_ctx_global.ticket_ctx, ++ session, start, end, tlen, lifetime); ++} ++ ++ ++static int tls_mbedtls_ssl_ticket_parse(void *p_ticket, ++ mbedtls_ssl_session *session, ++ unsigned char *buf, ++ size_t len) ++{ ++ /* XXX: TODO: not implemented in client; ++ * mbedtls_ssl_conf_session_tickets_cb() callbacks only for TLS server*/ ++ ++ if (len == 0) ++ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; ++ ++ struct tls_connection *conn = p_ticket; ++ if (conn && conn->session_ticket_cb) { ++ /* XXX: have random and secret been initialized yet? ++ * or must keys first be exported? ++ * EAP-FAST uses all args, EAP-TEAP only uses secret */ ++ struct tls_random data; ++ if (tls_connection_get_random(NULL, conn, &data) != 0) ++ return MBEDTLS_ERR_SSL_INTERNAL_ERROR; ++ int ret = ++ conn->session_ticket_cb(conn->session_ticket_cb_ctx, ++ buf, len, ++ data.client_random, ++ data.server_random, ++ conn->expkey_secret); ++ if (ret == 1) { ++ conn->resumed = 1; ++ return 0; ++ } ++ emsg(MSG_ERROR, "EAP session ticket ext not implemented"); ++ return MBEDTLS_ERR_SSL_INVALID_MAC; ++ /*(non-zero return used for mbedtls debug logging)*/ ++ } ++ ++ /* XXX: TODO always use tls_mbedtls_ssl_ticket_parse() for callback? */ ++ int rc = mbedtls_ssl_ticket_parse(&tls_ctx_global.ticket_ctx, ++ session, buf, len); ++ if (conn) ++ conn->resumed = (rc == 0); ++ return rc; ++} ++ ++#endif /* TLS_MBEDTLS_SESSION_TICKETS */ ++ ++ ++__attribute_cold__ ++int tls_global_set_params(void *tls_ctx, ++ const struct tls_connection_params *params) ++{ ++ /* XXX: why might global_set_params be called more than once? */ ++ if (tls_ctx_global.tls_conf) ++ tls_conf_deinit(tls_ctx_global.tls_conf); ++ tls_ctx_global.tls_conf = tls_conf_init(tls_ctx); ++ if (tls_ctx_global.tls_conf == NULL) ++ return -1; ++ ++ #ifdef MBEDTLS_SSL_SESSION_TICKETS ++ #ifdef MBEDTLS_SSL_TICKET_C ++ if (!(params->flags & TLS_CONN_DISABLE_SESSION_TICKET)) ++ #ifdef TLS_MBEDTLS_SESSION_TICKETS ++ mbedtls_ssl_conf_session_tickets_cb(&tls_ctx_global.tls_conf->conf, ++ tls_mbedtls_ssl_ticket_write, ++ tls_mbedtls_ssl_ticket_parse, ++ NULL); ++ #else ++ mbedtls_ssl_conf_session_tickets_cb(&tls_ctx_global.tls_conf->conf, ++ mbedtls_ssl_ticket_write, ++ mbedtls_ssl_ticket_parse, ++ &tls_ctx_global.ticket_ctx); ++ #endif ++ #endif ++ #endif ++ ++ os_free(tls_ctx_global.ocsp_stapling_response); ++ tls_ctx_global.ocsp_stapling_response = NULL; ++ if (params->ocsp_stapling_response) ++ tls_ctx_global.ocsp_stapling_response = ++ os_strdup(params->ocsp_stapling_response); ++ ++ os_free(tls_ctx_global.ca_cert_file); ++ tls_ctx_global.ca_cert_file = NULL; ++ if (params->ca_cert) ++ tls_ctx_global.ca_cert_file = os_strdup(params->ca_cert); ++ return tls_mbedtls_set_params(tls_ctx_global.tls_conf, params); ++} ++ ++ ++int tls_global_set_verify(void *tls_ctx, int check_crl, int strict) ++{ ++ tls_ctx_global.tls_conf->check_crl = check_crl; ++ tls_ctx_global.tls_conf->check_crl_strict = strict; /*(time checks)*/ ++ return 0; ++} ++ ++ ++int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn, ++ int verify_peer, unsigned int flags, ++ const u8 *session_ctx, size_t session_ctx_len) ++{ ++ /*(EAP server-side calls this from eap_server_tls_ssl_init())*/ ++ if (conn == NULL) ++ return -1; ++ ++ conn->tls_conf->flags |= flags;/* TODO: reprocess flags, if necessary */ ++ ++ int authmode; ++ switch (verify_peer) { ++ case 2: authmode = MBEDTLS_SSL_VERIFY_OPTIONAL; break;/*(eap_teap_init())*/ ++ case 1: authmode = MBEDTLS_SSL_VERIFY_REQUIRED; break; ++ default: authmode = MBEDTLS_SSL_VERIFY_NONE; break; ++ } ++ mbedtls_ssl_set_hs_authmode(&conn->ssl, authmode); ++ ++ if ((conn->verify_peer = (authmode != MBEDTLS_SSL_VERIFY_NONE))) ++ mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn); ++ else ++ mbedtls_ssl_set_verify(&conn->ssl, NULL, NULL); ++ ++ return 0; ++} ++ ++ ++#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ ++static void tls_connection_export_keys_cb( ++ void *p_expkey, mbedtls_ssl_key_export_type secret_type, ++ const unsigned char *secret, size_t secret_len, ++ const unsigned char client_random[MBEDTLS_EXPKEY_RAND_LEN], ++ const unsigned char server_random[MBEDTLS_EXPKEY_RAND_LEN], ++ mbedtls_tls_prf_types tls_prf_type) ++{ ++ struct tls_connection *conn = p_expkey; ++ conn->tls_prf_type = tls_prf_type; ++ if (!tls_prf_type) ++ return; ++ if (secret_len > sizeof(conn->expkey_secret)) { ++ emsg(MSG_ERROR, "tls_connection_export_keys_cb secret too long"); ++ conn->tls_prf_type = MBEDTLS_SSL_TLS_PRF_NONE; /* 0 */ ++ return; ++ } ++ conn->expkey_secret_len = secret_len; ++ os_memcpy(conn->expkey_secret, secret, secret_len); ++ os_memcpy(conn->expkey_randbytes, ++ client_random, MBEDTLS_EXPKEY_RAND_LEN); ++ os_memcpy(conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN, ++ server_random, MBEDTLS_EXPKEY_RAND_LEN); ++} ++#elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ ++static int tls_connection_export_keys_cb( ++ void *p_expkey, ++ const unsigned char *ms, ++ const unsigned char *kb, ++ size_t maclen, ++ size_t keylen, ++ size_t ivlen, ++ const unsigned char client_random[MBEDTLS_EXPKEY_RAND_LEN], ++ const unsigned char server_random[MBEDTLS_EXPKEY_RAND_LEN], ++ mbedtls_tls_prf_types tls_prf_type ) ++{ ++ struct tls_connection *conn = p_expkey; ++ conn->tls_prf_type = tls_prf_type; ++ if (!tls_prf_type) ++ return -1; /*(return value ignored by mbedtls)*/ ++ conn->expkey_keyblock_size = maclen + keylen + ivlen; ++ conn->expkey_secret_len = MBEDTLS_EXPKEY_FIXED_SECRET_LEN; ++ os_memcpy(conn->expkey_secret, ms, MBEDTLS_EXPKEY_FIXED_SECRET_LEN); ++ os_memcpy(conn->expkey_randbytes, ++ client_random, MBEDTLS_EXPKEY_RAND_LEN); ++ os_memcpy(conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN, ++ server_random, MBEDTLS_EXPKEY_RAND_LEN); ++ return 0; ++} ++#endif ++ ++ ++int tls_connection_get_random(void *tls_ctx, struct tls_connection *conn, ++ struct tls_random *data) ++{ ++ if (!conn || !conn->tls_prf_type) ++ return -1; ++ data->client_random = conn->expkey_randbytes; ++ data->client_random_len = MBEDTLS_EXPKEY_RAND_LEN; ++ data->server_random = conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN; ++ data->server_random_len = MBEDTLS_EXPKEY_RAND_LEN; ++ return 0; ++} ++ ++ ++int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn, ++ const char *label, const u8 *context, ++ size_t context_len, u8 *out, size_t out_len) ++{ ++ /* (EAP-PEAP EAP-TLS EAP-TTLS) */ ++ #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ ++ return (conn && conn->established && conn->tls_prf_type) ++ ? mbedtls_ssl_tls_prf(conn->tls_prf_type, ++ conn->expkey_secret, conn->expkey_secret_len, label, ++ conn->expkey_randbytes, ++ sizeof(conn->expkey_randbytes), out, out_len) ++ : -1; ++ #else ++ /* not implemented here for mbedtls < 2.18.0 */ ++ return -1; ++ #endif ++} ++ ++ ++#ifdef TLS_MBEDTLS_EAP_FAST ++ ++#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ ++/* keyblock size info is not exposed in mbed TLS 3.0.0 */ ++/* extracted from mbedtls library/ssl_tls.c:ssl_tls12_populate_transform() */ ++#include ++#include ++static size_t tls_mbedtls_ssl_keyblock_size (mbedtls_ssl_context *ssl) ++{ ++ #if !defined(MBEDTLS_USE_PSA_CRYPTO) /* XXX: (not extracted for PSA crypto) */ ++ #if defined(MBEDTLS_SSL_PROTO_TLS1_3) ++ if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) ++ return 0; /* (calculation not extracted) */ ++ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ ++ ++ int ciphersuite = mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl); ++ const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ++ mbedtls_ssl_ciphersuite_from_id(ciphersuite); ++ if (ciphersuite_info == NULL) ++ return 0; ++ ++ const mbedtls_cipher_info_t *cipher_info = ++ mbedtls_cipher_info_from_type(ciphersuite_info->MBEDTLS_PRIVATE(cipher)); ++ if (cipher_info == NULL) ++ return 0; ++ ++ #if MBEDTLS_VERSION_NUMBER >= 0x03010000 /* mbedtls 3.1.0 */ ++ size_t keylen = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8; ++ mbedtls_cipher_mode_t mode = mbedtls_cipher_info_get_mode(cipher_info); ++ #else ++ size_t keylen = cipher_info->MBEDTLS_PRIVATE(key_bitlen) / 8; ++ mbedtls_cipher_mode_t mode = cipher_info->MBEDTLS_PRIVATE(mode); ++ #endif ++ #if defined(MBEDTLS_GCM_C) || \ ++ defined(MBEDTLS_CCM_C) || \ ++ defined(MBEDTLS_CHACHAPOLY_C) ++ if (mode == MBEDTLS_MODE_GCM || mode == MBEDTLS_MODE_CCM) ++ return keylen + 4; ++ else if (mode == MBEDTLS_MODE_CHACHAPOLY) ++ return keylen + 12; ++ else ++ #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */ ++ #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) ++ { ++ const mbedtls_md_info_t *md_info = ++ mbedtls_md_info_from_type(ciphersuite_info->MBEDTLS_PRIVATE(mac)); ++ if (md_info == NULL) ++ return 0; ++ size_t mac_key_len = mbedtls_md_get_size(md_info); ++ size_t ivlen = mbedtls_cipher_info_get_iv_size(cipher_info); ++ return keylen + mac_key_len + ivlen; ++ } ++ #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ ++ #endif /* !MBEDTLS_USE_PSA_CRYPTO *//* (not extracted for PSA crypto) */ ++ return 0; ++} ++#endif /* MBEDTLS_VERSION_NUMBER >= 0x03000000 *//* mbedtls 3.0.0 */ ++ ++ ++int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, ++ u8 *out, size_t out_len) ++{ ++ /* XXX: has export keys callback been run? */ ++ if (!conn || !conn->tls_prf_type) ++ return -1; ++ ++ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ ++ conn->expkey_keyblock_size = tls_mbedtls_ssl_keyblock_size(&conn->ssl); ++ if (conn->expkey_keyblock_size == 0) ++ return -1; ++ #endif ++ size_t skip = conn->expkey_keyblock_size * 2; ++ unsigned char *tmp_out = os_malloc(skip + out_len); ++ if (!tmp_out) ++ return -1; ++ ++ /* server_random and then client_random */ ++ unsigned char seed[MBEDTLS_EXPKEY_RAND_LEN*2]; ++ os_memcpy(seed, conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN, ++ MBEDTLS_EXPKEY_RAND_LEN); ++ os_memcpy(seed + MBEDTLS_EXPKEY_RAND_LEN, conn->expkey_randbytes, ++ MBEDTLS_EXPKEY_RAND_LEN); ++ ++ #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ ++ int ret = mbedtls_ssl_tls_prf(conn->tls_prf_type, ++ conn->expkey_secret, conn->expkey_secret_len, ++ "key expansion", seed, sizeof(seed), ++ tmp_out, skip + out_len); ++ if (ret == 0) ++ os_memcpy(out, tmp_out + skip, out_len); ++ #else ++ int ret = -1; /*(not reached if not impl; return -1 at top of func)*/ ++ #endif ++ ++ bin_clear_free(tmp_out, skip + out_len); ++ forced_memzero(seed, sizeof(seed)); ++ return ret; ++} ++ ++#endif /* TLS_MBEDTLS_EAP_FAST */ ++ ++ ++__attribute_cold__ ++static void tls_mbedtls_suiteb_handshake_alert (struct tls_connection *conn) ++{ ++ /* tests/hwsim/test_suite_b.py test_suite_b_192_rsa_insufficient_dh */ ++ if (!(conn->tls_conf->flags & TLS_CONN_SUITEB)) ++ return; ++ if (tls_ctx_global.tls_conf) /*(is server; want issue event on client)*/ ++ return; ++ #if 0 ++ /*(info not available on client; ++ * mbed TLS library enforces dhm min bitlen in ServerKeyExchange)*/ ++ if (MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 == ++ #if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */ ++ mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl) ++ #else ++ mbedtls_ssl_get_ciphersuite_id( ++ mbedtls_ssl_get_ciphersuite(&conn->ssl)) ++ #endif ++ && mbedtls_mpi_size(&conn->tls_conf->conf.MBEDTLS_PRIVATE(dhm_P)) ++ < 384 /*(3072/8)*/) ++ #endif ++ { ++ struct tls_config *init_conf = &tls_ctx_global.init_conf; ++ if (init_conf->event_cb) { ++ union tls_event_data ev; ++ os_memset(&ev, 0, sizeof(ev)); ++ ev.alert.is_local = 1; ++ ev.alert.type = "fatal"; ++ /*"internal error" string for tests/hwsim/test_suiteb.py */ ++ ev.alert.description = "internal error: handshake failure"; ++ /*ev.alert.description = "insufficient security";*/ ++ init_conf->event_cb(init_conf->cb_ctx, TLS_ALERT, &ev); ++ } ++ } ++} ++ ++ ++struct wpabuf * tls_connection_handshake(void *tls_ctx, ++ struct tls_connection *conn, ++ const struct wpabuf *in_data, ++ struct wpabuf **appl_data) ++{ ++ if (appl_data) ++ *appl_data = NULL; ++ ++ if (in_data && wpabuf_len(in_data)) { ++ /*(unsure why tls_gnutls.c discards buffer contents; skip here)*/ ++ if (conn->pull_buf && 0) /* disable; appears unwise */ ++ tls_pull_buf_discard(conn, __func__); ++ if (!tls_pull_buf_append(conn, in_data)) ++ return NULL; ++ } ++ ++ if (conn->tls_conf == NULL) { ++ struct tls_connection_params params; ++ os_memset(¶ms, 0, sizeof(params)); ++ params.openssl_ciphers = ++ tls_ctx_global.init_conf.openssl_ciphers; ++ params.flags = tls_ctx_global.tls_conf->flags; ++ if (tls_connection_set_params(tls_ctx, conn, ¶ms) != 0) ++ return NULL; ++ } ++ ++ if (conn->verify_peer) /*(call here might be redundant; nbd)*/ ++ mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn); ++ ++ #ifdef TLS_MBEDTLS_SESSION_TICKETS ++ if (conn->clienthello_session_ticket) ++ /*(starting handshake for EAP-FAST and EAP-TEAP)*/ ++ tls_mbedtls_clienthello_session_ticket_set(conn); ++ ++ /* (not thread-safe due to need to set userdata 'conn' for callback) */ ++ /* (unable to use mbedtls_ssl_set_user_data_p() with mbedtls 3.2.0+ ++ * since ticket write and parse callbacks take (mbedtls_ssl_session *) ++ * param instead of (mbedtls_ssl_context *) param) */ ++ if (conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET) ++ mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, ++ NULL, NULL, NULL); ++ else ++ mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, ++ tls_mbedtls_ssl_ticket_write, ++ tls_mbedtls_ssl_ticket_parse, ++ conn); ++ #endif ++ ++ #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ ++ int ret = mbedtls_ssl_handshake(&conn->ssl); ++ #else ++ int ret = 0; ++ while (conn->ssl.MBEDTLS_PRIVATE(state) != MBEDTLS_SSL_HANDSHAKE_OVER) { ++ ret = mbedtls_ssl_handshake_step(&conn->ssl); ++ if (ret != 0) ++ break; ++ } ++ #endif ++ ++ #ifdef TLS_MBEDTLS_SESSION_TICKETS ++ mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, ++ tls_mbedtls_ssl_ticket_write, ++ tls_mbedtls_ssl_ticket_parse, ++ NULL); ++ #endif ++ ++ switch (ret) { ++ case 0: ++ conn->established = 1; ++ if (conn->push_buf == NULL) ++ /* Need to return something to get final TLS ACK. */ ++ conn->push_buf = wpabuf_alloc(0); ++ ++ if (appl_data /*&& conn->pull_buf && wpabuf_len(conn->pull_buf)*/) ++ *appl_data = NULL; /* RFE: check for application data */ ++ break; ++ case MBEDTLS_ERR_SSL_WANT_WRITE: ++ case MBEDTLS_ERR_SSL_WANT_READ: ++ case MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS: ++ case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: ++ if (tls_ctx_global.tls_conf /*(is server)*/ ++ && conn->established && conn->push_buf == NULL) ++ /* Need to return something to trigger completion of EAP-TLS. */ ++ conn->push_buf = wpabuf_alloc(0); ++ break; ++ default: ++ ++conn->failed; ++ switch (ret) { ++ case MBEDTLS_ERR_SSL_CLIENT_RECONNECT: ++ case MBEDTLS_ERR_NET_CONN_RESET: ++ case MBEDTLS_ERR_NET_SEND_FAILED: ++ ++conn->write_alerts; ++ break; ++ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ ++ case MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE: ++ #else ++ case MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE: ++ #endif ++ tls_mbedtls_suiteb_handshake_alert(conn); ++ /* fall through */ ++ case MBEDTLS_ERR_NET_RECV_FAILED: ++ case MBEDTLS_ERR_SSL_CONN_EOF: ++ case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: ++ case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE: ++ ++conn->read_alerts; ++ break; ++ default: ++ break; ++ } ++ ++ ilog(ret, "mbedtls_ssl_handshake"); ++ break; ++ } ++ ++ struct wpabuf *out_data = conn->push_buf; ++ conn->push_buf = NULL; ++ return out_data; ++} ++ ++ ++struct wpabuf * tls_connection_server_handshake(void *tls_ctx, ++ struct tls_connection *conn, ++ const struct wpabuf *in_data, ++ struct wpabuf **appl_data) ++{ ++ conn->is_server = 1; ++ return tls_connection_handshake(tls_ctx, conn, in_data, appl_data); ++} ++ ++ ++struct wpabuf * tls_connection_encrypt(void *tls_ctx, ++ struct tls_connection *conn, ++ const struct wpabuf *in_data) ++{ ++ int res = mbedtls_ssl_write(&conn->ssl, ++ wpabuf_head_u8(in_data), wpabuf_len(in_data)); ++ if (res < 0) { ++ elog(res, "mbedtls_ssl_write"); ++ return NULL; ++ } ++ ++ struct wpabuf *buf = conn->push_buf; ++ conn->push_buf = NULL; ++ return buf; ++} ++ ++ ++struct wpabuf * tls_connection_decrypt(void *tls_ctx, ++ struct tls_connection *conn, ++ const struct wpabuf *in_data) ++{ ++ int res; ++ struct wpabuf *out; ++ ++ /*assert(in_data != NULL);*/ ++ if (!tls_pull_buf_append(conn, in_data)) ++ return NULL; ++ ++ #if defined(MBEDTLS_ZLIB_SUPPORT) /* removed in mbedtls 3.x */ ++ /* Add extra buffer space to handle the possibility of decrypted ++ * data being longer than input data due to TLS compression. */ ++ out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); ++ #else /* TLS compression is disabled in mbedtls 3.x */ ++ out = wpabuf_alloc(wpabuf_len(in_data)); ++ #endif ++ if (out == NULL) ++ return NULL; ++ ++ res = mbedtls_ssl_read(&conn->ssl, wpabuf_mhead(out), wpabuf_size(out)); ++ if (res < 0) { ++ #if 1 /*(seems like a different error if wpabuf_len(in_data) == 0)*/ ++ if (res == MBEDTLS_ERR_SSL_WANT_READ) ++ return out; ++ #endif ++ elog(res, "mbedtls_ssl_read"); ++ wpabuf_free(out); ++ return NULL; ++ } ++ wpabuf_put(out, res); ++ ++ return out; ++} ++ ++ ++int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn) ++{ ++ /* XXX: might need to detect if session resumed from TLS session ticket ++ * even if not special session ticket handling for EAP-FAST, EAP-TEAP */ ++ /* (?ssl->handshake->resume during session ticket validation?) */ ++ return conn && conn->resumed; ++} ++ ++ ++#ifdef TLS_MBEDTLS_EAP_FAST ++int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, ++ u8 *ciphers) ++{ ++ /* ciphers is list of TLS_CIPHER_* from hostap/src/crypto/tls.h */ ++ int ids[7]; ++ const int idsz = (int)sizeof(ids); ++ int nids = -1, id; ++ for ( ; *ciphers != TLS_CIPHER_NONE; ++ciphers) { ++ switch (*ciphers) { ++ case TLS_CIPHER_RC4_SHA: ++ #ifdef MBEDTLS_TLS_RSA_WITH_RC4_128_SHA ++ id = MBEDTLS_TLS_RSA_WITH_RC4_128_SHA; ++ break; ++ #else ++ continue; /*(not supported in mbedtls 3.x; ignore)*/ ++ #endif ++ case TLS_CIPHER_AES128_SHA: ++ id = MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA; ++ break; ++ case TLS_CIPHER_RSA_DHE_AES128_SHA: ++ id = MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA; ++ break; ++ case TLS_CIPHER_ANON_DH_AES128_SHA: ++ continue; /*(not supported in mbedtls; ignore)*/ ++ case TLS_CIPHER_RSA_DHE_AES256_SHA: ++ id = MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA; ++ break; ++ case TLS_CIPHER_AES256_SHA: ++ id = MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA; ++ break; ++ default: ++ return -1; /* should not happen */ ++ } ++ if (++nids == idsz) ++ return -1; /* should not happen */ ++ ids[nids] = id; ++ } ++ if (nids < 0) ++ return 0; /* nothing to do */ ++ if (++nids == idsz) ++ return -1; /* should not happen */ ++ ids[nids] = 0; /* terminate list */ ++ ++nids; ++ ++ return tls_mbedtls_set_ciphersuites(conn->tls_conf, ids, nids) ? 0 : -1; ++} ++#endif ++ ++ ++int tls_get_version(void *ssl_ctx, struct tls_connection *conn, ++ char *buf, size_t buflen) ++{ ++ if (conn == NULL) ++ return -1; ++ os_strlcpy(buf, mbedtls_ssl_get_version(&conn->ssl), buflen); ++ return buf[0] != 'u' ? 0 : -1; /*(-1 if "unknown")*/ ++} ++ ++ ++#ifdef TLS_MBEDTLS_EAP_TEAP ++u16 tls_connection_get_cipher_suite(struct tls_connection *conn) ++{ ++ if (conn == NULL) ++ return 0; ++ return (u16)mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl); ++} ++#endif ++ ++ ++int tls_get_cipher(void *tls_ctx, struct tls_connection *conn, ++ char *buf, size_t buflen) ++{ ++ if (conn == NULL) ++ return -1; ++ const int id = mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl); ++ return tls_mbedtls_translate_ciphername(id, buf, buflen) ? 0 : -1; ++} ++ ++ ++#ifdef TLS_MBEDTLS_SESSION_TICKETS ++ ++int tls_connection_enable_workaround(void *tls_ctx, ++ struct tls_connection *conn) ++{ ++ /* (see comment in src/eap_peer/eap_fast.c:eap_fast_init()) */ ++ /* XXX: is there a relevant setting for this in mbed TLS? */ ++ /* (do we even care that much about older CBC ciphers?) */ ++ return 0; ++} ++ ++ ++int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn, ++ int ext_type, const u8 *data, ++ size_t data_len) ++{ ++ /* (EAP-FAST and EAP-TEAP) */ ++ if (ext_type == MBEDTLS_TLS_EXT_SESSION_TICKET) /*(ext_type == 35)*/ ++ return tls_mbedtls_clienthello_session_ticket_prep(conn, data, ++ data_len); ++ ++ return -1; ++} ++ ++#endif /* TLS_MBEDTLS_SESSION_TICKETS */ ++ ++ ++int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn) ++{ ++ return conn ? conn->failed : -1; ++} ++ ++ ++int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn) ++{ ++ return conn ? conn->read_alerts : -1; ++} ++ ++ ++int tls_connection_get_write_alerts(void *tls_ctx, ++ struct tls_connection *conn) ++{ ++ return conn ? conn->write_alerts : -1; ++} ++ ++ ++#ifdef TLS_MBEDTLS_SESSION_TICKETS ++int tls_connection_set_session_ticket_cb( ++ void *tls_ctx, struct tls_connection *conn, ++ tls_session_ticket_cb cb, void *ctx) ++{ ++ if (!(conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET)) { ++ /* (EAP-FAST and EAP-TEAP) */ ++ conn->session_ticket_cb = cb; ++ conn->session_ticket_cb_ctx = ctx; ++ return 0; ++ } ++ return -1; ++} ++#endif ++ ++ ++int tls_get_library_version(char *buf, size_t buf_len) ++{ ++ #ifndef MBEDTLS_VERSION_C ++ const char * const ver = "n/a"; ++ #else ++ char ver[9]; ++ mbedtls_version_get_string(ver); ++ #endif ++ return os_snprintf(buf, buf_len, ++ "mbed TLS build=" MBEDTLS_VERSION_STRING " run=%s", ver); ++} ++ ++ ++void tls_connection_set_success_data(struct tls_connection *conn, ++ struct wpabuf *data) ++{ ++ wpabuf_free(conn->success_data); ++ conn->success_data = data; ++} ++ ++ ++void tls_connection_set_success_data_resumed(struct tls_connection *conn) ++{ ++} ++ ++ ++const struct wpabuf * ++tls_connection_get_success_data(struct tls_connection *conn) ++{ ++ return conn->success_data; ++} ++ ++ ++void tls_connection_remove_session(struct tls_connection *conn) ++{ ++} ++ ++ ++#ifdef TLS_MBEDTLS_EAP_TEAP ++int tls_get_tls_unique(struct tls_connection *conn, u8 *buf, size_t max_len) ++{ ++ #if defined(MBEDTLS_SSL_RENEGOTIATION) /* XXX: renegotiation or resumption? */ ++ /* data from TLS handshake Finished message */ ++ size_t verify_len = conn->ssl.MBEDTLS_PRIVATE(verify_data_len); ++ char *verify_data = (conn->is_server ^ conn->resumed) ++ ? conn->ssl.MBEDTLS_PRIVATE(peer_verify_data) ++ : conn->ssl.MBEDTLS_PRIVATE(own_verify_data); ++ if (verify_len && verify_len <= max_len) { ++ os_memcpy(buf, verify_data, verify_len); ++ return (int)verify_len; ++ } ++ #endif ++ return -1; ++} ++#endif ++ ++ ++__attribute_noinline__ ++static void tls_mbedtls_set_peer_subject(struct tls_connection *conn, const mbedtls_x509_crt *crt) ++{ ++ if (conn->peer_subject) ++ return; ++ char buf[MBEDTLS_X509_MAX_DN_NAME_SIZE*2]; ++ int buflen = mbedtls_x509_dn_gets(buf, sizeof(buf), &crt->subject); ++ if (buflen >= 0 && (conn->peer_subject = os_malloc((size_t)buflen+1))) ++ os_memcpy(conn->peer_subject, buf, (size_t)buflen+1); ++} ++ ++ ++#ifdef TLS_MBEDTLS_EAP_TEAP ++const char * tls_connection_get_peer_subject(struct tls_connection *conn) ++{ ++ if (!conn) ++ return NULL; ++ if (!conn->peer_subject) { /*(if not set during cert verify)*/ ++ const mbedtls_x509_crt *peer_cert = ++ mbedtls_ssl_get_peer_cert(&conn->ssl); ++ if (peer_cert) ++ tls_mbedtls_set_peer_subject(conn, peer_cert); ++ } ++ return conn->peer_subject; ++} ++#endif ++ ++ ++#ifdef TLS_MBEDTLS_EAP_TEAP ++bool tls_connection_get_own_cert_used(struct tls_connection *conn) ++{ ++ /* XXX: availability of cert does not necessary mean that client ++ * received certificate request from server and then sent cert. ++ * ? step handshake in tls_connection_handshake() looking for ++ * MBEDTLS_SSL_CERTIFICATE_REQUEST ? */ ++ const struct tls_conf * const tls_conf = conn->tls_conf; ++ return (tls_conf->has_client_cert && tls_conf->has_private_key); ++} ++#endif ++ ++ ++#if defined(CONFIG_FIPS) ++#define TLS_MBEDTLS_CONFIG_FIPS ++#endif ++ ++#if defined(CONFIG_SHA256) ++#define TLS_MBEDTLS_TLS_PRF_SHA256 ++#endif ++ ++#if defined(CONFIG_SHA384) ++#define TLS_MBEDTLS_TLS_PRF_SHA384 ++#endif ++ ++ ++#ifndef TLS_MBEDTLS_CONFIG_FIPS ++#if defined(CONFIG_MODULE_TESTS) ++/* unused with CONFIG_TLS=mbedtls except in crypto_module_tests.c */ ++#if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ \ ++ && MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ ++/* sha1-tlsprf.c */ ++#include "sha1.h" ++int tls_prf_sha1_md5(const u8 *secret, size_t secret_len, const char *label, ++ const u8 *seed, size_t seed_len, u8 *out, size_t outlen) ++{ ++ return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_TLS1, ++ secret, secret_len, label, ++ seed, seed_len, out, outlen) ? -1 : 0; ++} ++#else ++#include "sha1-tlsprf.c" /* pull in hostap local implementation */ ++#endif ++#endif ++#endif ++ ++#ifdef TLS_MBEDTLS_TLS_PRF_SHA256 ++/* sha256-tlsprf.c */ ++#if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ ++#include "sha256.h" ++int tls_prf_sha256(const u8 *secret, size_t secret_len, const char *label, ++ const u8 *seed, size_t seed_len, u8 *out, size_t outlen) ++{ ++ return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_SHA256, ++ secret, secret_len, label, ++ seed, seed_len, out, outlen) ? -1 : 0; ++} ++#else ++#include "sha256-tlsprf.c" /* pull in hostap local implementation */ ++#endif ++#endif ++ ++#ifdef TLS_MBEDTLS_TLS_PRF_SHA384 ++/* sha384-tlsprf.c */ ++#if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ ++#include "sha384.h" ++int tls_prf_sha384(const u8 *secret, size_t secret_len, const char *label, ++ const u8 *seed, size_t seed_len, u8 *out, size_t outlen) ++{ ++ return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_SHA384, ++ secret, secret_len, label, ++ seed, seed_len, out, outlen) ? -1 : 0; ++} ++#else ++#include "sha384-tlsprf.c" /* pull in hostap local implementation */ ++#endif ++#endif ++ ++ ++#if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */ ++#define mbedtls_x509_crt_has_ext_type(crt, ext_type) \ ++ ((crt)->MBEDTLS_PRIVATE(ext_types) & (ext_type)) ++#endif ++ ++struct mlist { const char *p; size_t n; }; ++ ++ ++static int ++tls_mbedtls_match_altsubject(mbedtls_x509_crt *crt, const char *match) ++{ ++ /* RFE: this could be pre-parsed into structured data at config time */ ++ struct mlist list[256]; /*(much larger than expected)*/ ++ int nlist = 0; ++ if ( os_strncmp(match, "EMAIL:", 6) != 0 ++ && os_strncmp(match, "DNS:", 4) != 0 ++ && os_strncmp(match, "URI:", 4) != 0 ) { ++ wpa_printf(MSG_INFO, "MTLS: Invalid altSubjectName match '%s'", match); ++ return 0; ++ } ++ for (const char *s = match, *tok; *s; s = tok ? tok+1 : "") { ++ do { } while ((tok = os_strchr(s, ';')) ++ && os_strncmp(tok+1, "EMAIL:", 6) != 0 ++ && os_strncmp(tok+1, "DNS:", 4) != 0 ++ && os_strncmp(tok+1, "URI:", 4) != 0); ++ list[nlist].p = s; ++ list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s); ++ if (list[nlist].n && ++nlist == sizeof(list)/sizeof(*list)) { ++ wpa_printf(MSG_INFO, "MTLS: excessive altSubjectName match '%s'", ++ match); ++ break; /* truncate huge list and continue */ ++ } ++ } ++ ++ if (!mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME)) ++ return 0; ++ ++ const mbedtls_x509_sequence *cur = &crt->subject_alt_names; ++ for (; cur != NULL; cur = cur->next) { ++ const unsigned char san_type = (unsigned char)cur->buf.tag ++ & MBEDTLS_ASN1_TAG_VALUE_MASK; ++ char t; ++ size_t step = 4; ++ switch (san_type) { /* "EMAIL:" or "DNS:" or "URI:" */ ++ case MBEDTLS_X509_SAN_RFC822_NAME: step = 6; t = 'E'; break; ++ case MBEDTLS_X509_SAN_DNS_NAME: t = 'D'; break; ++ case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: t = 'U'; break; ++ default: continue; ++ } ++ ++ for (int i = 0; i < nlist; ++i) { ++ /* step over "EMAIL:" or "DNS:" or "URI:" in list[i].p */ ++ /* Note: v is not '\0'-terminated, but is a known length vlen, ++ * so okay to pass to os_strncasecmp() even though not z-string */ ++ if (cur->buf.len == list[i].n - step && t == *list[i].p ++ && 0 == os_strncasecmp((char *)cur->buf.p, ++ list[i].p+step, cur->buf.len)) { ++ return 1; /* match */ ++ } ++ } ++ } ++ return 0; /* no match */ ++} ++ ++ ++static int ++tls_mbedtls_match_suffix(const char *v, size_t vlen, ++ const struct mlist *list, int nlist, int full) ++{ ++ /* Note: v is not '\0'-terminated, but is a known length vlen, ++ * so okay to pass to os_strncasecmp() even though not z-string */ ++ for (int i = 0; i < nlist; ++i) { ++ size_t n = list[i].n; ++ if ((n == vlen || (n < vlen && v[vlen-n-1] == '.' && !full)) ++ && 0 == os_strncasecmp(v+vlen-n, list[i].p, n)) ++ return 1; /* match */ ++ } ++ return 0; /* no match */ ++} ++ ++ ++static int ++tls_mbedtls_match_suffixes(mbedtls_x509_crt *crt, const char *match, int full) ++{ ++ /* RFE: this could be pre-parsed into structured data at config time */ ++ struct mlist list[256]; /*(much larger than expected)*/ ++ int nlist = 0; ++ for (const char *s = match, *tok; *s; s = tok ? tok+1 : "") { ++ tok = os_strchr(s, ';'); ++ list[nlist].p = s; ++ list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s); ++ if (list[nlist].n && ++nlist == sizeof(list)/sizeof(*list)) { ++ wpa_printf(MSG_INFO, "MTLS: excessive suffix match '%s'", match); ++ break; /* truncate huge list and continue */ ++ } ++ } ++ ++ /* check subjectAltNames */ ++ if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME)) { ++ const mbedtls_x509_sequence *cur = &crt->subject_alt_names; ++ for (; cur != NULL; cur = cur->next) { ++ const unsigned char san_type = (unsigned char)cur->buf.tag ++ & MBEDTLS_ASN1_TAG_VALUE_MASK; ++ if (san_type == MBEDTLS_X509_SAN_DNS_NAME ++ && tls_mbedtls_match_suffix((char *)cur->buf.p, ++ cur->buf.len, ++ list, nlist, full)) { ++ return 1; /* match */ ++ } ++ } ++ } ++ ++ /* check subject CN */ ++ const mbedtls_x509_name *name = &crt->subject; ++ for (; name != NULL; name = name->next) { ++ if (name->oid.p && MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid) == 0) ++ break; ++ } ++ if (name && tls_mbedtls_match_suffix((char *)name->val.p, name->val.len, ++ list, nlist, full)) { ++ return 1; /* match */ ++ } ++ ++ return 0; /* no match */ ++} ++ ++ ++static int ++tls_mbedtls_match_dn_field(mbedtls_x509_crt *crt, const char *match) ++{ ++ /* RFE: this could be pre-parsed into structured data at config time */ ++ struct mlistoid { const char *p; size_t n; ++ const char *oid; size_t olen; ++ int prefix; }; ++ struct mlistoid list[32]; /*(much larger than expected)*/ ++ int nlist = 0; ++ for (const char *s = match, *tok, *e; *s; s = tok ? tok+1 : "") { ++ tok = os_strchr(s, '/'); ++ list[nlist].oid = NULL; ++ list[nlist].olen = 0; ++ list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s); ++ e = memchr(s, '=', list[nlist].n); ++ if (e == NULL) { ++ if (list[nlist].n == 0) ++ continue; /* skip consecutive, repeated '/' */ ++ if (list[nlist].n == 1 && *s == '*') { ++ /* special-case "*" to match any OID and value */ ++ s = e = "=*"; ++ list[nlist].n = 2; ++ list[nlist].oid = ""; ++ } ++ else { ++ wpa_printf(MSG_INFO, ++ "MTLS: invalid check_cert_subject '%s' missing '='", ++ match); ++ return 0; ++ } ++ } ++ switch (e - s) { ++ case 1: ++ if (*s == 'C') { ++ list[nlist].oid = MBEDTLS_OID_AT_COUNTRY; ++ list[nlist].olen = sizeof(MBEDTLS_OID_AT_COUNTRY)-1; ++ } ++ else if (*s == 'L') { ++ list[nlist].oid = MBEDTLS_OID_AT_LOCALITY; ++ list[nlist].olen = sizeof(MBEDTLS_OID_AT_LOCALITY)-1; ++ } ++ else if (*s == 'O') { ++ list[nlist].oid = MBEDTLS_OID_AT_ORGANIZATION; ++ list[nlist].olen = sizeof(MBEDTLS_OID_AT_ORGANIZATION)-1; ++ } ++ break; ++ case 2: ++ if (s[0] == 'C' && s[1] == 'N') { ++ list[nlist].oid = MBEDTLS_OID_AT_CN; ++ list[nlist].olen = sizeof(MBEDTLS_OID_AT_CN)-1; ++ } ++ else if (s[0] == 'S' && s[1] == 'T') { ++ list[nlist].oid = MBEDTLS_OID_AT_STATE; ++ list[nlist].olen = sizeof(MBEDTLS_OID_AT_STATE)-1; ++ } ++ else if (s[0] == 'O' && s[1] == 'U') { ++ list[nlist].oid = MBEDTLS_OID_AT_ORG_UNIT; ++ list[nlist].olen = sizeof(MBEDTLS_OID_AT_ORG_UNIT)-1; ++ } ++ break; ++ case 12: ++ if (os_memcmp(s, "emailAddress", 12) == 0) { ++ list[nlist].oid = MBEDTLS_OID_PKCS9_EMAIL; ++ list[nlist].olen = sizeof(MBEDTLS_OID_PKCS9_EMAIL)-1; ++ } ++ break; ++ default: ++ break; ++ } ++ if (list[nlist].oid == NULL) { ++ wpa_printf(MSG_INFO, ++ "MTLS: Unknown field in check_cert_subject '%s'", ++ match); ++ return 0; ++ } ++ list[nlist].n -= (size_t)(++e - s); ++ list[nlist].p = e; ++ if (list[nlist].n && e[list[nlist].n-1] == '*') { ++ --list[nlist].n; ++ list[nlist].prefix = 1; ++ } ++ /*(could easily add support for suffix matches if value begins with '*', ++ * but suffix match is not currently supported by other TLS modules)*/ ++ ++ if (list[nlist].n && ++nlist == sizeof(list)/sizeof(*list)) { ++ wpa_printf(MSG_INFO, ++ "MTLS: excessive check_cert_subject match '%s'", ++ match); ++ break; /* truncate huge list and continue */ ++ } ++ } ++ ++ /* each component in match string must match cert Subject in order listed ++ * The behavior below preserves ordering but is slightly different than ++ * the grossly inefficient contortions implemented in tls_openssl.c */ ++ const mbedtls_x509_name *name = &crt->subject; ++ for (int i = 0; i < nlist; ++i) { ++ int found = 0; ++ for (; name != NULL && !found; name = name->next) { ++ if (!name->oid.p) ++ continue; ++ /* special-case "*" to match any OID and value */ ++ if (list[i].olen == 0) { ++ found = 1; ++ continue; ++ } ++ /* perform equalent of !MBEDTLS_OID_CMP() with oid ptr and len */ ++ if (list[i].olen != name->oid.len ++ || os_memcmp(list[i].oid, name->oid.p, name->oid.len) != 0) ++ continue; ++ /* Note: v is not '\0'-terminated, but is a known length vlen, ++ * so okay to pass to os_strncasecmp() even though not z-string */ ++ if ((list[i].prefix ++ ? list[i].n <= name->val.len /* prefix match */ ++ : list[i].n == name->val.len) /* full match */ ++ && 0 == os_strncasecmp((char *)name->val.p, ++ list[i].p, list[i].n)) { ++ found = 1; ++ continue; ++ } ++ } ++ if (!found) ++ return 0; /* no match */ ++ } ++ return 1; /* match */ ++} ++ ++ ++__attribute_cold__ ++static void ++tls_mbedtls_verify_fail_event (mbedtls_x509_crt *crt, int depth, ++ const char *errmsg, enum tls_fail_reason reason) ++{ ++ struct tls_config *init_conf = &tls_ctx_global.init_conf; ++ if (init_conf->event_cb == NULL) ++ return; ++ ++ struct wpabuf *certbuf = wpabuf_alloc_copy(crt->raw.p, crt->raw.len); ++ char subject[MBEDTLS_X509_MAX_DN_NAME_SIZE*2]; ++ if (mbedtls_x509_dn_gets(subject, sizeof(subject), &crt->subject) < 0) ++ subject[0] = '\0'; ++ union tls_event_data ev; ++ os_memset(&ev, 0, sizeof(ev)); ++ ev.cert_fail.reason = reason; ++ ev.cert_fail.depth = depth; ++ ev.cert_fail.subject = subject; ++ ev.cert_fail.reason_txt = errmsg; ++ ev.cert_fail.cert = certbuf; ++ ++ init_conf->event_cb(init_conf->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev); ++ ++ wpabuf_free(certbuf); ++} ++ ++ ++__attribute_noinline__ ++static void ++tls_mbedtls_verify_cert_event (struct tls_connection *conn, ++ mbedtls_x509_crt *crt, int depth) ++{ ++ struct tls_config *init_conf = &tls_ctx_global.init_conf; ++ if (init_conf->event_cb == NULL) ++ return; ++ ++ struct wpabuf *certbuf = NULL; ++ union tls_event_data ev; ++ os_memset(&ev, 0, sizeof(ev)); ++ ++ #ifdef MBEDTLS_SHA256_C ++ u8 hash[SHA256_DIGEST_LENGTH]; ++ const u8 *addr[] = { (u8 *)crt->raw.p }; ++ if (sha256_vector(1, addr, &crt->raw.len, hash) == 0) { ++ ev.peer_cert.hash = hash; ++ ev.peer_cert.hash_len = sizeof(hash); ++ } ++ #endif ++ ev.peer_cert.depth = depth; ++ char subject[MBEDTLS_X509_MAX_DN_NAME_SIZE*2]; ++ if (depth == 0) ++ ev.peer_cert.subject = conn->peer_subject; ++ if (ev.peer_cert.subject == NULL) { ++ ev.peer_cert.subject = subject; ++ if (mbedtls_x509_dn_gets(subject, sizeof(subject), &crt->subject) < 0) ++ subject[0] = '\0'; ++ } ++ ++ char serial_num[128+1]; ++ ev.peer_cert.serial_num = ++ tls_mbedtls_peer_serial_num(crt, serial_num, sizeof(serial_num)); ++ ++ const mbedtls_x509_sequence *cur; ++ ++ cur = NULL; ++ if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME)) ++ cur = &crt->subject_alt_names; ++ for (; cur != NULL; cur = cur->next) { ++ const unsigned char san_type = (unsigned char)cur->buf.tag ++ & MBEDTLS_ASN1_TAG_VALUE_MASK; ++ size_t prelen = 4; ++ const char *pre; ++ switch (san_type) { ++ case MBEDTLS_X509_SAN_RFC822_NAME: prelen = 6; pre = "EMAIL:";break; ++ case MBEDTLS_X509_SAN_DNS_NAME: pre = "DNS:"; break; ++ case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: pre = "URI:"; break; ++ default: continue; ++ } ++ ++ char *pos = os_malloc(prelen + cur->buf.len + 1); ++ if (pos == NULL) ++ break; ++ ev.peer_cert.altsubject[ev.peer_cert.num_altsubject] = pos; ++ os_memcpy(pos, pre, prelen); ++ /* data should be properly backslash-escaped if needed, ++ * so code below does not re-escape, but does replace CTLs */ ++ /*os_memcpy(pos+prelen, cur->buf.p, cur->buf.len);*/ ++ /*pos[prelen+cur->buf.len] = '\0';*/ ++ pos += prelen; ++ for (size_t i = 0; i < cur->buf.len; ++i) { ++ unsigned char c = cur->buf.p[i]; ++ *pos++ = (c >= 32 && c != 127) ? c : '?'; ++ } ++ *pos = '\0'; ++ ++ if (++ev.peer_cert.num_altsubject == TLS_MAX_ALT_SUBJECT) ++ break; ++ } ++ ++ cur = NULL; ++ if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_CERTIFICATE_POLICIES)) ++ cur = &crt->certificate_policies; ++ for (; cur != NULL; cur = cur->next) { ++ if (cur->buf.len != 11) /* len of OID_TOD_STRICT or OID_TOD_TOFU */ ++ continue; ++ /* TOD-STRICT "1.3.6.1.4.1.40808.1.3.1" */ ++ /* TOD-TOFU "1.3.6.1.4.1.40808.1.3.2" */ ++ #define OID_TOD_STRICT "\x2b\x06\x01\x04\x01\x82\xbe\x68\x01\x03\x01" ++ #define OID_TOD_TOFU "\x2b\x06\x01\x04\x01\x82\xbe\x68\x01\x03\x02" ++ if (os_memcmp(cur->buf.p, ++ OID_TOD_STRICT, sizeof(OID_TOD_STRICT)-1) == 0) { ++ ev.peer_cert.tod = 1; /* TOD-STRICT */ ++ break; ++ } ++ if (os_memcmp(cur->buf.p, ++ OID_TOD_TOFU, sizeof(OID_TOD_TOFU)-1) == 0) { ++ ev.peer_cert.tod = 2; /* TOD-TOFU */ ++ break; ++ } ++ } ++ ++ struct tls_conf *tls_conf = conn->tls_conf; ++ if (tls_conf->ca_cert_probe || (tls_conf->flags & TLS_CONN_EXT_CERT_CHECK) ++ || init_conf->cert_in_cb) { ++ certbuf = wpabuf_alloc_copy(crt->raw.p, crt->raw.len); ++ ev.peer_cert.cert = certbuf; ++ } ++ ++ init_conf->event_cb(init_conf->cb_ctx, TLS_PEER_CERTIFICATE, &ev); ++ ++ wpabuf_free(certbuf); ++ char **altsubject; ++ *(const char ***)&altsubject = ev.peer_cert.altsubject; ++ for (size_t i = 0; i < ev.peer_cert.num_altsubject; ++i) ++ os_free(altsubject[i]); ++} ++ ++ ++static int ++tls_mbedtls_verify_cb (void *arg, mbedtls_x509_crt *crt, int depth, uint32_t *flags) ++{ ++ /* XXX: N.B. verify code not carefully tested besides hwsim tests ++ * ++ * RFE: mbedtls_x509_crt_verify_info() and enhance log trace messages ++ * RFE: review and add support for additional TLS_CONN_* flags ++ * not handling OCSP (not available in mbedtls) ++ * ... */ ++ ++ struct tls_connection *conn = (struct tls_connection *)arg; ++ struct tls_conf *tls_conf = conn->tls_conf; ++ uint32_t flags_in = *flags; ++ ++ if (depth > 8) { /*(depth 8 picked as arbitrary limit)*/ ++ emsg(MSG_WARNING, "client cert chain too long"); ++ *flags |= MBEDTLS_X509_BADCERT_OTHER; /* cert chain too long */ ++ tls_mbedtls_verify_fail_event(crt, depth, ++ "client cert chain too long", ++ TLS_FAIL_BAD_CERTIFICATE); ++ } ++ else if (tls_conf->verify_depth0_only) { ++ if (depth > 0) ++ *flags = 0; ++ else { ++ #ifdef MBEDTLS_SHA256_C ++ u8 hash[SHA256_DIGEST_LENGTH]; ++ const u8 *addr[] = { (u8 *)crt->raw.p }; ++ if (sha256_vector(1, addr, &crt->raw.len, hash) < 0 ++ || os_memcmp(tls_conf->ca_cert_hash, hash, sizeof(hash)) != 0) { ++ *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; ++ tls_mbedtls_verify_fail_event(crt, depth, ++ "cert hash mismatch", ++ TLS_FAIL_UNTRUSTED); ++ } ++ else /* hash matches; ignore other issues *except* if revoked)*/ ++ *flags &= MBEDTLS_X509_BADCERT_REVOKED; ++ #endif ++ } ++ } ++ else if (depth == 0) { ++ if (!conn->peer_subject) ++ tls_mbedtls_set_peer_subject(conn, crt); ++ /*(use same labels to tls_mbedtls_verify_fail_event() as used in ++ * other TLS modules so that hwsim tests find exact string match)*/ ++ if (!conn->peer_subject) { /* error copying subject string */ ++ *flags |= MBEDTLS_X509_BADCERT_OTHER; ++ tls_mbedtls_verify_fail_event(crt, depth, ++ "internal error", ++ TLS_FAIL_UNSPECIFIED); ++ } ++ /*(use os_strstr() for subject match as is done in tls_mbedtls.c ++ * to follow the same behavior, even though a suffix match would ++ * make more sense. Also, note that strstr match does not ++ * normalize whitespace (between components) for comparison)*/ ++ else if (tls_conf->subject_match ++ && os_strstr(conn->peer_subject, ++ tls_conf->subject_match) == NULL) { ++ wpa_printf(MSG_WARNING, ++ "MTLS: Subject '%s' did not match with '%s'", ++ conn->peer_subject, tls_conf->subject_match); ++ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; ++ tls_mbedtls_verify_fail_event(crt, depth, ++ "Subject mismatch", ++ TLS_FAIL_SUBJECT_MISMATCH); ++ } ++ if (tls_conf->altsubject_match ++ && !tls_mbedtls_match_altsubject(crt, tls_conf->altsubject_match)) { ++ wpa_printf(MSG_WARNING, ++ "MTLS: altSubjectName match '%s' not found", ++ tls_conf->altsubject_match); ++ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; ++ tls_mbedtls_verify_fail_event(crt, depth, ++ "AltSubject mismatch", ++ TLS_FAIL_ALTSUBJECT_MISMATCH); ++ } ++ if (tls_conf->suffix_match ++ && !tls_mbedtls_match_suffixes(crt, tls_conf->suffix_match, 0)) { ++ wpa_printf(MSG_WARNING, ++ "MTLS: Domain suffix match '%s' not found", ++ tls_conf->suffix_match); ++ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; ++ tls_mbedtls_verify_fail_event(crt, depth, ++ "Domain suffix mismatch", ++ TLS_FAIL_DOMAIN_SUFFIX_MISMATCH); ++ } ++ if (tls_conf->domain_match ++ && !tls_mbedtls_match_suffixes(crt, tls_conf->domain_match, 1)) { ++ wpa_printf(MSG_WARNING, ++ "MTLS: Domain match '%s' not found", ++ tls_conf->domain_match); ++ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; ++ tls_mbedtls_verify_fail_event(crt, depth, ++ "Domain mismatch", ++ TLS_FAIL_DOMAIN_MISMATCH); ++ } ++ if (tls_conf->check_cert_subject ++ && !tls_mbedtls_match_dn_field(crt, tls_conf->check_cert_subject)) { ++ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; ++ tls_mbedtls_verify_fail_event(crt, depth, ++ "Distinguished Name", ++ TLS_FAIL_DN_MISMATCH); ++ } ++ if (tls_conf->flags & TLS_CONN_SUITEB) { ++ /* check RSA modulus size (public key bitlen) */ ++ const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type(&crt->pk); ++ if ((pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS) ++ && mbedtls_pk_get_bitlen(&crt->pk) < 3072) { ++ /* hwsim suite_b RSA tests expect 3072 ++ * suite_b_192_rsa_ecdhe_radius_rsa2048_client ++ * suite_b_192_rsa_dhe_radius_rsa2048_client */ ++ *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; ++ tls_mbedtls_verify_fail_event(crt, depth, ++ "Insufficient RSA modulus size", ++ TLS_FAIL_INSUFFICIENT_KEY_LEN); ++ } ++ } ++ if (tls_conf->check_crl && tls_conf->crl == NULL) { ++ /* see tests/hwsim test_ap_eap.py ap_wpa2_eap_tls_check_crl */ ++ emsg(MSG_WARNING, "check_crl set but no CRL loaded; reject all?"); ++ *flags |= MBEDTLS_X509_BADCERT_OTHER; ++ tls_mbedtls_verify_fail_event(crt, depth, ++ "check_crl set but no CRL loaded; " ++ "reject all?", ++ TLS_FAIL_BAD_CERTIFICATE); ++ } ++ } ++ else { ++ if (tls_conf->check_crl != 2) /* 2 == verify CRLs for all certs */ ++ *flags &= ~MBEDTLS_X509_BADCERT_REVOKED; ++ } ++ ++ if (!tls_conf->check_crl_strict) { ++ *flags &= ~MBEDTLS_X509_BADCRL_EXPIRED; ++ *flags &= ~MBEDTLS_X509_BADCRL_FUTURE; ++ } ++ ++ if (tls_conf->flags & TLS_CONN_DISABLE_TIME_CHECKS) { ++ *flags &= ~MBEDTLS_X509_BADCERT_EXPIRED; ++ *flags &= ~MBEDTLS_X509_BADCERT_FUTURE; ++ } ++ ++ tls_mbedtls_verify_cert_event(conn, crt, depth); ++ ++ if (*flags) { ++ if (*flags & (MBEDTLS_X509_BADCERT_NOT_TRUSTED ++ |MBEDTLS_X509_BADCERT_CN_MISMATCH ++ |MBEDTLS_X509_BADCERT_REVOKED)) { ++ emsg(MSG_WARNING, "client cert not trusted"); ++ } ++ /* report event if flags set but no additional flags set above */ ++ /* (could translate flags to more detailed TLS_FAIL_* if needed) */ ++ if (!(*flags & ~flags_in)) { ++ enum tls_fail_reason reason = TLS_FAIL_UNSPECIFIED; ++ const char *errmsg = "cert verify fail unspecified"; ++ if (*flags & MBEDTLS_X509_BADCERT_NOT_TRUSTED) { ++ reason = TLS_FAIL_UNTRUSTED; ++ errmsg = "certificate not trusted"; ++ } ++ if (*flags & MBEDTLS_X509_BADCERT_REVOKED) { ++ reason = TLS_FAIL_REVOKED; ++ errmsg = "certificate has been revoked"; ++ } ++ if (*flags & MBEDTLS_X509_BADCERT_FUTURE) { ++ reason = TLS_FAIL_NOT_YET_VALID; ++ errmsg = "certificate not yet valid"; ++ } ++ if (*flags & MBEDTLS_X509_BADCERT_EXPIRED) { ++ reason = TLS_FAIL_EXPIRED; ++ errmsg = "certificate has expired"; ++ } ++ if (*flags & MBEDTLS_X509_BADCERT_BAD_MD) { ++ reason = TLS_FAIL_BAD_CERTIFICATE; ++ errmsg = "certificate uses insecure algorithm"; ++ } ++ tls_mbedtls_verify_fail_event(crt, depth, errmsg, reason); ++ } ++ #if 0 ++ /* ??? send (again) cert events for all certs in chain ??? ++ * (should already have been called for greater depths) */ ++ /* tls_openssl.c:tls_verify_cb() sends cert events for all certs ++ * in chain if certificate validation fails, but sends all events ++ * with depth set to 0 (might be a bug) */ ++ if (depth > 0) { ++ int pdepth = depth + 1; ++ for (mbedtls_x509_crt *pcrt; (pcrt = crt->next); ++pdepth) { ++ tls_mbedtls_verify_cert_event(conn, pcrt, pdepth); ++ } ++ } ++ #endif ++ /*(do not preserve subject if verification failed but was optional)*/ ++ if (depth == 0 && conn->peer_subject) { ++ os_free(conn->peer_subject); ++ conn->peer_subject = NULL; ++ } ++ } ++ else if (depth == 0) { ++ struct tls_config *init_conf = &tls_ctx_global.init_conf; ++ if (tls_conf->ca_cert_probe) { ++ /* reject server certificate on probe-only run */ ++ *flags |= MBEDTLS_X509_BADCERT_OTHER; ++ tls_mbedtls_verify_fail_event(crt, depth, ++ "server chain probe", ++ TLS_FAIL_SERVER_CHAIN_PROBE); ++ } ++ else if (init_conf->event_cb) { ++ /* ??? send event as soon as depth == 0 is verified ??? ++ * What about rest of chain? ++ * Follows tls_mbedtls.c behavior: */ ++ init_conf->event_cb(init_conf->cb_ctx, ++ TLS_CERT_CHAIN_SUCCESS, NULL); ++ } ++ } ++ ++ return 0; ++} +--- /dev/null ++++ b/tests/build/build-wpa_supplicant-mbedtls.config +@@ -0,0 +1,24 @@ ++CONFIG_TLS=mbedtls ++ ++CONFIG_WPS=y ++CONFIG_EAP_TLS=y ++CONFIG_EAP_MSCHAPV2=y ++ ++CONFIG_EAP_PSK=y ++CONFIG_EAP_GPSK=y ++CONFIG_EAP_AKA=y ++CONFIG_EAP_SIM=y ++CONFIG_EAP_SAKE=y ++CONFIG_EAP_PAX=y ++CONFIG_EAP_FAST=y ++CONFIG_EAP_IKEV2=y ++ ++CONFIG_SAE=y ++CONFIG_FILS=y ++CONFIG_FILS_SK_PFS=y ++CONFIG_OWE=y ++CONFIG_DPP=y ++CONFIG_SUITEB=y ++CONFIG_SUITEB192=y ++ ++CFLAGS += -Werror +--- a/tests/hwsim/example-hostapd.config ++++ b/tests/hwsim/example-hostapd.config +@@ -4,6 +4,7 @@ CONFIG_DRIVER_NONE=y + CONFIG_DRIVER_NL80211=y + CONFIG_RSN_PREAUTH=y + ++#CONFIG_TLS=mbedtls + #CONFIG_TLS=internal + #CONFIG_INTERNAL_LIBTOMMATH=y + #CONFIG_INTERNAL_LIBTOMMATH_FAST=y +@@ -39,6 +40,9 @@ endif + ifeq ($(CONFIG_TLS), wolfssl) + CONFIG_EAP_PWD=y + endif ++ifeq ($(CONFIG_TLS), mbedtls) ++CONFIG_EAP_PWD=y ++endif + CONFIG_EAP_EKE=y + CONFIG_PKCS12=y + CONFIG_RADIUS_SERVER=y +--- a/tests/hwsim/example-wpa_supplicant.config ++++ b/tests/hwsim/example-wpa_supplicant.config +@@ -2,6 +2,7 @@ + + CONFIG_TLS=openssl + #CONFIG_TLS=wolfssl ++#CONFIG_TLS=mbedtls + #CONFIG_TLS=internal + #CONFIG_INTERNAL_LIBTOMMATH=y + #CONFIG_INTERNAL_LIBTOMMATH_FAST=y +@@ -41,6 +42,9 @@ endif + ifeq ($(CONFIG_TLS), wolfssl) + CONFIG_EAP_PWD=y + endif ++ifeq ($(CONFIG_TLS), mbedtls) ++CONFIG_EAP_PWD=y ++endif + + CONFIG_USIM_SIMULATOR=y + CONFIG_SIM_SIMULATOR=y +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -1163,6 +1163,29 @@ endif + CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\" + endif + ++ifeq ($(CONFIG_TLS), mbedtls) ++ifndef CONFIG_CRYPTO ++CONFIG_CRYPTO=mbedtls ++endif ++ifdef TLS_FUNCS ++OBJS += ../src/crypto/tls_mbedtls.o ++LIBS += -lmbedtls -lmbedx509 ++endif ++OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o ++OBJS_p += ../src/crypto/crypto_$(CONFIG_CRYPTO).o ++OBJS_priv += ../src/crypto/crypto_$(CONFIG_CRYPTO).o ++ifdef NEED_FIPS186_2_PRF ++OBJS += ../src/crypto/fips_prf_internal.o ++SHA1OBJS += ../src/crypto/sha1-internal.o ++endif ++ifeq ($(CONFIG_CRYPTO), mbedtls) ++LIBS += -lmbedcrypto ++LIBS_p += -lmbedcrypto ++# XXX: create a config option? ++CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 ++endif ++endif ++ + ifeq ($(CONFIG_TLS), gnutls) + ifndef CONFIG_CRYPTO + # default to libgcrypt +@@ -1355,9 +1378,11 @@ endif + + ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + NEED_INTERNAL_AES_WRAP=y + endif + endif ++endif + ifdef CONFIG_OPENSSL_INTERNAL_AES_WRAP + # Seems to be needed at least with BoringSSL + NEED_INTERNAL_AES_WRAP=y +@@ -1371,9 +1396,11 @@ endif + + ifdef NEED_INTERNAL_AES_WRAP + ifneq ($(CONFIG_TLS), linux) ++ifneq ($(CONFIG_TLS), mbedtls) + AESOBJS += ../src/crypto/aes-unwrap.o + endif + endif ++endif + ifdef NEED_AES_EAX + AESOBJS += ../src/crypto/aes-eax.o + NEED_AES_CTR=y +@@ -1383,35 +1410,45 @@ AESOBJS += ../src/crypto/aes-siv.o + NEED_AES_CTR=y + endif + ifdef NEED_AES_CTR ++ifneq ($(CONFIG_TLS), mbedtls) + AESOBJS += ../src/crypto/aes-ctr.o + endif ++endif + ifdef NEED_AES_ENCBLOCK ++ifneq ($(CONFIG_TLS), mbedtls) + AESOBJS += ../src/crypto/aes-encblock.o + endif ++endif + NEED_AES_ENC=y + ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), linux) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + AESOBJS += ../src/crypto/aes-omac1.o + endif + endif + endif ++endif + ifdef NEED_AES_WRAP + NEED_AES_ENC=y + ifdef NEED_INTERNAL_AES_WRAP ++ifneq ($(CONFIG_TLS), mbedtls) + AESOBJS += ../src/crypto/aes-wrap.o + endif + endif ++endif + ifdef NEED_AES_CBC + NEED_AES_ENC=y + ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), linux) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + AESOBJS += ../src/crypto/aes-cbc.o + endif + endif + endif + endif ++endif + ifdef NEED_AES_ENC + ifdef CONFIG_INTERNAL_AES + AESOBJS += ../src/crypto/aes-internal-enc.o +@@ -1426,12 +1463,16 @@ ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), linux) + ifneq ($(CONFIG_TLS), gnutls) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + SHA1OBJS += ../src/crypto/sha1.o + endif + endif + endif + endif ++endif ++ifneq ($(CONFIG_TLS), mbedtls) + SHA1OBJS += ../src/crypto/sha1-prf.o ++endif + ifdef CONFIG_INTERNAL_SHA1 + SHA1OBJS += ../src/crypto/sha1-internal.o + ifdef NEED_FIPS186_2_PRF +@@ -1443,29 +1484,37 @@ CFLAGS += -DCONFIG_NO_PBKDF2 + else + ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + SHA1OBJS += ../src/crypto/sha1-pbkdf2.o + endif + endif + endif ++endif + ifdef NEED_T_PRF ++ifneq ($(CONFIG_TLS), mbedtls) + SHA1OBJS += ../src/crypto/sha1-tprf.o + endif ++endif + ifdef NEED_TLS_PRF ++ifneq ($(CONFIG_TLS), mbedtls) + SHA1OBJS += ../src/crypto/sha1-tlsprf.o + endif + endif ++endif + + ifndef CONFIG_FIPS + ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), linux) + ifneq ($(CONFIG_TLS), gnutls) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + MD5OBJS += ../src/crypto/md5.o + endif + endif + endif + endif + endif ++endif + ifdef NEED_MD5 + ifdef CONFIG_INTERNAL_MD5 + MD5OBJS += ../src/crypto/md5-internal.o +@@ -1520,12 +1569,17 @@ ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), linux) + ifneq ($(CONFIG_TLS), gnutls) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + SHA256OBJS += ../src/crypto/sha256.o + endif + endif + endif + endif ++endif ++ ++ifneq ($(CONFIG_TLS), mbedtls) + SHA256OBJS += ../src/crypto/sha256-prf.o ++endif + ifdef CONFIG_INTERNAL_SHA256 + SHA256OBJS += ../src/crypto/sha256-internal.o + endif +@@ -1538,50 +1592,68 @@ CFLAGS += -DCONFIG_INTERNAL_SHA512 + SHA256OBJS += ../src/crypto/sha512-internal.o + endif + ifdef NEED_TLS_PRF_SHA256 ++ifneq ($(CONFIG_TLS), mbedtls) + SHA256OBJS += ../src/crypto/sha256-tlsprf.o + endif ++endif + ifdef NEED_TLS_PRF_SHA384 ++ifneq ($(CONFIG_TLS), mbedtls) + SHA256OBJS += ../src/crypto/sha384-tlsprf.o + endif ++endif + ifdef NEED_HMAC_SHA256_KDF + CFLAGS += -DCONFIG_HMAC_SHA256_KDF ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/sha256-kdf.o + endif ++endif + ifdef NEED_HMAC_SHA384_KDF + CFLAGS += -DCONFIG_HMAC_SHA384_KDF ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/sha384-kdf.o + endif ++endif + ifdef NEED_HMAC_SHA512_KDF + CFLAGS += -DCONFIG_HMAC_SHA512_KDF ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/sha512-kdf.o + endif ++endif + OBJS += $(SHA256OBJS) + ifdef NEED_SHA384 + ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), linux) + ifneq ($(CONFIG_TLS), gnutls) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/sha384.o + endif + endif + endif + endif ++endif + CFLAGS += -DCONFIG_SHA384 ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/sha384-prf.o + endif ++endif + ifdef NEED_SHA512 + ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), linux) + ifneq ($(CONFIG_TLS), gnutls) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/sha512.o + endif + endif + endif + endif ++endif + CFLAGS += -DCONFIG_SHA512 ++ifneq ($(CONFIG_TLS), mbedtls) + OBJS += ../src/crypto/sha512-prf.o + endif ++endif + + ifdef NEED_ASN1 + OBJS += ../src/tls/asn1.o +@@ -1756,10 +1828,12 @@ ifdef CONFIG_FIPS + CFLAGS += -DCONFIG_FIPS + ifneq ($(CONFIG_TLS), openssl) + ifneq ($(CONFIG_TLS), wolfssl) ++ifneq ($(CONFIG_TLS), mbedtls) + $(error CONFIG_FIPS=y requires CONFIG_TLS=openssl) + endif + endif + endif ++endif + + OBJS += $(SHA1OBJS) $(DESOBJS) + +--- a/wpa_supplicant/defconfig ++++ b/wpa_supplicant/defconfig +@@ -10,8 +10,8 @@ + # to override previous values of the variables. + + +-# Uncomment following two lines and fix the paths if you have installed OpenSSL +-# or GnuTLS in non-default location ++# Uncomment following two lines and fix the paths if you have installed TLS ++# libraries in a non-default location + #CFLAGS += -I/usr/local/openssl/include + #LIBS += -L/usr/local/openssl/lib + +@@ -20,6 +20,7 @@ + # used to fix build issues on such systems (krb5.h not found). + #CFLAGS += -I/usr/include/kerberos + ++ + # Driver interface for generic Linux wireless extensions + # Note: WEXT is deprecated in the current Linux kernel version and no new + # functionality is added to it. nl80211-based interface is the new +@@ -326,6 +327,7 @@ CONFIG_BACKEND=file + # openssl = OpenSSL (default) + # gnutls = GnuTLS + # internal = Internal TLSv1 implementation (experimental) ++# mbedtls = mbed TLS + # linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) + # none = Empty template + #CONFIG_TLS=openssl diff --git a/feeds/ipq95xx/hostapd/patches/120-mbedtls-fips186_2_prf.patch b/feeds/ipq95xx/hostapd/patches/120-mbedtls-fips186_2_prf.patch new file mode 100644 index 00000000..a4872526 --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/120-mbedtls-fips186_2_prf.patch @@ -0,0 +1,114 @@ +From c8dba4bd750269bcc80fed3d546e2077cb4cdf0e Mon Sep 17 00:00:00 2001 +From: Glenn Strauss +Date: Tue, 19 Jul 2022 20:02:21 -0400 +Subject: [PATCH 2/7] mbedtls: fips186_2_prf() + +Signed-off-by: Glenn Strauss +--- + hostapd/Makefile | 4 --- + src/crypto/crypto_mbedtls.c | 60 +++++++++++++++++++++++++++++++++++++ + wpa_supplicant/Makefile | 4 --- + 3 files changed, 60 insertions(+), 8 deletions(-) + +--- a/hostapd/Makefile ++++ b/hostapd/Makefile +@@ -759,10 +759,6 @@ endif + OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o + HOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o + SOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o +-ifdef NEED_FIPS186_2_PRF +-OBJS += ../src/crypto/fips_prf_internal.o +-SHA1OBJS += ../src/crypto/sha1-internal.o +-endif + ifeq ($(CONFIG_CRYPTO), mbedtls) + ifdef CONFIG_DPP + LIBS += -lmbedx509 +--- a/src/crypto/crypto_mbedtls.c ++++ b/src/crypto/crypto_mbedtls.c +@@ -132,6 +132,12 @@ + #define CRYPTO_MBEDTLS_HMAC_KDF_SHA512 + #endif + ++#if defined(EAP_SIM) || defined(EAP_SIM_DYNAMIC) || defined(EAP_SERVER_SIM) \ ++ || defined(EAP_AKA) || defined(EAP_AKA_DYNAMIC) || defined(EAP_SERVER_AKA) ++/* EAP_SIM=y EAP_AKA=y */ ++#define CRYPTO_MBEDTLS_FIPS186_2_PRF ++#endif ++ + #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) \ + || defined(EAP_TEAP) || defined(EAP_TEAP_DYNAMIC) || defined(EAP_SERVER_FAST) + #define CRYPTO_MBEDTLS_SHA1_T_PRF +@@ -813,6 +819,60 @@ int sha1_t_prf(const u8 *key, size_t key + + #endif /* CRYPTO_MBEDTLS_SHA1_T_PRF */ + ++#ifdef CRYPTO_MBEDTLS_FIPS186_2_PRF ++ ++/* fips_prf_internal.c sha1-internal.c */ ++ ++/* used only by src/eap_common/eap_sim_common.c:eap_sim_prf() ++ * for eap_sim_derive_keys() and eap_sim_derive_keys_reauth() ++ * where xlen is 160 */ ++ ++int fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen) ++{ ++ /* FIPS 186-2 + change notice 1 */ ++ ++ mbedtls_sha1_context ctx; ++ u8 * const xkey = ctx.MBEDTLS_PRIVATE(buffer); ++ u32 * const xstate = ctx.MBEDTLS_PRIVATE(state); ++ const u32 xstate_init[] = ++ { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }; ++ ++ mbedtls_sha1_init(&ctx); ++ os_memcpy(xkey, seed, seed_len < 64 ? seed_len : 64); ++ ++ /* note: does not fill extra bytes if (xlen % 20) (SHA1_MAC_LEN) */ ++ for (; xlen >= 20; xlen -= 20) { ++ /* XSEED_j = 0 */ ++ /* XVAL = (XKEY + XSEED_j) mod 2^b */ ++ ++ /* w_i = G(t, XVAL) */ ++ os_memcpy(xstate, xstate_init, sizeof(xstate_init)); ++ mbedtls_internal_sha1_process(&ctx, xkey); ++ ++ #if __BYTE_ORDER == __LITTLE_ENDIAN ++ xstate[0] = host_to_be32(xstate[0]); ++ xstate[1] = host_to_be32(xstate[1]); ++ xstate[2] = host_to_be32(xstate[2]); ++ xstate[3] = host_to_be32(xstate[3]); ++ xstate[4] = host_to_be32(xstate[4]); ++ #endif ++ os_memcpy(x, xstate, 20); ++ if (xlen == 20) /*(done; skip prep for next loop)*/ ++ break; ++ ++ /* XKEY = (1 + XKEY + w_i) mod 2^b */ ++ for (u32 carry = 1, k = 20; k-- > 0; carry >>= 8) ++ xkey[k] = (carry += xkey[k] + x[k]) & 0xff; ++ x += 20; ++ /* x_j = w_0|w_1 (each pair of iterations through loop)*/ ++ } ++ ++ mbedtls_sha1_free(&ctx); ++ return 0; ++} ++ ++#endif /* CRYPTO_MBEDTLS_FIPS186_2_PRF */ ++ + #endif /* MBEDTLS_SHA1_C */ + + +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -1174,10 +1174,6 @@ endif + OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o + OBJS_p += ../src/crypto/crypto_$(CONFIG_CRYPTO).o + OBJS_priv += ../src/crypto/crypto_$(CONFIG_CRYPTO).o +-ifdef NEED_FIPS186_2_PRF +-OBJS += ../src/crypto/fips_prf_internal.o +-SHA1OBJS += ../src/crypto/sha1-internal.o +-endif + ifeq ($(CONFIG_CRYPTO), mbedtls) + LIBS += -lmbedcrypto + LIBS_p += -lmbedcrypto diff --git a/feeds/ipq95xx/hostapd/patches/130-mbedtls-annotate-with-TEST_FAIL-for-hwsim-tests.patch b/feeds/ipq95xx/hostapd/patches/130-mbedtls-annotate-with-TEST_FAIL-for-hwsim-tests.patch new file mode 100644 index 00000000..ae7620b9 --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/130-mbedtls-annotate-with-TEST_FAIL-for-hwsim-tests.patch @@ -0,0 +1,421 @@ +From 31bd19e0e0254b910cccfd3ddc6a6a9222bbcfc0 Mon Sep 17 00:00:00 2001 +From: Glenn Strauss +Date: Sun, 9 Oct 2022 05:12:17 -0400 +Subject: [PATCH 3/7] mbedtls: annotate with TEST_FAIL() for hwsim tests + +Signed-off-by: Glenn Strauss +--- + src/crypto/crypto_mbedtls.c | 124 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 124 insertions(+) + +--- a/src/crypto/crypto_mbedtls.c ++++ b/src/crypto/crypto_mbedtls.c +@@ -280,6 +280,9 @@ __attribute_noinline__ + static int md_vector(size_t num_elem, const u8 *addr[], const size_t *len, + u8 *mac, mbedtls_md_type_t md_type) + { ++ if (TEST_FAIL()) ++ return -1; ++ + mbedtls_md_context_t ctx; + mbedtls_md_init(&ctx); + if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0) != 0){ +@@ -343,6 +346,9 @@ __attribute_noinline__ + static int sha384_512_vector(size_t num_elem, const u8 *addr[], + const size_t *len, u8 *mac, int is384) + { ++ if (TEST_FAIL()) ++ return -1; ++ + struct mbedtls_sha512_context ctx; + mbedtls_sha512_init(&ctx); + #if MBEDTLS_VERSION_MAJOR >= 3 +@@ -375,6 +381,9 @@ int sha384_vector(size_t num_elem, const + #include + int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) + { ++ if (TEST_FAIL()) ++ return -1; ++ + struct mbedtls_sha256_context ctx; + mbedtls_sha256_init(&ctx); + #if MBEDTLS_VERSION_MAJOR >= 3 +@@ -397,6 +406,9 @@ int sha256_vector(size_t num_elem, const + #include + int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) + { ++ if (TEST_FAIL()) ++ return -1; ++ + struct mbedtls_sha1_context ctx; + mbedtls_sha1_init(&ctx); + #if MBEDTLS_VERSION_MAJOR >= 3 +@@ -419,6 +431,9 @@ int sha1_vector(size_t num_elem, const u + #include + int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) + { ++ if (TEST_FAIL()) ++ return -1; ++ + struct mbedtls_md5_context ctx; + mbedtls_md5_init(&ctx); + #if MBEDTLS_VERSION_MAJOR >= 3 +@@ -441,6 +456,9 @@ int md5_vector(size_t num_elem, const u8 + #include + int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) + { ++ if (TEST_FAIL()) ++ return -1; ++ + struct mbedtls_md4_context ctx; + mbedtls_md4_init(&ctx); + mbedtls_md4_starts_ret(&ctx); +@@ -460,6 +478,9 @@ static int hmac_vector(const u8 *key, si + const u8 *addr[], const size_t *len, u8 *mac, + mbedtls_md_type_t md_type) + { ++ if (TEST_FAIL()) ++ return -1; ++ + mbedtls_md_context_t ctx; + mbedtls_md_init(&ctx); + if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1) != 0){ +@@ -571,6 +592,9 @@ static int hmac_kdf_expand(const u8 *prk + const char *label, const u8 *info, size_t info_len, + u8 *okm, size_t okm_len, mbedtls_md_type_t md_type) + { ++ if (TEST_FAIL()) ++ return -1; ++ + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); + #ifdef MBEDTLS_HKDF_C + if (label == NULL) /* RFC 5869 HKDF-Expand when (label == NULL) */ +@@ -663,6 +687,9 @@ static int hmac_prf_bits(const u8 *key, + const u8 *data, size_t data_len, u8 *buf, + size_t buf_len_bits, mbedtls_md_type_t md_type) + { ++ if (TEST_FAIL()) ++ return -1; ++ + mbedtls_md_context_t ctx; + mbedtls_md_init(&ctx); + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); +@@ -938,6 +965,9 @@ int pbkdf2_sha1(const char *passphrase, + + static void *aes_crypt_init_mode(const u8 *key, size_t len, int mode) + { ++ if (TEST_FAIL()) ++ return NULL; ++ + mbedtls_aes_context *aes = os_malloc(sizeof(*aes)); + if (!aes) + return NULL; +@@ -996,6 +1026,9 @@ void aes_decrypt_deinit(void *ctx) + /* aes-wrap.c */ + int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher) + { ++ if (TEST_FAIL()) ++ return -1; ++ + mbedtls_nist_kw_context ctx; + mbedtls_nist_kw_init(&ctx); + size_t olen; +@@ -1010,6 +1043,9 @@ int aes_wrap(const u8 *kek, size_t kek_l + /* aes-unwrap.c */ + int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, u8 *plain) + { ++ if (TEST_FAIL()) ++ return -1; ++ + mbedtls_nist_kw_context ctx; + mbedtls_nist_kw_init(&ctx); + size_t olen; +@@ -1041,6 +1077,9 @@ int omac1_aes_vector( + const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], + const size_t *len, u8 *mac) + { ++ if (TEST_FAIL()) ++ return -1; ++ + mbedtls_cipher_type_t cipher_type; + switch (key_len) { + case 16: cipher_type = MBEDTLS_CIPHER_AES_128_ECB; break; +@@ -1103,6 +1142,9 @@ int omac1_aes_256(const u8 *key, const u + /* aes-encblock.c */ + int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out) + { ++ if (TEST_FAIL()) ++ return -1; ++ + mbedtls_aes_context aes; + mbedtls_aes_init(&aes); + int ret = mbedtls_aes_setkey_enc(&aes, key, 128) +@@ -1118,6 +1160,9 @@ int aes_128_encrypt_block(const u8 *key, + int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, + u8 *data, size_t data_len) + { ++ if (TEST_FAIL()) ++ return -1; ++ + unsigned char counter[MBEDTLS_AES_BLOCK_SIZE]; + unsigned char stream_block[MBEDTLS_AES_BLOCK_SIZE]; + os_memcpy(counter, nonce, MBEDTLS_AES_BLOCK_SIZE);/*(must be writable)*/ +@@ -1160,11 +1205,17 @@ static int aes_128_cbc_oper(const u8 *ke + + int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) + { ++ if (TEST_FAIL()) ++ return -1; ++ + return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_ENCRYPT); + } + + int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) + { ++ if (TEST_FAIL()) ++ return -1; ++ + return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_DECRYPT); + } + +@@ -1407,6 +1458,10 @@ int crypto_hash_finish(struct crypto_has + } + mbedtls_md_free(mctx); + os_free(mctx); ++ ++ if (TEST_FAIL()) ++ return -1; ++ + return 0; + } + +@@ -1421,6 +1476,9 @@ int crypto_hash_finish(struct crypto_has + + struct crypto_bignum *crypto_bignum_init(void) + { ++ if (TEST_FAIL()) ++ return NULL; ++ + mbedtls_mpi *bn = os_malloc(sizeof(*bn)); + if (bn) + mbedtls_mpi_init(bn); +@@ -1429,6 +1487,9 @@ struct crypto_bignum *crypto_bignum_init + + struct crypto_bignum *crypto_bignum_init_set(const u8 *buf, size_t len) + { ++ if (TEST_FAIL()) ++ return NULL; ++ + mbedtls_mpi *bn = os_malloc(sizeof(*bn)); + if (bn) { + mbedtls_mpi_init(bn); +@@ -1442,6 +1503,9 @@ struct crypto_bignum *crypto_bignum_init + + struct crypto_bignum *crypto_bignum_init_uint(unsigned int val) + { ++ if (TEST_FAIL()) ++ return NULL; ++ + #if 0 /*(hostap use of this interface passes int, not uint)*/ + val = host_to_be32(val); + return crypto_bignum_init_set((const u8 *)&val, sizeof(val)); +@@ -1467,6 +1531,9 @@ void crypto_bignum_deinit(struct crypto_ + int crypto_bignum_to_bin(const struct crypto_bignum *a, + u8 *buf, size_t buflen, size_t padlen) + { ++ if (TEST_FAIL()) ++ return -1; ++ + size_t n = mbedtls_mpi_size((mbedtls_mpi *)a); + if (n < padlen) + n = padlen; +@@ -1477,6 +1544,9 @@ int crypto_bignum_to_bin(const struct cr + + int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m) + { ++ if (TEST_FAIL()) ++ return -1; ++ + /*assert(r != m);*//* r must not be same as m for mbedtls_mpi_random()*/ + #if MBEDTLS_VERSION_NUMBER >= 0x021B0000 /* mbedtls 2.27.0 */ + return mbedtls_mpi_random((mbedtls_mpi *)r, 0, (mbedtls_mpi *)m, +@@ -1513,6 +1583,9 @@ int crypto_bignum_exptmod(const struct c + const struct crypto_bignum *c, + struct crypto_bignum *d) + { ++ if (TEST_FAIL()) ++ return -1; ++ + /* (check if input params match d; d is the result) */ + /* (a == d) is ok in current mbedtls implementation */ + if (b == d || c == d) { /*(not ok; store result in intermediate)*/ +@@ -1540,6 +1613,9 @@ int crypto_bignum_inverse(const struct c + const struct crypto_bignum *b, + struct crypto_bignum *c) + { ++ if (TEST_FAIL()) ++ return -1; ++ + return mbedtls_mpi_inv_mod((mbedtls_mpi *)c, + (const mbedtls_mpi *)a, + (const mbedtls_mpi *)b) ? -1 : 0; +@@ -1549,6 +1625,9 @@ int crypto_bignum_sub(const struct crypt + const struct crypto_bignum *b, + struct crypto_bignum *c) + { ++ if (TEST_FAIL()) ++ return -1; ++ + return mbedtls_mpi_sub_mpi((mbedtls_mpi *)c, + (const mbedtls_mpi *)a, + (const mbedtls_mpi *)b) ? -1 : 0; +@@ -1558,6 +1637,9 @@ int crypto_bignum_div(const struct crypt + const struct crypto_bignum *b, + struct crypto_bignum *c) + { ++ if (TEST_FAIL()) ++ return -1; ++ + /*(most current use of this crypto.h interface has a == c (result), + * so store result in an intermediate to avoid overwritten input)*/ + mbedtls_mpi R; +@@ -1575,6 +1657,9 @@ int crypto_bignum_addmod(const struct cr + const struct crypto_bignum *c, + struct crypto_bignum *d) + { ++ if (TEST_FAIL()) ++ return -1; ++ + return mbedtls_mpi_add_mpi((mbedtls_mpi *)d, + (const mbedtls_mpi *)a, + (const mbedtls_mpi *)b) +@@ -1588,6 +1673,9 @@ int crypto_bignum_mulmod(const struct cr + const struct crypto_bignum *c, + struct crypto_bignum *d) + { ++ if (TEST_FAIL()) ++ return -1; ++ + return mbedtls_mpi_mul_mpi((mbedtls_mpi *)d, + (const mbedtls_mpi *)a, + (const mbedtls_mpi *)b) +@@ -1600,6 +1688,9 @@ int crypto_bignum_sqrmod(const struct cr + const struct crypto_bignum *b, + struct crypto_bignum *c) + { ++ if (TEST_FAIL()) ++ return -1; ++ + #if 1 + return crypto_bignum_mulmod(a, a, b, c); + #else +@@ -1650,6 +1741,9 @@ int crypto_bignum_is_odd(const struct cr + int crypto_bignum_legendre(const struct crypto_bignum *a, + const struct crypto_bignum *p) + { ++ if (TEST_FAIL()) ++ return -2; ++ + /* Security Note: + * mbedtls_mpi_exp_mod() is not documented to run in constant time, + * though mbedtls/library/bignum.c uses constant_time_internal.h funcs. +@@ -1702,6 +1796,9 @@ int crypto_mod_exp(const u8 *base, size_ + const u8 *modulus, size_t modulus_len, + u8 *result, size_t *result_len) + { ++ if (TEST_FAIL()) ++ return -1; ++ + mbedtls_mpi bn_base, bn_exp, bn_modulus, bn_result; + mbedtls_mpi_init(&bn_base); + mbedtls_mpi_init(&bn_exp); +@@ -1769,6 +1866,9 @@ static int crypto_mbedtls_dh_init_public + int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey, + u8 *pubkey) + { ++ if (TEST_FAIL()) ++ return -1; ++ + #if 0 /*(crypto_dh_init() duplicated (and identical) in crypto_*.c modules)*/ + size_t pubkey_len, pad; + +@@ -1810,6 +1910,9 @@ int crypto_dh_derive_secret(u8 generator + const u8 *pubkey, size_t pubkey_len, + u8 *secret, size_t *len) + { ++ if (TEST_FAIL()) ++ return -1; ++ + #if 0 + if (pubkey_len > prime_len || + (pubkey_len == prime_len && +@@ -2512,6 +2615,9 @@ const struct crypto_ec_point * crypto_ec + + struct crypto_ec_point *crypto_ec_point_init(struct crypto_ec *e) + { ++ if (TEST_FAIL()) ++ return NULL; ++ + mbedtls_ecp_point *p = os_malloc(sizeof(*p)); + if (p != NULL) + mbedtls_ecp_point_init(p); +@@ -2536,6 +2642,9 @@ int crypto_ec_point_x(struct crypto_ec * + int crypto_ec_point_to_bin(struct crypto_ec *e, + const struct crypto_ec_point *point, u8 *x, u8 *y) + { ++ if (TEST_FAIL()) ++ return -1; ++ + /* crypto.h documents crypto_ec_point_to_bin() output is big-endian */ + size_t len = CRYPTO_EC_plen(e); + if (x) { +@@ -2563,6 +2672,9 @@ int crypto_ec_point_to_bin(struct crypto + struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e, + const u8 *val) + { ++ if (TEST_FAIL()) ++ return NULL; ++ + size_t len = CRYPTO_EC_plen(e); + mbedtls_ecp_point *p = os_malloc(sizeof(*p)); + u8 buf[1+MBEDTLS_MPI_MAX_SIZE*2]; +@@ -2615,6 +2727,9 @@ int crypto_ec_point_add(struct crypto_ec + const struct crypto_ec_point *b, + struct crypto_ec_point *c) + { ++ if (TEST_FAIL()) ++ return -1; ++ + /* mbedtls does not provide an mbedtls_ecp_point add function */ + mbedtls_mpi one; + mbedtls_mpi_init(&one); +@@ -2631,6 +2746,9 @@ int crypto_ec_point_mul(struct crypto_ec + const struct crypto_bignum *b, + struct crypto_ec_point *res) + { ++ if (TEST_FAIL()) ++ return -1; ++ + return mbedtls_ecp_mul( + (mbedtls_ecp_group *)e, (mbedtls_ecp_point *)res, + (const mbedtls_mpi *)b, (const mbedtls_ecp_point *)p, +@@ -2639,6 +2757,9 @@ int crypto_ec_point_mul(struct crypto_ec + + int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p) + { ++ if (TEST_FAIL()) ++ return -1; ++ + if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) + == MBEDTLS_ECP_TYPE_MONTGOMERY) { + /* e.g. MBEDTLS_ECP_DP_CURVE25519 and MBEDTLS_ECP_DP_CURVE448 */ +@@ -2751,6 +2872,9 @@ struct crypto_bignum * + crypto_ec_point_compute_y_sqr(struct crypto_ec *e, + const struct crypto_bignum *x) + { ++ if (TEST_FAIL()) ++ return NULL; ++ + mbedtls_mpi *y2 = os_malloc(sizeof(*y2)); + if (y2 == NULL) + return NULL; diff --git a/feeds/ipq95xx/hostapd/patches/135-mbedtls-fix-owe-association.patch b/feeds/ipq95xx/hostapd/patches/135-mbedtls-fix-owe-association.patch new file mode 100644 index 00000000..0c29432d --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/135-mbedtls-fix-owe-association.patch @@ -0,0 +1,91 @@ +The code for hostapd-mbedtls did not work when used for OWE association. + +When handling association requests, the buffer offsets and length assumptions were incorrect, leading to never calculating the y point, thus denying association. + +Also when crafting the association response, the buffer contained the trailing key-type. + +Fix up both issues to adhere to the specification and make hostapd-mbedtls work with the OWE security type. + +--- a/src/crypto/crypto_mbedtls.c ++++ b/src/crypto/crypto_mbedtls.c +@@ -2299,25 +2299,30 @@ struct crypto_ecdh * crypto_ecdh_init2(i + struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y) + { + mbedtls_ecp_group *grp = &ecdh->grp; +- size_t len = CRYPTO_EC_plen(grp); ++ size_t prime_len = CRYPTO_EC_plen(grp); ++ size_t output_len = prime_len; ++ u8 output_offset = 0; ++ u8 buf[256]; ++ + #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED + /* len */ + #endif + #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED +- if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) +- len = inc_y ? len*2+1 : len+1; ++ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { ++ output_len = inc_y ? prime_len * 2 + 1 : prime_len + 1; ++ output_offset = 1; ++ } + #endif +- struct wpabuf *buf = wpabuf_alloc(len); +- if (buf == NULL) ++ ++ if (output_len > sizeof(buf)) + return NULL; ++ + inc_y = inc_y ? MBEDTLS_ECP_PF_UNCOMPRESSED : MBEDTLS_ECP_PF_COMPRESSED; +- if (mbedtls_ecp_point_write_binary(grp, &ecdh->Q, inc_y, &len, +- wpabuf_mhead_u8(buf), len) == 0) { +- wpabuf_put(buf, len); +- return buf; ++ if (mbedtls_ecp_point_write_binary(grp, &ecdh->Q, inc_y, &output_len, ++ buf, output_len) == 0) { ++ return wpabuf_alloc_copy(buf + output_offset, output_len - output_offset); + } + +- wpabuf_free(buf); + return NULL; + } + +@@ -2379,10 +2384,7 @@ struct wpabuf * crypto_ecdh_set_peerkey( + os_memcpy(buf+2, key, len); + } + len >>= 1; /*(repurpose len to prime_len)*/ +- } +- else if (key[0] == 0x02 || key[0] == 0x03) { /* (inc_y == 0) */ +- --len; /*(repurpose len to prime_len)*/ +- ++ } else { /* (inc_y == 0) */ + /* mbedtls_ecp_point_read_binary() does not currently support + * MBEDTLS_ECP_PF_COMPRESSED format (buf[1] = 0x02 or 0x03) + * (returns MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) */ +@@ -2390,22 +2392,21 @@ struct wpabuf * crypto_ecdh_set_peerkey( + /* derive y, amend buf[] with y for UNCOMPRESSED format */ + if (sizeof(buf)-2 < len*2 || len == 0) + return NULL; ++ + buf[0] = (u8)(1+len*2); + buf[1] = 0x04; ++ os_memcpy(buf+2, key, len); ++ + mbedtls_mpi bn; + mbedtls_mpi_init(&bn); +- int ret = mbedtls_mpi_read_binary(&bn, key+1, len) +- || crypto_mbedtls_short_weierstrass_derive_y(grp, &bn, +- key[0] & 1) ++ int ret = mbedtls_mpi_read_binary(&bn, key, len) ++ || crypto_mbedtls_short_weierstrass_derive_y(grp, &bn, 0) + || mbedtls_mpi_write_binary(&bn, buf+2+len, len); + mbedtls_mpi_free(&bn); + if (ret != 0) + return NULL; + } + +- if (key[0] == 0) /*(repurpose len to prime_len)*/ +- len = CRYPTO_EC_plen(grp); +- + if (mbedtls_ecdh_read_public(&ecdh->ctx, buf, buf[0]+1)) + return NULL; + } diff --git a/feeds/ipq95xx/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch b/feeds/ipq95xx/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch new file mode 100644 index 00000000..e967cff4 --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch @@ -0,0 +1,1358 @@ +From f24933dc175e0faf44a3cce3330c256a59649ca6 Mon Sep 17 00:00:00 2001 +From: Glenn Strauss +Date: Tue, 19 Jul 2022 23:01:17 -0400 +Subject: [PATCH 4/7] tests/Makefile make run-tests with CONFIG_TLS=... + +add test-crypto_module.c to run crypto_module_tests() + +adjust some tests/hwsim/*.py for mbed TLS (work in progress) + +option to build and run-tests with CONFIG_TLS=internal # (default) +$ cd tests; make clean +$ make run-tests + +option to build and run-tests with CONFIG_TLS=gnutls +$ cd tests; make clean CONFIG_TLS=gnutls +$ make run-tests CONFIG_TLS=gnutls + +option to build and run-tests with CONFIG_TLS=mbedtls +$ cd tests; make clean CONFIG_TLS=mbedtls +$ make run-tests CONFIG_TLS=mbedtls + +option to build and run-tests with CONFIG_TLS=openssl +$ cd tests; make clean CONFIG_TLS=openssl +$ make run-tests CONFIG_TLS=openssl + +option to build and run-tests with CONFIG_TLS=wolfssl +$ cd tests; make clean CONFIG_TLS=wolfssl +$ make run-tests CONFIG_TLS=wolfssl + +RFE: Makefile logic for crypto objects should be centralized + instead of being duplicated in hostapd/Makefile, + wpa_supplicant/Makefile, src/crypto/Makefile, + tests/Makefile, ... + +Signed-off-by: Glenn Strauss +--- + hostapd/Makefile | 6 + + src/crypto/Makefile | 129 ++++++++++++++++++++- + src/crypto/crypto_module_tests.c | 134 ++++++++++++++++++++++ + src/tls/Makefile | 11 ++ + tests/Makefile | 75 +++++++++--- + tests/hwsim/example-hostapd.config | 11 +- + tests/hwsim/example-wpa_supplicant.config | 12 +- + tests/hwsim/test_ap_eap.py | 114 +++++++++++++----- + tests/hwsim/test_ap_ft.py | 4 +- + tests/hwsim/test_authsrv.py | 9 +- + tests/hwsim/test_dpp.py | 19 ++- + tests/hwsim/test_erp.py | 16 +-- + tests/hwsim/test_fils.py | 5 +- + tests/hwsim/test_pmksa_cache.py | 4 +- + tests/hwsim/test_sae.py | 7 ++ + tests/hwsim/test_suite_b.py | 3 + + tests/hwsim/test_wpas_ctrl.py | 2 +- + tests/hwsim/utils.py | 8 +- + tests/test-crypto_module.c | 16 +++ + tests/test-https.c | 12 +- + tests/test-https_server.c | 12 +- + wpa_supplicant/Makefile | 6 + + 22 files changed, 524 insertions(+), 91 deletions(-) + create mode 100644 tests/test-crypto_module.c + +--- a/hostapd/Makefile ++++ b/hostapd/Makefile +@@ -696,6 +696,7 @@ CFLAGS += -DCONFIG_TLSV12 + endif + + ifeq ($(CONFIG_TLS), wolfssl) ++CFLAGS += -DCONFIG_TLS_WOLFSSL + CONFIG_CRYPTO=wolfssl + ifdef TLS_FUNCS + OBJS += ../src/crypto/tls_wolfssl.o +@@ -716,6 +717,7 @@ endif + endif + + ifeq ($(CONFIG_TLS), openssl) ++CFLAGS += -DCONFIG_TLS_OPENSSL + CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 + CONFIG_CRYPTO=openssl + ifdef TLS_FUNCS +@@ -746,6 +748,7 @@ CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONF + endif + + ifeq ($(CONFIG_TLS), mbedtls) ++CFLAGS += -DCONFIG_TLS_MBEDTLS + ifndef CONFIG_CRYPTO + CONFIG_CRYPTO=mbedtls + endif +@@ -776,6 +779,7 @@ endif + endif + + ifeq ($(CONFIG_TLS), gnutls) ++CFLAGS += -DCONFIG_TLS_GNUTLS + ifndef CONFIG_CRYPTO + # default to libgcrypt + CONFIG_CRYPTO=gnutls +@@ -806,6 +810,7 @@ endif + endif + + ifeq ($(CONFIG_TLS), internal) ++CFLAGS += -DCONFIG_TLS_INTERNAL + ifndef CONFIG_CRYPTO + CONFIG_CRYPTO=internal + endif +@@ -884,6 +889,7 @@ endif + endif + + ifeq ($(CONFIG_TLS), linux) ++CFLAGS += -DCONFIG_TLS_INTERNAL + OBJS += ../src/crypto/crypto_linux.o + ifdef TLS_FUNCS + OBJS += ../src/crypto/crypto_internal-rsa.o +--- a/src/crypto/Makefile ++++ b/src/crypto/Makefile +@@ -1,10 +1,121 @@ +-CFLAGS += -DCONFIG_CRYPTO_INTERNAL +-CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT +-CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER + #CFLAGS += -DALL_DH_GROUPS + CFLAGS += -DCONFIG_SHA256 + CFLAGS += -DCONFIG_SHA384 ++CFLAGS += -DCONFIG_HMAC_SHA256_KDF + CFLAGS += -DCONFIG_HMAC_SHA384_KDF ++ ++# crypto_module_tests.c ++CFLAGS += -DCONFIG_MODULE_TESTS ++CFLAGS += -DCONFIG_DPP ++#CFLAGS += -DCONFIG_DPP2 ++#CFLAGS += -DCONFIG_DPP3 ++CFLAGS += -DCONFIG_ECC ++CFLAGS += -DCONFIG_MESH ++CFLAGS += -DEAP_PSK ++CFLAGS += -DEAP_FAST ++ ++ifeq ($(CONFIG_TLS),mbedtls) ++ ++# (enable features for 'cd tests; make run-tests CONFIG_TLS=mbedtls') ++CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 ++CFLAGS += -DCONFIG_DES ++CFLAGS += -DEAP_IKEV2 ++CFLAGS += -DEAP_MSCHAPv2 ++CFLAGS += -DEAP_SIM ++ ++LIB_OBJS = tls_mbedtls.o crypto_mbedtls.o ++LIB_OBJS+= \ ++ aes-eax.o \ ++ aes-siv.o \ ++ dh_groups.o \ ++ milenage.o \ ++ ms_funcs.o ++ ++else ++ifeq ($(CONFIG_TLS),openssl) ++ ++# (enable features for 'cd tests; make run-tests CONFIG_TLS=openssl') ++ifndef CONFIG_TLS_DEFAULT_CIPHERS ++CONFIG_TLS_DEFAULT_CIPHERS = "DEFAULT:!EXP:!LOW" ++endif ++CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\" ++CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 ++CFLAGS += -DEAP_TLS_OPENSSL ++ ++LIB_OBJS = tls_openssl.o fips_prf_openssl.o crypto_openssl.o ++LIB_OBJS+= \ ++ aes-ctr.o \ ++ aes-eax.o \ ++ aes-encblock.o \ ++ aes-siv.o \ ++ dh_groups.o \ ++ milenage.o \ ++ ms_funcs.o \ ++ sha1-prf.o \ ++ sha1-tlsprf.o \ ++ sha1-tprf.o \ ++ sha256-kdf.o \ ++ sha256-prf.o \ ++ sha256-tlsprf.o ++ ++else ++ifeq ($(CONFIG_TLS),wolfssl) ++ ++# (wolfssl libraries must be built with ./configure --enable-wpas) ++# (enable features for 'cd tests; make run-tests CONFIG_TLS=wolfssl') ++CFLAGS += -DWOLFSSL_DER_LOAD ++CFLAGS += -DCONFIG_DES ++ ++LIB_OBJS = tls_wolfssl.o fips_prf_wolfssl.o crypto_wolfssl.o ++LIB_OBJS+= \ ++ aes-ctr.o \ ++ aes-eax.o \ ++ aes-encblock.o \ ++ aes-siv.o \ ++ dh_groups.o \ ++ milenage.o \ ++ ms_funcs.o \ ++ sha1-prf.o \ ++ sha1-tlsprf.o \ ++ sha1-tprf.o \ ++ sha256-kdf.o \ ++ sha256-prf.o \ ++ sha256-tlsprf.o ++ ++else ++ifeq ($(CONFIG_TLS),gnutls) ++ ++# (enable features for 'cd tests; make run-tests CONFIG_TLS=gnutls') ++LIB_OBJS = tls_gnutls.o crypto_gnutls.o ++LIB_OBJS+= \ ++ aes-cbc.o \ ++ aes-ctr.o \ ++ aes-eax.o \ ++ aes-encblock.o \ ++ aes-omac1.o \ ++ aes-siv.o \ ++ aes-unwrap.o \ ++ aes-wrap.o \ ++ dh_group5.o \ ++ dh_groups.o \ ++ milenage.o \ ++ ms_funcs.o \ ++ rc4.o \ ++ sha1-pbkdf2.o \ ++ sha1-prf.o \ ++ fips_prf_internal.o \ ++ sha1-internal.o \ ++ sha1-tlsprf.o \ ++ sha1-tprf.o \ ++ sha256-kdf.o \ ++ sha256-prf.o \ ++ sha256-tlsprf.o ++ ++else ++ ++CFLAGS += -DCONFIG_CRYPTO_INTERNAL ++CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT ++CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER + CFLAGS += -DCONFIG_INTERNAL_SHA384 + + LIB_OBJS= \ +@@ -13,7 +124,6 @@ LIB_OBJS= \ + aes-ctr.o \ + aes-eax.o \ + aes-encblock.o \ +- aes-gcm.o \ + aes-internal.o \ + aes-internal-dec.o \ + aes-internal-enc.o \ +@@ -37,6 +147,7 @@ LIB_OBJS= \ + sha1-tlsprf.o \ + sha1-tprf.o \ + sha256.o \ ++ sha256-kdf.o \ + sha256-prf.o \ + sha256-tlsprf.o \ + sha256-internal.o \ +@@ -53,6 +164,16 @@ LIB_OBJS += crypto_internal-modexp.o + LIB_OBJS += crypto_internal-rsa.o + LIB_OBJS += tls_internal.o + LIB_OBJS += fips_prf_internal.o ++ ++endif ++endif ++endif ++endif ++ ++ ++# (used by wlantest/{bip,gcmp,rx_mgmt}.c and tests/test-aes.c) ++LIB_OBJS += aes-gcm.o ++ + ifndef TEST_FUZZ + LIB_OBJS += random.o + endif +--- a/src/crypto/crypto_module_tests.c ++++ b/src/crypto/crypto_module_tests.c +@@ -2469,6 +2469,139 @@ static int test_hpke(void) + } + + ++static int test_ecc(void) ++{ ++#ifdef CONFIG_ECC ++#ifndef CONFIG_TLS_INTERNAL ++#ifndef CONFIG_TLS_GNUTLS ++#if defined(CONFIG_TLS_MBEDTLS) \ ++ || defined(CONFIG_TLS_OPENSSL) \ ++ || defined(CONFIG_TLS_WOLFSSL) ++ wpa_printf(MSG_INFO, "Testing ECC"); ++ /* Note: some tests below are valid on supported Short Weierstrass ++ * curves, but not on Montgomery curves (e.g. IKE groups 31 and 32) ++ * (e.g. deriving and comparing y^2 test below not valid on Montgomery) ++ */ ++#ifdef CONFIG_TLS_MBEDTLS ++ const int grps[] = {19, 20, 21, 25, 26, 28}; ++#endif ++#ifdef CONFIG_TLS_OPENSSL ++ const int grps[] = {19, 20, 21, 26}; ++#endif ++#ifdef CONFIG_TLS_WOLFSSL ++ const int grps[] = {19, 20, 21, 26}; ++#endif ++ uint32_t i; ++ struct crypto_ec *e = NULL; ++ struct crypto_ec_point *p = NULL, *q = NULL; ++ struct crypto_bignum *x = NULL, *y = NULL; ++#ifdef CONFIG_DPP ++ u8 bin[4096]; ++#endif ++ for (i = 0; i < ARRAY_SIZE(grps); ++i) { ++ e = crypto_ec_init(grps[i]); ++ if (e == NULL ++ || crypto_ec_prime_len(e) == 0 ++ || crypto_ec_prime_len_bits(e) == 0 ++ || crypto_ec_order_len(e) == 0 ++ || crypto_ec_get_prime(e) == NULL ++ || crypto_ec_get_order(e) == NULL ++ || crypto_ec_get_a(e) == NULL ++ || crypto_ec_get_b(e) == NULL ++ || crypto_ec_get_generator(e) == NULL) { ++ break; ++ } ++#ifdef CONFIG_DPP ++ struct crypto_ec_key *key = crypto_ec_key_gen(grps[i]); ++ if (key == NULL) ++ break; ++ p = crypto_ec_key_get_public_key(key); ++ q = crypto_ec_key_get_public_key(key); ++ crypto_ec_key_deinit(key); ++ if (p == NULL || q == NULL) ++ break; ++ if (!crypto_ec_point_is_on_curve(e, p)) ++ break; ++ ++ /* inverted point should not match original; ++ * double-invert should match */ ++ if (crypto_ec_point_invert(e, q) != 0 ++ || crypto_ec_point_cmp(e, p, q) == 0 ++ || crypto_ec_point_invert(e, q) != 0 ++ || crypto_ec_point_cmp(e, p, q) != 0) { ++ break; ++ } ++ ++ /* crypto_ec_point_to_bin() and crypto_ec_point_from_bin() ++ * imbalanced interfaces? */ ++ size_t prime_len = crypto_ec_prime_len(e); ++ if (prime_len * 2 > sizeof(bin)) ++ break; ++ if (crypto_ec_point_to_bin(e, p, bin, bin+prime_len) != 0) ++ break; ++ struct crypto_ec_point *tmp = crypto_ec_point_from_bin(e, bin); ++ if (tmp == NULL) ++ break; ++ if (crypto_ec_point_cmp(e, p, tmp) != 0) { ++ crypto_ec_point_deinit(tmp, 0); ++ break; ++ } ++ crypto_ec_point_deinit(tmp, 0); ++ ++ x = crypto_bignum_init(); ++ y = crypto_bignum_init_set(bin+prime_len, prime_len); ++ if (x == NULL || y == NULL || crypto_ec_point_x(e, p, x) != 0) ++ break; ++ struct crypto_bignum *y2 = crypto_ec_point_compute_y_sqr(e, x); ++ if (y2 == NULL) ++ break; ++ if (crypto_bignum_sqrmod(y, crypto_ec_get_prime(e), y) != 0 ++ || crypto_bignum_cmp(y, y2) != 0) { ++ crypto_bignum_deinit(y2, 0); ++ break; ++ } ++ crypto_bignum_deinit(y2, 0); ++ crypto_bignum_deinit(x, 0); ++ crypto_bignum_deinit(y, 0); ++ x = NULL; ++ y = NULL; ++ ++ x = crypto_bignum_init(); ++ if (x == NULL) ++ break; ++ if (crypto_bignum_rand(x, crypto_ec_get_prime(e)) != 0) ++ break; ++ crypto_bignum_deinit(x, 0); ++ x = NULL; ++ ++ crypto_ec_point_deinit(p, 0); ++ p = NULL; ++ crypto_ec_point_deinit(q, 0); ++ q = NULL; ++#endif /* CONFIG_DPP */ ++ crypto_ec_deinit(e); ++ e = NULL; ++ } ++ if (i != ARRAY_SIZE(grps)) { ++ crypto_bignum_deinit(x, 0); ++ crypto_bignum_deinit(y, 0); ++ crypto_ec_point_deinit(p, 0); ++ crypto_ec_point_deinit(q, 0); ++ crypto_ec_deinit(e); ++ wpa_printf(MSG_INFO, ++ "ECC test case failed tls_id:%d", grps[i]); ++ return -1; ++ } ++ ++ wpa_printf(MSG_INFO, "ECC test cases passed"); ++#endif ++#endif /* !CONFIG_TLS_GNUTLS */ ++#endif /* !CONFIG_TLS_INTERNAL */ ++#endif /* CONFIG_ECC */ ++ return 0; ++} ++ ++ + static int test_ms_funcs(void) + { + #ifndef CONFIG_FIPS +@@ -2590,6 +2723,7 @@ int crypto_module_tests(void) + test_fips186_2_prf() || + test_extract_expand_hkdf() || + test_hpke() || ++ test_ecc() || + test_ms_funcs()) + ret = -1; + +--- a/src/tls/Makefile ++++ b/src/tls/Makefile +@@ -1,3 +1,10 @@ ++LIB_OBJS= asn1.o ++ ++ifneq ($(CONFIG_TLS),gnutls) ++ifneq ($(CONFIG_TLS),mbedtls) ++ifneq ($(CONFIG_TLS),openssl) ++ifneq ($(CONFIG_TLS),wolfssl) ++ + CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH + CFLAGS += -DCONFIG_CRYPTO_INTERNAL + CFLAGS += -DCONFIG_TLSV11 +@@ -21,5 +28,9 @@ LIB_OBJS= \ + tlsv1_server_read.o \ + tlsv1_server_write.o \ + x509v3.o ++endif ++endif ++endif ++endif + + include ../lib.rules +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -1,8 +1,10 @@ +-ALL=test-base64 test-md4 test-milenage \ +- test-rsa-sig-ver \ +- test-sha1 \ +- test-https test-https_server \ +- test-sha256 test-aes test-x509v3 test-list test-rc4 ++RUN_TESTS= \ ++ test-list \ ++ test-md4 test-rc4 test-sha1 test-sha256 \ ++ test-milenage test-aes \ ++ test-crypto_module ++ ++ALL=$(RUN_TESTS) test-base64 test-https test-https_server + + include ../src/build.rules + +@@ -24,13 +26,27 @@ CFLAGS += -DCONFIG_IEEE80211R_AP + CFLAGS += -DCONFIG_IEEE80211R + CFLAGS += -DCONFIG_TDLS + ++# test-crypto_module ++CFLAGS += -DCONFIG_MODULE_TESTS ++CFLAGS += -DCONFIG_DPP ++#CFLAGS += -DCONFIG_DPP2 ++#CFLAGS += -DCONFIG_DPP3 ++CFLAGS += -DCONFIG_ECC ++CFLAGS += -DCONFIG_HMAC_SHA256_KDF ++CFLAGS += -DCONFIG_HMAC_SHA384_KDF ++CFLAGS += -DCONFIG_MESH ++CFLAGS += -DCONFIG_SHA256 ++CFLAGS += -DCONFIG_SHA384 ++CFLAGS += -DEAP_PSK ++CFLAGS += -DEAP_FAST ++ + CFLAGS += -I../src + CFLAGS += -I../src/utils + + SLIBS = ../src/utils/libutils.a + +-DLIBS = ../src/crypto/libcrypto.a \ +- ../src/tls/libtls.a ++DLIBS = ../src/tls/libtls.a \ ++ ../src/crypto/libcrypto.a + + _OBJS_VAR := LLIBS + include ../src/objs.mk +@@ -42,12 +58,43 @@ include ../src/objs.mk + LIBS = $(SLIBS) $(DLIBS) + LLIBS = -Wl,--start-group $(DLIBS) -Wl,--end-group $(SLIBS) + ++ifeq ($(CONFIG_TLS),mbedtls) ++CFLAGS += -DCONFIG_TLS_MBEDTLS ++LLIBS += -lmbedtls -lmbedx509 -lmbedcrypto ++else ++ifeq ($(CONFIG_TLS),openssl) ++CFLAGS += -DCONFIG_TLS_OPENSSL ++LLIBS += -lssl -lcrypto ++else ++ifeq ($(CONFIG_TLS),gnutls) ++CFLAGS += -DCONFIG_TLS_GNUTLS ++LLIBS += -lgnutls -lgpg-error -lgcrypt ++else ++ifeq ($(CONFIG_TLS),wolfssl) ++CFLAGS += -DCONFIG_TLS_WOLFSSL ++LLIBS += -lwolfssl -lm ++else ++CFLAGS += -DCONFIG_TLS_INTERNAL ++CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER ++ALL += test-rsa-sig-ver ++ALL += test-x509v3 ++clean-config_tls_internal: ++ rm -f test_x509v3_nist.out.* ++ rm -f test_x509v3_nist2.out.* ++endif ++endif ++endif ++endif ++ + # glibc < 2.17 needs -lrt for clock_gettime() + LLIBS += -lrt + + test-aes: $(call BUILDOBJ,test-aes.o) $(LIBS) + $(LDO) $(LDFLAGS) -o $@ $^ $(LLIBS) + ++test-crypto_module: $(call BUILDOBJ,test-crypto_module.o) $(LIBS) ++ $(LDO) $(LDFLAGS) -o $@ $< $(LLIBS) ++ + test-base64: $(call BUILDOBJ,test-base64.o) $(LIBS) + $(LDO) $(LDFLAGS) -o $@ $^ $(LLIBS) + +@@ -83,17 +130,11 @@ test-x509v3: $(call BUILDOBJ,test-x509v3 + + + run-tests: $(ALL) +- ./test-aes +- ./test-list +- ./test-md4 +- ./test-milenage +- ./test-rsa-sig-ver +- ./test-sha1 +- ./test-sha256 ++ @set -ex; for i in $(RUN_TESTS); do ./$$i; done + @echo + @echo All tests completed successfully. + +-clean: common-clean ++clean: common-clean clean-config_tls_internal + rm -f *~ +- rm -f test_x509v3_nist.out.* +- rm -f test_x509v3_nist2.out.* ++ ++.PHONY: run-tests clean-config_tls_internal +--- a/tests/hwsim/example-hostapd.config ++++ b/tests/hwsim/example-hostapd.config +@@ -34,15 +34,7 @@ CONFIG_EAP_TNC=y + CFLAGS += -DTNC_CONFIG_FILE=\"tnc/tnc_config\" + LIBS += -rdynamic + CONFIG_EAP_UNAUTH_TLS=y +-ifeq ($(CONFIG_TLS), openssl) +-CONFIG_EAP_PWD=y +-endif +-ifeq ($(CONFIG_TLS), wolfssl) +-CONFIG_EAP_PWD=y +-endif +-ifeq ($(CONFIG_TLS), mbedtls) +-CONFIG_EAP_PWD=y +-endif ++CONFIG_EAP_PWD=$(if $(filter openssl wolfssl mbedtls,$(CONFIG_TLS)),y,) + CONFIG_EAP_EKE=y + CONFIG_PKCS12=y + CONFIG_RADIUS_SERVER=y +@@ -89,6 +81,7 @@ CFLAGS += -DCONFIG_RADIUS_TEST + CONFIG_MODULE_TESTS=y + + CONFIG_SUITEB=y ++CONFIG_SUITEB192=$(if $(filter openssl mbedtls,$(CONFIG_TLS)),y,) + + # AddressSanitizer (ASan) can be enabled by uncommenting the following lines. + # This can be used as a more efficient memory error detector than valgrind +--- a/tests/hwsim/example-wpa_supplicant.config ++++ b/tests/hwsim/example-wpa_supplicant.config +@@ -35,16 +35,7 @@ LIBS += -rdynamic + CONFIG_EAP_FAST=y + CONFIG_EAP_TEAP=y + CONFIG_EAP_IKEV2=y +- +-ifeq ($(CONFIG_TLS), openssl) +-CONFIG_EAP_PWD=y +-endif +-ifeq ($(CONFIG_TLS), wolfssl) +-CONFIG_EAP_PWD=y +-endif +-ifeq ($(CONFIG_TLS), mbedtls) +-CONFIG_EAP_PWD=y +-endif ++CONFIG_EAP_PWD=$(if $(filter openssl wolfssl mbedtls,$(CONFIG_TLS)),y,) + + CONFIG_USIM_SIMULATOR=y + CONFIG_SIM_SIMULATOR=y +@@ -137,6 +128,7 @@ CONFIG_TESTING_OPTIONS=y + CONFIG_MODULE_TESTS=y + + CONFIG_SUITEB=y ++CONFIG_SUITEB192=$(if $(filter openssl mbedtls,$(CONFIG_TLS)),y,) + + # AddressSanitizer (ASan) can be enabled by uncommenting the following lines. + # This can be used as a more efficient memory error detector than valgrind +--- a/tests/hwsim/test_ap_eap.py ++++ b/tests/hwsim/test_ap_eap.py +@@ -42,20 +42,42 @@ def check_eap_capa(dev, method): + res = dev.get_capability("eap") + if method not in res: + raise HwsimSkip("EAP method %s not supported in the build" % method) ++ if method == "FAST" or method == "TEAP": ++ tls = dev.request("GET tls_library") ++ if tls.startswith("mbed TLS"): ++ raise HwsimSkip("EAP-%s not supported with this TLS library: " % method + tls) + + def check_subject_match_support(dev): + tls = dev.request("GET tls_library") +- if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): ++ if tls.startswith("OpenSSL"): ++ return ++ elif tls.startswith("wolfSSL"): ++ return ++ elif tls.startswith("mbed TLS"): ++ return ++ else: + raise HwsimSkip("subject_match not supported with this TLS library: " + tls) + + def check_check_cert_subject_support(dev): + tls = dev.request("GET tls_library") +- if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): ++ if tls.startswith("OpenSSL"): ++ return ++ elif tls.startswith("wolfSSL"): ++ return ++ elif tls.startswith("mbed TLS"): ++ return ++ else: + raise HwsimSkip("check_cert_subject not supported with this TLS library: " + tls) + + def check_altsubject_match_support(dev): + tls = dev.request("GET tls_library") +- if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): ++ if tls.startswith("OpenSSL"): ++ return ++ elif tls.startswith("wolfSSL"): ++ return ++ elif tls.startswith("mbed TLS"): ++ return ++ else: + raise HwsimSkip("altsubject_match not supported with this TLS library: " + tls) + + def check_domain_match(dev): +@@ -70,7 +92,13 @@ def check_domain_suffix_match(dev): + + def check_domain_match_full(dev): + tls = dev.request("GET tls_library") +- if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): ++ if tls.startswith("OpenSSL"): ++ return ++ elif tls.startswith("wolfSSL"): ++ return ++ elif tls.startswith("mbed TLS"): ++ return ++ else: + raise HwsimSkip("domain_suffix_match requires full match with this TLS library: " + tls) + + def check_cert_probe_support(dev): +@@ -79,8 +107,15 @@ def check_cert_probe_support(dev): + raise HwsimSkip("Certificate probing not supported with this TLS library: " + tls) + + def check_ext_cert_check_support(dev): ++ if not openssl_imported: ++ raise HwsimSkip("OpenSSL python method not available") ++ + tls = dev.request("GET tls_library") +- if not tls.startswith("OpenSSL"): ++ if tls.startswith("OpenSSL"): ++ return ++ elif tls.startswith("mbed TLS"): ++ return ++ else: + raise HwsimSkip("ext_cert_check not supported with this TLS library: " + tls) + + def check_ocsp_support(dev): +@@ -91,14 +126,18 @@ def check_ocsp_support(dev): + # raise HwsimSkip("OCSP not supported with this TLS library: " + tls) + #if tls.startswith("wolfSSL"): + # raise HwsimSkip("OCSP not supported with this TLS library: " + tls) ++ if tls.startswith("mbed TLS"): ++ raise HwsimSkip("OCSP not supported with this TLS library: " + tls) + + def check_pkcs5_v15_support(dev): + tls = dev.request("GET tls_library") +- if "BoringSSL" in tls or "GnuTLS" in tls: ++ if "BoringSSL" in tls or "GnuTLS" in tls or "mbed TLS" in tls: + raise HwsimSkip("PKCS#5 v1.5 not supported with this TLS library: " + tls) + + def check_tls13_support(dev): + tls = dev.request("GET tls_library") ++ if tls.startswith("mbed TLS"): ++ raise HwsimSkip("TLS v1.3 not supported") + if "run=OpenSSL 1.1.1" not in tls and "run=OpenSSL 3.0" not in tls and "wolfSSL" not in tls: + raise HwsimSkip("TLS v1.3 not supported") + +@@ -118,11 +157,15 @@ def check_pkcs12_support(dev): + # raise HwsimSkip("PKCS#12 not supported with this TLS library: " + tls) + if tls.startswith("wolfSSL"): + raise HwsimSkip("PKCS#12 not supported with this TLS library: " + tls) ++ if tls.startswith("mbed TLS"): ++ raise HwsimSkip("PKCS#12 not supported with this TLS library: " + tls) + + def check_dh_dsa_support(dev): + tls = dev.request("GET tls_library") + if tls.startswith("internal"): + raise HwsimSkip("DH DSA not supported with this TLS library: " + tls) ++ if tls.startswith("mbed TLS"): ++ raise HwsimSkip("DH DSA not supported with this TLS library: " + tls) + + def check_ec_support(dev): + tls = dev.request("GET tls_library") +@@ -1595,7 +1638,7 @@ def test_ap_wpa2_eap_ttls_pap_subject_ma + eap_connect(dev[0], hapd, "TTLS", "pap user", + anonymous_identity="ttls", password="password", + ca_cert="auth_serv/ca.pem", phase2="auth=PAP", +- subject_match="/C=FI/O=w1.fi/CN=server.w1.fi", ++ check_cert_subject="/C=FI/O=w1.fi/CN=server.w1.fi", + altsubject_match="EMAIL:noone@example.com;DNS:server.w1.fi;URI:http://example.com/") + eap_reauth(dev[0], "TTLS") + +@@ -2830,6 +2873,7 @@ def test_ap_wpa2_eap_tls_neg_domain_matc + + def test_ap_wpa2_eap_tls_neg_subject_match(dev, apdev): + """WPA2-Enterprise negative test - subject mismatch""" ++ check_subject_match_support(dev[0]) + params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") + hostapd.add_ap(apdev[0], params) + dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", +@@ -2890,6 +2934,7 @@ def test_ap_wpa2_eap_tls_neg_subject_mat + + def test_ap_wpa2_eap_tls_neg_altsubject_match(dev, apdev): + """WPA2-Enterprise negative test - altsubject mismatch""" ++ check_altsubject_match_support(dev[0]) + params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") + hostapd.add_ap(apdev[0], params) + +@@ -3430,7 +3475,7 @@ def test_ap_wpa2_eap_ikev2_oom(dev, apde + dev[0].request("REMOVE_NETWORK all") + + tls = dev[0].request("GET tls_library") +- if not tls.startswith("wolfSSL"): ++ if not tls.startswith("wolfSSL") and not tls.startswith("mbed TLS"): + tests = [(1, "os_get_random;dh_init")] + else: + tests = [(1, "crypto_dh_init;dh_init")] +@@ -4744,7 +4789,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca + params["private_key"] = "auth_serv/iCA-server/server.key" + hostapd.add_ap(apdev[0], params) + tls = dev[0].request("GET tls_library") +- if "GnuTLS" in tls or "wolfSSL" in tls: ++ if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: + ca_cert = "auth_serv/iCA-user/ca-and-root.pem" + client_cert = "auth_serv/iCA-user/user_and_ica.pem" + else: +@@ -4810,6 +4855,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca + run_ap_wpa2_eap_tls_intermediate_ca_ocsp(dev, apdev, params, "-sha1") + + def run_ap_wpa2_eap_tls_intermediate_ca_ocsp(dev, apdev, params, md): ++ check_ocsp_support(dev[0]) + params = int_eap_server_params() + params["ca_cert"] = "auth_serv/iCA-server/ca-and-root.pem" + params["server_cert"] = "auth_serv/iCA-server/server.pem" +@@ -4819,7 +4865,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ + try: + hostapd.add_ap(apdev[0], params) + tls = dev[0].request("GET tls_library") +- if "GnuTLS" in tls or "wolfSSL" in tls: ++ if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: + ca_cert = "auth_serv/iCA-user/ca-and-root.pem" + client_cert = "auth_serv/iCA-user/user_and_ica.pem" + else: +@@ -4855,7 +4901,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ + try: + hostapd.add_ap(apdev[0], params) + tls = dev[0].request("GET tls_library") +- if "GnuTLS" in tls or "wolfSSL" in tls: ++ if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: + ca_cert = "auth_serv/iCA-user/ca-and-root.pem" + client_cert = "auth_serv/iCA-user/user_and_ica.pem" + else: +@@ -4905,7 +4951,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca + try: + hostapd.add_ap(apdev[0], params) + tls = dev[0].request("GET tls_library") +- if "GnuTLS" in tls or "wolfSSL" in tls: ++ if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: + ca_cert = "auth_serv/iCA-user/ca-and-root.pem" + client_cert = "auth_serv/iCA-user/user_and_ica.pem" + else: +@@ -4972,7 +5018,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca + + hostapd.add_ap(apdev[0], params) + tls = dev[0].request("GET tls_library") +- if "GnuTLS" in tls or "wolfSSL" in tls: ++ if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: + ca_cert = "auth_serv/iCA-user/ca-and-root.pem" + client_cert = "auth_serv/iCA-user/user_and_ica.pem" + else: +@@ -5230,6 +5276,7 @@ def test_ap_wpa2_eap_ttls_server_cert_ek + + def test_ap_wpa2_eap_ttls_server_pkcs12(dev, apdev): + """WPA2-Enterprise using EAP-TTLS and server PKCS#12 file""" ++ check_pkcs12_support(dev[0]) + skip_with_fips(dev[0]) + params = int_eap_server_params() + del params["server_cert"] +@@ -5242,6 +5289,7 @@ def test_ap_wpa2_eap_ttls_server_pkcs12( + + def test_ap_wpa2_eap_ttls_server_pkcs12_extra(dev, apdev): + """EAP-TTLS and server PKCS#12 file with extra certs""" ++ check_pkcs12_support(dev[0]) + skip_with_fips(dev[0]) + params = int_eap_server_params() + del params["server_cert"] +@@ -5264,6 +5312,7 @@ def test_ap_wpa2_eap_ttls_dh_params_serv + + def test_ap_wpa2_eap_ttls_dh_params_dsa_server(dev, apdev): + """WPA2-Enterprise using EAP-TTLS and alternative server dhparams (DSA)""" ++ check_dh_dsa_support(dev[0]) + params = int_eap_server_params() + params["dh_file"] = "auth_serv/dsaparam.pem" + hapd = hostapd.add_ap(apdev[0], params) +@@ -5575,8 +5624,8 @@ def test_ap_wpa2_eap_non_ascii_identity2 + def test_openssl_cipher_suite_config_wpas(dev, apdev): + """OpenSSL cipher suite configuration on wpa_supplicant""" + tls = dev[0].request("GET tls_library") +- if not tls.startswith("OpenSSL"): +- raise HwsimSkip("TLS library is not OpenSSL: " + tls) ++ if not tls.startswith("OpenSSL") and not tls.startswith("mbed TLS"): ++ raise HwsimSkip("TLS library is not OpenSSL or mbed TLS: " + tls) + params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") + hapd = hostapd.add_ap(apdev[0], params) + eap_connect(dev[0], hapd, "TTLS", "pap user", +@@ -5602,14 +5651,14 @@ def test_openssl_cipher_suite_config_wpa + def test_openssl_cipher_suite_config_hapd(dev, apdev): + """OpenSSL cipher suite configuration on hostapd""" + tls = dev[0].request("GET tls_library") +- if not tls.startswith("OpenSSL"): +- raise HwsimSkip("wpa_supplicant TLS library is not OpenSSL: " + tls) ++ if not tls.startswith("OpenSSL") and not tls.startswith("mbed TLS"): ++ raise HwsimSkip("wpa_supplicant TLS library is not OpenSSL or mbed TLS: " + tls) + params = int_eap_server_params() + params['openssl_ciphers'] = "AES256" + hapd = hostapd.add_ap(apdev[0], params) + tls = hapd.request("GET tls_library") +- if not tls.startswith("OpenSSL"): +- raise HwsimSkip("hostapd TLS library is not OpenSSL: " + tls) ++ if not tls.startswith("OpenSSL") and not tls.startswith("mbed TLS"): ++ raise HwsimSkip("hostapd TLS library is not OpenSSL or mbed TLS: " + tls) + eap_connect(dev[0], hapd, "TTLS", "pap user", + anonymous_identity="ttls", password="password", + ca_cert="auth_serv/ca.pem", phase2="auth=PAP") +@@ -6051,13 +6100,17 @@ def test_ap_wpa2_eap_tls_versions(dev, a + check_tls_ver(dev[0], hapd, + "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1", + "TLSv1.2") +- elif tls.startswith("internal"): ++ elif tls.startswith("internal") or tls.startswith("mbed TLS"): + check_tls_ver(dev[0], hapd, + "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1", "TLSv1.2") +- check_tls_ver(dev[1], hapd, +- "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=0 tls_disable_tlsv1_2=1", "TLSv1.1") +- check_tls_ver(dev[2], hapd, +- "tls_disable_tlsv1_0=0 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1", "TLSv1") ++ if tls.startswith("mbed TLS"): ++ check_tls_ver(dev[2], hapd, ++ "tls_disable_tlsv1_0=0 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1", "TLSv1.0") ++ else: ++ check_tls_ver(dev[1], hapd, ++ "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=0 tls_disable_tlsv1_2=1", "TLSv1.1") ++ check_tls_ver(dev[2], hapd, ++ "tls_disable_tlsv1_0=0 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1", "TLSv1") + if "run=OpenSSL 1.1.1" in tls or "run=OpenSSL 3.0" in tls: + check_tls_ver(dev[0], hapd, + "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1 tls_disable_tlsv1_3=0", "TLSv1.3") +@@ -6079,6 +6132,11 @@ def test_ap_wpa2_eap_tls_versions_server + tests = [("TLSv1", "[ENABLE-TLSv1.0][DISABLE-TLSv1.1][DISABLE-TLSv1.2][DISABLE-TLSv1.3]"), + ("TLSv1.1", "[ENABLE-TLSv1.0][ENABLE-TLSv1.1][DISABLE-TLSv1.2][DISABLE-TLSv1.3]"), + ("TLSv1.2", "[ENABLE-TLSv1.0][ENABLE-TLSv1.1][ENABLE-TLSv1.2][DISABLE-TLSv1.3]")] ++ tls = dev[0].request("GET tls_library") ++ if tls.startswith("mbed TLS"): ++ tests = [#("TLSv1.0", "[ENABLE-TLSv1.0][DISABLE-TLSv1.1][DISABLE-TLSv1.2][DISABLE-TLSv1.3]"), ++ #("TLSv1.1", "[ENABLE-TLSv1.0][ENABLE-TLSv1.1][DISABLE-TLSv1.2][DISABLE-TLSv1.3]"), ++ ("TLSv1.2", "[ENABLE-TLSv1.0][ENABLE-TLSv1.1][ENABLE-TLSv1.2][DISABLE-TLSv1.3]")] + for exp, flags in tests: + hapd.disable() + hapd.set("tls_flags", flags) +@@ -7138,6 +7196,7 @@ def test_ap_wpa2_eap_assoc_rsn(dev, apde + def test_eap_tls_ext_cert_check(dev, apdev): + """EAP-TLS and external server certification validation""" + # With internal server certificate chain validation ++ check_ext_cert_check_support(dev[0]) + id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TLS", + identity="tls user", + ca_cert="auth_serv/ca.pem", +@@ -7150,6 +7209,7 @@ def test_eap_tls_ext_cert_check(dev, apd + def test_eap_ttls_ext_cert_check(dev, apdev): + """EAP-TTLS and external server certification validation""" + # Without internal server certificate chain validation ++ check_ext_cert_check_support(dev[0]) + id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", + identity="pap user", anonymous_identity="ttls", + password="password", phase2="auth=PAP", +@@ -7160,6 +7220,7 @@ def test_eap_ttls_ext_cert_check(dev, ap + def test_eap_peap_ext_cert_check(dev, apdev): + """EAP-PEAP and external server certification validation""" + # With internal server certificate chain validation ++ check_ext_cert_check_support(dev[0]) + id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="PEAP", + identity="user", anonymous_identity="peap", + ca_cert="auth_serv/ca.pem", +@@ -7170,6 +7231,7 @@ def test_eap_peap_ext_cert_check(dev, ap + + def test_eap_fast_ext_cert_check(dev, apdev): + """EAP-FAST and external server certification validation""" ++ check_ext_cert_check_support(dev[0]) + check_eap_capa(dev[0], "FAST") + # With internal server certificate chain validation + dev[0].request("SET blob fast_pac_auth_ext ") +@@ -7184,10 +7246,6 @@ def test_eap_fast_ext_cert_check(dev, ap + run_ext_cert_check(dev, apdev, id) + + def run_ext_cert_check(dev, apdev, net_id): +- check_ext_cert_check_support(dev[0]) +- if not openssl_imported: +- raise HwsimSkip("OpenSSL python method not available") +- + params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") + hapd = hostapd.add_ap(apdev[0], params) + +--- a/tests/hwsim/test_ap_ft.py ++++ b/tests/hwsim/test_ap_ft.py +@@ -2474,11 +2474,11 @@ def test_ap_ft_ap_oom5(dev, apdev): + # This will fail to roam + dev[0].roam(bssid1, check_bssid=False) + +- with fail_test(hapd1, 1, "sha256_prf_bits;wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): ++ with fail_test(hapd1, 1, "sha256_prf;wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): + # This will fail to roam + dev[0].roam(bssid1, check_bssid=False) + +- with fail_test(hapd1, 3, "wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): ++ with fail_test(hapd1, 2, "wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): + # This will fail to roam + dev[0].roam(bssid1, check_bssid=False) + +--- a/tests/hwsim/test_authsrv.py ++++ b/tests/hwsim/test_authsrv.py +@@ -156,9 +156,12 @@ def test_authsrv_oom(dev, apdev): + if "FAIL" not in authsrv.request("ENABLE"): + raise Exception("ENABLE succeeded during OOM") + +- with alloc_fail(authsrv, 1, "tls_init;authsrv_init"): +- if "FAIL" not in authsrv.request("ENABLE"): +- raise Exception("ENABLE succeeded during OOM") ++ # tls_mbedtls.c:tls_init() does not alloc memory (no alloc fail trigger) ++ tls = dev[0].request("GET tls_library") ++ if not tls.startswith("mbed TLS"): ++ with alloc_fail(authsrv, 1, "tls_init;authsrv_init"): ++ if "FAIL" not in authsrv.request("ENABLE"): ++ raise Exception("ENABLE succeeded during OOM") + + for count in range(1, 3): + with alloc_fail(authsrv, count, "eap_sim_db_init;authsrv_init"): +--- a/tests/hwsim/test_dpp.py ++++ b/tests/hwsim/test_dpp.py +@@ -39,7 +39,8 @@ def check_dpp_capab(dev, brainpool=False + raise HwsimSkip("DPP not supported") + if brainpool: + tls = dev.request("GET tls_library") +- if (not tls.startswith("OpenSSL") or "run=BoringSSL" in tls) and not tls.startswith("wolfSSL"): ++ if (not tls.startswith("OpenSSL") or "run=BoringSSL" in tls) and not tls.startswith("wolfSSL") \ ++ and not tls.startswith("mbed TLS"): + raise HwsimSkip("Crypto library does not support Brainpool curves: " + tls) + capa = dev.request("GET_CAPABILITY dpp") + ver = 1 +@@ -3892,6 +3893,9 @@ def test_dpp_proto_auth_req_no_i_proto_k + + def test_dpp_proto_auth_req_invalid_i_proto_key(dev, apdev): + """DPP protocol testing - invalid I-proto key in Auth Req""" ++ tls = dev[0].request("GET tls_library") ++ if tls.startswith("mbed TLS"): ++ raise HwsimSkip("mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key; no response") + run_dpp_proto_auth_req_missing(dev, 66, "Invalid Initiator Protocol Key") + + def test_dpp_proto_auth_req_no_i_nonce(dev, apdev): +@@ -3987,7 +3991,12 @@ def test_dpp_proto_auth_resp_no_r_proto_ + + def test_dpp_proto_auth_resp_invalid_r_proto_key(dev, apdev): + """DPP protocol testing - invalid R-Proto Key in Auth Resp""" +- run_dpp_proto_auth_resp_missing(dev, 67, "Invalid Responder Protocol Key") ++ tls = dev[0].request("GET tls_library") ++ if tls.startswith("mbed TLS"): ++ # mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key ++ run_dpp_proto_auth_resp_missing(dev, 67, "Failed to derive ECDH shared secret") ++ else: ++ run_dpp_proto_auth_resp_missing(dev, 67, "Invalid Responder Protocol Key") + + def test_dpp_proto_auth_resp_no_r_nonce(dev, apdev): + """DPP protocol testing - no R-nonce in Auth Resp""" +@@ -4349,11 +4358,17 @@ def test_dpp_proto_pkex_exchange_resp_in + + def test_dpp_proto_pkex_cr_req_invalid_bootstrap_key(dev, apdev): + """DPP protocol testing - invalid Bootstrap Key in PKEX Commit-Reveal Request""" ++ tls = dev[0].request("GET tls_library") ++ if tls.startswith("mbed TLS"): ++ raise HwsimSkip("mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key; no response") + run_dpp_proto_pkex_req_missing(dev, 47, + "Peer bootstrapping key is invalid") + + def test_dpp_proto_pkex_cr_resp_invalid_bootstrap_key(dev, apdev): + """DPP protocol testing - invalid Bootstrap Key in PKEX Commit-Reveal Response""" ++ tls = dev[0].request("GET tls_library") ++ if tls.startswith("mbed TLS"): ++ raise HwsimSkip("mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key; no response") + run_dpp_proto_pkex_resp_missing(dev, 48, + "Peer bootstrapping key is invalid") + +--- a/tests/hwsim/test_erp.py ++++ b/tests/hwsim/test_erp.py +@@ -12,7 +12,7 @@ import time + + import hostapd + from utils import * +-from test_ap_eap import int_eap_server_params, check_tls13_support ++from test_ap_eap import int_eap_server_params, check_tls13_support, check_eap_capa + from test_ap_psk import find_wpas_process, read_process_memory, verify_not_present, get_key_locations + + def test_erp_initiate_reauth_start(dev, apdev): +@@ -276,6 +276,7 @@ def test_erp_radius_eap_methods(dev, apd + params['erp_domain'] = 'example.com' + params['disable_pmksa_caching'] = '1' + hapd = hostapd.add_ap(apdev[0], params) ++ tls = dev[0].request("GET tls_library") + + erp_test(dev[0], hapd, eap="AKA", identity="0232010000000000@example.com", + password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123") +@@ -289,7 +290,7 @@ def test_erp_radius_eap_methods(dev, apd + password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123") + erp_test(dev[0], hapd, eap="EKE", identity="erp-eke@example.com", + password="hello") +- if "FAST" in eap_methods: ++ if "FAST" in eap_methods and check_eap_capa(dev[0], "FAST"): + erp_test(dev[0], hapd, eap="FAST", identity="erp-fast@example.com", + password="password", ca_cert="auth_serv/ca.pem", + phase2="auth=GTC", +@@ -301,13 +302,14 @@ def test_erp_radius_eap_methods(dev, apd + password="password") + erp_test(dev[0], hapd, eap="PAX", identity="erp-pax@example.com", + password_hex="0123456789abcdef0123456789abcdef") +- if "MSCHAPV2" in eap_methods: ++ if "MSCHAPV2" in eap_methods and check_eap_capa(dev[0], "MSCHAPV2"): + erp_test(dev[0], hapd, eap="PEAP", identity="erp-peap@example.com", + password="password", ca_cert="auth_serv/ca.pem", + phase2="auth=MSCHAPV2") +- erp_test(dev[0], hapd, eap="TEAP", identity="erp-teap@example.com", +- password="password", ca_cert="auth_serv/ca.pem", +- phase2="auth=MSCHAPV2", pac_file="blob://teap_pac") ++ if check_eap_capa(dev[0], "TEAP"): ++ erp_test(dev[0], hapd, eap="TEAP", identity="erp-teap@example.com", ++ password="password", ca_cert="auth_serv/ca.pem", ++ phase2="auth=MSCHAPV2", pac_file="blob://teap_pac") + erp_test(dev[0], hapd, eap="PSK", identity="erp-psk@example.com", + password_hex="0123456789abcdef0123456789abcdef") + if "PWD" in eap_methods: +@@ -640,7 +642,7 @@ def test_erp_local_errors(dev, apdev): + dev[0].request("REMOVE_NETWORK all") + dev[0].wait_disconnected() + +- for count in range(1, 6): ++ for count in range(1, 4): + dev[0].request("ERP_FLUSH") + with fail_test(dev[0], count, "hmac_sha256_kdf;eap_peer_erp_init"): + dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", +--- a/tests/hwsim/test_fils.py ++++ b/tests/hwsim/test_fils.py +@@ -1422,7 +1422,10 @@ def run_fils_sk_pfs(dev, apdev, group, p + check_erp_capa(dev[0]) + + tls = dev[0].request("GET tls_library") +- if not tls.startswith("wolfSSL"): ++ if tls.startswith("mbed TLS"): ++ if int(group) == 27: ++ raise HwsimSkip("Brainpool EC group 27 not supported by mbed TLS") ++ elif not tls.startswith("wolfSSL"): + if int(group) in [25]: + if not (tls.startswith("OpenSSL") and ("build=OpenSSL 1.0.2" in tls or "build=OpenSSL 1.1" in tls or "build=OpenSSL 3.0" in tls) and ("run=OpenSSL 1.0.2" in tls or "run=OpenSSL 1.1" in tls or "run=OpenSSL 3.0" in tls)): + raise HwsimSkip("EC group not supported") +--- a/tests/hwsim/test_pmksa_cache.py ++++ b/tests/hwsim/test_pmksa_cache.py +@@ -955,7 +955,7 @@ def test_pmksa_cache_preauth_wpas_oom(de + eap_connect(dev[0], hapd, "PAX", "pax.user@example.com", + password_hex="0123456789abcdef0123456789abcdef", + bssid=apdev[0]['bssid']) +- for i in range(1, 11): ++ for i in range(1, 10): + with alloc_fail(dev[0], i, "rsn_preauth_init"): + res = dev[0].request("PREAUTH f2:11:22:33:44:55").strip() + logger.info("Iteration %d - PREAUTH command results: %s" % (i, res)) +@@ -963,7 +963,7 @@ def test_pmksa_cache_preauth_wpas_oom(de + state = dev[0].request('GET_ALLOC_FAIL') + if state.startswith('0:'): + break +- time.sleep(0.05) ++ time.sleep(0.10) + + def test_pmksa_cache_ctrl(dev, apdev): + """PMKSA cache control interface operations""" +--- a/tests/hwsim/test_sae.py ++++ b/tests/hwsim/test_sae.py +@@ -177,6 +177,11 @@ def test_sae_groups(dev, apdev): + if tls.startswith("OpenSSL") and "run=OpenSSL 1." in tls: + logger.info("Add Brainpool EC groups since OpenSSL is new enough") + sae_groups += [27, 28, 29, 30] ++ if tls.startswith("mbed TLS"): ++ # secp224k1 and secp224r1 (26) have prime p = 1 mod 4, and mbedtls ++ # does not have code to derive y from compressed format for those curves ++ sae_groups = [19, 25, 20, 21, 1, 2, 5, 14, 15, 16, 22, 23, 24] ++ sae_groups += [27, 28, 29, 30] + heavy_groups = [14, 15, 16] + suitable_groups = [15, 16, 17, 18, 19, 20, 21] + groups = [str(g) for g in sae_groups] +@@ -2193,6 +2198,8 @@ def run_sae_pwe_group(dev, apdev, group) + logger.info("Add Brainpool EC groups since OpenSSL is new enough") + elif tls.startswith("wolfSSL"): + logger.info("Make sure Brainpool EC groups were enabled when compiling wolfSSL") ++ elif tls.startswith("mbed TLS"): ++ logger.info("Make sure Brainpool EC groups were enabled when compiling mbed TLS") + else: + raise HwsimSkip("Brainpool curve not supported") + start_sae_pwe_ap(apdev[0], group, 2) +--- a/tests/hwsim/test_suite_b.py ++++ b/tests/hwsim/test_suite_b.py +@@ -27,6 +27,8 @@ def check_suite_b_tls_lib(dev, dhe=False + return + if tls.startswith("wolfSSL"): + return ++ if tls.startswith("mbed TLS"): ++ return + if not tls.startswith("OpenSSL"): + raise HwsimSkip("TLS library not supported for Suite B: " + tls) + supported = False +@@ -520,6 +522,7 @@ def test_suite_b_192_rsa_insufficient_dh + + dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192", + ieee80211w="2", ++ openssl_ciphers="DHE-RSA-AES256-GCM-SHA384", + phase1="tls_suiteb=1", + eap="TLS", identity="tls user", + ca_cert="auth_serv/rsa3072-ca.pem", +--- a/tests/hwsim/test_wpas_ctrl.py ++++ b/tests/hwsim/test_wpas_ctrl.py +@@ -1842,7 +1842,7 @@ def _test_wpas_ctrl_oom(dev): + tls = dev[0].request("GET tls_library") + if not tls.startswith("internal"): + tests.append(('NFC_GET_HANDOVER_SEL NDEF P2P-CR-TAG', 'FAIL', +- 4, 'wpas_ctrl_nfc_get_handover_sel_p2p')) ++ 3, 'wpas_ctrl_nfc_get_handover_sel_p2p')) + for cmd, exp, count, func in tests: + with alloc_fail(dev[0], count, func): + res = dev[0].request(cmd) +--- a/tests/hwsim/utils.py ++++ b/tests/hwsim/utils.py +@@ -141,7 +141,13 @@ def check_imsi_privacy_support(dev): + + def check_tls_tod(dev): + tls = dev.request("GET tls_library") +- if not tls.startswith("OpenSSL") and not tls.startswith("internal"): ++ if tls.startswith("OpenSSL"): ++ return ++ elif tls.startswith("internal"): ++ return ++ elif tls.startswith("mbed TLS"): ++ return ++ else: + raise HwsimSkip("TLS TOD-TOFU/STRICT not supported with this TLS library: " + tls) + + def vht_supported(): +--- /dev/null ++++ b/tests/test-crypto_module.c +@@ -0,0 +1,16 @@ ++/* ++ * crypto module tests - test program ++ * Copyright (c) 2022, Glenn Strauss ++ * ++ * This software may be distributed under the terms of the BSD license. ++ * See README for more details. ++ */ ++ ++#include "utils/includes.h" ++#include "utils/module_tests.h" ++#include "crypto/crypto_module_tests.c" ++ ++int main(int argc, char *argv[]) ++{ ++ return crypto_module_tests(); ++} +--- a/tests/test-https.c ++++ b/tests/test-https.c +@@ -75,7 +75,7 @@ static int https_client(int s, const cha + struct tls_connection *conn; + struct wpabuf *in, *out, *appl; + int res = -1; +- int need_more_data; ++ int need_more_data = 0; + + os_memset(&conf, 0, sizeof(conf)); + conf.event_cb = https_tls_event_cb; +@@ -93,8 +93,12 @@ static int https_client(int s, const cha + + for (;;) { + appl = NULL; ++#ifdef CONFIG_TLS_INTERNAL_SERVER + out = tls_connection_handshake2(tls, conn, in, &appl, + &need_more_data); ++#else ++ out = tls_connection_handshake(tls, conn, in, &appl); ++#endif + wpabuf_free(in); + in = NULL; + if (out == NULL) { +@@ -152,11 +156,15 @@ static int https_client(int s, const cha + + wpa_printf(MSG_INFO, "Reading HTTP response"); + for (;;) { +- int need_more_data; ++ int need_more_data = 0; + in = https_recv(s); + if (in == NULL) + goto done; ++#ifdef CONFIG_TLS_INTERNAL_SERVER + out = tls_connection_decrypt2(tls, conn, in, &need_more_data); ++#else ++ out = tls_connection_decrypt(tls, conn, in); ++#endif + if (need_more_data) + wpa_printf(MSG_DEBUG, "HTTP: Need more data"); + wpabuf_free(in); +--- a/tests/test-https_server.c ++++ b/tests/test-https_server.c +@@ -67,10 +67,12 @@ static struct wpabuf * https_recv(int s, + } + + ++#ifdef CONFIG_TLS_INTERNAL_SERVER + static void https_tls_log_cb(void *ctx, const char *msg) + { + wpa_printf(MSG_DEBUG, "TLS: %s", msg); + } ++#endif + + + static int https_server(int s) +@@ -79,7 +81,7 @@ static int https_server(int s) + void *tls; + struct tls_connection_params params; + struct tls_connection *conn; +- struct wpabuf *in, *out, *appl; ++ struct wpabuf *in = NULL, *out = NULL, *appl = NULL; + int res = -1; + + os_memset(&conf, 0, sizeof(conf)); +@@ -106,7 +108,9 @@ static int https_server(int s) + return -1; + } + ++#ifdef CONFIG_TLS_INTERNAL_SERVER + tls_connection_set_log_cb(conn, https_tls_log_cb, NULL); ++#endif + + for (;;) { + in = https_recv(s, 5000); +@@ -147,12 +151,16 @@ static int https_server(int s) + + wpa_printf(MSG_INFO, "Reading HTTP request"); + for (;;) { +- int need_more_data; ++ int need_more_data = 0; + + in = https_recv(s, 5000); + if (!in) + goto done; ++#ifdef CONFIG_TLS_INTERNAL_SERVER + out = tls_connection_decrypt2(tls, conn, in, &need_more_data); ++#else ++ out = tls_connection_decrypt(tls, conn, in); ++#endif + wpabuf_free(in); + in = NULL; + if (need_more_data) { +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -1122,6 +1122,7 @@ CFLAGS += -DCONFIG_TLSV12 + endif + + ifeq ($(CONFIG_TLS), wolfssl) ++CFLAGS += -DCONFIG_TLS_WOLFSSL + ifdef TLS_FUNCS + CFLAGS += -DWOLFSSL_DER_LOAD + OBJS += ../src/crypto/tls_wolfssl.o +@@ -1137,6 +1138,7 @@ LIBS_p += -lwolfssl -lm + endif + + ifeq ($(CONFIG_TLS), openssl) ++CFLAGS += -DCONFIG_TLS_OPENSSL + CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 + ifdef TLS_FUNCS + CFLAGS += -DEAP_TLS_OPENSSL +@@ -1164,6 +1166,7 @@ CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONF + endif + + ifeq ($(CONFIG_TLS), mbedtls) ++CFLAGS += -DCONFIG_TLS_MBEDTLS + ifndef CONFIG_CRYPTO + CONFIG_CRYPTO=mbedtls + endif +@@ -1183,6 +1186,7 @@ endif + endif + + ifeq ($(CONFIG_TLS), gnutls) ++CFLAGS += -DCONFIG_TLS_GNUTLS + ifndef CONFIG_CRYPTO + # default to libgcrypt + CONFIG_CRYPTO=gnutls +@@ -1213,6 +1217,7 @@ endif + endif + + ifeq ($(CONFIG_TLS), internal) ++CFLAGS += -DCONFIG_TLS_INTERNAL + ifndef CONFIG_CRYPTO + CONFIG_CRYPTO=internal + endif +@@ -1293,6 +1298,7 @@ endif + endif + + ifeq ($(CONFIG_TLS), linux) ++CFLAGS += -DCONFIG_TLS_INTERNAL + OBJS += ../src/crypto/crypto_linux.o + OBJS_p += ../src/crypto/crypto_linux.o + ifdef TLS_FUNCS diff --git a/feeds/ipq95xx/hostapd/patches/150-add-NULL-checks-encountered-during-tests-hwsim.patch b/feeds/ipq95xx/hostapd/patches/150-add-NULL-checks-encountered-during-tests-hwsim.patch new file mode 100644 index 00000000..c8c3ff33 --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/150-add-NULL-checks-encountered-during-tests-hwsim.patch @@ -0,0 +1,45 @@ +From 33afce36c54b0cad38643629ded10ff5d727f077 Mon Sep 17 00:00:00 2001 +From: Glenn Strauss +Date: Fri, 12 Aug 2022 05:34:47 -0400 +Subject: [PATCH 5/7] add NULL checks (encountered during tests/hwsim) + +sae_derive_commit_element_ecc NULL pwe_ecc check +dpp_gen_keypair() NULL curve check + +Signed-off-by: Glenn Strauss +--- + src/common/dpp_crypto.c | 6 ++++++ + src/common/sae.c | 7 +++++++ + 2 files changed, 13 insertions(+) + +--- a/src/common/dpp_crypto.c ++++ b/src/common/dpp_crypto.c +@@ -269,6 +269,12 @@ int dpp_get_pubkey_hash(struct crypto_ec + + struct crypto_ec_key * dpp_gen_keypair(const struct dpp_curve_params *curve) + { ++ if (curve == NULL) { ++ wpa_printf(MSG_DEBUG, ++ "DPP: %s curve must be initialized", __func__); ++ return NULL; ++ } ++ + struct crypto_ec_key *key; + + wpa_printf(MSG_DEBUG, "DPP: Generating a keypair"); +--- a/src/common/sae.c ++++ b/src/common/sae.c +@@ -1278,6 +1278,13 @@ void sae_deinit_pt(struct sae_pt *pt) + static int sae_derive_commit_element_ecc(struct sae_data *sae, + struct crypto_bignum *mask) + { ++ if (sae->tmp->pwe_ecc == NULL) { ++ wpa_printf(MSG_DEBUG, ++ "SAE: %s sae->tmp->pwe_ecc must be initialized", ++ __func__); ++ return -1; ++ } ++ + /* COMMIT-ELEMENT = inverse(scalar-op(mask, PWE)) */ + if (!sae->tmp->own_commit_element_ecc) { + sae->tmp->own_commit_element_ecc = diff --git a/feeds/ipq95xx/hostapd/patches/160-dpp_pkex-EC-point-mul-w-value-prime.patch b/feeds/ipq95xx/hostapd/patches/160-dpp_pkex-EC-point-mul-w-value-prime.patch new file mode 100644 index 00000000..db4fcfe2 --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/160-dpp_pkex-EC-point-mul-w-value-prime.patch @@ -0,0 +1,26 @@ +From 54211caa2e0e5163aefef390daf88a971367a702 Mon Sep 17 00:00:00 2001 +From: Glenn Strauss +Date: Tue, 4 Oct 2022 17:09:24 -0400 +Subject: [PATCH 6/7] dpp_pkex: EC point mul w/ value < prime + +crypto_ec_point_mul() with mbedtls requires point +be multiplied by a multiplicand with value < prime + +Signed-off-by: Glenn Strauss +--- + src/common/dpp_crypto.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/src/common/dpp_crypto.c ++++ b/src/common/dpp_crypto.c +@@ -1588,7 +1588,9 @@ dpp_pkex_derive_Qr(const struct dpp_curv + Pr = crypto_ec_key_get_public_key(Pr_key); + Qr = crypto_ec_point_init(ec); + hash_bn = crypto_bignum_init_set(hash, curve->hash_len); +- if (!Pr || !Qr || !hash_bn || crypto_ec_point_mul(ec, Pr, hash_bn, Qr)) ++ if (!Pr || !Qr || !hash_bn || ++ crypto_bignum_mod(hash_bn, crypto_ec_get_prime(ec), hash_bn) || ++ crypto_ec_point_mul(ec, Pr, hash_bn, Qr)) + goto fail; + + if (crypto_ec_point_is_at_infinity(ec, Qr)) { diff --git a/feeds/ipq95xx/hostapd/patches/180-driver_nl80211-fix-setting-QoS-map-on-secondary-BSSs.patch b/feeds/ipq95xx/hostapd/patches/180-driver_nl80211-fix-setting-QoS-map-on-secondary-BSSs.patch new file mode 100644 index 00000000..4929c581 --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/180-driver_nl80211-fix-setting-QoS-map-on-secondary-BSSs.patch @@ -0,0 +1,20 @@ +From: Felix Fietkau +Date: Thu, 14 Sep 2023 10:53:50 +0200 +Subject: [PATCH] driver_nl80211: fix setting QoS map on secondary BSSs + +The setting is per-BSS, not per PHY + +Signed-off-by: Felix Fietkau +--- + +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -11341,7 +11341,7 @@ static int nl80211_set_qos_map(void *pri + wpa_hexdump(MSG_DEBUG, "nl80211: Setting QoS Map", + qos_map_set, qos_map_set_len); + +- if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_QOS_MAP)) || ++ if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_QOS_MAP)) || + nla_put(msg, NL80211_ATTR_QOS_MAP, qos_map_set_len, qos_map_set)) { + nlmsg_free(msg); + return -ENOBUFS; diff --git a/feeds/ipq95xx/hostapd/patches/181-driver_nl80211-update-drv-ifindex-on-removing-the-fi.patch b/feeds/ipq95xx/hostapd/patches/181-driver_nl80211-update-drv-ifindex-on-removing-the-fi.patch new file mode 100644 index 00000000..adfb21fb --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/181-driver_nl80211-update-drv-ifindex-on-removing-the-fi.patch @@ -0,0 +1,18 @@ +From: Felix Fietkau +Date: Thu, 14 Sep 2023 11:28:03 +0200 +Subject: [PATCH] driver_nl80211: update drv->ifindex on removing the first + BSS + +Signed-off-by: Felix Fietkau +--- + +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -8867,6 +8867,7 @@ static int wpa_driver_nl80211_if_remove( + if (drv->first_bss->next) { + drv->first_bss = drv->first_bss->next; + drv->ctx = drv->first_bss->ctx; ++ drv->ifindex = drv->first_bss->ifindex; + os_free(bss); + } else { + wpa_printf(MSG_DEBUG, "nl80211: No second BSS to reassign context to"); diff --git a/feeds/ipq95xx/hostapd/patches/182-nl80211-move-nl80211_put_freq_params-call-outside-of.patch b/feeds/ipq95xx/hostapd/patches/182-nl80211-move-nl80211_put_freq_params-call-outside-of.patch new file mode 100644 index 00000000..395c6459 --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/182-nl80211-move-nl80211_put_freq_params-call-outside-of.patch @@ -0,0 +1,34 @@ +From: Felix Fietkau +Date: Mon, 18 Sep 2023 16:47:41 +0200 +Subject: [PATCH] nl80211: move nl80211_put_freq_params call outside of + 802.11ax #ifdef + +The relevance of this call is not specific to 802.11ax, so it should be done +even with CONFIG_IEEE80211AX disabled. + +Fixes: b3921db426ea ("nl80211: Add frequency info in start AP command") +Signed-off-by: Felix Fietkau +--- + +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -5226,6 +5226,9 @@ static int wpa_driver_nl80211_set_ap(voi + nla_nest_end(msg, ftm); + } + ++ if (params->freq && nl80211_put_freq_params(msg, params->freq) < 0) ++ goto fail; ++ + #ifdef CONFIG_IEEE80211AX + if (params->he_spr_ctrl) { + struct nlattr *spr; +@@ -5260,9 +5263,6 @@ static int wpa_driver_nl80211_set_ap(voi + nla_nest_end(msg, spr); + } + +- if (params->freq && nl80211_put_freq_params(msg, params->freq) < 0) +- goto fail; +- + if (params->freq && params->freq->he_enabled) { + struct nlattr *bss_color; + diff --git a/feeds/ipq95xx/hostapd/patches/183-hostapd-cancel-channel_list_update_timeout-in-hostap.patch b/feeds/ipq95xx/hostapd/patches/183-hostapd-cancel-channel_list_update_timeout-in-hostap.patch new file mode 100644 index 00000000..fe813183 --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/183-hostapd-cancel-channel_list_update_timeout-in-hostap.patch @@ -0,0 +1,28 @@ +From: Felix Fietkau +Date: Wed, 20 Sep 2023 13:41:10 +0200 +Subject: [PATCH] hostapd: cancel channel_list_update_timeout in + hostapd_cleanup_iface_partial + +Fixes a crash when disabling an interface during channel list update + +Signed-off-by: Felix Fietkau +--- + +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c +@@ -569,6 +569,7 @@ static void sta_track_deinit(struct host + void hostapd_cleanup_iface_partial(struct hostapd_iface *iface) + { + wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); ++ eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); + #ifdef NEED_AP_MLME + hostapd_stop_setup_timers(iface); + #endif /* NEED_AP_MLME */ +@@ -598,7 +599,6 @@ void hostapd_cleanup_iface_partial(struc + static void hostapd_cleanup_iface(struct hostapd_iface *iface) + { + wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); +- eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); + eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface, + NULL); + diff --git a/feeds/ipq95xx/hostapd/patches/200-multicall.patch b/feeds/ipq95xx/hostapd/patches/200-multicall.patch index 3d0e8035..e3ed00f2 100644 --- a/feeds/ipq95xx/hostapd/patches/200-multicall.patch +++ b/feeds/ipq95xx/hostapd/patches/200-multicall.patch @@ -18,7 +18,7 @@ OBJS += ../src/ap/vlan_init.o OBJS += ../src/ap/vlan_ifconfig.o OBJS += ../src/ap/vlan.o -@@ -349,10 +351,14 @@ CFLAGS += -DCONFIG_MBO +@@ -357,10 +359,14 @@ CFLAGS += -DCONFIG_MBO OBJS += ../src/ap/mbo_ap.o endif @@ -36,7 +36,7 @@ LIBS += $(DRV_AP_LIBS) ifdef CONFIG_L2_PACKET -@@ -1277,6 +1283,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR) +@@ -1380,6 +1386,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR) _OBJS_VAR := OBJS include ../src/objs.mk @@ -49,7 +49,7 @@ hostapd: $(OBJS) $(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS) @$(E) " LD " $@ -@@ -1351,6 +1363,12 @@ include ../src/objs.mk +@@ -1460,6 +1472,12 @@ include ../src/objs.mk _OBJS_VAR := SOBJS include ../src/objs.mk @@ -64,15 +64,15 @@ @$(E) " LD " $@ --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile -@@ -17,6 +17,7 @@ endif +@@ -10,6 +10,7 @@ ALL += dbus/fi.w1.wpa_supplicant1.servic EXTRA_TARGETS=dynamic_eap_methods CONFIG_FILE=.config +-include $(if $(MULTICALL),../hostapd/.config) include ../src/build.rules - ifdef LIBS -@@ -354,7 +355,9 @@ endif + ifdef CONFIG_BUILD_PASN_SO +@@ -382,7 +383,9 @@ endif ifdef CONFIG_IBSS_RSN NEED_RSN_AUTHENTICATOR=y CFLAGS += -DCONFIG_IBSS_RSN @@ -82,7 +82,7 @@ OBJS += ibss_rsn.o endif -@@ -886,6 +889,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS +@@ -924,6 +927,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS LIBS += -ldl -rdynamic endif @@ -93,7 +93,7 @@ endif ifdef CONFIG_AP -@@ -893,9 +900,11 @@ NEED_EAP_COMMON=y +@@ -931,9 +938,11 @@ NEED_EAP_COMMON=y NEED_RSN_AUTHENTICATOR=y CFLAGS += -DCONFIG_AP OBJS += ap.o @@ -105,7 +105,7 @@ OBJS += ../src/ap/hostapd.o OBJS += ../src/ap/wpa_auth_glue.o OBJS += ../src/ap/utils.o -@@ -975,6 +984,12 @@ endif +@@ -1022,6 +1031,12 @@ endif ifdef CONFIG_HS20 OBJS += ../src/ap/hs20.o endif @@ -118,7 +118,7 @@ endif ifdef CONFIG_MBO -@@ -983,7 +998,9 @@ CFLAGS += -DCONFIG_MBO +@@ -1030,7 +1045,9 @@ CFLAGS += -DCONFIG_MBO endif ifdef NEED_RSN_AUTHENTICATOR @@ -128,7 +128,7 @@ NEED_AES_WRAP=y OBJS += ../src/ap/wpa_auth.o OBJS += ../src/ap/wpa_auth_ie.o -@@ -1878,6 +1895,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv) +@@ -2010,6 +2027,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv) _OBJS_VAR := OBJS include ../src/objs.mk @@ -141,7 +141,7 @@ wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) $(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) @$(E) " LD " $@ -@@ -1983,6 +2006,12 @@ eap_eke.so: ../src/eap_peer/eap_eke.c .. +@@ -2142,6 +2165,12 @@ eap_gpsk.so: $(SRC_EAP_GPSK) $(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@ @$(E) " sed" $< @@ -156,7 +156,7 @@ wpa_cli.exe: wpa_cli --- a/src/drivers/driver.h +++ b/src/drivers/driver.h -@@ -6018,8 +6018,8 @@ union wpa_event_data { +@@ -6667,8 +6667,8 @@ union wpa_event_data { * Driver wrapper code should call this function whenever an event is received * from the driver. */ @@ -167,7 +167,7 @@ /** * wpa_supplicant_event_global - Report a driver event for wpa_supplicant -@@ -6031,7 +6031,7 @@ void wpa_supplicant_event(void *ctx, enu +@@ -6680,7 +6680,7 @@ void wpa_supplicant_event(void *ctx, enu * Same as wpa_supplicant_event(), but we search for the interface in * wpa_global. */ @@ -178,7 +178,7 @@ /* --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c -@@ -1827,8 +1827,8 @@ err: +@@ -2184,8 +2184,8 @@ err: #endif /* CONFIG_OWE */ @@ -189,7 +189,7 @@ { struct hostapd_data *hapd = ctx; #ifndef CONFIG_NO_STDOUT_DEBUG -@@ -2073,7 +2073,7 @@ void wpa_supplicant_event(void *ctx, enu +@@ -2489,7 +2489,7 @@ void wpa_supplicant_event(void *ctx, enu } @@ -200,7 +200,7 @@ struct hapd_interfaces *interfaces = ctx; --- a/wpa_supplicant/wpa_priv.c +++ b/wpa_supplicant/wpa_priv.c -@@ -1038,8 +1038,8 @@ static void wpa_priv_send_ft_response(st +@@ -1039,8 +1039,8 @@ static void wpa_priv_send_ft_response(st } @@ -211,7 +211,7 @@ { struct wpa_priv_interface *iface = ctx; -@@ -1102,7 +1102,7 @@ void wpa_supplicant_event(void *ctx, enu +@@ -1103,7 +1103,7 @@ void wpa_supplicant_event(void *ctx, enu } @@ -220,7 +220,7 @@ union wpa_event_data *data) { struct wpa_priv_global *global = ctx; -@@ -1215,6 +1215,8 @@ int main(int argc, char *argv[]) +@@ -1217,6 +1217,8 @@ int main(int argc, char *argv[]) if (os_program_init()) return -1; @@ -231,7 +231,7 @@ os_memset(&global, 0, sizeof(global)); --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c -@@ -4666,8 +4666,8 @@ static void wpas_event_unprot_beacon(str +@@ -5353,8 +5353,8 @@ static void wpas_link_reconfig(struct wp } @@ -242,7 +242,7 @@ { struct wpa_supplicant *wpa_s = ctx; int resched; -@@ -5512,7 +5512,7 @@ void wpa_supplicant_event(void *ctx, enu +@@ -6272,7 +6272,7 @@ void wpa_supplicant_event(void *ctx, enu } @@ -253,7 +253,7 @@ struct wpa_supplicant *wpa_s; --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -6814,7 +6814,6 @@ struct wpa_interface * wpa_supplicant_ma +@@ -7462,7 +7462,6 @@ struct wpa_interface * wpa_supplicant_ma return NULL; } @@ -261,7 +261,7 @@ /** * wpa_supplicant_match_existing - Match existing interfaces * @global: Pointer to global data from wpa_supplicant_init() -@@ -6849,6 +6848,11 @@ static int wpa_supplicant_match_existing +@@ -7497,6 +7496,11 @@ static int wpa_supplicant_match_existing #endif /* CONFIG_MATCH_IFACE */ @@ -273,7 +273,7 @@ /** * wpa_supplicant_add_iface - Add a new network interface -@@ -7105,6 +7109,8 @@ struct wpa_global * wpa_supplicant_init( +@@ -7753,6 +7757,8 @@ struct wpa_global * wpa_supplicant_init( #ifndef CONFIG_NO_WPA_MSG wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb); #endif /* CONFIG_NO_WPA_MSG */ @@ -284,7 +284,7 @@ wpa_debug_open_file(params->wpa_debug_file_path); --- a/hostapd/main.c +++ b/hostapd/main.c -@@ -590,6 +590,11 @@ fail: +@@ -698,6 +698,11 @@ fail: return -1; } @@ -296,14 +296,14 @@ #ifdef CONFIG_WPS static int gen_uuid(const char *txt_addr) -@@ -683,6 +688,8 @@ int main(int argc, char *argv[]) +@@ -791,6 +796,8 @@ int main(int argc, char *argv[]) return -1; #endif /* CONFIG_DPP */ + wpa_supplicant_event = hostapd_wpa_event; + wpa_supplicant_event_global = hostapd_wpa_event_global; for (;;) { - c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:vg:G:"); + c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:vg:G:q"); if (c < 0) --- a/src/drivers/drivers.c +++ b/src/drivers/drivers.c @@ -320,7 +320,7 @@ { --- a/wpa_supplicant/eapol_test.c +++ b/wpa_supplicant/eapol_test.c -@@ -30,7 +30,12 @@ +@@ -31,7 +31,12 @@ #include "ctrl_iface.h" #include "pcsc_funcs.h" #include "wpas_glue.h" @@ -333,7 +333,7 @@ const struct wpa_driver_ops *const wpa_drivers[] = { NULL }; -@@ -1292,6 +1297,10 @@ static void usage(void) +@@ -1303,6 +1308,10 @@ static void usage(void) "option several times.\n"); } @@ -344,7 +344,7 @@ int main(int argc, char *argv[]) { -@@ -1312,6 +1321,8 @@ int main(int argc, char *argv[]) +@@ -1323,6 +1332,8 @@ int main(int argc, char *argv[]) if (os_program_init()) return -1; diff --git a/feeds/ipq95xx/hostapd/patches/300-noscan.patch b/feeds/ipq95xx/hostapd/patches/300-noscan.patch index 98a43177..3b5f4325 100644 --- a/feeds/ipq95xx/hostapd/patches/300-noscan.patch +++ b/feeds/ipq95xx/hostapd/patches/300-noscan.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3439,6 +3439,10 @@ static int hostapd_config_fill(struct ho +@@ -3448,6 +3448,10 @@ static int hostapd_config_fill(struct ho if (bss->ocv && !bss->ieee80211w) bss->ieee80211w = 1; #endif /* CONFIG_OCV */ @@ -13,7 +13,7 @@ } else if (os_strcmp(buf, "ht_capab") == 0) { --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h -@@ -995,6 +995,8 @@ struct hostapd_config { +@@ -1075,6 +1075,8 @@ struct hostapd_config { int ht_op_mode_fixed; u16 ht_capab; @@ -24,7 +24,7 @@ int no_pri_sec_switch; --- a/src/ap/hw_features.c +++ b/src/ap/hw_features.c -@@ -517,7 +517,8 @@ static int ieee80211n_check_40mhz(struct +@@ -546,7 +546,8 @@ static int ieee80211n_check_40mhz(struct int ret; /* Check that HT40 is used and PRI / SEC switch is allowed */ @@ -36,7 +36,7 @@ hostapd_set_state(iface, HAPD_IFACE_HT_SCAN); --- a/src/ap/ieee802_11_ht.c +++ b/src/ap/ieee802_11_ht.c -@@ -230,6 +230,9 @@ void hostapd_2040_coex_action(struct hos +@@ -239,6 +239,9 @@ void hostapd_2040_coex_action(struct hos return; } @@ -46,7 +46,7 @@ if (len < IEEE80211_HDRLEN + 2 + sizeof(*bc_ie)) { wpa_printf(MSG_DEBUG, "Ignore too short 20/40 BSS Coexistence Management frame"); -@@ -390,6 +393,9 @@ void ht40_intolerant_add(struct hostapd_ +@@ -399,6 +402,9 @@ void ht40_intolerant_add(struct hostapd_ if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G) return; diff --git a/feeds/ipq95xx/hostapd/patches/301-mesh-noscan.patch b/feeds/ipq95xx/hostapd/patches/301-mesh-noscan.patch deleted file mode 100644 index a301e9fa..00000000 --- a/feeds/ipq95xx/hostapd/patches/301-mesh-noscan.patch +++ /dev/null @@ -1,81 +0,0 @@ -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/config.c -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config.c -@@ -2532,6 +2532,7 @@ static const struct parse_data ssid_fiel - #else /* CONFIG_MESH */ - { INT_RANGE(mode, 0, 4) }, - #endif /* CONFIG_MESH */ -+ { INT_RANGE(noscan, 0, 1) }, - { INT_RANGE(proactive_key_caching, 0, 1) }, - { INT_RANGE(disabled, 0, 2) }, - { STR(id_str) }, -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config_file.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/config_file.c -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config_file.c -@@ -769,6 +769,7 @@ static void wpa_config_write_network(FIL - #endif /* IEEE8021X_EAPOL */ - INT(mode); - INT(no_auto_peer); -+ INT(noscan); - INT(mesh_fwding); - INT(frequency); - INT(enable_edmg); -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/mesh.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/mesh.c -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/mesh.c -@@ -505,6 +505,8 @@ static int wpa_supplicant_mesh_init(stru - frequency); - goto out_free; - } -+ if (ssid->noscan) -+ conf->noscan = 1; - - if (ssid->mesh_basic_rates == NULL) { - /* -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/wpa_supplicant.c -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.c -@@ -2433,7 +2433,7 @@ void ibss_mesh_setup_freq(struct wpa_sup - int ieee80211_mode = wpas_mode_to_ieee80211_mode(ssid->mode); - enum hostapd_hw_mode hw_mode; - struct hostapd_hw_modes *mode = NULL; -- int ht40plus[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157, -+ int ht40plus[] = { 1, 2, 3, 4, 5, 6, 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157, - 184, 192 }; - int bw80[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5955, - 6035, 6115, 6195, 6275, 6355, 6435, 6515, -@@ -2441,7 +2441,7 @@ void ibss_mesh_setup_freq(struct wpa_sup - int bw160[] = { 5955, 6115, 6275, 6435, 6595, 6755, 6915 }; - struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL; - u8 channel; -- int i, chan_idx, ht40 = -1, res, obss_scan = 1; -+ int i, chan_idx, ht40 = -1, res, obss_scan = !(ssid->noscan); - unsigned int j, k; - struct hostapd_freq_params vht_freq; - int chwidth, seg0, seg1; -@@ -2530,7 +2530,7 @@ void ibss_mesh_setup_freq(struct wpa_sup - #endif /* CONFIG_HE_OVERRIDES */ - - /* Setup higher BW only for 5 GHz */ -- if (mode->mode != HOSTAPD_MODE_IEEE80211A) -+ if (mode->mode != HOSTAPD_MODE_IEEE80211A && !(ssid->noscan)) - return; - - for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) { -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config_ssid.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/config_ssid.h -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config_ssid.h -@@ -974,6 +974,8 @@ struct wpa_ssid { - */ - int no_auto_peer; - -+ int noscan; -+ - /** - * mesh_rssi_threshold - Set mesh parameter mesh_rssi_threshold (dBm) - * diff --git a/feeds/ipq95xx/hostapd/patches/310-rescan_immediately.patch b/feeds/ipq95xx/hostapd/patches/310-rescan_immediately.patch index 41f1b1e4..6e0244bc 100644 --- a/feeds/ipq95xx/hostapd/patches/310-rescan_immediately.patch +++ b/feeds/ipq95xx/hostapd/patches/310-rescan_immediately.patch @@ -1,6 +1,6 @@ --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -5147,7 +5147,7 @@ wpa_supplicant_alloc(struct wpa_supplica +@@ -5769,7 +5769,7 @@ wpa_supplicant_alloc(struct wpa_supplica if (wpa_s == NULL) return NULL; wpa_s->scan_req = INITIAL_SCAN_REQ; diff --git a/feeds/ipq95xx/hostapd/patches/320-optional_rfkill.patch b/feeds/ipq95xx/hostapd/patches/320-optional_rfkill.patch index a703c7e1..01537790 100644 --- a/feeds/ipq95xx/hostapd/patches/320-optional_rfkill.patch +++ b/feeds/ipq95xx/hostapd/patches/320-optional_rfkill.patch @@ -1,6 +1,6 @@ --- a/src/drivers/drivers.mak +++ b/src/drivers/drivers.mak -@@ -50,7 +50,6 @@ NEED_SME=y +@@ -54,7 +54,6 @@ NEED_SME=y NEED_AP_MLME=y NEED_NETLINK=y NEED_LINUX_IOCTL=y @@ -8,7 +8,7 @@ NEED_RADIOTAP=y NEED_LIBNL=y endif -@@ -107,7 +106,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT +@@ -111,7 +110,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT CONFIG_WIRELESS_EXTENSION=y NEED_NETLINK=y NEED_LINUX_IOCTL=y @@ -16,7 +16,7 @@ endif ifdef CONFIG_DRIVER_NDIS -@@ -133,7 +131,6 @@ endif +@@ -137,7 +135,6 @@ endif ifdef CONFIG_WIRELESS_EXTENSION DRV_WPA_CFLAGS += -DCONFIG_WIRELESS_EXTENSION DRV_WPA_OBJS += ../src/drivers/driver_wext.o @@ -24,7 +24,7 @@ endif ifdef NEED_NETLINK -@@ -142,6 +139,7 @@ endif +@@ -146,6 +143,7 @@ endif ifdef NEED_RFKILL DRV_OBJS += ../src/drivers/rfkill.o diff --git a/feeds/ipq95xx/hostapd/patches/330-nl80211_fix_set_freq.patch b/feeds/ipq95xx/hostapd/patches/330-nl80211_fix_set_freq.patch index e1070d0f..c11c9572 100644 --- a/feeds/ipq95xx/hostapd/patches/330-nl80211_fix_set_freq.patch +++ b/feeds/ipq95xx/hostapd/patches/330-nl80211_fix_set_freq.patch @@ -1,8 +1,8 @@ --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -4919,7 +4919,7 @@ static int nl80211_set_channel(struct i8 - freq->freq, freq->ht_enabled, freq->vht_enabled, freq->he_enabled, - freq->bandwidth, freq->center_freq1, freq->center_freq2); +@@ -5407,7 +5407,7 @@ static int nl80211_set_channel(struct i8 + freq->he_enabled, freq->eht_enabled, freq->bandwidth, + freq->center_freq1, freq->center_freq2); - msg = nl80211_drv_msg(drv, 0, set_chan ? NL80211_CMD_SET_CHANNEL : + msg = nl80211_bss_msg(bss, 0, set_chan ? NL80211_CMD_SET_CHANNEL : diff --git a/feeds/ipq95xx/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch b/feeds/ipq95xx/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch index 73f81f65..f5ed0d29 100644 --- a/feeds/ipq95xx/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch +++ b/feeds/ipq95xx/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch @@ -1,13 +1,18 @@ ---- a/wpa_supplicant/ap.c -+++ b/wpa_supplicant/ap.c -@@ -1513,15 +1513,35 @@ int ap_switch_channel(struct wpa_supplic +Index: hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/ap.c +=================================================================== +--- hostapd-2023-02-21-ath12.3-cs.orig/wpa_supplicant/ap.c ++++ hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/ap.c +@@ -1852,25 +1852,35 @@ int ap_switch_channel(struct wpa_supplic #ifdef CONFIG_CTRL_IFACE +-int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos) + +static int __ap_ctrl_iface_chanswitch(struct hostapd_iface *iface, + struct csa_settings *settings) -+{ + { +- struct csa_settings settings; +- int ret; +#ifdef NEED_AP_MLME + if (!iface || !iface->bss[0]) + return 0; @@ -17,17 +22,25 @@ + return -1; +#endif +} -+ -+ - int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos) - { - struct csa_settings settings; - int ret = hostapd_parse_csa_settings(pos, &settings); +- if (wpa_s->ifmsh && wpa_s->ifmsh->conf->disable_csa_dfs == 1) { +- wpa_printf(MSG_DEBUG, "wpa chanswitch interface %s :" +- " cancelling radar handling timeout", +- wpa_s->ifmsh->conf->bss[0]->iface); +- eloop_cancel_timeout(hostapd_dfs_radar_handling_timeout, +- wpa_s->ifmsh, NULL); +- } + +- ret = hostapd_parse_csa_settings(pos, &settings); ++int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos) ++{ ++ struct csa_settings settings; ++ int ret = hostapd_parse_csa_settings(pos, &settings); ++ + if (!(wpa_s->ap_iface && wpa_s->ap_iface->bss[0]) && + !(wpa_s->ifmsh && wpa_s->ifmsh->bss[0])) + return -1; -+ + + ret = __ap_ctrl_iface_chanswitch(wpa_s->ap_iface, &settings); if (ret) return ret; diff --git a/feeds/ipq95xx/hostapd/patches/350-nl80211_del_beacon_bss.patch b/feeds/ipq95xx/hostapd/patches/350-nl80211_del_beacon_bss.patch deleted file mode 100644 index 41e427c2..00000000 --- a/feeds/ipq95xx/hostapd/patches/350-nl80211_del_beacon_bss.patch +++ /dev/null @@ -1,54 +0,0 @@ ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -2891,10 +2891,15 @@ static int wpa_driver_nl80211_del_beacon - struct nl_msg *msg; - struct wpa_driver_nl80211_data *drv = bss->drv; - -+ if (!bss->beacon_set) -+ return 0; -+ -+ bss->beacon_set = 0; -+ - wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)", -- drv->ifindex); -+ bss->ifindex); - nl80211_put_wiphy_data_ap(bss); -- msg = nl80211_drv_msg(drv, 0, NL80211_CMD_DEL_BEACON); -+ msg = nl80211_bss_msg(bss, 0, NL80211_CMD_DEL_BEACON); - return send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL); - } - -@@ -5550,7 +5555,7 @@ static void nl80211_teardown_ap(struct i - nl80211_mgmt_unsubscribe(bss, "AP teardown"); - - nl80211_put_wiphy_data_ap(bss); -- bss->beacon_set = 0; -+ wpa_driver_nl80211_del_beacon(bss); - } - - -@@ -7990,8 +7995,6 @@ static int wpa_driver_nl80211_if_remove( - } else { - wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context"); - nl80211_teardown_ap(bss); -- if (!bss->added_if && !drv->first_bss->next) -- wpa_driver_nl80211_del_beacon(bss); - nl80211_destroy_bss(bss); - if (!bss->added_if) - i802_set_iface_flags(bss, 0); -@@ -8388,7 +8391,6 @@ static int wpa_driver_nl80211_deinit_ap( - if (!is_ap_interface(drv->nlmode)) - return -1; - wpa_driver_nl80211_del_beacon(bss); -- bss->beacon_set = 0; - - /* - * If the P2P GO interface was dynamically added, then it is -@@ -8408,7 +8410,6 @@ static int wpa_driver_nl80211_stop_ap(vo - if (!is_ap_interface(drv->nlmode)) - return -1; - wpa_driver_nl80211_del_beacon(bss); -- bss->beacon_set = 0; - return 0; - } - diff --git a/feeds/ipq95xx/hostapd/patches/380-disable_ctrl_iface_mib.patch b/feeds/ipq95xx/hostapd/patches/380-disable_ctrl_iface_mib.patch index 80500414..df01a085 100644 --- a/feeds/ipq95xx/hostapd/patches/380-disable_ctrl_iface_mib.patch +++ b/feeds/ipq95xx/hostapd/patches/380-disable_ctrl_iface_mib.patch @@ -1,5 +1,7 @@ ---- a/hostapd/Makefile -+++ b/hostapd/Makefile +Index: hostapd-2023-02-21-ath12.3-cs/hostapd/Makefile +=================================================================== +--- hostapd-2023-02-21-ath12.3-cs.orig/hostapd/Makefile ++++ hostapd-2023-02-21-ath12.3-cs/hostapd/Makefile @@ -221,6 +221,9 @@ endif ifdef CONFIG_NO_CTRL_IFACE CFLAGS += -DCONFIG_NO_CTRL_IFACE @@ -10,9 +12,11 @@ ifeq ($(CONFIG_CTRL_IFACE), udp) CFLAGS += -DCONFIG_CTRL_IFACE_UDP else ---- a/hostapd/ctrl_iface.c -+++ b/hostapd/ctrl_iface.c -@@ -3388,6 +3388,7 @@ static int hostapd_ctrl_iface_receive_pr +Index: hostapd-2023-02-21-ath12.3-cs/hostapd/ctrl_iface.c +=================================================================== +--- hostapd-2023-02-21-ath12.3-cs.orig/hostapd/ctrl_iface.c ++++ hostapd-2023-02-21-ath12.3-cs/hostapd/ctrl_iface.c +@@ -3805,6 +3805,7 @@ static int hostapd_ctrl_iface_receive_pr reply_size); } else if (os_strcmp(buf, "STATUS-DRIVER") == 0) { reply_len = hostapd_drv_status(hapd, reply, reply_size); @@ -20,7 +24,7 @@ } else if (os_strcmp(buf, "MIB") == 0) { reply_len = ieee802_11_get_mib(hapd, reply, reply_size); if (reply_len >= 0) { -@@ -3429,6 +3430,7 @@ static int hostapd_ctrl_iface_receive_pr +@@ -3846,6 +3847,7 @@ static int hostapd_ctrl_iface_receive_pr } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply, reply_size); @@ -28,9 +32,11 @@ } else if (os_strcmp(buf, "ATTACH") == 0) { if (hostapd_ctrl_iface_attach(hapd, from, fromlen, NULL)) reply_len = -1; ---- a/wpa_supplicant/Makefile -+++ b/wpa_supplicant/Makefile -@@ -942,6 +942,9 @@ ifdef CONFIG_FILS +Index: hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/Makefile +=================================================================== +--- hostapd-2023-02-21-ath12.3-cs.orig/wpa_supplicant/Makefile ++++ hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/Makefile +@@ -987,6 +987,9 @@ ifdef CONFIG_FILS OBJS += ../src/ap/fils_hlp.o endif ifdef CONFIG_CTRL_IFACE @@ -40,9 +46,11 @@ OBJS += ../src/ap/ctrl_iface_ap.o endif ---- a/wpa_supplicant/ctrl_iface.c -+++ b/wpa_supplicant/ctrl_iface.c -@@ -2294,7 +2294,7 @@ static int wpa_supplicant_ctrl_iface_sta +Index: hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/ctrl_iface.c +=================================================================== +--- hostapd-2023-02-21-ath12.3-cs.orig/wpa_supplicant/ctrl_iface.c ++++ hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/ctrl_iface.c +@@ -2327,7 +2327,7 @@ static int wpa_supplicant_ctrl_iface_sta pos += ret; } @@ -51,7 +59,7 @@ if (wpa_s->ap_iface) { pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos, end - pos, -@@ -10602,6 +10602,7 @@ char * wpa_supplicant_ctrl_iface_process +@@ -11989,6 +11989,7 @@ char * wpa_supplicant_ctrl_iface_process reply_len = -1; } else if (os_strncmp(buf, "NOTE ", 5) == 0) { wpa_printf(MSG_INFO, "NOTE: %s", buf + 5); @@ -59,7 +67,7 @@ } else if (os_strcmp(buf, "MIB") == 0) { reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); if (reply_len >= 0) { -@@ -10614,6 +10615,7 @@ char * wpa_supplicant_ctrl_iface_process +@@ -12001,6 +12002,7 @@ char * wpa_supplicant_ctrl_iface_process reply_size - reply_len); #endif /* CONFIG_MACSEC */ } @@ -67,7 +75,7 @@ } else if (os_strncmp(buf, "STATUS", 6) == 0) { reply_len = wpa_supplicant_ctrl_iface_status( wpa_s, buf + 6, reply, reply_size); -@@ -11102,6 +11104,7 @@ char * wpa_supplicant_ctrl_iface_process +@@ -12489,6 +12491,7 @@ char * wpa_supplicant_ctrl_iface_process reply_len = wpa_supplicant_ctrl_iface_bss( wpa_s, buf + 4, reply, reply_size); #ifdef CONFIG_AP @@ -75,7 +83,7 @@ } else if (os_strcmp(buf, "STA-FIRST") == 0) { reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size); } else if (os_strncmp(buf, "STA ", 4) == 0) { -@@ -11110,12 +11113,15 @@ char * wpa_supplicant_ctrl_iface_process +@@ -12497,12 +12500,15 @@ char * wpa_supplicant_ctrl_iface_process } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply, reply_size); @@ -91,17 +99,19 @@ } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) { if (ap_ctrl_iface_chanswitch(wpa_s, buf + 12)) reply_len = -1; ---- a/src/ap/ctrl_iface_ap.c -+++ b/src/ap/ctrl_iface_ap.c -@@ -25,6 +25,7 @@ - #include "mbo_ap.h" +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/ctrl_iface_ap.c +=================================================================== +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/ctrl_iface_ap.c ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/ctrl_iface_ap.c +@@ -26,6 +26,7 @@ #include "taxonomy.h" + #include "wnm_ap.h" +#ifdef CONFIG_CTRL_IFACE_MIB - static size_t hostapd_write_ht_mcs_bitmask(char *buf, size_t buflen, - size_t curr_len, const u8 *mcs_set) -@@ -451,6 +452,7 @@ int hostapd_ctrl_iface_sta_next(struct h + typedef enum { + BAND_UNII_1 = 1, +@@ -760,6 +761,7 @@ int hostapd_ctrl_iface_sta_next(struct h return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen); } @@ -109,7 +119,7 @@ #ifdef CONFIG_P2P_MANAGER static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype, -@@ -807,12 +809,12 @@ int hostapd_ctrl_iface_status(struct hos +@@ -1192,12 +1194,12 @@ int hostapd_ctrl_iface_status(struct hos return len; len += ret; } @@ -124,9 +134,11 @@ if (iface->current_rates && iface->num_rates) { ret = os_snprintf(buf + len, buflen - len, "supported_rates="); if (os_snprintf_error(buflen - len, ret)) ---- a/src/ap/ieee802_1x.c -+++ b/src/ap/ieee802_1x.c -@@ -2712,6 +2712,7 @@ static const char * bool_txt(bool val) +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/ieee802_1x.c +=================================================================== +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/ieee802_1x.c ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/ieee802_1x.c +@@ -2768,6 +2768,7 @@ static const char * bool_txt(bool val) return val ? "TRUE" : "FALSE"; } @@ -134,7 +146,7 @@ int ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen) { -@@ -2898,6 +2899,7 @@ int ieee802_1x_get_mib_sta(struct hostap +@@ -2954,6 +2955,7 @@ int ieee802_1x_get_mib_sta(struct hostap return len; } @@ -142,9 +154,11 @@ #ifdef CONFIG_HS20 static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx) ---- a/src/ap/wpa_auth.c -+++ b/src/ap/wpa_auth.c -@@ -4503,6 +4503,7 @@ static const char * wpa_bool_txt(int val +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/wpa_auth.c +=================================================================== +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/wpa_auth.c ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/wpa_auth.c +@@ -5715,6 +5715,7 @@ static const char * wpa_bool_txt(int val return val ? "TRUE" : "FALSE"; } @@ -152,7 +166,7 @@ #define RSN_SUITE "%02x-%02x-%02x-%d" #define RSN_SUITE_ARG(s) \ -@@ -4653,7 +4654,7 @@ int wpa_get_mib_sta(struct wpa_state_mac +@@ -5867,7 +5868,7 @@ int wpa_get_mib_sta(struct wpa_state_mac return len; } @@ -161,9 +175,11 @@ void wpa_auth_countermeasures_start(struct wpa_authenticator *wpa_auth) { ---- a/src/rsn_supp/wpa.c -+++ b/src/rsn_supp/wpa.c -@@ -2763,6 +2763,8 @@ static u32 wpa_key_mgmt_suite(struct wpa +Index: hostapd-2023-02-21-ath12.3-cs/src/rsn_supp/wpa.c +=================================================================== +--- hostapd-2023-02-21-ath12.3-cs.orig/src/rsn_supp/wpa.c ++++ hostapd-2023-02-21-ath12.3-cs/src/rsn_supp/wpa.c +@@ -3835,6 +3835,8 @@ static u32 wpa_key_mgmt_suite(struct wpa } @@ -172,7 +188,7 @@ #define RSN_SUITE "%02x-%02x-%02x-%d" #define RSN_SUITE_ARG(s) \ ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff -@@ -2844,6 +2846,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch +@@ -3916,6 +3918,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch return (int) len; } @@ -180,9 +196,11 @@ #endif /* CONFIG_CTRL_IFACE */ ---- a/wpa_supplicant/ap.c -+++ b/wpa_supplicant/ap.c -@@ -1364,7 +1364,7 @@ int wpas_ap_wps_nfc_report_handover(stru +Index: hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/ap.c +=================================================================== +--- hostapd-2023-02-21-ath12.3-cs.orig/wpa_supplicant/ap.c ++++ hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/ap.c +@@ -1512,7 +1512,7 @@ int wpas_ap_wps_nfc_report_handover(stru #endif /* CONFIG_WPS */ diff --git a/feeds/ipq95xx/hostapd/patches/381-hostapd_cli_UNKNOWN-COMMAND.patch b/feeds/ipq95xx/hostapd/patches/381-hostapd_cli_UNKNOWN-COMMAND.patch index d2414faf..e9083f6e 100644 --- a/feeds/ipq95xx/hostapd/patches/381-hostapd_cli_UNKNOWN-COMMAND.patch +++ b/feeds/ipq95xx/hostapd/patches/381-hostapd_cli_UNKNOWN-COMMAND.patch @@ -1,6 +1,6 @@ --- a/hostapd/hostapd_cli.c +++ b/hostapd/hostapd_cli.c -@@ -744,7 +744,7 @@ static int wpa_ctrl_command_sta(struct w +@@ -757,7 +757,7 @@ static int wpa_ctrl_command_sta(struct w } buf[len] = '\0'; diff --git a/feeds/ipq95xx/hostapd/patches/390-wpa_ie_cap_workaround.patch b/feeds/ipq95xx/hostapd/patches/390-wpa_ie_cap_workaround.patch index 65a8b07e..4592c341 100644 --- a/feeds/ipq95xx/hostapd/patches/390-wpa_ie_cap_workaround.patch +++ b/feeds/ipq95xx/hostapd/patches/390-wpa_ie_cap_workaround.patch @@ -1,6 +1,6 @@ --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c -@@ -2444,6 +2444,31 @@ u32 wpa_akm_to_suite(int akm) +@@ -2841,6 +2841,31 @@ u32 wpa_akm_to_suite(int akm) } @@ -32,7 +32,7 @@ int wpa_compare_rsn_ie(int ft_initial_assoc, const u8 *ie1, size_t ie1len, const u8 *ie2, size_t ie2len) -@@ -2451,8 +2476,19 @@ int wpa_compare_rsn_ie(int ft_initial_as +@@ -2848,8 +2873,19 @@ int wpa_compare_rsn_ie(int ft_initial_as if (ie1 == NULL || ie2 == NULL) return -1; diff --git a/feeds/ipq95xx/hostapd/patches/400-wps_single_auth_enc_type.patch b/feeds/ipq95xx/hostapd/patches/400-wps_single_auth_enc_type.patch index 73a8c769..edcd9852 100644 --- a/feeds/ipq95xx/hostapd/patches/400-wps_single_auth_enc_type.patch +++ b/feeds/ipq95xx/hostapd/patches/400-wps_single_auth_enc_type.patch @@ -11,7 +11,7 @@ bss->wpa_pairwise |= WPA_CIPHER_TKIP; #endif /* CONFIG_NO_TKIP */ bss->rsn_pairwise = bss->wpa_pairwise; -@@ -1178,8 +1177,7 @@ int hostapd_init_wps(struct hostapd_data +@@ -1181,8 +1180,7 @@ int hostapd_init_wps(struct hostapd_data WPA_CIPHER_GCMP_256)) { wps->encr_types |= WPS_ENCR_AES; wps->encr_types_rsn |= WPS_ENCR_AES; diff --git a/feeds/ipq95xx/hostapd/patches/410-limit_debug_messages.patch b/feeds/ipq95xx/hostapd/patches/410-limit_debug_messages.patch index d2713fc2..48a55892 100644 --- a/feeds/ipq95xx/hostapd/patches/410-limit_debug_messages.patch +++ b/feeds/ipq95xx/hostapd/patches/410-limit_debug_messages.patch @@ -60,7 +60,7 @@ #ifdef CONFIG_DEBUG_FILE static char *last_path = NULL; #endif /* CONFIG_DEBUG_FILE */ -@@ -636,7 +610,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_ +@@ -644,7 +618,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_ } @@ -69,7 +69,7 @@ { va_list ap; char *buf; -@@ -674,7 +648,7 @@ void wpa_msg(void *ctx, int level, const +@@ -682,7 +656,7 @@ void wpa_msg(void *ctx, int level, const } @@ -80,9 +80,9 @@ char *buf; --- a/src/utils/wpa_debug.h +++ b/src/utils/wpa_debug.h -@@ -50,6 +50,17 @@ int wpa_debug_reopen_file(void); - void wpa_debug_close_file(void); +@@ -51,6 +51,17 @@ void wpa_debug_close_file(void); void wpa_debug_setup_stdout(void); + void wpa_debug_stop_log(void); +/* internal */ +void _wpa_hexdump(int level, const char *title, const u8 *buf, @@ -98,7 +98,7 @@ /** * wpa_debug_printf_timestamp - Print timestamp for debug output * -@@ -70,9 +81,15 @@ void wpa_debug_print_timestamp(void); +@@ -71,9 +82,15 @@ void wpa_debug_print_timestamp(void); * * Note: New line '\n' is added to the end of the text when printing to stdout. */ @@ -115,7 +115,7 @@ /** * wpa_hexdump - conditional hex dump * @level: priority level (MSG_*) of the message -@@ -84,7 +101,13 @@ PRINTF_FORMAT(2, 3); +@@ -85,7 +102,13 @@ PRINTF_FORMAT(2, 3); * output may be directed to stdout, stderr, and/or syslog based on * configuration. The contents of buf is printed out has hex dump. */ @@ -130,7 +130,7 @@ static inline void wpa_hexdump_buf(int level, const char *title, const struct wpabuf *buf) -@@ -106,7 +129,13 @@ static inline void wpa_hexdump_buf(int l +@@ -107,7 +130,13 @@ static inline void wpa_hexdump_buf(int l * like wpa_hexdump(), but by default, does not include secret keys (passwords, * etc.) in debug output. */ @@ -145,7 +145,7 @@ static inline void wpa_hexdump_buf_key(int level, const char *title, const struct wpabuf *buf) -@@ -128,8 +157,14 @@ static inline void wpa_hexdump_buf_key(i +@@ -129,8 +158,14 @@ static inline void wpa_hexdump_buf_key(i * the hex numbers and ASCII characters (for printable range) are shown. 16 * bytes per line will be shown. */ @@ -162,7 +162,7 @@ /** * wpa_hexdump_ascii_key - conditional hex dump, hide keys -@@ -145,8 +180,14 @@ void wpa_hexdump_ascii(int level, const +@@ -146,8 +181,14 @@ void wpa_hexdump_ascii(int level, const * bytes per line will be shown. This works like wpa_hexdump_ascii(), but by * default, does not include secret keys (passwords, etc.) in debug output. */ @@ -179,7 +179,7 @@ /* * wpa_dbg() behaves like wpa_msg(), but it can be removed from build to reduce -@@ -183,7 +224,12 @@ void wpa_hexdump_ascii_key(int level, co +@@ -184,7 +225,12 @@ void wpa_hexdump_ascii_key(int level, co * * Note: New line '\n' is added to the end of the text when printing to stdout. */ @@ -193,7 +193,7 @@ /** * wpa_msg_ctrl - Conditional printf for ctrl_iface monitors -@@ -197,8 +243,13 @@ void wpa_msg(void *ctx, int level, const +@@ -198,8 +244,13 @@ void wpa_msg(void *ctx, int level, const * attached ctrl_iface monitors. In other words, it can be used for frequent * events that do not need to be sent to syslog. */ diff --git a/feeds/ipq95xx/hostapd/patches/420-indicate-features.patch b/feeds/ipq95xx/hostapd/patches/420-indicate-features.patch index f74db4c0..07df8e5a 100644 --- a/feeds/ipq95xx/hostapd/patches/420-indicate-features.patch +++ b/feeds/ipq95xx/hostapd/patches/420-indicate-features.patch @@ -1,23 +1,24 @@ --- a/hostapd/main.c +++ b/hostapd/main.c -@@ -15,6 +15,7 @@ - #include "utils/common.h" - #include "utils/eloop.h" - #include "utils/uuid.h" -+#include "utils/build_features.h" - #include "crypto/random.h" - #include "crypto/tls.h" - #include "common/version.h" -@@ -691,7 +692,7 @@ int main(int argc, char *argv[]) +@@ -31,7 +31,7 @@ + #include "config_file.h" + #include "eap_register.h" + #include "ctrl_iface.h" +- ++#include "build_features.h" + + struct hapd_global { + void **drv_priv; +@@ -799,7 +799,7 @@ int main(int argc, char *argv[]) wpa_supplicant_event = hostapd_wpa_event; wpa_supplicant_event_global = hostapd_wpa_event_global; for (;;) { -- c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:vg:G:"); -+ c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:g:G:v::"); +- c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:vg:G:q"); ++ c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:g:G:qv::"); if (c < 0) break; switch (c) { -@@ -728,6 +729,8 @@ int main(int argc, char *argv[]) +@@ -836,6 +836,8 @@ int main(int argc, char *argv[]) break; #endif /* CONFIG_DEBUG_LINUX_TRACING */ case 'v': @@ -25,7 +26,7 @@ + exit(!has_feature(optarg)); show_version(); exit(1); - break; + case 'g': --- a/wpa_supplicant/main.c +++ b/wpa_supplicant/main.c @@ -12,6 +12,7 @@ @@ -33,10 +34,10 @@ #include "common.h" +#include "build_features.h" + #include "crypto/crypto.h" #include "fst/fst.h" #include "wpa_supplicant_i.h" - #include "driver_i.h" -@@ -201,7 +202,7 @@ int main(int argc, char *argv[]) +@@ -202,7 +203,7 @@ int main(int argc, char *argv[]) for (;;) { c = getopt(argc, argv, @@ -45,7 +46,7 @@ if (c < 0) break; switch (c) { -@@ -301,8 +302,12 @@ int main(int argc, char *argv[]) +@@ -302,8 +303,12 @@ int main(int argc, char *argv[]) break; #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ case 'v': diff --git a/feeds/ipq95xx/hostapd/patches/430-hostapd_cli_ifdef.patch b/feeds/ipq95xx/hostapd/patches/430-hostapd_cli_ifdef.patch index 49ad781d..a21f0bf7 100644 --- a/feeds/ipq95xx/hostapd/patches/430-hostapd_cli_ifdef.patch +++ b/feeds/ipq95xx/hostapd/patches/430-hostapd_cli_ifdef.patch @@ -1,6 +1,6 @@ --- a/hostapd/hostapd_cli.c +++ b/hostapd/hostapd_cli.c -@@ -388,7 +388,6 @@ static int hostapd_cli_cmd_disassociate( +@@ -401,7 +401,6 @@ static int hostapd_cli_cmd_disassociate( } @@ -8,7 +8,7 @@ static int hostapd_cli_cmd_signature(struct wpa_ctrl *ctrl, int argc, char *argv[]) { -@@ -401,7 +400,6 @@ static int hostapd_cli_cmd_signature(str +@@ -414,7 +413,6 @@ static int hostapd_cli_cmd_signature(str os_snprintf(buf, sizeof(buf), "SIGNATURE %s", argv[0]); return wpa_ctrl_command(ctrl, buf); } @@ -16,7 +16,7 @@ static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc, -@@ -418,7 +416,6 @@ static int hostapd_cli_cmd_sa_query(stru +@@ -431,7 +429,6 @@ static int hostapd_cli_cmd_sa_query(stru } @@ -24,7 +24,7 @@ static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) { -@@ -644,7 +641,6 @@ static int hostapd_cli_cmd_wps_config(st +@@ -657,7 +654,6 @@ static int hostapd_cli_cmd_wps_config(st ssid_hex, argv[1]); return wpa_ctrl_command(ctrl, buf); } @@ -32,7 +32,7 @@ static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc, -@@ -1571,13 +1567,10 @@ static const struct hostapd_cli_cmd host +@@ -1610,13 +1606,10 @@ static const struct hostapd_cli_cmd host { "disassociate", hostapd_cli_cmd_disassociate, hostapd_complete_stations, " = disassociate a station" }, @@ -46,7 +46,7 @@ { "wps_pin", hostapd_cli_cmd_wps_pin, NULL, " [timeout] [addr] = add WPS Enrollee PIN" }, { "wps_check_pin", hostapd_cli_cmd_wps_check_pin, NULL, -@@ -1602,7 +1595,6 @@ static const struct hostapd_cli_cmd host +@@ -1641,7 +1634,6 @@ static const struct hostapd_cli_cmd host " = configure AP" }, { "wps_get_status", hostapd_cli_cmd_wps_get_status, NULL, "= show current WPS status" }, diff --git a/feeds/ipq95xx/hostapd/patches/432-missing-typedef.patch b/feeds/ipq95xx/hostapd/patches/432-missing-typedef.patch deleted file mode 100644 index 7a100f1a..00000000 --- a/feeds/ipq95xx/hostapd/patches/432-missing-typedef.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/src/drivers/linux_wext.h -+++ b/src/drivers/linux_wext.h -@@ -26,6 +26,7 @@ typedef int32_t __s32; - typedef uint16_t __u16; - typedef int16_t __s16; - typedef uint8_t __u8; -+typedef int8_t __s8; - #ifndef __user - #define __user - #endif /* __user */ diff --git a/feeds/ipq95xx/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch b/feeds/ipq95xx/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch index e395faaf..dc19553e 100644 --- a/feeds/ipq95xx/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch +++ b/feeds/ipq95xx/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch @@ -22,7 +22,7 @@ Signed-hostap: Antonio Quartulli #include "common/defs.h" #include "common/ieee802_11_defs.h" #include "common/wpa_common.h" -@@ -851,6 +852,9 @@ struct wpa_driver_associate_params { +@@ -953,6 +954,9 @@ struct wpa_driver_associate_params { * responsible for selecting with which BSS to associate. */ const u8 *bssid; @@ -42,7 +42,7 @@ Signed-hostap: Antonio Quartulli #include "config.h" -@@ -2321,6 +2322,97 @@ static char * wpa_config_write_peerkey(c +@@ -2389,6 +2390,97 @@ static char * wpa_config_write_mac_value #endif /* NO_CONFIG_WRITE */ @@ -140,7 +140,7 @@ Signed-hostap: Antonio Quartulli /* Helper macros for network block parser */ #ifdef OFFSET -@@ -2606,6 +2698,8 @@ static const struct parse_data ssid_fiel +@@ -2674,6 +2766,8 @@ static const struct parse_data ssid_fiel { INT(ap_max_inactivity) }, { INT(dtim_period) }, { INT(beacon_int) }, @@ -162,7 +162,7 @@ Signed-hostap: Antonio Quartulli #define DEFAULT_EAP_WORKAROUND ((unsigned int) -1) -@@ -843,6 +845,9 @@ struct wpa_ssid { +@@ -879,6 +881,9 @@ struct wpa_ssid { */ void *parent_cred; @@ -174,7 +174,7 @@ Signed-hostap: Antonio Quartulli * macsec_policy - Determines the policy for MACsec secure session --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -3673,6 +3673,12 @@ static void wpas_start_assoc_cb(struct w +@@ -4177,6 +4177,12 @@ static void wpas_start_assoc_cb(struct w params.beacon_int = ssid->beacon_int; else params.beacon_int = wpa_s->conf->beacon_int; diff --git a/feeds/ipq95xx/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch b/feeds/ipq95xx/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch deleted file mode 100644 index 19165d02..00000000 --- a/feeds/ipq95xx/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch +++ /dev/null @@ -1,59 +0,0 @@ -From ffc4445958a3ed4064f2e1bf73fa478a61c5cf7b Mon Sep 17 00:00:00 2001 -From: Antonio Quartulli -Date: Sun, 3 Jun 2012 18:42:25 +0200 -Subject: [PATCHv2 602/602] driver_nl80211: use new parameters during ibss join - -Signed-hostap: Antonio Quartulli ---- - src/drivers/driver_nl80211.c | 33 ++++++++++++++++++++++++++++++++- - 1 file changed, 32 insertions(+), 1 deletion(-) - ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -5886,7 +5886,7 @@ static int wpa_driver_nl80211_ibss(struc - struct wpa_driver_associate_params *params) - { - struct nl_msg *msg; -- int ret = -1; -+ int ret = -1, i; - int count = 0; - - wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex); -@@ -5913,6 +5913,37 @@ retry: - nl80211_put_beacon_int(msg, params->beacon_int)) - goto fail; - -+ if (params->fixed_freq) { -+ wpa_printf(MSG_DEBUG, " * fixed_freq"); -+ nla_put_flag(msg, NL80211_ATTR_FREQ_FIXED); -+ } -+ -+ if (params->beacon_int > 0) { -+ wpa_printf(MSG_DEBUG, " * beacon_int=%d", -+ params->beacon_int); -+ nla_put_u32(msg, NL80211_ATTR_BEACON_INTERVAL, -+ params->beacon_int); -+ } -+ -+ if (params->rates[0] > 0) { -+ wpa_printf(MSG_DEBUG, " * basic_rates:"); -+ i = 0; -+ while (i < NL80211_MAX_SUPP_RATES && -+ params->rates[i] > 0) { -+ wpa_printf(MSG_DEBUG, " %.1f", -+ (double)params->rates[i] / 2); -+ i++; -+ } -+ nla_put(msg, NL80211_ATTR_BSS_BASIC_RATES, i, -+ params->rates); -+ } -+ -+ if (params->mcast_rate > 0) { -+ wpa_printf(MSG_DEBUG, " * mcast_rate=%.1f", -+ (double)params->mcast_rate / 10); -+ nla_put_u32(msg, NL80211_ATTR_MCAST_RATE, params->mcast_rate); -+ } -+ - ret = nl80211_set_conn_keys(params, msg); - if (ret) - goto fail; diff --git a/feeds/ipq95xx/hostapd/patches/463-add-mcast_rate-to-11s.patch b/feeds/ipq95xx/hostapd/patches/463-add-mcast_rate-to-11s.patch deleted file mode 100644 index 395c6d31..00000000 --- a/feeds/ipq95xx/hostapd/patches/463-add-mcast_rate-to-11s.patch +++ /dev/null @@ -1,68 +0,0 @@ -From: Sven Eckelmann -Date: Thu, 11 May 2017 08:21:45 +0200 -Subject: [PATCH] set mcast_rate in mesh mode - -The wpa_supplicant code for IBSS allows to set the mcast rate. It is -recommended to increase this value from 1 or 6 Mbit/s to something higher -when using a mesh protocol on top which uses the multicast packet loss as -indicator for the link quality. - -This setting was unfortunately not applied for mesh mode. But it would be -beneficial when wpa_supplicant would behave similar to IBSS mode and set -this argument during mesh join like authsae already does. At least it is -helpful for companies/projects which are currently switching to 802.11s -(without mesh_fwding and with mesh_ttl set to 1) as replacement for IBSS -because newer drivers seem to support 802.11s but not IBSS anymore. - -Signed-off-by: Sven Eckelmann -Tested-by: Simon Wunderlich - ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -1618,6 +1618,7 @@ struct wpa_driver_mesh_join_params { - #define WPA_DRIVER_MESH_FLAG_AMPE 0x00000008 - unsigned int flags; - bool handle_dfs; -+ int mcast_rate; - }; - - struct wpa_driver_set_key_params { ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -10398,6 +10398,18 @@ static int nl80211_put_mesh_id(struct nl - } - - -+static int nl80211_put_mcast_rate(struct nl_msg *msg, int mcast_rate) -+{ -+ if (mcast_rate > 0) { -+ wpa_printf(MSG_DEBUG, " * mcast_rate=%.1f", -+ (double)mcast_rate / 10); -+ return nla_put_u32(msg, NL80211_ATTR_MCAST_RATE, mcast_rate); -+ } -+ -+ return 0; -+} -+ -+ - static int nl80211_put_mesh_config(struct nl_msg *msg, - struct wpa_driver_mesh_bss_params *params) - { -@@ -10459,6 +10471,7 @@ static int nl80211_join_mesh(struct i802 - nl80211_put_basic_rates(msg, params->basic_rates) || - nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) || - nl80211_put_beacon_int(msg, params->beacon_int) || -+ nl80211_put_mcast_rate(msg, params->mcast_rate) || - nl80211_put_dtim_period(msg, params->dtim_period)) - goto fail; - ---- a/wpa_supplicant/mesh.c -+++ b/wpa_supplicant/mesh.c -@@ -600,6 +600,7 @@ int wpa_supplicant_join_mesh(struct wpa_ - - params->meshid = ssid->ssid; - params->meshid_len = ssid->ssid_len; -+ params->mcast_rate = ssid->mcast_rate; - ibss_mesh_setup_freq(wpa_s, ssid, ¶ms->freq); - wpa_s->mesh_ht_enabled = !!params->freq.ht_enabled; - wpa_s->mesh_vht_enabled = !!params->freq.vht_enabled; diff --git a/feeds/ipq95xx/hostapd/patches/464-fix-mesh-obss-check.patch b/feeds/ipq95xx/hostapd/patches/464-fix-mesh-obss-check.patch index 0e9d2590..30049104 100644 --- a/feeds/ipq95xx/hostapd/patches/464-fix-mesh-obss-check.patch +++ b/feeds/ipq95xx/hostapd/patches/464-fix-mesh-obss-check.patch @@ -1,19 +1,14 @@ ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -2403,11 +2403,13 @@ void ibss_mesh_setup_freq(struct wpa_sup - for (j = 0; j < wpa_s->last_scan_res_used; j++) { - struct wpa_bss *bss = wpa_s->last_scan_res[j]; +Index: hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/wpa_supplicant.c +=================================================================== +--- hostapd-2023-02-21-ath12.3-cs.orig/wpa_supplicant/wpa_supplicant.c ++++ hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/wpa_supplicant.c +@@ -2744,6 +2744,9 @@ void ibss_mesh_setup_freq(struct wpa_sup + bool is_24ghz, is_6ghz; -- if (ssid->mode != WPAS_MODE_IBSS) -+ /* Don't adjust control freq in case of fixed_freq */ -+ if (ssid->fixed_freq) { -+ obss_scan = 0; - break; -+ } + freq->freq = ssid->frequency; ++ if (ssid->fixed_freq) { ++ obss_scan = 0; ++ } -- /* Don't adjust control freq in case of fixed_freq */ -- if (ssid->fixed_freq) -+ if (ssid->mode != WPAS_MODE_IBSS) - break; - - if (!bss_is_ibss(bss)) + for (j = 0; j < wpa_s->last_scan_res_used; j++) { + struct wpa_bss *bss = wpa_s->last_scan_res[j]; diff --git a/feeds/ipq95xx/hostapd/patches/470-survey_data_fallback.patch b/feeds/ipq95xx/hostapd/patches/470-survey_data_fallback.patch index 4b791c7f..79ab48c5 100644 --- a/feeds/ipq95xx/hostapd/patches/470-survey_data_fallback.patch +++ b/feeds/ipq95xx/hostapd/patches/470-survey_data_fallback.patch @@ -1,44 +1,29 @@ -Index: hostapd-2021-12-13-b26f5c0f/src/ap/acs.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/acs.c -+++ hostapd-2021-12-13-b26f5c0f/src/ap/acs.c -@@ -302,16 +302,12 @@ static void acs_fail(struct hostapd_ifac - static long double - acs_survey_interference_factor(struct freq_survey *survey, s8 min_nf) - { -- long double factor, busy, total; -+ long double factor, busy = 0, total; - - if (survey->filled & SURVEY_HAS_CHAN_TIME_BUSY) - busy = survey->channel_time_busy; - else if (survey->filled & SURVEY_HAS_CHAN_TIME_RX) - busy = survey->channel_time_rx; -- else { -- wpa_printf(MSG_ERROR, "ACS: Survey data missing"); -- return 0; -- } - - total = survey->channel_time; - -@@ -420,20 +416,19 @@ static int acs_usable_bw160_chan(const s +--- a/src/ap/acs.c ++++ b/src/ap/acs.c +@@ -455,17 +455,17 @@ static int acs_get_bw_center_chan(int fr static int acs_survey_is_sufficient(struct freq_survey *survey) { if (!(survey->filled & SURVEY_HAS_NF)) { + survey->nf = -95; - wpa_printf(MSG_INFO, "ACS: Survey is missing noise floor"); + wpa_printf(MSG_INFO, + "ACS: Survey for freq %d is missing noise floor", + survey->freq); - return 0; } if (!(survey->filled & SURVEY_HAS_CHAN_TIME)) { + survey->channel_time = 0; - wpa_printf(MSG_INFO, "ACS: Survey is missing channel time"); + wpa_printf(MSG_INFO, + "ACS: Survey for freq %d is missing channel time", + survey->freq); - return 0; } if (!(survey->filled & SURVEY_HAS_CHAN_TIME_BUSY) && - !(survey->filled & SURVEY_HAS_CHAN_TIME_RX)) { +@@ -473,7 +473,6 @@ static int acs_survey_is_sufficient(stru wpa_printf(MSG_INFO, - "ACS: Survey is missing RX and busy time (at least one is required)"); + "ACS: Survey for freq %d is missing RX and busy time (at least one is required)", + survey->freq); - return 0; } diff --git a/feeds/ipq95xx/hostapd/patches/500-lto-jobserver-support.patch b/feeds/ipq95xx/hostapd/patches/500-lto-jobserver-support.patch index 7ba3e096..67312c50 100644 --- a/feeds/ipq95xx/hostapd/patches/500-lto-jobserver-support.patch +++ b/feeds/ipq95xx/hostapd/patches/500-lto-jobserver-support.patch @@ -1,6 +1,6 @@ --- a/hostapd/Makefile +++ b/hostapd/Makefile -@@ -1293,7 +1293,7 @@ hostapd_multi.a: $(BCHECK) $(OBJS) +@@ -1396,7 +1396,7 @@ hostapd_multi.a: $(BCHECK) $(OBJS) @$(AR) cr $@ hostapd_multi.o $(OBJS) hostapd: $(OBJS) @@ -9,7 +9,7 @@ @$(E) " LD " $@ ifdef CONFIG_WPA_TRACE -@@ -1304,7 +1304,7 @@ _OBJS_VAR := OBJS_c +@@ -1407,7 +1407,7 @@ _OBJS_VAR := OBJS_c include ../src/objs.mk hostapd_cli: $(OBJS_c) @@ -20,7 +20,7 @@ NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o $(SHA1OBJS) --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile -@@ -1905,31 +1905,31 @@ wpa_supplicant_multi.a: .config $(BCHECK +@@ -2037,31 +2037,31 @@ wpa_supplicant_multi.a: .config $(BCHECK @$(AR) cr $@ wpa_supplicant_multi.o $(OBJS) wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) diff --git a/feeds/ipq95xx/hostapd/patches/590-rrm-wnm-statistics.patch b/feeds/ipq95xx/hostapd/patches/590-rrm-wnm-statistics.patch index 737fdbb5..0efa6db9 100644 --- a/feeds/ipq95xx/hostapd/patches/590-rrm-wnm-statistics.patch +++ b/feeds/ipq95xx/hostapd/patches/590-rrm-wnm-statistics.patch @@ -1,6 +1,6 @@ --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h -@@ -148,6 +148,21 @@ struct hostapd_sae_commit_queue { +@@ -163,6 +163,21 @@ struct hostapd_sae_commit_queue { }; /** @@ -22,9 +22,9 @@ * struct hostapd_data - hostapd per-BSS data structure */ struct hostapd_data { -@@ -161,6 +176,9 @@ struct hostapd_data { +@@ -182,6 +197,9 @@ struct hostapd_data { - u8 own_addr[ETH_ALEN]; + struct hostapd_data *mld_first_bss; + /* OpenWrt specific statistics */ + struct hostapd_openwrt_stats openwrt_stats; @@ -42,9 +42,9 @@ wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to " MACSTR " dialog_token=%u req_mode=0x%x disassoc_timer=%u " "validity_interval=%u", -@@ -646,10 +647,12 @@ int ieee802_11_rx_wnm_action_ap(struct h - - switch (action) { +@@ -790,10 +791,12 @@ int ieee802_11_rx_wnm_action_ap(struct h + plen); + return 0; case WNM_BSS_TRANS_MGMT_QUERY: + hapd->openwrt_stats.wnm.bss_transition_query_rx++; ieee802_11_rx_bss_trans_mgmt_query(hapd, mgmt->sa, payload, @@ -55,7 +55,7 @@ ieee802_11_rx_bss_trans_mgmt_resp(hapd, mgmt->sa, payload, plen); return 0; -@@ -696,6 +699,7 @@ int wnm_send_disassoc_imminent(struct ho +@@ -840,6 +843,7 @@ int wnm_send_disassoc_imminent(struct ho pos = mgmt->u.action.u.bss_tm_req.variable; @@ -63,7 +63,7 @@ wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request frame to indicate imminent disassociation (disassoc_timer=%d) to " MACSTR, disassoc_timer, MAC2STR(sta->addr)); if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0, NULL, 0, 0) < 0) { -@@ -777,6 +781,7 @@ int wnm_send_ess_disassoc_imminent(struc +@@ -921,6 +925,7 @@ int wnm_send_ess_disassoc_imminent(struc return -1; } @@ -71,7 +71,7 @@ if (disassoc_timer) { /* send disassociation frame after time-out */ set_disassoc_timer(hapd, sta, disassoc_timer); -@@ -856,6 +861,7 @@ int wnm_send_bss_tm_req(struct hostapd_d +@@ -1001,6 +1006,7 @@ int wnm_send_bss_tm_req(struct hostapd_d } os_free(buf); diff --git a/feeds/ipq95xx/hostapd/patches/600-ubus_support.patch b/feeds/ipq95xx/hostapd/patches/600-ubus_support.patch index ad48368a..c858abde 100644 --- a/feeds/ipq95xx/hostapd/patches/600-ubus_support.patch +++ b/feeds/ipq95xx/hostapd/patches/600-ubus_support.patch @@ -1,7 +1,7 @@ -Index: hostapd-2021-02-20-59e9794c/hostapd/Makefile +Index: hostapd-2023-02-21-ath12.3-cs/hostapd/Makefile =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/hostapd/Makefile -+++ hostapd-2021-02-20-59e9794c/hostapd/Makefile +--- hostapd-2023-02-21-ath12.3-cs.orig/hostapd/Makefile ++++ hostapd-2023-02-21-ath12.3-cs/hostapd/Makefile @@ -166,6 +166,12 @@ OBJS += ../src/common/hw_features_common OBJS += ../src/eapol_auth/eapol_auth_sm.o @@ -15,11 +15,11 @@ Index: hostapd-2021-02-20-59e9794c/hostapd/Makefile ifdef CONFIG_CODE_COVERAGE CFLAGS += -O0 -fprofile-arcs -ftest-coverage -Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.h +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/hostapd.h =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.h -+++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.h -@@ -17,6 +17,7 @@ +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/hostapd.h ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/hostapd.h +@@ -18,6 +18,7 @@ #include "utils/list.h" #include "ap_config.h" #include "drivers/driver.h" @@ -27,15 +27,15 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.h #define OCE_STA_CFON_ENABLED(hapd) \ ((hapd->conf->oce & OCE_STA_CFON) && \ -@@ -169,6 +170,7 @@ struct hostapd_data { - struct hostapd_iface *iface; +@@ -203,6 +204,7 @@ struct hostapd_data { + #endif struct hostapd_config *iconf; struct hostapd_bss_config *conf; + struct hostapd_ubus_bss ubus; int interface_added; /* virtual interface added for this BSS */ unsigned int started:1; unsigned int disabled:1; -@@ -626,6 +628,7 @@ hostapd_alloc_bss_data(struct hostapd_if +@@ -741,6 +743,7 @@ hostapd_alloc_bss_data(struct hostapd_if struct hostapd_bss_config *bss); int hostapd_setup_interface(struct hostapd_iface *iface); int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err); @@ -43,11 +43,11 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.h void hostapd_interface_deinit(struct hostapd_iface *iface); void hostapd_interface_free(struct hostapd_iface *iface); struct hostapd_iface * hostapd_alloc_iface(void); -Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/hostapd.c =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.c -+++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.c -@@ -376,6 +376,7 @@ void hostapd_free_hapd_data(struct hosta +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/hostapd.c ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/hostapd.c +@@ -471,6 +471,7 @@ void hostapd_free_hapd_data(struct hosta hapd->beacon_set_done = 0; wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); @@ -55,7 +55,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c accounting_deinit(hapd); hostapd_deinit_wpa(hapd); vlan_deinit(hapd); -@@ -1398,6 +1399,8 @@ static int hostapd_setup_bss(struct host +@@ -1224,6 +1225,8 @@ static int hostapd_start_beacon(struct h if (hapd->driver && hapd->driver->set_operstate) hapd->driver->set_operstate(hapd->drv_priv, 1); @@ -64,15 +64,15 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c return 0; } -@@ -1983,6 +1986,7 @@ static int hostapd_setup_interface_compl +@@ -2331,6 +2334,7 @@ static int hostapd_setup_interface_compl if (err) goto fail; + hostapd_ubus_add_iface(iface); wpa_printf(MSG_DEBUG, "Completing interface initialization"); + if (iface->freq) { - #ifdef NEED_AP_MLME -@@ -2180,6 +2184,7 @@ dfs_offload: +@@ -2567,6 +2571,7 @@ dfs_offload: fail: wpa_printf(MSG_ERROR, "Interface initialization failed"); @@ -80,7 +80,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c hostapd_set_state(iface, HAPD_IFACE_DISABLED); wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); #ifdef CONFIG_FST -@@ -2653,6 +2658,7 @@ void hostapd_interface_deinit_free(struc +@@ -3464,6 +3469,7 @@ void hostapd_interface_deinit_free(struc (unsigned int) iface->conf->num_bss); driver = iface->bss[0]->driver; drv_priv = iface->bss[0]->drv_priv; @@ -88,11 +88,21 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c hostapd_interface_deinit(iface); wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", __func__, driver, drv_priv); -Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/ieee802_11.c =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/ieee802_11.c -+++ hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c -@@ -3421,13 +3421,18 @@ static void handle_auth(struct hostapd_d +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/ieee802_11.c ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/ieee802_11.c +@@ -87,8 +87,7 @@ static size_t hostapd_eid_basic_resp_mle + + static void handle_auth(struct hostapd_data *hapd, + struct ieee80211_mgmt *mgmt, size_t len, +- int rssi, int from_queue, +- struct hostapd_frame_info *fi); ++ int rssi, int from_queue); + + + u8 * hostapd_eid_multi_ap(struct hostapd_data *hapd, u8 *eid) +@@ -2785,7 +2784,7 @@ static void handle_auth(struct hostapd_d u16 auth_alg, auth_transaction, status_code; u16 resp = WLAN_STATUS_SUCCESS; struct sta_info *sta = NULL; @@ -101,9 +111,10 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c u16 fc; const u8 *challenge = NULL; u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN]; - size_t resp_ies_len = 0; - u16 seq_ctrl; - struct radius_sta rad_info; +@@ -2800,6 +2799,11 @@ static void handle_auth(struct hostapd_d + const u8 *token = NULL; + size_t token_len = 0; + int parsed_len = 0; + struct hostapd_ubus_request req = { + .type = HOSTAPD_UBUS_AUTH_REQ, + .mgmt_frame = mgmt, @@ -112,7 +123,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)", -@@ -3595,6 +3600,13 @@ static void handle_auth(struct hostapd_d +@@ -3019,6 +3023,13 @@ skip_ml_parsing: resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } @@ -126,7 +137,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c if (res == HOSTAPD_ACL_PENDING) return; -@@ -5322,7 +5334,7 @@ static void handle_assoc(struct hostapd_ +@@ -5519,7 +5530,7 @@ static void handle_assoc(struct hostapd_ int resp = WLAN_STATUS_SUCCESS; u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE; const u8 *pos; @@ -135,7 +146,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c struct sta_info *sta; u8 *tmp = NULL; #ifdef CONFIG_FILS -@@ -5535,6 +5547,11 @@ static void handle_assoc(struct hostapd_ +@@ -5733,6 +5744,11 @@ static void handle_assoc(struct hostapd_ left = res; } #endif /* CONFIG_FILS */ @@ -147,7 +158,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c /* followed by SSID and Supported rates; and HT capabilities if 802.11n * is used */ -@@ -5633,6 +5650,13 @@ static void handle_assoc(struct hostapd_ +@@ -5840,6 +5856,13 @@ static void handle_assoc(struct hostapd_ } #endif /* CONFIG_FILS */ @@ -161,31 +172,30 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c fail: /* -@@ -5726,6 +5750,7 @@ static void handle_disassoc(struct hosta - wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d", - MAC2STR(mgmt->sa), - le_to_host16(mgmt->u.disassoc.reason_code)); +@@ -6019,6 +6042,7 @@ static void handle_deauth(struct hostapd + + /* Clear the PTKSA cache entries for PASN */ + ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE); ++ hostapd_ubus_notify(hapd, "deauth", mgmt->sa); + + sta = ap_get_sta(hapd, mgmt->sa); + if (sta == NULL) { +@@ -6141,6 +6165,7 @@ static int handle_action(struct hostapd_ + sta->last_seq_ctrl = seq_ctrl; + sta->last_subtype = WLAN_FC_STYPE_ACTION; + } + hostapd_ubus_notify(hapd, "disassoc", mgmt->sa); - sta = ap_get_sta(hapd, mgmt->sa); - if (sta == NULL) { -@@ -5792,6 +5817,8 @@ static void handle_deauth(struct hostapd - " reason_code=%d", - MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code)); - -+ hostapd_ubus_notify(hapd, "deauth", mgmt->sa); -+ - sta = ap_get_sta(hapd, mgmt->sa); - if (sta == NULL) { - wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying " -Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c + switch (mgmt->u.action.category) { + #ifdef CONFIG_IEEE80211R_AP +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/beacon.c =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/beacon.c -+++ hostapd-2021-02-20-59e9794c/src/ap/beacon.c -@@ -823,6 +823,12 @@ void handle_probe_req(struct hostapd_dat - u16 csa_offs[2]; +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/beacon.c ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/beacon.c +@@ -1424,6 +1424,12 @@ void handle_probe_req(struct hostapd_dat size_t csa_offs_len; struct radius_sta rad_info; + struct multi_link_data ml_data; + struct hostapd_ubus_request req = { + .type = HOSTAPD_UBUS_PROBE_REQ, + .mgmt_frame = mgmt, @@ -193,9 +203,9 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c + .elems = &elems, + }; - if (hapd->iconf->rssi_ignore_probe_request && ssi_signal && - ssi_signal < hapd->iconf->rssi_ignore_probe_request) -@@ -1009,6 +1015,12 @@ void handle_probe_req(struct hostapd_dat + os_memset(&ml_data, 0, sizeof(struct multi_link_data)); + +@@ -1612,6 +1618,12 @@ void handle_probe_req(struct hostapd_dat } #endif /* CONFIG_P2P */ @@ -208,11 +218,11 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c /* TODO: verify that supp_rates contains at least one matching rate * with AP configuration */ -Index: hostapd-2021-02-20-59e9794c/src/ap/drv_callbacks.c +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/drv_callbacks.c =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/drv_callbacks.c -+++ hostapd-2021-02-20-59e9794c/src/ap/drv_callbacks.c -@@ -145,6 +145,10 @@ int hostapd_notif_assoc(struct hostapd_d +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/drv_callbacks.c ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/drv_callbacks.c +@@ -147,6 +147,10 @@ int hostapd_notif_assoc(struct hostapd_d u16 reason = WLAN_REASON_UNSPECIFIED; int status = WLAN_STATUS_SUCCESS; const u8 *p2p_dev_addr = NULL; @@ -223,7 +233,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/drv_callbacks.c if (addr == NULL) { /* -@@ -237,6 +241,12 @@ int hostapd_notif_assoc(struct hostapd_d +@@ -239,6 +243,12 @@ int hostapd_notif_assoc(struct hostapd_d goto fail; } @@ -236,23 +246,11 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/drv_callbacks.c #ifdef CONFIG_P2P if (elems.p2p) { wpabuf_free(sta->p2p_ie); -@@ -981,9 +991,11 @@ void hostapd_event_ch_switch(struct host - - wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED - "freq=%d dfs=%d", freq, is_dfs); -+ hostapd_ubus_notify_csa(hapd, freq); - } else if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) { - wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED - "freq=%d dfs=%d", freq, is_dfs); -+ hostapd_ubus_notify_csa(hapd, freq); - } else if (is_dfs && - hostapd_is_dfs_required(hapd->iface) && - !hostapd_is_dfs_chan_available(hapd->iface) && -Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.c +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/sta_info.c =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/sta_info.c -+++ hostapd-2021-02-20-59e9794c/src/ap/sta_info.c -@@ -458,6 +458,7 @@ void ap_handle_timer(void *eloop_ctx, vo +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/sta_info.c ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/sta_info.c +@@ -597,6 +597,7 @@ void ap_handle_timer(void *eloop_ctx, vo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "deauthenticated due to " "local deauth request"); @@ -260,7 +258,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.c ap_free_sta(hapd, sta); return; } -@@ -613,6 +614,7 @@ skip_poll: +@@ -752,6 +753,7 @@ skip_poll: mlme_deauthenticate_indication( hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID); @@ -268,7 +266,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.c ap_free_sta(hapd, sta); break; } -@@ -1298,12 +1300,25 @@ void ap_sta_set_authorized(struct hostap +@@ -1592,15 +1594,28 @@ void ap_sta_set_authorized(struct hostap sta->addr, authorized, dev_addr); if (authorized) { @@ -283,18 +281,21 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.c + [WLAN_AUTH_PASN] = "pasn", + }; + const char *auth_alg = NULL; + const u8 *dpp_pkhash; const char *keyid; + char dpp_pkhash_buf[100]; char keyid_buf[100]; char ip_addr[100]; + char alg_buf[100]; + dpp_pkhash_buf[0] = '\0'; keyid_buf[0] = '\0'; ip_addr[0] = '\0'; + alg_buf[0] = '\0'; #ifdef CONFIG_P2P if (wpa_auth_get_ip_addr(sta->wpa_sm, ip_addr_buf) == 0) { os_snprintf(ip_addr, sizeof(ip_addr), -@@ -1313,22 +1328,31 @@ void ap_sta_set_authorized(struct hostap +@@ -1610,6 +1625,13 @@ void ap_sta_set_authorized(struct hostap } #endif /* CONFIG_P2P */ @@ -308,33 +309,35 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.c keyid = ap_sta_wpa_get_keyid(hapd, sta); if (keyid) { os_snprintf(keyid_buf, sizeof(keyid_buf), - " keyid=%s", keyid); +@@ -1628,17 +1650,19 @@ void ap_sta_set_authorized(struct hostap + dpp_pkhash, SHA256_MAC_LEN); } -- wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s", -- buf, ip_addr, keyid_buf); -+ hostapd_ubus_notify_authorized(hapd, sta); -+ wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s", -+ buf, ip_addr, keyid_buf, alg_buf); +- wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s", +- buf, ip_addr, keyid_buf, dpp_pkhash_buf); ++ hostapd_ubus_notify_authorized(hapd, sta, auth_alg); ++ wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s%s", ++ buf, ip_addr, keyid_buf, dpp_pkhash_buf, alg_buf); if (hapd->msg_ctx_parent && hapd->msg_ctx_parent != hapd->msg_ctx) wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO, -- AP_STA_CONNECTED "%s%s%s", -- buf, ip_addr, keyid_buf); -+ AP_STA_CONNECTED "%s%s%s%s", -+ buf, ip_addr, keyid_buf, alg_buf); +- AP_STA_CONNECTED "%s%s%s%s", ++ AP_STA_CONNECTED "%s%s%s%s%s", + buf, ip_addr, keyid_buf, +- dpp_pkhash_buf); ++ dpp_pkhash_buf, alg_buf); } else { wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf); + hostapd_ubus_notify(hapd, "disassoc", sta->addr); if (hapd->msg_ctx_parent && hapd->msg_ctx_parent != hapd->msg_ctx) -Index: hostapd-2021-02-20-59e9794c/src/ap/wpa_auth_glue.c +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/wpa_auth_glue.c =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/wpa_auth_glue.c -+++ hostapd-2021-02-20-59e9794c/src/ap/wpa_auth_glue.c -@@ -265,6 +265,7 @@ static void hostapd_wpa_auth_psk_failure +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/wpa_auth_glue.c ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/wpa_auth_glue.c +@@ -270,6 +270,7 @@ static void hostapd_wpa_auth_psk_failure struct hostapd_data *hapd = ctx; wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR, MAC2STR(addr)); @@ -342,11 +345,11 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/wpa_auth_glue.c } -Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/Makefile +Index: hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/Makefile =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/Makefile -+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/Makefile -@@ -169,6 +169,13 @@ ifdef CONFIG_EAPOL_TEST +--- hostapd-2023-02-21-ath12.3-cs.orig/wpa_supplicant/Makefile ++++ hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/Makefile +@@ -192,6 +192,13 @@ ifdef CONFIG_EAPOL_TEST CFLAGS += -Werror -DEAPOL_TEST endif @@ -360,7 +363,7 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/Makefile ifdef CONFIG_CODE_COVERAGE CFLAGS += -O0 -fprofile-arcs -ftest-coverage LIBS += -lgcov -@@ -946,6 +953,9 @@ ifdef CONFIG_CTRL_IFACE_MIB +@@ -991,6 +998,9 @@ ifdef CONFIG_CTRL_IFACE_MIB CFLAGS += -DCONFIG_CTRL_IFACE_MIB endif OBJS += ../src/ap/ctrl_iface_ap.o @@ -370,11 +373,11 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/Makefile endif CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY -Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c +Index: hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/wpa_supplicant.c =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant.c -+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c -@@ -6943,6 +6943,8 @@ struct wpa_supplicant * wpa_supplicant_a +--- hostapd-2023-02-21-ath12.3-cs.orig/wpa_supplicant/wpa_supplicant.c ++++ hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/wpa_supplicant.c +@@ -7640,6 +7640,8 @@ struct wpa_supplicant * wpa_supplicant_a } #endif /* CONFIG_P2P */ @@ -383,7 +386,7 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c return wpa_s; } -@@ -6969,6 +6971,8 @@ int wpa_supplicant_remove_iface(struct w +@@ -7666,6 +7668,8 @@ int wpa_supplicant_remove_iface(struct w struct wpa_supplicant *parent = wpa_s->parent; #endif /* CONFIG_MESH */ @@ -392,7 +395,7 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c /* Remove interface from the global list of interfaces */ prev = global->ifaces; if (prev == wpa_s) { -@@ -7272,8 +7276,12 @@ int wpa_supplicant_run(struct wpa_global +@@ -8012,8 +8016,12 @@ int wpa_supplicant_run(struct wpa_global eloop_register_signal_terminate(wpa_supplicant_terminate, global); eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); @@ -405,19 +408,19 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c return 0; } -Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h +Index: hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/wpa_supplicant_i.h =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant_i.h -+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h -@@ -19,6 +19,7 @@ - #include "wps/wps_defs.h" +--- hostapd-2023-02-21-ath12.3-cs.orig/wpa_supplicant/wpa_supplicant_i.h ++++ hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/wpa_supplicant_i.h +@@ -21,6 +21,7 @@ #include "config_ssid.h" #include "wmm_ac.h" + #include "pasn/pasn_common.h" +#include "ubus.h" extern const char *const wpa_supplicant_version; extern const char *const wpa_supplicant_license; -@@ -316,6 +317,8 @@ struct wpa_global { +@@ -319,6 +320,8 @@ struct wpa_global { #endif /* CONFIG_WIFI_DISPLAY */ struct psk_list_entry *add_psk; /* From group formation */ @@ -426,7 +429,7 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h }; -@@ -596,6 +599,7 @@ struct wpa_supplicant { +@@ -650,6 +653,7 @@ struct wpa_supplicant { unsigned char own_addr[ETH_ALEN]; unsigned char perm_addr[ETH_ALEN]; char ifname[100]; @@ -434,10 +437,10 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h #ifdef CONFIG_MATCH_IFACE int matched; #endif /* CONFIG_MATCH_IFACE */ -Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wps_supplicant.c +Index: hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/wps_supplicant.c =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wps_supplicant.c -+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wps_supplicant.c +--- hostapd-2023-02-21-ath12.3-cs.orig/wpa_supplicant/wps_supplicant.c ++++ hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/wps_supplicant.c @@ -33,6 +33,7 @@ #include "p2p/p2p.h" #include "p2p_supplicant.h" @@ -446,7 +449,7 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wps_supplicant.c #ifndef WPS_PIN_SCAN_IGNORE_SEL_REG -@@ -392,6 +393,8 @@ static int wpa_supplicant_wps_cred(void +@@ -402,6 +403,8 @@ static int wpa_supplicant_wps_cred(void wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute", cred->cred_attr, cred->cred_attr_len); @@ -455,11 +458,11 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wps_supplicant.c if (wpa_s->conf->wps_cred_processing == 1) return 0; -Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/main.c +Index: hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/main.c =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/main.c -+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/main.c -@@ -202,7 +202,7 @@ int main(int argc, char *argv[]) +--- hostapd-2023-02-21-ath12.3-cs.orig/wpa_supplicant/main.c ++++ hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/main.c +@@ -203,7 +203,7 @@ int main(int argc, char *argv[]) for (;;) { c = getopt(argc, argv, @@ -468,7 +471,7 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/main.c if (c < 0) break; switch (c) { -@@ -267,6 +267,9 @@ int main(int argc, char *argv[]) +@@ -268,6 +268,9 @@ int main(int argc, char *argv[]) params.conf_p2p_dev = optarg; break; #endif /* CONFIG_P2P */ @@ -478,10 +481,10 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/main.c case 'o': params.override_driver = optarg; break; -Index: hostapd-2021-02-20-59e9794c/src/ap/rrm.c +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/rrm.c =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/rrm.c -+++ hostapd-2021-02-20-59e9794c/src/ap/rrm.c +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/rrm.c ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/rrm.c @@ -89,6 +89,9 @@ static void hostapd_handle_beacon_report return; wpa_msg(hapd->msg_ctx, MSG_INFO, BEACON_RESP_RX MACSTR " %u %02x %s", @@ -492,10 +495,18 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/rrm.c } -Index: hostapd-2021-02-20-59e9794c/src/ap/vlan_init.c +@@ -360,6 +363,7 @@ void hostapd_handle_radio_measurement(st + break; + case WLAN_RRM_LINK_MEASUREMENT_REPORT: + hostapd_handle_link_mesr_report(hapd, buf, len); ++ hostapd_ubus_handle_link_measurement(hapd, buf, len); + break; + default: + wpa_printf(MSG_DEBUG, "RRM action %u is not supported", +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/vlan_init.c =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/vlan_init.c -+++ hostapd-2021-02-20-59e9794c/src/ap/vlan_init.c +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/vlan_init.c ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/vlan_init.c @@ -22,6 +22,7 @@ static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan, int existsok) @@ -532,11 +543,11 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/vlan_init.c return hostapd_vlan_if_remove(hapd, vlan->ifname); } -Index: hostapd-2021-02-20-59e9794c/src/ap/dfs.c +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/dfs.c =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/dfs.c -+++ hostapd-2021-02-20-59e9794c/src/ap/dfs.c -@@ -1226,6 +1226,8 @@ int hostapd_dfs_nop_finished(struct host +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/dfs.c ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/dfs.c +@@ -1331,6 +1331,8 @@ int hostapd_dfs_pre_cac_expired(struct h "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", freq, ht_enabled, chan_offset, chan_width, cf1, cf2); @@ -545,11 +556,11 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/dfs.c /* Proceed only if DFS is not offloaded to the driver */ if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) return 0; -Index: hostapd-2021-02-20-59e9794c/src/ap/airtime_policy.c +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/airtime_policy.c =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/airtime_policy.c -+++ hostapd-2021-02-20-59e9794c/src/ap/airtime_policy.c -@@ -108,8 +108,14 @@ static void set_sta_weights(struct hosta +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/airtime_policy.c ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/airtime_policy.c +@@ -112,8 +112,14 @@ static void set_sta_weights(struct hosta { struct sta_info *sta; @@ -566,7 +577,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/airtime_policy.c } -@@ -240,7 +246,10 @@ int airtime_policy_new_sta(struct hostap +@@ -244,7 +250,10 @@ int airtime_policy_new_sta(struct hostap unsigned int weight; if (hapd->iconf->airtime_mode == AIRTIME_MODE_STATIC) { @@ -578,11 +589,11 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/airtime_policy.c if (weight) return sta_set_airtime_weight(hapd, sta, weight); } -Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.h +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/sta_info.h =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/sta_info.h -+++ hostapd-2021-02-20-59e9794c/src/ap/sta_info.h -@@ -323,6 +323,7 @@ struct sta_info { +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/sta_info.h ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/sta_info.h +@@ -322,6 +322,7 @@ struct sta_info { #endif /* CONFIG_TESTING_OPTIONS */ #ifdef CONFIG_AIRTIME_POLICY unsigned int airtime_weight; @@ -590,13 +601,13 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.h struct os_reltime backlogged_until; #endif /* CONFIG_AIRTIME_POLICY */ -Index: hostapd-2021-02-20-59e9794c/src/ap/wnm_ap.c +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/wnm_ap.c =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/wnm_ap.c -+++ hostapd-2021-02-20-59e9794c/src/ap/wnm_ap.c -@@ -442,7 +442,8 @@ static void ieee802_11_rx_bss_trans_mgmt - wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries", - pos, end - pos); +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/wnm_ap.c ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/wnm_ap.c +@@ -495,7 +495,8 @@ static void ieee802_11_rx_bss_trans_mgmt + MAC2STR(addr), reason, hex ? " neighbor=" : "", hex); + os_free(hex); - ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token); + if (!hostapd_ubus_notify_bss_transition_query(hapd, addr, dialog_token, reason, pos, end - pos)) @@ -604,7 +615,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/wnm_ap.c } -@@ -464,7 +465,7 @@ static void ieee802_11_rx_bss_trans_mgmt +@@ -517,7 +518,7 @@ static void ieee802_11_rx_bss_trans_mgmt size_t len) { u8 dialog_token, status_code, bss_termination_delay; @@ -613,7 +624,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/wnm_ap.c int enabled = hapd->conf->bss_transition; struct sta_info *sta; -@@ -511,6 +512,7 @@ static void ieee802_11_rx_bss_trans_mgmt +@@ -564,6 +565,7 @@ static void ieee802_11_rx_bss_trans_mgmt wpa_printf(MSG_DEBUG, "WNM: not enough room for Target BSSID field"); return; } @@ -621,7 +632,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/wnm_ap.c sta->agreed_to_steer = 1; eloop_cancel_timeout(ap_sta_reset_steer_flag_timer, hapd, sta); eloop_register_timeout(2, 0, ap_sta_reset_steer_flag_timer, -@@ -530,6 +532,10 @@ static void ieee802_11_rx_bss_trans_mgmt +@@ -583,6 +585,10 @@ static void ieee802_11_rx_bss_trans_mgmt MAC2STR(addr), status_code, bss_termination_delay); } @@ -632,10 +643,10 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/wnm_ap.c wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries", pos, end - pos); } -Index: hostapd-2021-02-20-59e9794c/src/utils/eloop.c +Index: hostapd-2023-02-21-ath12.3-cs/src/utils/eloop.c =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/utils/eloop.c -+++ hostapd-2021-02-20-59e9794c/src/utils/eloop.c +--- hostapd-2023-02-21-ath12.3-cs.orig/src/utils/eloop.c ++++ hostapd-2023-02-21-ath12.3-cs/src/utils/eloop.c @@ -77,6 +77,9 @@ struct eloop_sock_table { struct eloop_data { int max_sock; @@ -646,7 +657,7 @@ Index: hostapd-2021-02-20-59e9794c/src/utils/eloop.c size_t count; /* sum of all table counts */ #ifdef CONFIG_ELOOP_POLL size_t max_pollfd_map; /* number of pollfds_map currently allocated */ -@@ -1116,6 +1119,12 @@ void eloop_run(void) +@@ -1121,6 +1124,12 @@ void eloop_run(void) os_reltime_sub(&timeout->time, &now, &tv); else tv.sec = tv.usec = 0; @@ -659,7 +670,7 @@ Index: hostapd-2021-02-20-59e9794c/src/utils/eloop.c #if defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) timeout_ms = tv.sec * 1000 + tv.usec / 1000; #endif /* defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) */ -@@ -1185,7 +1194,8 @@ void eloop_run(void) +@@ -1190,7 +1199,8 @@ void eloop_run(void) eloop.exceptions.changed = 0; eloop_process_pending_signals(); @@ -669,7 +680,7 @@ Index: hostapd-2021-02-20-59e9794c/src/utils/eloop.c /* check if some registered timeouts have occurred */ timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, -@@ -1247,6 +1257,14 @@ out: +@@ -1252,6 +1262,14 @@ out: return; } @@ -684,10 +695,10 @@ Index: hostapd-2021-02-20-59e9794c/src/utils/eloop.c void eloop_terminate(void) { -Index: hostapd-2021-02-20-59e9794c/src/utils/eloop.h +Index: hostapd-2023-02-21-ath12.3-cs/src/utils/eloop.h =================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/utils/eloop.h -+++ hostapd-2021-02-20-59e9794c/src/utils/eloop.h +--- hostapd-2023-02-21-ath12.3-cs.orig/src/utils/eloop.h ++++ hostapd-2023-02-21-ath12.3-cs/src/utils/eloop.h @@ -65,6 +65,9 @@ typedef void (*eloop_timeout_handler)(vo */ typedef void (*eloop_signal_handler)(int sig, void *signal_ctx); @@ -717,10 +728,10 @@ Index: hostapd-2021-02-20-59e9794c/src/utils/eloop.h /** * eloop_run - Start the event loop * -Index: hostapd-2021-02-20-59e9794c/src/utils/uloop.c +Index: hostapd-2023-02-21-ath12.3-cs/src/utils/uloop.c =================================================================== --- /dev/null -+++ hostapd-2021-02-20-59e9794c/src/utils/uloop.c ++++ hostapd-2023-02-21-ath12.3-cs/src/utils/uloop.c @@ -0,0 +1,64 @@ +#include +#include "includes.h" diff --git a/feeds/ipq95xx/hostapd/patches/601-ucode_support.patch b/feeds/ipq95xx/hostapd/patches/601-ucode_support.patch index fabf8103..dd7af7c7 100644 --- a/feeds/ipq95xx/hostapd/patches/601-ucode_support.patch +++ b/feeds/ipq95xx/hostapd/patches/601-ucode_support.patch @@ -1,7 +1,7 @@ -Index: hostapd-2021-12-13-b26f5c0f/hostapd/Makefile +Index: hostapd-2023-02-21-ath12.3-cs/hostapd/Makefile =================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/hostapd/Makefile -+++ hostapd-2021-12-13-b26f5c0f/hostapd/Makefile +--- hostapd-2023-02-21-ath12.3-cs.orig/hostapd/Makefile ++++ hostapd-2023-02-21-ath12.3-cs/hostapd/Makefile @@ -168,9 +168,21 @@ OBJS += ../src/eapol_auth/eapol_auth_sm. ifdef CONFIG_UBUS @@ -26,11 +26,11 @@ Index: hostapd-2021-12-13-b26f5c0f/hostapd/Makefile endif ifdef CONFIG_CODE_COVERAGE -Index: hostapd-2021-12-13-b26f5c0f/hostapd/main.c +Index: hostapd-2023-02-21-ath12.3-cs/hostapd/main.c =================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/hostapd/main.c -+++ hostapd-2021-12-13-b26f5c0f/hostapd/main.c -@@ -898,6 +898,7 @@ int main(int argc, char *argv[]) +--- hostapd-2023-02-21-ath12.3-cs.orig/hostapd/main.c ++++ hostapd-2023-02-21-ath12.3-cs/hostapd/main.c +@@ -985,6 +985,7 @@ int main(int argc, char *argv[]) } hostapd_global_ctrl_iface_init(&interfaces); @@ -38,19 +38,19 @@ Index: hostapd-2021-12-13-b26f5c0f/hostapd/main.c if (hostapd_global_run(&interfaces, daemonize, pid_file)) { wpa_printf(MSG_ERROR, "Failed to start eloop"); -@@ -907,6 +908,7 @@ int main(int argc, char *argv[]) +@@ -994,6 +995,7 @@ int main(int argc, char *argv[]) ret = 0; out: + hostapd_ucode_free(); hostapd_global_ctrl_iface_deinit(&interfaces); - /* Deinitialize all interfaces */ - for (i = 0; i < interfaces.count; i++) { -Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.h + /* Sending deauth to all stations before deinit */ + hostapd_deauthenticate_stations(&interfaces); +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/hostapd.h =================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/hostapd.h -+++ hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.h -@@ -18,6 +18,7 @@ +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/hostapd.h ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/hostapd.h +@@ -19,6 +19,7 @@ #include "ap_config.h" #include "drivers/driver.h" #include "ubus.h" @@ -58,7 +58,7 @@ Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.h #define OCE_STA_CFON_ENABLED(hapd) \ ((hapd->conf->oce & OCE_STA_CFON) && \ -@@ -50,6 +51,10 @@ struct hapd_interfaces { +@@ -56,6 +57,10 @@ struct hapd_interfaces { struct hostapd_config * (*config_read_cb)(const char *config_fname); int (*ctrl_iface_init)(struct hostapd_data *hapd); void (*ctrl_iface_deinit)(struct hostapd_data *hapd); @@ -69,7 +69,7 @@ Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.h int (*for_each_interface)(struct hapd_interfaces *interfaces, int (*cb)(struct hostapd_iface *iface, void *ctx), void *ctx); -@@ -173,6 +178,7 @@ struct hostapd_data { +@@ -205,6 +210,7 @@ struct hostapd_data { struct hostapd_config *iconf; struct hostapd_bss_config *conf; struct hostapd_ubus_bss ubus; @@ -77,7 +77,7 @@ Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.h int interface_added; /* virtual interface added for this BSS */ unsigned int started:1; unsigned int disabled:1; -@@ -467,6 +473,7 @@ struct hostapd_sta_info { +@@ -540,6 +546,7 @@ struct hostapd_mld { */ struct hostapd_iface { struct hapd_interfaces *interfaces; @@ -85,7 +85,7 @@ Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.h void *owner; char *config_fname; struct hostapd_config *conf; -@@ -641,6 +648,8 @@ struct hostapd_iface * hostapd_init(stru +@@ -752,6 +759,8 @@ struct hostapd_iface * hostapd_init(stru struct hostapd_iface * hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy, const char *config_fname, int debug); @@ -94,11 +94,11 @@ Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.h void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, int reassoc); void hostapd_interface_deinit_free(struct hostapd_iface *iface); -Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.c +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/hostapd.c =================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/hostapd.c -+++ hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.c -@@ -217,6 +217,8 @@ int hostapd_reload_config(struct hostapd +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/hostapd.c ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/hostapd.c +@@ -285,6 +285,8 @@ int hostapd_reload_config(struct hostapd struct hostapd_config *newconf, *oldconf; size_t j; @@ -107,7 +107,7 @@ Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.c if (iface->config_fname == NULL) { /* Only in-memory config in use - assume it has been updated */ hostapd_clear_old(iface); -@@ -377,6 +379,7 @@ void hostapd_free_hapd_data(struct hosta +@@ -471,6 +473,7 @@ void hostapd_free_hapd_data(struct hosta hapd->beacon_set_done = 0; wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); @@ -115,24 +115,15 @@ Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.c hostapd_ubus_free_bss(hapd); accounting_deinit(hapd); hostapd_deinit_wpa(hapd); -@@ -534,6 +537,7 @@ void hostapd_cleanup_iface_partial(struc +@@ -637,6 +640,7 @@ void hostapd_cleanup_iface_partial(struc static void hostapd_cleanup_iface(struct hostapd_iface *iface) { wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); + hostapd_ucode_free_iface(iface); - eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface, NULL); -@@ -1108,7 +1112,7 @@ static int db_table_create_radius_attrib - * initialized. Most of the modules that are initialized here will be - * deinitialized in hostapd_cleanup(). - */ --static int hostapd_setup_bss(struct hostapd_data *hapd, int first) -+int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool set_beacon) - { - struct hostapd_bss_config *conf = hapd->conf; - u8 ssid[SSID_MAX_LEN + 1]; -@@ -1405,6 +1409,7 @@ static int hostapd_setup_bss(struct host + +@@ -1226,6 +1230,7 @@ static int hostapd_start_beacon(struct h hapd->driver->set_operstate(hapd->drv_priv, 1); hostapd_ubus_add_bss(hapd); @@ -140,16 +131,17 @@ Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.c return 0; } -@@ -2116,7 +2121,7 @@ static int hostapd_setup_interface_compl - hapd = iface->bss[j]; - if (j) - os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN); -- if (hostapd_setup_bss(hapd, j == 0)) { -+ if (hostapd_setup_bss(hapd, j == 0, true)) { - for (;;) { - hapd = iface->bss[j]; - hostapd_bss_deinit_no_free(hapd); -@@ -2396,7 +2401,7 @@ hostapd_alloc_bss_data(struct hostapd_if +@@ -1248,8 +1253,7 @@ static int hostapd_start_beacon(struct h + * initialized. Most of the modules that are initialized here will be + * deinitialized in hostapd_cleanup(). + */ +-static int hostapd_setup_bss(struct hostapd_data *hapd, int first, +- bool start_beacon) ++int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon) + { + struct hostapd_bss_config *conf = hapd->conf; + u8 ssid[SSID_MAX_LEN + 1]; +@@ -2919,7 +2923,7 @@ hostapd_alloc_bss_data(struct hostapd_if } @@ -158,16 +150,7 @@ Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.c { if (!hapd) return; -@@ -3013,7 +3018,7 @@ int hostapd_add_iface(struct hapd_interf - - if (start_ctrl_iface_bss(hapd) < 0 || - (hapd_iface->state == HAPD_IFACE_ENABLED && -- hostapd_setup_bss(hapd, -1))) { -+ hostapd_setup_bss(hapd, -1, true))) { - hostapd_cleanup(hapd); - hapd_iface->bss[hapd_iface->num_bss - 1] = NULL; - hapd_iface->conf->num_bss--; -@@ -3165,7 +3170,8 @@ int hostapd_remove_iface(struct hapd_int +@@ -4086,7 +4090,8 @@ int hostapd_remove_iface(struct hapd_int hapd_iface = interfaces->iface[i]; if (hapd_iface == NULL) return -1; @@ -177,11 +160,11 @@ Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.c wpa_printf(MSG_INFO, "Remove interface '%s'", buf); hapd_iface->driver_ap_teardown = !!(hapd_iface->drv_flags & -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/Makefile +Index: hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/Makefile =================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/Makefile -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/Makefile -@@ -177,8 +177,20 @@ endif +--- hostapd-2023-02-21-ath12.3-cs.orig/wpa_supplicant/Makefile ++++ hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/Makefile +@@ -195,8 +195,20 @@ endif ifdef CONFIG_UBUS CFLAGS += -DUBUS_SUPPORT OBJS += ubus.o @@ -203,7 +186,7 @@ Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/Makefile endif ifdef CONFIG_CODE_COVERAGE -@@ -969,6 +981,9 @@ OBJS += ../src/ap/ctrl_iface_ap.o +@@ -1001,6 +1013,9 @@ OBJS += ../src/ap/ctrl_iface_ap.o ifdef CONFIG_UBUS OBJS += ../src/ap/ubus.o endif @@ -213,11 +196,11 @@ Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/Makefile endif CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.c +Index: hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/wpa_supplicant.c =================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/wpa_supplicant.c -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.c -@@ -1033,6 +1033,7 @@ void wpa_supplicant_set_state(struct wpa +--- hostapd-2023-02-21-ath12.3-cs.orig/wpa_supplicant/wpa_supplicant.c ++++ hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/wpa_supplicant.c +@@ -1044,6 +1044,7 @@ void wpa_supplicant_set_state(struct wpa sme_sched_obss_scan(wpa_s, 0); } wpa_s->wpa_state = state; @@ -225,7 +208,7 @@ Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.c #ifdef CONFIG_BGSCAN if (state == WPA_COMPLETED && wpa_s->current_ssid != wpa_s->bgscan_ssid) -@@ -7155,6 +7156,7 @@ struct wpa_supplicant * wpa_supplicant_a +@@ -7641,6 +7642,7 @@ struct wpa_supplicant * wpa_supplicant_a #endif /* CONFIG_P2P */ wpas_ubus_add_bss(wpa_s); @@ -233,7 +216,7 @@ Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.c return wpa_s; } -@@ -7182,6 +7184,7 @@ int wpa_supplicant_remove_iface(struct w +@@ -7668,6 +7670,7 @@ int wpa_supplicant_remove_iface(struct w struct wpa_supplicant *parent = wpa_s->parent; #endif /* CONFIG_MESH */ @@ -241,7 +224,7 @@ Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.c wpas_ubus_free_bss(wpa_s); /* Remove interface from the global list of interfaces */ -@@ -7449,6 +7452,7 @@ struct wpa_global * wpa_supplicant_init( +@@ -7978,6 +7981,7 @@ struct wpa_global * wpa_supplicant_init( eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0, wpas_periodic, global, NULL); @@ -249,7 +232,7 @@ Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.c return global; } -@@ -7487,12 +7491,8 @@ int wpa_supplicant_run(struct wpa_global +@@ -8016,12 +8020,8 @@ int wpa_supplicant_run(struct wpa_global eloop_register_signal_terminate(wpa_supplicant_terminate, global); eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); @@ -262,7 +245,7 @@ Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.c return 0; } -@@ -7525,6 +7525,8 @@ void wpa_supplicant_deinit(struct wpa_gl +@@ -8054,6 +8054,8 @@ void wpa_supplicant_deinit(struct wpa_gl wpas_notify_supplicant_deinitialized(global); @@ -271,19 +254,19 @@ Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.c eap_peer_unregister_methods(); #ifdef CONFIG_AP eap_server_unregister_methods(); -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant_i.h +Index: hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/wpa_supplicant_i.h =================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/wpa_supplicant_i.h -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant_i.h -@@ -20,6 +20,7 @@ - #include "config_ssid.h" +--- hostapd-2023-02-21-ath12.3-cs.orig/wpa_supplicant/wpa_supplicant_i.h ++++ hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/wpa_supplicant_i.h +@@ -22,6 +22,7 @@ #include "wmm_ac.h" + #include "pasn/pasn_common.h" #include "ubus.h" +#include "ucode.h" extern const char *const wpa_supplicant_version; extern const char *const wpa_supplicant_license; -@@ -707,6 +708,7 @@ struct wpa_supplicant { +@@ -654,6 +655,7 @@ struct wpa_supplicant { unsigned char perm_addr[ETH_ALEN]; char ifname[100]; struct wpas_ubus_bss ubus; @@ -291,11 +274,11 @@ Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant_i.h #ifdef CONFIG_MATCH_IFACE int matched; #endif /* CONFIG_MATCH_IFACE */ -Index: hostapd-2021-12-13-b26f5c0f/hostapd/ctrl_iface.c +Index: hostapd-2023-02-21-ath12.3-cs/hostapd/ctrl_iface.c =================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/hostapd/ctrl_iface.c -+++ hostapd-2021-12-13-b26f5c0f/hostapd/ctrl_iface.c -@@ -5023,6 +5023,7 @@ try_again: +--- hostapd-2023-02-21-ath12.3-cs.orig/hostapd/ctrl_iface.c ++++ hostapd-2023-02-21-ath12.3-cs/hostapd/ctrl_iface.c +@@ -5369,6 +5369,7 @@ try_again: return -1; } @@ -303,7 +286,7 @@ Index: hostapd-2021-12-13-b26f5c0f/hostapd/ctrl_iface.c wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb); return 0; -@@ -5124,6 +5125,7 @@ fail: +@@ -5470,6 +5471,7 @@ fail: os_free(fname); interface->global_ctrl_sock = s; @@ -311,11 +294,11 @@ Index: hostapd-2021-12-13-b26f5c0f/hostapd/ctrl_iface.c eloop_register_read_sock(s, hostapd_global_ctrl_iface_receive, interface, NULL); -Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver.h +Index: hostapd-2023-02-21-ath12.3-cs/src/drivers/driver.h =================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/drivers/driver.h -+++ hostapd-2021-12-13-b26f5c0f/src/drivers/driver.h -@@ -3366,6 +3366,25 @@ struct wpa_driver_ops { +--- hostapd-2023-02-21-ath12.3-cs.orig/src/drivers/driver.h ++++ hostapd-2023-02-21-ath12.3-cs/src/drivers/driver.h +@@ -3899,6 +3899,25 @@ struct wpa_driver_ops { const char *ifname); /** @@ -341,7 +324,7 @@ Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver.h * set_sta_vlan - Bind a station into a specific interface (AP only) * @priv: Private driver interface data * @ifname: Interface (main or virtual BSS or VLAN) -@@ -5842,6 +5861,7 @@ union wpa_event_data { +@@ -6525,6 +6544,7 @@ union wpa_event_data { /** * struct ch_switch @@ -349,56 +332,58 @@ Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver.h * @freq: Frequency of new channel in MHz * @ht_enabled: Whether this is an HT channel * @ch_offset: Secondary channel offset -@@ -5850,6 +5870,7 @@ union wpa_event_data { - * @cf2: Center frequency 2 +@@ -6534,6 +6554,7 @@ union wpa_event_data { + * @link_id: Link ID of the MLO link */ struct ch_switch { + int count; int freq; int ht_enabled; int ch_offset; -Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211_event.c +Index: hostapd-2023-02-21-ath12.3-cs/src/drivers/driver_nl80211_event.c =================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/drivers/driver_nl80211_event.c -+++ hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211_event.c -@@ -684,6 +684,7 @@ static void mlme_event_ch_switch(struct - struct nlattr *ifindex, struct nlattr *freq, - struct nlattr *type, struct nlattr *bw, - struct nlattr *cf1, struct nlattr *cf2, +--- hostapd-2023-02-21-ath12.3-cs.orig/src/drivers/driver_nl80211_event.c ++++ hostapd-2023-02-21-ath12.3-cs/src/drivers/driver_nl80211_event.c +@@ -1002,6 +1002,7 @@ static void mlme_event_ch_switch(struct + struct nlattr *cf2, + struct nlattr *ru_punct_bitmap, + struct nlattr *ru_punct_ofdma, + struct nlattr *count, int finished) { struct i802_bss *bss; -@@ -745,6 +746,8 @@ static void mlme_event_ch_switch(struct - data.ch_switch.cf1 = nla_get_u32(cf1); - if (cf2) - data.ch_switch.cf2 = nla_get_u32(cf2); +@@ -1092,7 +1093,9 @@ static void mlme_event_ch_switch(struct + if (ru_punct_ofdma) + data.ch_switch.ru_punct_ofdma = nla_get_flag(ru_punct_ofdma); + } +- + if (count) + data.ch_switch.count = nla_get_u32(count); - ++ if (finished) bss->freq = data.ch_switch.freq; -@@ -3003,6 +3006,7 @@ static void do_process_drv_event(struct - tb[NL80211_ATTR_CHANNEL_WIDTH], - tb[NL80211_ATTR_CENTER_FREQ1], + +@@ -3833,6 +3836,7 @@ static void do_process_drv_event(struct tb[NL80211_ATTR_CENTER_FREQ2], + tb[NL80211_ATTR_RU_PUNCT_BITMAP], + tb[NL80211_ATTR_RU_PUNCT_SUPP_HE], + tb[NL80211_ATTR_CH_SWITCH_COUNT], 0); break; case NL80211_CMD_CH_SWITCH_NOTIFY: -@@ -3013,6 +3017,7 @@ static void do_process_drv_event(struct - tb[NL80211_ATTR_CHANNEL_WIDTH], - tb[NL80211_ATTR_CENTER_FREQ1], +@@ -3846,6 +3850,7 @@ static void do_process_drv_event(struct tb[NL80211_ATTR_CENTER_FREQ2], -+ NULL, + tb[NL80211_ATTR_RU_PUNCT_BITMAP], + tb[NL80211_ATTR_RU_PUNCT_SUPP_HE], ++ NULL, 1); break; case NL80211_CMD_DISCONNECT: -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/events.c +Index: hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/events.c =================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/events.c -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/events.c -@@ -4927,6 +4927,7 @@ void supplicant_event(void *ctx, enum wp +--- hostapd-2023-02-21-ath12.3-cs.orig/wpa_supplicant/events.c ++++ hostapd-2023-02-21-ath12.3-cs/wpa_supplicant/events.c +@@ -5294,6 +5294,7 @@ void supplicant_event(void *ctx, enum wp event_to_string(event), event); #endif /* CONFIG_NO_STDOUT_DEBUG */ @@ -406,11 +391,11 @@ Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/events.c switch (event) { case EVENT_AUTH: #ifdef CONFIG_FST -Index: hostapd-2021-12-13-b26f5c0f/src/ap/ap_drv_ops.h +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/ap_drv_ops.h =================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/ap_drv_ops.h -+++ hostapd-2021-12-13-b26f5c0f/src/ap/ap_drv_ops.h -@@ -367,6 +367,23 @@ static inline int hostapd_drv_stop_ap(st +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/ap_drv_ops.h ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/ap_drv_ops.h +@@ -415,6 +415,23 @@ static inline int hostapd_drv_stop_ap(st return hapd->driver->stop_ap(hapd->drv_priv); } @@ -434,11 +419,11 @@ Index: hostapd-2021-12-13-b26f5c0f/src/ap/ap_drv_ops.h static inline int hostapd_drv_channel_info(struct hostapd_data *hapd, struct wpa_channel_info *ci) { -Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211.c +Index: hostapd-2023-02-21-ath12.3-cs/src/drivers/driver_nl80211.c =================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/drivers/driver_nl80211.c -+++ hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211.c -@@ -1249,7 +1249,7 @@ static void wpa_driver_nl80211_event_rtm +--- hostapd-2023-02-21-ath12.3-cs.orig/src/drivers/driver_nl80211.c ++++ hostapd-2023-02-21-ath12.3-cs/src/drivers/driver_nl80211.c +@@ -1370,7 +1370,7 @@ static void wpa_driver_nl80211_event_rtm } wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)", namebuf, ifname); @@ -447,7 +432,7 @@ Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211.c wpa_printf(MSG_DEBUG, "nl80211: Not the main interface (%s) - do not indicate interface down", drv->first_bss->ifname); -@@ -1285,7 +1285,7 @@ static void wpa_driver_nl80211_event_rtm +@@ -1406,7 +1406,7 @@ static void wpa_driver_nl80211_event_rtm } wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)", namebuf, ifname); @@ -456,15 +441,15 @@ Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211.c wpa_printf(MSG_DEBUG, "nl80211: Not the main interface (%s) - do not indicate interface up", drv->first_bss->ifname); -@@ -7691,6 +7691,7 @@ static void *i802_init(struct hostapd_da - char master_ifname[IFNAMSIZ]; +@@ -8706,6 +8706,7 @@ static void *i802_init(struct hostapd_da int ifindex, br_ifindex = 0; int br_added = 0; + const u8 *set_addr; + int err; - bss = wpa_driver_nl80211_drv_init(hapd, params->ifname, - params->global_priv, 1, -@@ -7751,21 +7752,17 @@ static void *i802_init(struct hostapd_da + if (params->mld_addr) + set_addr = params->mld_addr; +@@ -8789,21 +8790,17 @@ static void *i802_init(struct hostapd_da add_ifidx(drv, br_ifindex, drv->ifindex); #ifdef CONFIG_LIBNL3_ROUTE @@ -496,7 +481,7 @@ Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211.c } #endif /* CONFIG_LIBNL3_ROUTE */ -@@ -8125,6 +8122,50 @@ static int wpa_driver_nl80211_if_remove( +@@ -9218,6 +9215,50 @@ static int wpa_driver_nl80211_if_remove( return 0; } @@ -547,7 +532,7 @@ Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211.c static int cookie_handler(struct nl_msg *msg, void *arg) { -@@ -9479,6 +9520,37 @@ static int driver_nl80211_if_remove(void +@@ -10784,6 +10825,37 @@ static int driver_nl80211_if_remove(void } @@ -585,7 +570,7 @@ Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211.c static int driver_nl80211_send_mlme(void *priv, const u8 *data, size_t data_len, int noack, unsigned int freq, -@@ -12183,6 +12255,8 @@ const struct wpa_driver_ops wpa_driver_n +@@ -13925,6 +13997,8 @@ const struct wpa_driver_ops wpa_driver_n .set_acl = wpa_driver_nl80211_set_acl, .if_add = wpa_driver_nl80211_if_add, .if_remove = driver_nl80211_if_remove, diff --git a/feeds/ipq95xx/hostapd/patches/610-hostapd_cli_ujail_permission.patch b/feeds/ipq95xx/hostapd/patches/610-hostapd_cli_ujail_permission.patch new file mode 100644 index 00000000..a03fcc9f --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/610-hostapd_cli_ujail_permission.patch @@ -0,0 +1,33 @@ +--- a/src/common/wpa_ctrl.c ++++ b/src/common/wpa_ctrl.c +@@ -135,7 +135,7 @@ try_again: + return NULL; + } + tries++; +-#ifdef ANDROID ++ + /* Set client socket file permissions so that bind() creates the client + * socket with these permissions and there is no need to try to change + * them with chmod() after bind() which would have potential issues with +@@ -147,7 +147,7 @@ try_again: + * operations to allow the response to go through. Those are using the + * no-deference-symlinks version to avoid races. */ + fchmod(ctrl->s, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); +-#endif /* ANDROID */ ++ + if (bind(ctrl->s, (struct sockaddr *) &ctrl->local, + sizeof(ctrl->local)) < 0) { + if (errno == EADDRINUSE && tries < 2) { +@@ -165,7 +165,11 @@ try_again: + return NULL; + } + +-#ifdef ANDROID ++#ifndef ANDROID ++ /* Set group even if we do not have privileges to change owner */ ++ lchown(ctrl->local.sun_path, -1, 101); ++ lchown(ctrl->local.sun_path, 101, 101); ++#else + /* Set group even if we do not have privileges to change owner */ + lchown(ctrl->local.sun_path, -1, AID_WIFI); + lchown(ctrl->local.sun_path, AID_SYSTEM, AID_WIFI); diff --git a/feeds/ipq95xx/hostapd/patches/701-reload_config_inline.patch b/feeds/ipq95xx/hostapd/patches/701-reload_config_inline.patch index 2f68e73e..3c62bf67 100644 --- a/feeds/ipq95xx/hostapd/patches/701-reload_config_inline.patch +++ b/feeds/ipq95xx/hostapd/patches/701-reload_config_inline.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -4699,7 +4699,12 @@ struct hostapd_config * hostapd_config_r +@@ -4816,7 +4816,12 @@ struct hostapd_config * hostapd_config_r int errors = 0; size_t i; @@ -16,7 +16,7 @@ "for reading.", fname); --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c -@@ -318,8 +318,13 @@ struct wpa_config * wpa_config_read(cons +@@ -326,8 +326,13 @@ struct wpa_config * wpa_config_read(cons while (cred_tail && cred_tail->next) cred_tail = cred_tail->next; diff --git a/feeds/ipq95xx/hostapd/patches/710-vlan_no_bridge.patch b/feeds/ipq95xx/hostapd/patches/710-vlan_no_bridge.patch index 0459bd47..63d1b8a3 100644 --- a/feeds/ipq95xx/hostapd/patches/710-vlan_no_bridge.patch +++ b/feeds/ipq95xx/hostapd/patches/710-vlan_no_bridge.patch @@ -1,6 +1,6 @@ --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h -@@ -115,6 +115,7 @@ struct hostapd_ssid { +@@ -121,6 +121,7 @@ struct hostapd_ssid { #define DYNAMIC_VLAN_OPTIONAL 1 #define DYNAMIC_VLAN_REQUIRED 2 int dynamic_vlan; @@ -30,7 +30,7 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3342,6 +3342,8 @@ static int hostapd_config_fill(struct ho +@@ -3351,6 +3351,8 @@ static int hostapd_config_fill(struct ho #ifndef CONFIG_NO_VLAN } else if (os_strcmp(buf, "dynamic_vlan") == 0) { bss->ssid.dynamic_vlan = atoi(pos); diff --git a/feeds/ipq95xx/hostapd/patches/711-wds_bridge_force.patch b/feeds/ipq95xx/hostapd/patches/711-wds_bridge_force.patch index f8bb3918..b7cca1b0 100644 --- a/feeds/ipq95xx/hostapd/patches/711-wds_bridge_force.patch +++ b/feeds/ipq95xx/hostapd/patches/711-wds_bridge_force.patch @@ -1,6 +1,8 @@ ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -2341,6 +2341,8 @@ static int hostapd_config_fill(struct ho +Index: hostapd-2023-02-21-a9012070/hostapd/config_file.c +=================================================================== +--- hostapd-2023-02-21-a9012070.orig/hostapd/config_file.c ++++ hostapd-2023-02-21-a9012070/hostapd/config_file.c +@@ -2316,6 +2316,8 @@ static int hostapd_config_fill(struct ho sizeof(conf->bss[0]->iface)); } else if (os_strcmp(buf, "bridge") == 0) { os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); @@ -9,9 +11,11 @@ } else if (os_strcmp(buf, "vlan_bridge") == 0) { os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge)); } else if (os_strcmp(buf, "wds_bridge") == 0) { ---- a/src/ap/ap_drv_ops.c -+++ b/src/ap/ap_drv_ops.c -@@ -340,8 +340,6 @@ int hostapd_set_wds_sta(struct hostapd_d +Index: hostapd-2023-02-21-a9012070/src/ap/ap_drv_ops.c +=================================================================== +--- hostapd-2023-02-21-a9012070.orig/src/ap/ap_drv_ops.c ++++ hostapd-2023-02-21-a9012070/src/ap/ap_drv_ops.c +@@ -348,8 +348,6 @@ int hostapd_set_wds_sta(struct hostapd_d return -1; if (hapd->conf->wds_bridge[0]) bridge = hapd->conf->wds_bridge; diff --git a/feeds/ipq95xx/hostapd/patches/720-iface_max_num_sta.patch b/feeds/ipq95xx/hostapd/patches/720-iface_max_num_sta.patch index cecc6d3f..64f87e8e 100644 --- a/feeds/ipq95xx/hostapd/patches/720-iface_max_num_sta.patch +++ b/feeds/ipq95xx/hostapd/patches/720-iface_max_num_sta.patch @@ -1,6 +1,8 @@ ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -2853,6 +2853,14 @@ static int hostapd_config_fill(struct ho +Index: hostapd-2023-02-21-ath12.3-cs/hostapd/config_file.c +=================================================================== +--- hostapd-2023-02-21-ath12.3-cs.orig/hostapd/config_file.c ++++ hostapd-2023-02-21-ath12.3-cs/hostapd/config_file.c +@@ -2778,6 +2778,14 @@ static int hostapd_config_fill(struct ho line, bss->max_num_sta, MAX_STA_COUNT); return 1; } @@ -15,22 +17,26 @@ } else if (os_strcmp(buf, "wpa") == 0) { bss->wpa = atoi(pos); } else if (os_strcmp(buf, "extended_key_id") == 0) { ---- a/src/ap/hostapd.h -+++ b/src/ap/hostapd.h -@@ -672,6 +672,7 @@ void hostapd_cleanup_cs_params(struct ho - void hostapd_periodic_iface(struct hostapd_iface *iface); +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/hostapd.h +=================================================================== +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/hostapd.h ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/hostapd.h +@@ -790,6 +790,7 @@ void hostapd_periodic_iface(struct hosta int hostapd_owe_trans_get_info(struct hostapd_data *hapd); void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx); + void free_beacon_data(struct beacon_data *beacon); +int hostapd_check_max_sta(struct hostapd_data *hapd); - /* utils.c */ - int hostapd_register_probereq_cb(struct hostapd_data *hapd, ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -209,6 +209,30 @@ static int hostapd_iface_conf_changed(st + void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap); + void hostapd_cleanup_cca_params(struct hostapd_data *hapd); +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/hostapd.c +=================================================================== +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/hostapd.c ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/hostapd.c +@@ -277,6 +277,29 @@ static int hostapd_iface_conf_changed(st + return 0; } - +static inline int hostapd_iface_num_sta(struct hostapd_iface *iface) +{ + int num_sta = 0; @@ -54,13 +60,14 @@ + + return 0; +} -+ + int hostapd_reload_config(struct hostapd_iface *iface) { - struct hapd_interfaces *interfaces = iface->interfaces; ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -1039,7 +1039,7 @@ void handle_probe_req(struct hostapd_dat +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/beacon.c +=================================================================== +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/beacon.c ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/beacon.c +@@ -1642,7 +1642,7 @@ void handle_probe_req(struct hostapd_dat if (hapd->conf->no_probe_resp_if_max_sta && is_multicast_ether_addr(mgmt->da) && is_multicast_ether_addr(mgmt->bssid) && @@ -69,9 +76,11 @@ !ap_get_sta(hapd, mgmt->sa)) { wpa_printf(MSG_MSGDUMP, "%s: Ignore Probe Request from " MACSTR " since no room for additional STA", ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -959,6 +959,8 @@ struct hostapd_config { +Index: hostapd-2023-02-21-ath12.3-cs/src/ap/ap_config.h +=================================================================== +--- hostapd-2023-02-21-ath12.3-cs.orig/src/ap/ap_config.h ++++ hostapd-2023-02-21-ath12.3-cs/src/ap/ap_config.h +@@ -1044,6 +1044,8 @@ struct hostapd_config { unsigned int track_sta_max_num; unsigned int track_sta_max_age; diff --git a/feeds/ipq95xx/hostapd/patches/730-ft_iface.patch b/feeds/ipq95xx/hostapd/patches/730-ft_iface.patch index 6bf85bfa..0795ed15 100644 --- a/feeds/ipq95xx/hostapd/patches/730-ft_iface.patch +++ b/feeds/ipq95xx/hostapd/patches/730-ft_iface.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3011,6 +3011,8 @@ static int hostapd_config_fill(struct ho +@@ -3007,6 +3007,8 @@ static int hostapd_config_fill(struct ho wpa_printf(MSG_INFO, "Line %d: Obsolete peerkey parameter ignored", line); #ifdef CONFIG_IEEE80211R_AP @@ -11,17 +11,17 @@ hexstr2bin(pos, bss->mobility_domain, --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h -@@ -275,6 +275,7 @@ struct airtime_sta_weight { +@@ -283,6 +283,7 @@ struct airtime_sta_weight { struct hostapd_bss_config { char iface[IFNAMSIZ + 1]; char bridge[IFNAMSIZ + 1]; + char ft_iface[IFNAMSIZ + 1]; char vlan_bridge[IFNAMSIZ + 1]; char wds_bridge[IFNAMSIZ + 1]; - + int bridge_hairpin; /* hairpin_mode on bridge members */ --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c -@@ -1565,8 +1565,12 @@ int hostapd_setup_wpa(struct hostapd_dat +@@ -1727,8 +1727,12 @@ int hostapd_setup_wpa(struct hostapd_dat wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt)) { const char *ft_iface; diff --git a/feeds/ipq95xx/hostapd/patches/740-snoop_iface.patch b/feeds/ipq95xx/hostapd/patches/740-snoop_iface.patch index 667c73ff..270891c0 100644 --- a/feeds/ipq95xx/hostapd/patches/740-snoop_iface.patch +++ b/feeds/ipq95xx/hostapd/patches/740-snoop_iface.patch @@ -1,6 +1,8 @@ ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -276,6 +276,7 @@ struct hostapd_bss_config { +Index: hostapd-2023-02-21-a9012070/src/ap/ap_config.h +=================================================================== +--- hostapd-2023-02-21-a9012070.orig/src/ap/ap_config.h ++++ hostapd-2023-02-21-a9012070/src/ap/ap_config.h +@@ -284,6 +284,7 @@ struct hostapd_bss_config { char iface[IFNAMSIZ + 1]; char bridge[IFNAMSIZ + 1]; char ft_iface[IFNAMSIZ + 1]; @@ -8,11 +10,13 @@ char vlan_bridge[IFNAMSIZ + 1]; char wds_bridge[IFNAMSIZ + 1]; ---- a/src/ap/x_snoop.c -+++ b/src/ap/x_snoop.c -@@ -31,28 +31,31 @@ int x_snoop_init(struct hostapd_data *ha - return -1; - } +Index: hostapd-2023-02-21-a9012070/src/ap/x_snoop.c +=================================================================== +--- hostapd-2023-02-21-a9012070.orig/src/ap/x_snoop.c ++++ hostapd-2023-02-21-a9012070/src/ap/x_snoop.c +@@ -33,28 +33,31 @@ int x_snoop_init(struct hostapd_data *ha + + hapd->x_snoop_initialized = true; - if (hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, + if (!conf->snoop_iface[0] && @@ -46,7 +50,7 @@ wpa_printf(MSG_DEBUG, "x_snoop: Failed to enable multicast snooping on the bridge"); return -1; -@@ -71,8 +74,12 @@ x_snoop_get_l2_packet(struct hostapd_dat +@@ -73,8 +76,12 @@ x_snoop_get_l2_packet(struct hostapd_dat { struct hostapd_bss_config *conf = hapd->conf; struct l2_packet_data *l2; @@ -60,32 +64,38 @@ if (l2 == NULL) { wpa_printf(MSG_DEBUG, "x_snoop: Failed to initialize L2 packet processing %s", -@@ -125,7 +132,10 @@ void x_snoop_mcast_to_ucast_convert_send +@@ -127,9 +134,12 @@ void x_snoop_mcast_to_ucast_convert_send void x_snoop_deinit(struct hostapd_data *hapd) { -- hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT, 0); + struct hostapd_bss_config *conf = hapd->conf; + + if (!hapd->x_snoop_initialized) + return; +- hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT, 0); + hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT, + conf->snoop_iface[0] ? conf->snoop_iface : NULL, 0); hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 0); hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, 0); - } ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -2343,6 +2343,8 @@ static int hostapd_config_fill(struct ho - os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); - if (!bss->wds_bridge[0]) + hapd->x_snoop_initialized = false; +Index: hostapd-2023-02-21-a9012070/hostapd/config_file.c +=================================================================== +--- hostapd-2023-02-21-a9012070.orig/hostapd/config_file.c ++++ hostapd-2023-02-21-a9012070/hostapd/config_file.c +@@ -2320,6 +2320,8 @@ static int hostapd_config_fill(struct ho os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge)); -+ } else if (os_strcmp(buf, "snoop_iface") == 0) { -+ os_strlcpy(bss->snoop_iface, pos, sizeof(bss->snoop_iface)); } else if (os_strcmp(buf, "vlan_bridge") == 0) { os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge)); ++ } else if (os_strcmp(buf, "snoop_iface") == 0) { ++ os_strlcpy(bss->snoop_iface, pos, sizeof(bss->snoop_iface)); } else if (os_strcmp(buf, "wds_bridge") == 0) { ---- a/src/ap/ap_drv_ops.h -+++ b/src/ap/ap_drv_ops.h -@@ -340,12 +340,12 @@ static inline int hostapd_drv_br_port_se + os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge)); + } else if (os_strcmp(buf, "driver") == 0) { +Index: hostapd-2023-02-21-a9012070/src/ap/ap_drv_ops.h +=================================================================== +--- hostapd-2023-02-21-a9012070.orig/src/ap/ap_drv_ops.h ++++ hostapd-2023-02-21-a9012070/src/ap/ap_drv_ops.h +@@ -359,12 +359,12 @@ static inline int hostapd_drv_br_port_se static inline int hostapd_drv_br_set_net_param(struct hostapd_data *hapd, enum drv_br_net_param param, @@ -100,9 +110,11 @@ } static inline int hostapd_drv_vendor_cmd(struct hostapd_data *hapd, ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -3756,7 +3756,7 @@ struct wpa_driver_ops { +Index: hostapd-2023-02-21-a9012070/src/drivers/driver.h +=================================================================== +--- hostapd-2023-02-21-a9012070.orig/src/drivers/driver.h ++++ hostapd-2023-02-21-a9012070/src/drivers/driver.h +@@ -4117,7 +4117,7 @@ struct wpa_driver_ops { * Returns: 0 on success, negative (<0) on failure */ int (*br_set_net_param)(void *priv, enum drv_br_net_param param, @@ -111,9 +123,11 @@ /** * get_wowlan - Get wake-on-wireless status ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -10825,7 +10825,7 @@ static const char * drv_br_net_param_str +Index: hostapd-2023-02-21-a9012070/src/drivers/driver_nl80211.c +=================================================================== +--- hostapd-2023-02-21-a9012070.orig/src/drivers/driver_nl80211.c ++++ hostapd-2023-02-21-a9012070/src/drivers/driver_nl80211.c +@@ -11732,7 +11732,7 @@ static const char * drv_br_net_param_str static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param, @@ -122,7 +136,7 @@ { struct i802_bss *bss = priv; char path[128]; -@@ -10851,8 +10851,11 @@ static int wpa_driver_br_set_net_param(v +@@ -11758,8 +11758,11 @@ static int wpa_driver_br_set_net_param(v return -EINVAL; } diff --git a/feeds/ipq95xx/hostapd/patches/750-qos_map_set_without_interworking.patch b/feeds/ipq95xx/hostapd/patches/750-qos_map_set_without_interworking.patch new file mode 100644 index 00000000..97c32df7 --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/750-qos_map_set_without_interworking.patch @@ -0,0 +1,97 @@ +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c +@@ -1604,6 +1604,8 @@ static int parse_anqp_elem(struct hostap + return 0; + } + ++#endif /* CONFIG_INTERWORKING */ ++ + + static int parse_qos_map_set(struct hostapd_bss_config *bss, + char *buf, int line) +@@ -1645,8 +1647,6 @@ static int parse_qos_map_set(struct host + return 0; + } + +-#endif /* CONFIG_INTERWORKING */ +- + + #ifdef CONFIG_HS20 + static int hs20_parse_conn_capab(struct hostapd_bss_config *bss, char *buf, +@@ -4062,10 +4062,10 @@ static int hostapd_config_fill(struct ho + bss->gas_frag_limit = val; + } else if (os_strcmp(buf, "gas_comeback_delay") == 0) { + bss->gas_comeback_delay = atoi(pos); ++#endif /* CONFIG_INTERWORKING */ + } else if (os_strcmp(buf, "qos_map_set") == 0) { + if (parse_qos_map_set(bss, pos, line) < 0) + return 1; +-#endif /* CONFIG_INTERWORKING */ + #ifdef CONFIG_RADIUS_TEST + } else if (os_strcmp(buf, "dump_msk_file") == 0) { + os_free(bss->dump_msk_file); +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c +@@ -1486,6 +1486,7 @@ int hostapd_setup_bss(struct hostapd_dat + wpa_printf(MSG_ERROR, "GAS server initialization failed"); + return -1; + } ++#endif /* CONFIG_INTERWORKING */ + + if (conf->qos_map_set_len && + hostapd_drv_set_qos_map(hapd, conf->qos_map_set, +@@ -1493,7 +1494,6 @@ int hostapd_setup_bss(struct hostapd_dat + wpa_printf(MSG_ERROR, "Failed to initialize QoS Map"); + return -1; + } +-#endif /* CONFIG_INTERWORKING */ + + if (conf->bss_load_update_period && bss_load_update_init(hapd)) { + wpa_printf(MSG_ERROR, "BSS Load initialization failed"); +--- a/wpa_supplicant/events.c ++++ b/wpa_supplicant/events.c +@@ -2683,8 +2683,6 @@ void wnm_bss_keep_alive_deinit(struct wp + } + + +-#ifdef CONFIG_INTERWORKING +- + static int wpas_qos_map_set(struct wpa_supplicant *wpa_s, const u8 *qos_map, + size_t len) + { +@@ -2717,8 +2715,6 @@ static void interworking_process_assoc_r + } + } + +-#endif /* CONFIG_INTERWORKING */ +- + + static void wpa_supplicant_set_4addr_mode(struct wpa_supplicant *wpa_s) + { +@@ -3098,10 +3094,8 @@ static int wpa_supplicant_event_associnf + wnm_process_assoc_resp(wpa_s, data->assoc_info.resp_ies, + data->assoc_info.resp_ies_len); + #endif /* CONFIG_WNM */ +-#ifdef CONFIG_INTERWORKING + interworking_process_assoc_resp(wpa_s, data->assoc_info.resp_ies, + data->assoc_info.resp_ies_len); +-#endif /* CONFIG_INTERWORKING */ + if (wpa_s->hw_capab == CAPAB_VHT && + get_ie(data->assoc_info.resp_ies, + data->assoc_info.resp_ies_len, WLAN_EID_VHT_CAP)) +--- a/src/ap/ieee802_11_shared.c ++++ b/src/ap/ieee802_11_shared.c +@@ -1116,13 +1116,11 @@ u8 * hostapd_eid_rsnxe(struct hostapd_da + u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta, + const u8 *ext_capab_ie, size_t ext_capab_ie_len) + { +-#ifdef CONFIG_INTERWORKING + /* check for QoS Map support */ + if (ext_capab_ie_len >= 5) { + if (ext_capab_ie[4] & 0x01) + sta->qos_map_enabled = 1; + } +-#endif /* CONFIG_INTERWORKING */ + + if (ext_capab_ie_len > 0) { + sta->ecsa_supported = !!(ext_capab_ie[0] & BIT(2)); diff --git a/feeds/ipq95xx/hostapd/patches/750-wispr.patch b/feeds/ipq95xx/hostapd/patches/750-wispr.patch deleted file mode 100644 index f40cc2b9..00000000 --- a/feeds/ipq95xx/hostapd/patches/750-wispr.patch +++ /dev/null @@ -1,105 +0,0 @@ ---- a/src/ap/ieee802_1x.c -+++ b/src/ap/ieee802_1x.c -@@ -1904,6 +1904,25 @@ static int ieee802_1x_update_vlan(struct - } - #endif /* CONFIG_NO_VLAN */ - -+static int ieee802_1x_update_wispr(struct hostapd_data *hapd, -+ struct sta_info *sta, -+ struct radius_msg *msg) -+{ -+ memset(sta->bandwidth, 0, sizeof(sta->bandwidth)); -+ -+ if (radius_msg_get_wispr(msg, &sta->bandwidth)) -+ return 0; -+ -+ if (!sta->bandwidth[0] && !sta->bandwidth[1]) -+ return 0; -+ -+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, -+ HOSTAPD_LEVEL_INFO, -+ "received wispr bandwidth from RADIUS server %d/%d", -+ sta->bandwidth[0], sta->bandwidth[1]); -+ -+ return 0; -+} - - /** - * ieee802_1x_receive_auth - Process RADIUS frames from Authentication Server -@@ -2029,6 +2048,7 @@ ieee802_1x_receive_auth(struct radius_ms - ieee802_1x_check_hs20(hapd, sta, msg, - session_timeout_set ? - (int) session_timeout : -1); -+ ieee802_1x_update_wispr(hapd, sta, msg); - break; - case RADIUS_CODE_ACCESS_REJECT: - sm->eap_if->aaaFail = true; ---- a/src/ap/sta_info.h -+++ b/src/ap/sta_info.h -@@ -116,6 +116,7 @@ struct sta_info { - u8 supported_rates[WLAN_SUPP_RATES_MAX]; - int supported_rates_len; - u8 qosinfo; /* Valid when WLAN_STA_WMM is set */ -+ u32 bandwidth[2]; - - #ifdef CONFIG_MESH - enum mesh_plink_state plink_state; ---- a/src/radius/radius.c -+++ b/src/radius/radius.c -@@ -1182,6 +1182,35 @@ radius_msg_get_cisco_keys(struct radius_ - return keys; - } - -+#define RADIUS_VENDOR_ID_WISPR 14122 -+#define RADIUS_WISPR_AV_BW_UP 7 -+#define RADIUS_WISPR_AV_BW_DOWN 8 -+ -+int -+radius_msg_get_wispr(struct radius_msg *msg, u32 *bandwidth) -+{ -+ int i; -+ -+ if (msg == NULL || bandwidth == NULL) -+ return 1; -+ -+ for (i = 0; i < 2; i++) { -+ size_t keylen; -+ u8 *key; -+ -+ key = radius_msg_get_vendor_attr(msg, RADIUS_VENDOR_ID_WISPR, -+ RADIUS_WISPR_AV_BW_UP + i, &keylen); -+ if (!key) -+ continue; -+ -+ if (keylen == 4) -+ bandwidth[i] = ntohl(*((u32 *)key)); -+ os_free(key); -+ } -+ -+ return 0; -+} -+ - - int radius_msg_add_mppe_keys(struct radius_msg *msg, - const u8 *req_authenticator, ---- a/src/radius/radius.h -+++ b/src/radius/radius.h -@@ -205,6 +205,10 @@ enum { - RADIUS_VENDOR_ATTR_WFA_HS20_T_C_URL = 10, - }; - -+#define RADIUS_VENDOR_ID_WISPR 14122 -+#define RADIUS_WISPR_AV_BW_UP 7 -+#define RADIUS_WISPR_AV_BW_DOWN 8 -+ - #ifdef _MSC_VER - #pragma pack(pop) - #endif /* _MSC_VER */ -@@ -277,6 +281,7 @@ radius_msg_get_ms_keys(struct radius_msg - struct radius_ms_mppe_keys * - radius_msg_get_cisco_keys(struct radius_msg *msg, struct radius_msg *sent_msg, - const u8 *secret, size_t secret_len); -+int radius_msg_get_wispr(struct radius_msg *msg, u32 *bandwidth); - int radius_msg_add_mppe_keys(struct radius_msg *msg, - const u8 *req_authenticator, - const u8 *secret, size_t secret_len, diff --git a/feeds/ipq95xx/hostapd/patches/751-qos_map_ignore_when_unsupported.patch b/feeds/ipq95xx/hostapd/patches/751-qos_map_ignore_when_unsupported.patch new file mode 100644 index 00000000..f5ebab70 --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/751-qos_map_ignore_when_unsupported.patch @@ -0,0 +1,12 @@ +--- a/src/ap/ap_drv_ops.c ++++ b/src/ap/ap_drv_ops.c +@@ -927,7 +927,8 @@ int hostapd_start_dfs_cac(struct hostapd + int hostapd_drv_set_qos_map(struct hostapd_data *hapd, + const u8 *qos_map_set, u8 qos_map_set_len) + { +- if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv) ++ if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv || ++ !(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_QOS_MAPPING)) + return 0; + return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set, + qos_map_set_len); diff --git a/feeds/ipq95xx/hostapd/patches/760-acs_exclude_dfs.patch b/feeds/ipq95xx/hostapd/patches/760-acs_exclude_dfs.patch deleted file mode 100644 index 27b3a616..00000000 --- a/feeds/ipq95xx/hostapd/patches/760-acs_exclude_dfs.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/src/ap/acs.c -+++ b/src/ap/acs.c -@@ -668,6 +668,10 @@ acs_find_ideal_chan_mode(struct hostapd_ - continue; - } - -+ if (iface->conf->acs_exclude_dfs && -+ (chan->flag & HOSTAPD_CHAN_RADAR)) -+ continue; -+ - /* HT40 on 5 GHz has a limited set of primary channels as per - * 11n Annex J */ - if (mode->mode == HOSTAPD_MODE_IEEE80211A && diff --git a/feeds/ipq95xx/hostapd/patches/760-dynamic_own_ip.patch b/feeds/ipq95xx/hostapd/patches/760-dynamic_own_ip.patch index ad6fa287..2c705a68 100644 --- a/feeds/ipq95xx/hostapd/patches/760-dynamic_own_ip.patch +++ b/feeds/ipq95xx/hostapd/patches/760-dynamic_own_ip.patch @@ -1,6 +1,6 @@ --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h -@@ -301,6 +301,7 @@ struct hostapd_bss_config { +@@ -310,6 +310,7 @@ struct hostapd_bss_config { unsigned int eap_sim_db_timeout; int eap_server_erp; /* Whether ERP is enabled on internal EAP server */ struct hostapd_ip_addr own_ip_addr; @@ -10,7 +10,7 @@ int acct_interim_interval; --- a/src/radius/radius_client.c +++ b/src/radius/radius_client.c -@@ -162,6 +162,8 @@ struct radius_client_data { +@@ -163,6 +163,8 @@ struct radius_client_data { */ void *ctx; @@ -19,7 +19,7 @@ /** * conf - RADIUS client configuration (list of RADIUS servers to use) */ -@@ -719,6 +721,30 @@ static void radius_client_list_add(struc +@@ -720,6 +722,30 @@ static void radius_client_list_add(struc /** @@ -50,7 +50,7 @@ * radius_client_send - Send a RADIUS request * @radius: RADIUS client context from radius_client_init() * @msg: RADIUS message to be sent -@@ -1219,6 +1245,10 @@ radius_change_server(struct radius_clien +@@ -1238,6 +1264,10 @@ radius_change_server(struct radius_clien wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u", inet_ntoa(claddr.sin_addr), ntohs(claddr.sin_port)); @@ -61,7 +61,7 @@ } break; #ifdef CONFIG_IPV6 -@@ -1230,6 +1260,10 @@ radius_change_server(struct radius_clien +@@ -1249,6 +1279,10 @@ radius_change_server(struct radius_clien inet_ntop(AF_INET6, &claddr6.sin6_addr, abuf, sizeof(abuf)), ntohs(claddr6.sin6_port)); @@ -74,7 +74,7 @@ } --- a/src/radius/radius_client.h +++ b/src/radius/radius_client.h -@@ -244,6 +244,8 @@ int radius_client_register(struct radius +@@ -249,6 +249,8 @@ int radius_client_register(struct radius void radius_client_set_interim_error_cb(struct radius_client_data *radius, void (*cb)(const u8 *addr, void *ctx), void *ctx); @@ -85,7 +85,7 @@ RadiusType msg_type, const u8 *addr); --- a/src/ap/ieee802_1x.c +++ b/src/ap/ieee802_1x.c -@@ -535,6 +535,10 @@ int add_common_radius_attr(struct hostap +@@ -598,6 +598,10 @@ int add_common_radius_attr(struct hostap struct hostapd_radius_attr *attr; int len; @@ -98,7 +98,7 @@ hapd->conf->own_ip_addr.af == AF_INET && --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -2696,6 +2696,8 @@ static int hostapd_config_fill(struct ho +@@ -2688,6 +2688,8 @@ static int hostapd_config_fill(struct ho } else if (os_strcmp(buf, "iapp_interface") == 0) { wpa_printf(MSG_INFO, "DEPRECATED: iapp_interface not used"); #endif /* CONFIG_IAPP */ diff --git a/feeds/ipq95xx/hostapd/patches/900-coa_multi.patch b/feeds/ipq95xx/hostapd/patches/761-shared_das_port.patch similarity index 86% rename from feeds/ipq95xx/hostapd/patches/900-coa_multi.patch rename to feeds/ipq95xx/hostapd/patches/761-shared_das_port.patch index 24927ea7..ed326778 100644 --- a/feeds/ipq95xx/hostapd/patches/900-coa_multi.patch +++ b/feeds/ipq95xx/hostapd/patches/761-shared_das_port.patch @@ -1,5 +1,7 @@ ---- a/src/radius/radius_das.h -+++ b/src/radius/radius_das.h +Index: hostapd-2023-02-21-a9012070/src/radius/radius_das.h +=================================================================== +--- hostapd-2023-02-21-a9012070.orig/src/radius/radius_das.h ++++ hostapd-2023-02-21-a9012070/src/radius/radius_das.h @@ -44,6 +44,7 @@ struct radius_das_attrs { struct radius_das_conf { int port; @@ -8,9 +10,11 @@ size_t shared_secret_len; const struct hostapd_ip_addr *client_addr; unsigned int time_window; ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -1325,6 +1325,7 @@ int hostapd_setup_bss(struct hostapd_dat +Index: hostapd-2023-02-21-a9012070/src/ap/hostapd.c +=================================================================== +--- hostapd-2023-02-21-a9012070.orig/src/ap/hostapd.c ++++ hostapd-2023-02-21-a9012070/src/ap/hostapd.c +@@ -1394,6 +1394,7 @@ int hostapd_setup_bss(struct hostapd_dat struct radius_das_conf das_conf; os_memset(&das_conf, 0, sizeof(das_conf)); das_conf.port = conf->radius_das_port; @@ -18,8 +22,10 @@ das_conf.shared_secret = conf->radius_das_shared_secret; das_conf.shared_secret_len = conf->radius_das_shared_secret_len; ---- a/src/radius/radius_das.c -+++ b/src/radius/radius_das.c +Index: hostapd-2023-02-21-a9012070/src/radius/radius_das.c +=================================================================== +--- hostapd-2023-02-21-a9012070.orig/src/radius/radius_das.c ++++ hostapd-2023-02-21-a9012070/src/radius/radius_das.c @@ -12,13 +12,26 @@ #include "utils/common.h" #include "utils/eloop.h" @@ -48,7 +54,7 @@ size_t shared_secret_len; struct hostapd_ip_addr client_addr; unsigned int time_window; -@@ -379,56 +392,17 @@ fail: +@@ -378,56 +391,17 @@ fail: } @@ -111,7 +117,7 @@ if (radius_msg_verify_das_req(msg, das->shared_secret, das->shared_secret_len, -@@ -495,9 +469,8 @@ static void radius_das_receive(int sock, +@@ -494,9 +468,8 @@ static void radius_das_receive(int sock, radius_msg_dump(reply); rbuf = radius_msg_get_buf(reply); @@ -123,11 +129,7 @@ if (res < 0) { wpa_printf(MSG_ERROR, "DAS: sendto(to %s:%d): %s", abuf, from_port, strerror(errno)); -@@ -505,10 +478,76 @@ static void radius_das_receive(int sock, - } - - fail: -- radius_msg_free(msg); +@@ -508,6 +481,72 @@ fail: radius_msg_free(reply); } @@ -193,7 +195,6 @@ + fromlen, abuf, from_port); + } + -+ radius_msg_free(msg); + if (!found) + wpa_printf(MSG_DEBUG, "DAS: Drop message from unknown client"); +} @@ -201,7 +202,7 @@ static int radius_das_open_socket(int port) { -@@ -534,6 +573,49 @@ static int radius_das_open_socket(int po +@@ -533,6 +572,49 @@ static int radius_das_open_socket(int po } @@ -251,7 +252,7 @@ struct radius_das_data * radius_das_init(struct radius_das_conf *conf) { -@@ -554,6 +636,8 @@ radius_das_init(struct radius_das_conf * +@@ -553,6 +635,8 @@ radius_das_init(struct radius_das_conf * das->ctx = conf->ctx; das->disconnect = conf->disconnect; das->coa = conf->coa; @@ -260,7 +261,7 @@ os_memcpy(&das->client_addr, conf->client_addr, sizeof(das->client_addr)); -@@ -566,19 +650,15 @@ radius_das_init(struct radius_das_conf * +@@ -565,19 +649,15 @@ radius_das_init(struct radius_das_conf * } das->shared_secret_len = conf->shared_secret_len; @@ -283,7 +284,7 @@ return das; } -@@ -589,11 +669,14 @@ void radius_das_deinit(struct radius_das +@@ -588,11 +668,14 @@ void radius_das_deinit(struct radius_das if (das == NULL) return; diff --git a/feeds/ipq95xx/hostapd/patches/770-radius_server.patch b/feeds/ipq95xx/hostapd/patches/770-radius_server.patch new file mode 100644 index 00000000..8837a262 --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/770-radius_server.patch @@ -0,0 +1,154 @@ +--- a/hostapd/Makefile ++++ b/hostapd/Makefile +@@ -63,6 +63,10 @@ endif + OBJS += main.o + OBJS += config_file.o + ++ifdef CONFIG_RADIUS_SERVER ++OBJS += radius.o ++endif ++ + OBJS += ../src/ap/hostapd.o + OBJS += ../src/ap/wpa_auth_glue.o + OBJS += ../src/ap/drv_callbacks.o +--- a/hostapd/main.c ++++ b/hostapd/main.c +@@ -40,6 +40,7 @@ struct hapd_global { + + static struct hapd_global global; + ++extern int radius_main(int argc, char **argv); + + #ifndef CONFIG_NO_HOSTAPD_LOGGER + static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module, +@@ -771,6 +772,11 @@ int main(int argc, char *argv[]) + if (os_program_init()) + return -1; + ++#ifdef RADIUS_SERVER ++ if (strstr(argv[0], "radius")) ++ return radius_main(argc, argv); ++#endif ++ + os_memset(&interfaces, 0, sizeof(interfaces)); + interfaces.reload_config = hostapd_reload_config; + interfaces.config_read_cb = hostapd_config_read; +--- a/src/radius/radius_server.c ++++ b/src/radius/radius_server.c +@@ -63,6 +63,12 @@ struct radius_server_counters { + u32 unknown_acct_types; + }; + ++struct radius_accept_attr { ++ u8 type; ++ u16 len; ++ void *data; ++}; ++ + /** + * struct radius_session - Internal RADIUS server data for a session + */ +@@ -90,7 +96,7 @@ struct radius_session { + unsigned int macacl:1; + unsigned int t_c_filtering:1; + +- struct hostapd_radius_attr *accept_attr; ++ struct radius_accept_attr *accept_attr; + + u32 t_c_timestamp; /* Last read T&C timestamp from user DB */ + }; +@@ -394,6 +400,7 @@ static void radius_server_session_free(s + radius_msg_free(sess->last_reply); + os_free(sess->username); + os_free(sess->nas_ip); ++ os_free(sess->accept_attr); + os_free(sess); + data->num_sess--; + } +@@ -554,6 +561,36 @@ radius_server_erp_find_key(struct radius + } + #endif /* CONFIG_ERP */ + ++static struct radius_accept_attr * ++radius_server_copy_attr(const struct hostapd_radius_attr *data) ++{ ++ const struct hostapd_radius_attr *attr; ++ struct radius_accept_attr *attr_new; ++ size_t data_size = 0; ++ void *data_buf; ++ int n_attr = 1; ++ ++ for (attr = data; attr; attr = attr->next) { ++ n_attr++; ++ data_size += wpabuf_len(attr->val); ++ } ++ ++ attr_new = os_zalloc(n_attr * sizeof(*attr) + data_size); ++ if (!attr_new) ++ return NULL; ++ ++ data_buf = &attr_new[n_attr]; ++ for (n_attr = 0, attr = data; attr; attr = attr->next) { ++ struct radius_accept_attr *cur = &attr_new[n_attr++]; ++ ++ cur->type = attr->type; ++ cur->len = wpabuf_len(attr->val); ++ cur->data = memcpy(data_buf, wpabuf_head(attr->val), cur->len); ++ data_buf += cur->len; ++ } ++ ++ return attr_new; ++} + + static struct radius_session * + radius_server_get_new_session(struct radius_server_data *data, +@@ -607,7 +644,7 @@ radius_server_get_new_session(struct rad + eap_user_free(tmp); + return NULL; + } +- sess->accept_attr = tmp->accept_attr; ++ sess->accept_attr = radius_server_copy_attr(tmp->accept_attr); + sess->macacl = tmp->macacl; + eap_user_free(tmp); + +@@ -1118,11 +1155,10 @@ radius_server_encapsulate_eap(struct rad + } + + if (code == RADIUS_CODE_ACCESS_ACCEPT) { +- struct hostapd_radius_attr *attr; +- for (attr = sess->accept_attr; attr; attr = attr->next) { +- if (!radius_msg_add_attr(msg, attr->type, +- wpabuf_head(attr->val), +- wpabuf_len(attr->val))) { ++ struct radius_accept_attr *attr; ++ for (attr = sess->accept_attr; attr->data; attr++) { ++ if (!radius_msg_add_attr(msg, attr->type, attr->data, ++ attr->len)) { + wpa_printf(MSG_ERROR, "Could not add RADIUS attribute"); + radius_msg_free(msg); + return NULL; +@@ -1211,11 +1247,10 @@ radius_server_macacl(struct radius_serve + } + + if (code == RADIUS_CODE_ACCESS_ACCEPT) { +- struct hostapd_radius_attr *attr; +- for (attr = sess->accept_attr; attr; attr = attr->next) { +- if (!radius_msg_add_attr(msg, attr->type, +- wpabuf_head(attr->val), +- wpabuf_len(attr->val))) { ++ struct radius_accept_attr *attr; ++ for (attr = sess->accept_attr; attr->data; attr++) { ++ if (!radius_msg_add_attr(msg, attr->type, attr->data, ++ attr->len)) { + wpa_printf(MSG_ERROR, "Could not add RADIUS attribute"); + radius_msg_free(msg); + return NULL; +@@ -2512,7 +2547,7 @@ static int radius_server_get_eap_user(vo + ret = data->get_eap_user(data->conf_ctx, identity, identity_len, + phase2, user); + if (ret == 0 && user) { +- sess->accept_attr = user->accept_attr; ++ sess->accept_attr = radius_server_copy_attr(user->accept_attr); + sess->remediation = user->remediation; + sess->macacl = user->macacl; + sess->t_c_timestamp = user->t_c_timestamp; diff --git a/feeds/ipq95xx/hostapd/patches/770-wds-hack.patch b/feeds/ipq95xx/hostapd/patches/770-wds-hack.patch deleted file mode 100644 index 5fa58585..00000000 --- a/feeds/ipq95xx/hostapd/patches/770-wds-hack.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -11,6 +11,8 @@ - #include - #endif /* CONFIG_SQLITE */ - -+#include -+ - #include "utils/common.h" - #include "utils/eloop.h" - #include "utils/crc32.h" -@@ -1198,6 +1200,22 @@ int hostapd_setup_bss(struct hostapd_dat - os_memcpy(hapd->own_addr, if_addr, ETH_ALEN); - } - -+ if (conf->wds_sta) { -+ char path[128]; -+ FILE *fp; -+ -+ sprintf(path, "/sys/kernel/debug/ieee80211/%s/netdev:%s/disable_offload", hostapd_drv_get_radio_name(hapd), conf->iface); -+ -+ fp = fopen(path, "w"); -+ if (fp) { -+ syslog(0, "WDS: disable encap - %s\n", path); -+ fprintf(fp, "1"); -+ fclose(fp); -+ } else { -+ syslog(0, "WDS: failed to disable encap - %s\n", path); -+ } -+ } -+ - if (conf->wmm_enabled < 0) - conf->wmm_enabled = hapd->iconf->ieee80211n; - diff --git a/feeds/ipq95xx/hostapd/patches/780-maxassoc.patch b/feeds/ipq95xx/hostapd/patches/780-maxassoc.patch deleted file mode 100644 index 07fc54e1..00000000 --- a/feeds/ipq95xx/hostapd/patches/780-maxassoc.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/src/ap/sta_info.c -+++ b/src/ap/sta_info.c -@@ -717,7 +717,7 @@ struct sta_info * ap_sta_add(struct host - return sta; - - wpa_printf(MSG_DEBUG, " New STA"); -- if (hapd->num_sta >= hapd->conf->max_num_sta) { -+ if (hostapd_check_max_sta(hapd)) { - /* FIX: might try to remove some old STAs first? */ - wpa_printf(MSG_DEBUG, "no more room for new STAs (%d/%d)", - hapd->num_sta, hapd->conf->max_num_sta); diff --git a/feeds/ipq95xx/hostapd/patches/800-fix-ap-sta-channel-setup-failed.patch b/feeds/ipq95xx/hostapd/patches/800-fix-ap-sta-channel-setup-failed.patch deleted file mode 100644 index 67e3d078..00000000 --- a/feeds/ipq95xx/hostapd/patches/800-fix-ap-sta-channel-setup-failed.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- a/src/common/hw_features_common.c -+++ b/src/common/hw_features_common.c -@@ -609,9 +609,21 @@ int hostapd_set_freq_params(struct hosta - center_segment0 == channel - 6) - data->center_freq1 = 5000 + center_segment0 * 5; - else { -- wpa_printf(MSG_ERROR, -- "Wrong coupling between HT and VHT/HE channel setting"); -- return -1; -+ if (channel <= 48) -+ center_segment0 = 42; -+ else if (channel <= 64) -+ center_segment0 = 58; -+ else if (channel <= 112) -+ center_segment0 = 106; -+ else if (channel <= 128) -+ center_segment0 = 122; -+ else if (channel <= 144) -+ center_segment0 = 138; -+ else if (channel <= 161) -+ center_segment0 = 155; -+ else if (channel <= 177) -+ center_segment0 = 171; -+ data->center_freq1 = 5000 + center_segment0 * 5; - } - } - break; diff --git a/feeds/ipq95xx/hostapd/patches/900-coa.patch b/feeds/ipq95xx/hostapd/patches/900-coa.patch deleted file mode 100644 index 3e1213a4..00000000 --- a/feeds/ipq95xx/hostapd/patches/900-coa.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/src/radius/radius_das.c -+++ b/src/radius/radius_das.c -@@ -48,6 +48,8 @@ static struct radius_msg * radius_das_di - RADIUS_ATTR_EVENT_TIMESTAMP, - RADIUS_ATTR_MESSAGE_AUTHENTICATOR, - RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, -+ RADIUS_ATTR_VENDOR_SPECIFIC, -+ RADIUS_ATTR_CALLED_STATION_ID, - #ifdef CONFIG_IPV6 - RADIUS_ATTR_NAS_IPV6_ADDRESS, - #endif /* CONFIG_IPV6 */ -@@ -205,9 +207,8 @@ static struct radius_msg * radius_das_co - RADIUS_ATTR_EVENT_TIMESTAMP, - RADIUS_ATTR_MESSAGE_AUTHENTICATOR, - RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, --#ifdef CONFIG_HS20 - RADIUS_ATTR_VENDOR_SPECIFIC, --#endif /* CONFIG_HS20 */ -+ RADIUS_ATTR_CALLED_STATION_ID, - #ifdef CONFIG_IPV6 - RADIUS_ATTR_NAS_IPV6_ADDRESS, - #endif /* CONFIG_IPV6 */ diff --git a/feeds/ipq95xx/hostapd/patches/901-cfg-section.patch b/feeds/ipq95xx/hostapd/patches/901-cfg-section.patch deleted file mode 100644 index 9122a423..00000000 --- a/feeds/ipq95xx/hostapd/patches/901-cfg-section.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -2366,6 +2366,8 @@ static int hostapd_config_fill(struct ho - return 1; - } - conf->driver = driver; -+ } else if (os_strcmp(buf, "uci_section") == 0) { -+ bss->uci_section = os_strdup(pos); - } else if (os_strcmp(buf, "driver_params") == 0) { - os_free(conf->driver_params); - conf->driver_params = os_strdup(pos); ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -279,6 +279,7 @@ struct hostapd_bss_config { - char snoop_iface[IFNAMSIZ + 1]; - char vlan_bridge[IFNAMSIZ + 1]; - char wds_bridge[IFNAMSIZ + 1]; -+ char *uci_section; - - enum hostapd_logger_level logger_syslog_level, logger_stdout_level; - ---- a/src/ap/ap_config.c -+++ b/src/ap/ap_config.c -@@ -785,6 +785,7 @@ void hostapd_config_free_bss(struct host - os_free(conf->radius_req_attr_sqlite); - os_free(conf->rsn_preauth_interfaces); - os_free(conf->ctrl_interface); -+ os_free(conf->uci_section); - os_free(conf->ca_cert); - os_free(conf->server_cert); - os_free(conf->server_cert2); diff --git a/feeds/ipq95xx/hostapd/patches/920-sta_driver_data.patch b/feeds/ipq95xx/hostapd/patches/920-sta_driver_data.patch deleted file mode 100644 index 4d11051d..00000000 --- a/feeds/ipq95xx/hostapd/patches/920-sta_driver_data.patch +++ /dev/null @@ -1,53 +0,0 @@ ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -2175,6 +2175,10 @@ struct hostap_sta_driver_data { - u8 tx_mcs; - u8 rx_vht_nss; - u8 tx_vht_nss; -+ u8 rx_hemcs; -+ u8 tx_hemcs; -+ u8 rx_he_nss; -+ u8 tx_he_nss; - }; - - struct hostapd_sta_add_params { ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -7010,6 +7010,8 @@ static int get_sta_handler(struct nl_msg - [NL80211_RATE_INFO_VHT_MCS] = { .type = NLA_U8 }, - [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG }, - [NL80211_RATE_INFO_VHT_NSS] = { .type = NLA_U8 }, -+ [NL80211_RATE_INFO_HE_NSS] = { .type = NLA_U8 }, -+ [NL80211_RATE_INFO_HE_MCS] = { .type = NLA_U8 }, - }; - - nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), -@@ -7102,6 +7104,10 @@ static int get_sta_handler(struct nl_msg - nla_get_u8(rate[NL80211_RATE_INFO_VHT_NSS]); - data->flags |= STA_DRV_DATA_TX_VHT_NSS; - } -+ if (rate[NL80211_RATE_INFO_HE_MCS]) -+ data->tx_hemcs = nla_get_u8(rate[NL80211_RATE_INFO_HE_MCS]); -+ if (rate[NL80211_RATE_INFO_HE_NSS]) -+ data->tx_he_nss = nla_get_u8(rate[NL80211_RATE_INFO_HE_NSS]); - } - - if (stats[NL80211_STA_INFO_RX_BITRATE] && -@@ -7132,11 +7138,16 @@ static int get_sta_handler(struct nl_msg - nla_get_u8(rate[NL80211_RATE_INFO_VHT_NSS]); - data->flags |= STA_DRV_DATA_RX_VHT_NSS; - } -+ if (rate[NL80211_RATE_INFO_HE_MCS]) -+ data->rx_hemcs = nla_get_u8(rate[NL80211_RATE_INFO_HE_MCS]); -+ if (rate[NL80211_RATE_INFO_HE_NSS]) -+ data->rx_he_nss = nla_get_u8(rate[NL80211_RATE_INFO_HE_NSS]); - } - - if (stats[NL80211_STA_INFO_TID_STATS]) - get_sta_tid_stats(data, stats[NL80211_STA_INFO_TID_STATS]); - -+ - return NL_SKIP; - } - - diff --git a/feeds/ipq95xx/hostapd/patches/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch b/feeds/ipq95xx/hostapd/patches/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch new file mode 100644 index 00000000..5809a3b7 --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch @@ -0,0 +1,33 @@ +From f0e9f5aab52b3eab85d28338cc996972ced4c39c Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Tue, 17 May 2022 23:07:59 +0200 +Subject: [PATCH] ctrl: make WNM_AP functions dependant on CONFIG_AP + +This fixes linking errors found when compiling wpa_supplicant with +CONFIG_WNM_AP enabled but CONFIG_AP disabled. + +Signed-off-by: David Bauer +--- + wpa_supplicant/ctrl_iface.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/wpa_supplicant/ctrl_iface.c ++++ b/wpa_supplicant/ctrl_iface.c +@@ -12763,7 +12763,7 @@ char * wpa_supplicant_ctrl_iface_process + if (wpas_ctrl_iface_coloc_intf_report(wpa_s, buf + 18)) + reply_len = -1; + #endif /* CONFIG_WNM */ +-#ifdef CONFIG_WNM_AP ++#if defined(CONFIG_AP) && defined(CONFIG_WNM_AP) + } else if (os_strncmp(buf, "DISASSOC_IMMINENT ", 18) == 0) { + if (ap_ctrl_iface_disassoc_imminent(wpa_s, buf + 18)) + reply_len = -1; +@@ -12773,7 +12773,7 @@ char * wpa_supplicant_ctrl_iface_process + } else if (os_strncmp(buf, "BSS_TM_REQ ", 11) == 0) { + if (ap_ctrl_iface_bss_tm_req(wpa_s, buf + 11)) + reply_len = -1; +-#endif /* CONFIG_WNM_AP */ ++#endif /* CONFIG_AP && CONFIG_WNM_AP */ + } else if (os_strcmp(buf, "FLUSH") == 0) { + wpa_supplicant_ctrl_iface_flush(wpa_s); + } else if (os_strncmp(buf, "RADIO_WORK ", 11) == 0) { diff --git a/feeds/ipq95xx/hostapd/patches/992-nl80211-add-extra-ies-only-if-allowed-by-driver.patch b/feeds/ipq95xx/hostapd/patches/992-nl80211-add-extra-ies-only-if-allowed-by-driver.patch new file mode 100644 index 00000000..c7b595da --- /dev/null +++ b/feeds/ipq95xx/hostapd/patches/992-nl80211-add-extra-ies-only-if-allowed-by-driver.patch @@ -0,0 +1,62 @@ +From: David Bauer +To: hostap@lists.infradead.org +Cc: =?utf-8?q?=C3=89tienne_Morice?= +Subject: [PATCH] nl80211: add extra-ies only if allowed by driver +Date: Sun, 30 Jan 2022 20:22:00 +0100 +Message-Id: <20220130192200.10883-1-mail@david-bauer.net> +List-Id: + +Upgrading wpa_supplicant from 2.9 to 2.10 breaks broadcom-wl +based adapters. The reason for it is hostapd tries to install additional +IEs for scanning while the driver does not support this. + +The kernel indicates the maximum number of bytes for additional scan IEs +using the NL80211_ATTR_MAX_SCAN_IE_LEN attribute. Save this value and +only add additional scan IEs in case the driver can accommodate these +additional IEs. + +Reported-by: Étienne Morice +Tested-by: Étienne Morice +Signed-off-by: David Bauer +--- + src/drivers/driver.h | 3 +++ + src/drivers/driver_nl80211_capa.c | 4 ++++ + src/drivers/driver_nl80211_scan.c | 2 +- + 3 files changed, 8 insertions(+), 1 deletion(-) + +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -2283,6 +2283,9 @@ struct wpa_driver_capa { + /** Maximum number of iterations in a single scan plan */ + u32 max_sched_scan_plan_iterations; + ++ /** Maximum number of extra IE bytes for scans */ ++ u16 max_scan_ie_len; ++ + /** Whether sched_scan (offloaded scanning) is supported */ + int sched_scan_supported; + +--- a/src/drivers/driver_nl80211_capa.c ++++ b/src/drivers/driver_nl80211_capa.c +@@ -949,6 +949,10 @@ static int wiphy_info_handler(struct nl_ + nla_get_u32(tb[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS]); + } + ++ if (tb[NL80211_ATTR_MAX_SCAN_IE_LEN]) ++ capa->max_scan_ie_len = ++ nla_get_u16(tb[NL80211_ATTR_MAX_SCAN_IE_LEN]); ++ + if (tb[NL80211_ATTR_MAX_MATCH_SETS]) + capa->max_match_sets = + nla_get_u8(tb[NL80211_ATTR_MAX_MATCH_SETS]); +--- a/src/drivers/driver_nl80211_scan.c ++++ b/src/drivers/driver_nl80211_scan.c +@@ -222,7 +222,7 @@ nl80211_scan_common(struct i802_bss *bss + wpa_printf(MSG_DEBUG, "nl80211: Passive scan requested"); + } + +- if (params->extra_ies) { ++ if (params->extra_ies && drv->capa.max_scan_ie_len >= params->extra_ies_len) { + wpa_hexdump(MSG_MSGDUMP, "nl80211: Scan extra IEs", + params->extra_ies, params->extra_ies_len); + if (nla_put(msg, NL80211_ATTR_IE, params->extra_ies_len, diff --git a/feeds/ipq95xx/hostapd/patches/999-das-proxy-state.patch b/feeds/ipq95xx/hostapd/patches/999-das-proxy-state.patch deleted file mode 100644 index 64b7aa4c..00000000 --- a/feeds/ipq95xx/hostapd/patches/999-das-proxy-state.patch +++ /dev/null @@ -1,95 +0,0 @@ -Index: hostapd-2021-02-20-59e9794c/src/radius/radius_das.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/radius/radius_das.c -+++ hostapd-2021-02-20-59e9794c/src/radius/radius_das.c -@@ -63,6 +63,7 @@ static struct radius_msg * radius_das_di - RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, - RADIUS_ATTR_VENDOR_SPECIFIC, - RADIUS_ATTR_CALLED_STATION_ID, -+ RADIUS_ATTR_PROXY_STATE, - #ifdef CONFIG_IPV6 - RADIUS_ATTR_NAS_IPV6_ADDRESS, - #endif /* CONFIG_IPV6 */ -@@ -159,6 +160,12 @@ static struct radius_msg * radius_das_di - attrs.cui_len = len; - } - -+ if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_PROXY_STATE, -+ &buf, &len, NULL) == 0) { -+ attrs.proxy = buf; -+ attrs.proxy_len = len; -+ } -+ - res = das->disconnect(das->ctx, &attrs); - switch (res) { - case RADIUS_DAS_NAS_MISMATCH: -@@ -167,10 +174,11 @@ static struct radius_msg * radius_das_di - error = 403; - break; - case RADIUS_DAS_SESSION_NOT_FOUND: -- wpa_printf(MSG_INFO, "DAS: Session not found for request from " -- "%s:%d", abuf, from_port); -- error = 503; -- break; -+ return NULL; -+// wpa_printf(MSG_INFO, "DAS: Session not found for request from " -+// "%s:%d", abuf, from_port); -+// error = 503; -+// break; - case RADIUS_DAS_MULTI_SESSION_MATCH: - wpa_printf(MSG_INFO, - "DAS: Multiple sessions match for request from %s:%d", -@@ -192,6 +200,9 @@ fail: - if (reply == NULL) - return NULL; - -+ if (attrs.proxy) -+ radius_msg_add_attr(reply, RADIUS_ATTR_PROXY_STATE, attrs.proxy, attrs.proxy_len); -+ - if (error) { - if (!radius_msg_add_attr_int32(reply, RADIUS_ATTR_ERROR_CAUSE, - error)) { -@@ -222,6 +233,7 @@ static struct radius_msg * radius_das_co - RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, - RADIUS_ATTR_VENDOR_SPECIFIC, - RADIUS_ATTR_CALLED_STATION_ID, -+ RADIUS_ATTR_PROXY_STATE, - #ifdef CONFIG_IPV6 - RADIUS_ATTR_NAS_IPV6_ADDRESS, - #endif /* CONFIG_IPV6 */ -@@ -347,6 +359,12 @@ static struct radius_msg * radius_das_co - } - #endif /* CONFIG_HS20 */ - -+ if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_PROXY_STATE, -+ &buf, &len, NULL) == 0) { -+ attrs.proxy = buf; -+ attrs.proxy_len = len; -+ } -+ - res = das->coa(das->ctx, &attrs); - switch (res) { - case RADIUS_DAS_NAS_MISMATCH: -@@ -382,6 +400,9 @@ fail: - if (!reply) - return NULL; - -+ if (attrs.proxy) -+ radius_msg_add_attr(reply, RADIUS_ATTR_PROXY_STATE, attrs.proxy, attrs.proxy_len); -+ - if (error && - !radius_msg_add_attr_int32(reply, RADIUS_ATTR_ERROR_CAUSE, error)) { - radius_msg_free(reply); -Index: hostapd-2021-02-20-59e9794c/src/radius/radius_das.h -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/radius/radius_das.h -+++ hostapd-2021-02-20-59e9794c/src/radius/radius_das.h -@@ -36,6 +36,8 @@ struct radius_das_attrs { - size_t acct_multi_session_id_len; - const u8 *cui; - size_t cui_len; -+ const u8 *proxy; -+ size_t proxy_len; - - /* Authorization changes */ - const u8 *hs20_t_c_filtering; diff --git a/feeds/ipq95xx/hostapd/patches/999-ft-anonce.patch b/feeds/ipq95xx/hostapd/patches/999-ft-anonce.patch deleted file mode 100644 index 40956fa6..00000000 --- a/feeds/ipq95xx/hostapd/patches/999-ft-anonce.patch +++ /dev/null @@ -1,48 +0,0 @@ -Index: hostapd-2021-02-20-59e9794c/src/ap/wpa_auth_ft.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/wpa_auth_ft.c -+++ hostapd-2021-02-20-59e9794c/src/ap/wpa_auth_ft.c -@@ -3067,6 +3067,7 @@ static int wpa_ft_process_auth_req(struc - size_t identity_len = 0, radius_cui_len = 0; - int use_sha384; - size_t pmk_r1_len, kdk_len; -+ struct os_reltime now; - - *resp_ies = NULL; - *resp_ies_len = 0; -@@ -3185,10 +3186,19 @@ pmk_r1_derived: - os_memcpy(sm->pmk_r1, pmk_r1, pmk_r1_len); - sm->pmk_r1_len = pmk_r1_len; - -- if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) { -- wpa_printf(MSG_DEBUG, "FT: Failed to get random data for " -- "ANonce"); -- return WLAN_STATUS_UNSPECIFIED_FAILURE; -+ if (os_get_reltime(&now) < 0 || -+ os_reltime_expired(&now, &sm->ANonce_time, 1)) { -+ if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) { -+ wpa_printf(MSG_DEBUG, "FT: Failed to get random data for " -+ "ANonce"); -+ return WLAN_STATUS_UNSPECIFIED_FAILURE; -+ } -+ sm->ANonce_time.sec = now.sec; -+ sm->ANonce_time.usec = now.usec; -+ wpa_printf(MSG_INFO, "FT: ANonce was randomized"); -+ } else { -+ wpa_printf(MSG_INFO, "FT: ANonce has not expired"); -+ - } - - wpa_hexdump(MSG_DEBUG, "FT: Received SNonce", -Index: hostapd-2021-02-20-59e9794c/src/ap/wpa_auth_i.h -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/wpa_auth_i.h -+++ hostapd-2021-02-20-59e9794c/src/ap/wpa_auth_i.h -@@ -54,6 +54,7 @@ struct wpa_state_machine { - bool MICVerified; - bool GUpdateStationKeys; - u8 ANonce[WPA_NONCE_LEN]; -+ struct os_reltime ANonce_time; - u8 SNonce[WPA_NONCE_LEN]; - u8 alt_SNonce[WPA_NONCE_LEN]; - u8 alt_replay_counter[WPA_REPLAY_COUNTER_LEN]; diff --git a/feeds/ipq95xx/hostapd/patches/999-probe-request.patch b/feeds/ipq95xx/hostapd/patches/999-probe-request.patch deleted file mode 100644 index a239c843..00000000 --- a/feeds/ipq95xx/hostapd/patches/999-probe-request.patch +++ /dev/null @@ -1,43 +0,0 @@ ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -3337,6 +3337,8 @@ static int hostapd_config_fill(struct ho - bss->ignore_broadcast_ssid = atoi(pos); - } else if (os_strcmp(buf, "no_probe_resp_if_max_sta") == 0) { - bss->no_probe_resp_if_max_sta = atoi(pos); -+ } else if (os_strcmp(buf, "dynamic_probe_resp") == 0) { -+ bss->dynamic_probe_resp = atoi(pos); - #ifdef CONFIG_WEP - } else if (os_strcmp(buf, "wep_default_key") == 0) { - bss->ssid.wep.idx = atoi(pos); ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -459,6 +459,7 @@ struct hostapd_bss_config { - int ap_max_inactivity; - int ignore_broadcast_ssid; - int no_probe_resp_if_max_sta; -+ int dynamic_probe_resp; - - int wmm_enabled; - int wmm_uapsd; ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -920,7 +920,8 @@ void handle_probe_req(struct hostapd_dat - } - #endif /* CONFIG_P2P */ - -- if (hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0 && -+ if (!hapd->conf->dynamic_probe_resp && -+ hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0 && - elems.ssid_list_len == 0 && elems.short_ssid_list_len == 0) { - wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for " - "broadcast SSID ignored", MAC2STR(mgmt->sa)); -@@ -967,7 +968,8 @@ void handle_probe_req(struct hostapd_dat - return; - } - -- if (hapd->conf->ignore_broadcast_ssid && res == WILDCARD_SSID_MATCH) { -+ if (!hapd->conf->dynamic_probe_resp && -+ hapd->conf->ignore_broadcast_ssid && res == WILDCARD_SSID_MATCH) { - wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for " - "broadcast SSID ignored", MAC2STR(mgmt->sa)); - return; diff --git a/feeds/ipq95xx/hostapd/patches/999-ssi_signal.patch b/feeds/ipq95xx/hostapd/patches/999-ssi_signal.patch deleted file mode 100644 index a5309d2d..00000000 --- a/feeds/ipq95xx/hostapd/patches/999-ssi_signal.patch +++ /dev/null @@ -1,75 +0,0 @@ ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -57,6 +57,17 @@ - #include "gas_query_ap.h" - - -+static int -+ewma(int new, int old) -+{ -+ #define ALPHA 10 -+ if (!old) -+ return new; -+ if (new >= 0) -+ return old; -+ return ((ALPHA * new) + ((100 - ALPHA) * old)) / 100; -+} -+ - #ifdef CONFIG_FILS - static struct wpabuf * - prepare_auth_resp_fils(struct hostapd_data *hapd, -@@ -5873,7 +5882,7 @@ static int robust_action_frame(u8 catego - - static int handle_action(struct hostapd_data *hapd, - const struct ieee80211_mgmt *mgmt, size_t len, -- unsigned int freq) -+ unsigned int freq, int ssi_signal) - { - struct sta_info *sta; - u8 *action __maybe_unused; -@@ -5930,6 +5939,7 @@ static int handle_action(struct hostapd_ - - sta->last_seq_ctrl = seq_ctrl; - sta->last_subtype = WLAN_FC_STYPE_ACTION; -+ sta->signal_mgmt = ewma(ssi_signal, sta->signal_mgmt);; - } - - switch (mgmt->u.action.category) { -@@ -6109,6 +6119,8 @@ int ieee802_11_mgmt(struct hostapd_data - unsigned int freq; - int ssi_signal = fi ? fi->ssi_signal : 0; - -+ hapd->signal_mgmt = ewma(ssi_signal, hapd->signal_mgmt);; -+ - if (len < 24) - return 0; - -@@ -6208,7 +6220,7 @@ int ieee802_11_mgmt(struct hostapd_data - break; - case WLAN_FC_STYPE_ACTION: - wpa_printf(MSG_DEBUG, "mgmt::action"); -- ret = handle_action(hapd, mgmt, len, freq); -+ ret = handle_action(hapd, mgmt, len, freq, ssi_signal); - break; - default: - hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, ---- a/src/ap/sta_info.h -+++ b/src/ap/sta_info.h -@@ -331,6 +331,7 @@ struct sta_info { - #ifdef CONFIG_PASN - struct pasn_data *pasn; - #endif /* CONFIG_PASN */ -+ int signal_mgmt; - }; - - ---- a/src/ap/hostapd.h -+++ b/src/ap/hostapd.h -@@ -451,6 +451,7 @@ struct hostapd_data { - #ifdef CONFIG_CTRL_IFACE_UDP - unsigned char ctrl_iface_cookie[CTRL_IFACE_COOKIE_LEN]; - #endif /* CONFIG_CTRL_IFACE_UDP */ -+ int signal_mgmt; - }; - - diff --git a/feeds/ipq95xx/hostapd/patches/a00-004-Add-provision-to-test-RADAR-detection-probablity-in-.patch b/feeds/ipq95xx/hostapd/patches/a00-004-Add-provision-to-test-RADAR-detection-probablity-in-.patch deleted file mode 100644 index 5df155ec..00000000 --- a/feeds/ipq95xx/hostapd/patches/a00-004-Add-provision-to-test-RADAR-detection-probablity-in-.patch +++ /dev/null @@ -1,153 +0,0 @@ ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -2424,6 +2424,8 @@ static int hostapd_config_fill(struct ho - conf->ieee80211d = atoi(pos); - } else if (os_strcmp(buf, "ieee80211h") == 0) { - conf->ieee80211h = atoi(pos); -+ } else if (os_strcmp(buf, "dfs_test_mode") == 0) { -+ conf->dfs_test_mode = atoi(pos); - } else if (os_strcmp(buf, "ieee8021x") == 0) { - bss->ieee802_1x = atoi(pos); - } else if (os_strcmp(buf, "eapol_version") == 0) { ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -950,6 +950,7 @@ struct hostapd_config { - int ieee80211d; - - int ieee80211h; /* DFS */ -+ int dfs_test_mode; - - /* - * Local power constraint is an octet encoded as an unsigned integer in ---- a/src/ap/dfs.c -+++ b/src/ap/dfs.c -@@ -17,6 +17,8 @@ - #include "ap_drv_ops.h" - #include "drivers/driver.h" - #include "dfs.h" -+#include "beacon.h" -+#include "eloop.h" - - - static int dfs_get_used_n_chans(struct hostapd_iface *iface, int *seg1) -@@ -1015,6 +1017,73 @@ static int hostapd_dfs_start_channel_swi - return err; - } - -+void hostapd_dfs_test_mode_csa_timeout(void *eloop_data, void *user_data) -+{ -+ struct hostapd_data *hapd = eloop_data; -+ -+ wpa_printf(MSG_INFO, "Stopping CSA in dfs test mode"); -+ hostapd_cleanup_cs_params(hapd); -+ ieee802_11_set_beacon(hapd); -+} -+ -+static int hostapd_dfs_testmode_set_beacon_csa(struct hostapd_iface *iface) -+{ -+ struct hostapd_data *hapd = iface->bss[0]; -+ struct csa_settings csa_settings; -+ int secondary_channel; -+ u8 vht_oper_centr_freq_seg0_idx; -+ u8 vht_oper_centr_freq_seg1_idx; -+ int err = 0; -+ -+ eloop_cancel_timeout(hostapd_dfs_test_mode_csa_timeout, hapd, NULL); -+ secondary_channel = iface->conf->secondary_channel; -+ vht_oper_centr_freq_seg0_idx = -+ iface->conf->vht_oper_centr_freq_seg0_idx; -+ vht_oper_centr_freq_seg1_idx = -+ iface->conf->vht_oper_centr_freq_seg1_idx; -+ -+ /* Setup CSA request */ -+ os_memset(&csa_settings, 0, sizeof(csa_settings)); -+ err = hostapd_set_freq_params(&csa_settings.freq_params, -+ iface->conf->hw_mode, -+ iface->freq, -+ iface->conf->channel, -+ iface->conf->ieee80211n, -+ iface->conf->ieee80211ac, -+ secondary_channel, -+ iface->conf->vht_oper_chwidth, -+ vht_oper_centr_freq_seg0_idx, -+ vht_oper_centr_freq_seg1_idx, -+ iface->current_mode->vht_capab); -+ -+ if (err) { -+ wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params"); -+ goto fail; -+ } -+ -+ if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA)) { -+ wpa_printf(MSG_INFO, "CSA is not supported"); -+ hostapd_disable_iface(iface); -+ return -1; -+ } -+ -+ hapd->cs_freq_params = csa_settings.freq_params; -+ hapd->cs_count = 3; -+ hapd->cs_block_tx = 1; -+ err = ieee802_11_set_beacon(hapd); -+ if (err) -+ goto fail; -+ wpa_printf(MSG_DEBUG, "CSA beacon configured for dfs mode, count %d", -+ hapd->cs_count); -+ hapd->csa_in_progress = 1; -+ eloop_register_timeout(HOSTAPD_DFS_TEST_MODE_CSA_DUR, 0, -+ hostapd_dfs_test_mode_csa_timeout, hapd, NULL); -+ return 0; -+ -+fail: -+ hostapd_disable_iface(iface); -+ return err; -+} - - static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface) - { -@@ -1049,6 +1118,9 @@ static int hostapd_dfs_start_channel_swi - if (iface->dfs_domain == HOSTAPD_DFS_REGION_ETSI) - skip_radar = 0; - -+ if (iface->conf->dfs_test_mode) -+ return hostapd_dfs_testmode_set_beacon_csa(iface); -+ - /* Perform channel switch/CSA */ - channel = dfs_get_valid_channel(iface, &secondary_channel, - &oper_centr_freq_seg0_idx, -@@ -1172,6 +1244,12 @@ int hostapd_dfs_radar_detected(struct ho - if (!res) - return 0; - -+ if (iface->conf->dfs_test_mode) { -+ set_dfs_state(iface, freq, ht_enabled, chan_offset, -+ chan_width, cf1, cf2, -+ HOSTAPD_CHAN_DFS_AVAILABLE); -+ } -+ - /* Skip if reported radar event not overlapped our channels */ - res = dfs_are_channels_overlapped(iface, freq, chan_width, cf1, cf2); - if (!res) ---- a/src/ap/dfs.h -+++ b/src/ap/dfs.h -@@ -9,6 +9,11 @@ - #ifndef DFS_H - #define DFS_H - -+/* CSA beacon duration in seconds for dfs testing mode */ -+#define HOSTAPD_DFS_TEST_MODE_CSA_DUR 1 -+ -+void hostapd_dfs_test_mode_csa_timeout(void *eloop_data, void *user_data); -+ - int hostapd_handle_dfs(struct hostapd_iface *iface); - - int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq, ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -2767,6 +2767,7 @@ int hostapd_disable_iface(struct hostapd - hostapd_cleanup_cs_params(hapd_iface->bss[j]); - #endif /* NEED_AP_MLME */ - -+ eloop_cancel_timeout(hostapd_dfs_test_mode_csa_timeout, hapd_iface, NULL); - /* same as hostapd_interface_deinit without deinitializing ctrl-iface */ - for (j = 0; j < hapd_iface->num_bss; j++) { - struct hostapd_data *hapd = hapd_iface->bss[j]; diff --git a/feeds/ipq95xx/hostapd/patches/b00-001-hostapd-fix-an-issue-related-with-wpa_group_state.patch b/feeds/ipq95xx/hostapd/patches/b00-001-hostapd-fix-an-issue-related-with-wpa_group_state.patch deleted file mode 100644 index ad96f8e7..00000000 --- a/feeds/ipq95xx/hostapd/patches/b00-001-hostapd-fix-an-issue-related-with-wpa_group_state.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- a/src/ap/drv_callbacks.c -+++ b/src/ap/drv_callbacks.c -@@ -31,6 +31,7 @@ - #include "tkip_countermeasures.h" - #include "ieee802_1x.h" - #include "wpa_auth.h" -+#include "wpa_auth_glue.h" - #include "wps_hostapd.h" - #include "ap_drv_ops.h" - #include "ap_config.h" -@@ -2030,6 +2031,7 @@ void hostapd_wpa_event(void *ctx, enum w - * Try to re-enable interface if the driver stopped it - * when the interface got disabled. - */ -+ hostapd_reconfig_wpa(hapd); - if (hapd->wpa_auth) - wpa_auth_reconfig_group_keys(hapd->wpa_auth); - else diff --git a/feeds/ipq95xx/hostapd/patches/b00-004-hostap-fix-compilation-issue.patch b/feeds/ipq95xx/hostapd/patches/b00-004-hostap-fix-compilation-issue.patch deleted file mode 100644 index 9b16a456..00000000 --- a/feeds/ipq95xx/hostapd/patches/b00-004-hostap-fix-compilation-issue.patch +++ /dev/null @@ -1,140 +0,0 @@ ---- a/src/ap/wpa_auth.c -+++ b/src/ap/wpa_auth.c -@@ -1051,7 +1051,7 @@ void wpa_receive(struct wpa_authenticato - mic_len, key_data_length); - wpa_hexdump(MSG_MSGDUMP, - "WPA: EAPOL-Key header (ending before Key MIC)", -- key, sizeof(*key)); -+ (u8 *)key, sizeof(*key)); - wpa_hexdump(MSG_MSGDUMP, "WPA: EAPOL-Key Key MIC", - mic, mic_len); - if (key_data_length > data_len - sizeof(*hdr) - keyhdrlen) { -@@ -3140,7 +3140,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) - idx = bitfield_get_first_zero(wpa_auth->ip_pool); - if (idx >= 0) { - u32 start = WPA_GET_BE32(wpa_auth->conf.ip_addr_start); -- bitfield_set(wpa_auth->ip_pool, idx); -+ bitfield_set_local(wpa_auth->ip_pool, idx); - WPA_PUT_BE32(sm->ip_addr, start + idx); - wpa_printf(MSG_DEBUG, - "P2P: Assigned IP address %u.%u.%u.%u to " ---- a/src/crypto/tls_openssl.c -+++ b/src/crypto/tls_openssl.c -@@ -1099,7 +1099,7 @@ void * tls_init(const struct tls_config - if (conf && conf->openssl_ciphers) - ciphers = conf->openssl_ciphers; - else -- ciphers = TLS_DEFAULT_CIPHERS; -+ ciphers = "DEFAULT:!EXP:!LOW"; - if (SSL_CTX_set_cipher_list(ssl, ciphers) != 1) { - wpa_printf(MSG_ERROR, - "OpenSSL: Failed to set cipher string '%s'", ---- a/src/utils/bitfield.c -+++ b/src/utils/bitfield.c -@@ -37,7 +37,7 @@ void bitfield_free(struct bitfield *bf) - } - - --void bitfield_set(struct bitfield *bf, size_t bit) -+void bitfield_set_local(struct bitfield *bf, size_t bit) - { - if (bit >= bf->max_bits) - return; ---- a/src/utils/bitfield.h -+++ b/src/utils/bitfield.h -@@ -13,7 +13,7 @@ struct bitfield; - - struct bitfield * bitfield_alloc(size_t max_bits); - void bitfield_free(struct bitfield *bf); --void bitfield_set(struct bitfield *bf, size_t bit); -+void bitfield_set_local(struct bitfield *bf, size_t bit); - void bitfield_clear(struct bitfield *bf, size_t bit); - int bitfield_is_set(struct bitfield *bf, size_t bit); - int bitfield_get_first_zero(struct bitfield *bf); ---- a/src/utils/utils_module_tests.c -+++ b/src/utils/utils_module_tests.c -@@ -142,7 +142,7 @@ static int bitfield_tests(void) - errors++; - if (i > 0 && bitfield_is_set(bf, i - 1)) - errors++; -- bitfield_set(bf, i); -+ bitfield_set_local(bf, i); - if (!bitfield_is_set(bf, i)) - errors++; - bitfield_clear(bf, i); -@@ -155,7 +155,7 @@ static int bitfield_tests(void) - errors++; - if (i > 0 && bitfield_is_set(bf, i - 1)) - errors++; -- bitfield_set(bf, i); -+ bitfield_set_local(bf, i); - if (bitfield_is_set(bf, i)) - errors++; - bitfield_clear(bf, i); -@@ -166,7 +166,7 @@ static int bitfield_tests(void) - for (i = 0; i < 123; i++) { - if (bitfield_is_set(bf, i) || bitfield_is_set(bf, i + 1)) - errors++; -- bitfield_set(bf, i); -+ bitfield_set_local(bf, i); - if (!bitfield_is_set(bf, i)) - errors++; - } -@@ -182,7 +182,7 @@ static int bitfield_tests(void) - for (i = 0; i < 123; i++) { - if (bitfield_get_first_zero(bf) != i) - errors++; -- bitfield_set(bf, i); -+ bitfield_set_local(bf, i); - } - if (bitfield_get_first_zero(bf) != -1) - errors++; -@@ -192,7 +192,7 @@ static int bitfield_tests(void) - bitfield_clear(bf, i); - if (bitfield_get_first_zero(bf) != i) - errors++; -- bitfield_set(bf, i); -+ bitfield_set_local(bf, i); - } - if (bitfield_get_first_zero(bf) != -1) - errors++; -@@ -205,7 +205,7 @@ static int bitfield_tests(void) - if (bitfield_get_first_zero(bf) != 0) - errors++; - for (i = 0; i < 8; i++) -- bitfield_set(bf, i); -+ bitfield_set_local(bf, i); - if (bitfield_get_first_zero(bf) != -1) - errors++; - bitfield_free(bf); ---- a/wpa_supplicant/rrm.c -+++ b/wpa_supplicant/rrm.c -@@ -1125,7 +1125,7 @@ static int wpas_rm_handle_beacon_req_sub - } - - for (i = 0; i < slen; i++) -- bitfield_set(data->eids, subelem[i]); -+ bitfield_set_local(data->eids, subelem[i]); - break; - case WLAN_BEACON_REQUEST_SUBELEM_AP_CHANNEL: - /* Skip - it will be processed when freqs are added */ ---- a/src/rsn_supp/tdls.c -+++ b/src/rsn_supp/tdls.c -@@ -1678,7 +1678,7 @@ static int copy_peer_he_capab(const stru - - peer->he_capab_len = kde->he_capab_len; - wpa_hexdump(MSG_DEBUG, "TDLS: Peer HE capabilities", -- peer->he_capabilities, peer->he_capab_len); -+ (u8 *)peer->he_capabilities, peer->he_capab_len); - - return 0; - } -@@ -1704,7 +1704,7 @@ static int copy_peer_he_6ghz_band_capab( - sizeof(struct ieee80211_he_6ghz_band_cap)); - - wpa_hexdump(MSG_DEBUG, "TDLS: Peer 6 GHz band HE capabilities", -- peer->he_6ghz_band_capabilities, -+ (u8 *)peer->he_6ghz_band_capabilities, - sizeof(struct ieee80211_he_6ghz_band_cap)); - - return 0; diff --git a/feeds/ipq95xx/hostapd/patches/b00-014-hostapd-add-ht40-allow-map.patch b/feeds/ipq95xx/hostapd/patches/b00-014-hostapd-add-ht40-allow-map.patch deleted file mode 100644 index a5bf7140..00000000 --- a/feeds/ipq95xx/hostapd/patches/b00-014-hostapd-add-ht40-allow-map.patch +++ /dev/null @@ -1,130 +0,0 @@ ---- a/hostapd/ctrl_iface.c -+++ b/hostapd/ctrl_iface.c -@@ -3112,6 +3112,92 @@ set: - return ret; - } - -+static int hostapd_2ghz_ht40_allow_map(struct hostapd_hw_modes *mode, -+ char *buf, size_t buflen) -+{ -+ int j, ret, len = 0; -+ -+ for (j = 0; j < mode->num_channels; j++) { -+ struct hostapd_channel_data *chan = &mode->channels[j]; -+ if (!(chan->flag & HOSTAPD_CHAN_DISABLED)) { -+ ret = os_snprintf(buf + len, buflen - len, -+ "Channel: %d : %d HT40%c%c\n", -+ chan->chan, chan->freq, -+ (chan->flag & HOSTAPD_CHAN_HT40MINUS) ? -+ '-' : ' ', -+ (chan->flag & HOSTAPD_CHAN_HT40PLUS) ? -+ '+' : ' '); -+ if (os_snprintf_error(buflen - len, ret)) -+ return len; -+ len += ret; -+ } -+ } -+ return len; -+} -+ -+static int hostapd_5ghz_ht40_allow_map(struct hostapd_hw_modes *mode, -+ char *buf, size_t buflen) -+{ -+ int j, k, ok, ret, len = 0, allowed[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 140, -+ 149, 157, 184, 192 }; -+ -+ for (j = 0; j < mode->num_channels; j++) { -+ struct hostapd_channel_data *chan = &mode->channels[j]; -+ -+ if ((chan->flag & HOSTAPD_CHAN_HT40MINUS) || -+ (chan->flag & HOSTAPD_CHAN_HT40PLUS)) { -+ ok = 0; -+ for (k = 0; k < ARRAY_SIZE(allowed); k++) { -+ if (chan->chan < allowed[k]) -+ break; -+ if (chan->chan == allowed[k]) { -+ ok = 1; -+ break; -+ } -+ } -+ -+ if (!ok && chan->chan != (allowed[k - 1] + 4)) -+ ok = -1; -+ -+ if (ok == 1 && (mode->channels[j + 1].flag & -+ HOSTAPD_CHAN_DISABLED)) -+ ok = -1; -+ -+ if (ok != -1) { -+ ret = os_snprintf(buf + len, buflen - len, -+ "Channel: %d : %d HT40%s\n", -+ chan->chan, chan->freq, -+ ok == 1 ? "+" : "-"); -+ -+ if (os_snprintf_error(buflen - len, ret)) -+ return len; -+ -+ len += ret; -+ } -+ } -+ } -+ return len; -+} -+ -+static int hostapd_ctrl_iface_ht40_allow_map(struct hostapd_iface *iface, -+ char *buf, size_t buflen) -+{ -+ struct hostapd_data *hapd = iface->bss[0]; -+ struct hostapd_hw_modes *mode; -+ int len = 0; -+ u16 num_modes, flags; -+ u8 dfs_domain; -+ -+ mode = hostapd_get_hw_feature_data(hapd, &num_modes, &flags, -+ &dfs_domain); -+ -+ if (mode->mode != HOSTAPD_MODE_IEEE80211A) -+ len = hostapd_2ghz_ht40_allow_map(mode, buf, buflen); -+ else -+ len = hostapd_5ghz_ht40_allow_map(mode, buf, buflen); -+ -+ return len; -+} - - static int hostapd_ctrl_iface_remove_neighbor(struct hostapd_data *hapd, - char *buf) -@@ -3790,6 +3876,10 @@ static int hostapd_ctrl_iface_receive_pr - if (radius_server_dac_request(hapd->radius_srv, buf + 12) < 0) - reply_len = -1; - #endif /* RADIUS_SERVER */ -+ } else if (os_strcmp(buf, "HT40_ALLOW_MAP") == 0) { -+ reply_len = hostapd_ctrl_iface_ht40_allow_map(hapd->iface, -+ reply, -+ reply_size); - } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) { - reply_len = hostapd_ctrl_iface_get_capability( - hapd, buf + 15, reply, reply_size); ---- a/hostapd/hostapd_cli.c -+++ b/hostapd/hostapd_cli.c -@@ -1362,6 +1362,12 @@ static int hostapd_cli_cmd_driver_flags( - return wpa_ctrl_command(ctrl, "DRIVER_FLAGS"); - } - -+static int hostapd_cli_cmd_ht40_allow_map(struct wpa_ctrl *ctrl, -+ int argc, char *argv[]) -+{ -+ return wpa_ctrl_command(ctrl, "HT40_ALLOW_MAP"); -+} -+ - - #ifdef CONFIG_DPP - -@@ -1705,6 +1711,8 @@ static const struct hostapd_cli_cmd host - "=Add/Delete/Show/Clear deny MAC ACL" }, - { "poll_sta", hostapd_cli_cmd_poll_sta, hostapd_complete_stations, - " = poll a STA to check connectivity with a QoS null frame" }, -+ { "ht40_allow_map", hostapd_cli_cmd_ht40_allow_map, NULL, -+ "= show ht40 allow map status" }, - { "req_beacon", hostapd_cli_cmd_req_beacon, NULL, - " [req_mode=] = send a Beacon report request to a station" }, - { "reload_wpa_psk", hostapd_cli_cmd_reload_wpa_psk, NULL, diff --git a/feeds/ipq95xx/hostapd/patches/b00-029-hostapd-disable-MAC-ACL-if-WPS-enabled.patch b/feeds/ipq95xx/hostapd/patches/b00-029-hostapd-disable-MAC-ACL-if-WPS-enabled.patch deleted file mode 100644 index 66a4ad2d..00000000 --- a/feeds/ipq95xx/hostapd/patches/b00-029-hostapd-disable-MAC-ACL-if-WPS-enabled.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- a/src/ap/ieee802_11_auth.c -+++ b/src/ap/ieee802_11_auth.c -@@ -174,6 +174,15 @@ static int hostapd_radius_acl_query(stru - int hostapd_check_acl(struct hostapd_data *hapd, const u8 *addr, - struct vlan_description *vlan_id) - { -+ -+#ifdef CONFIG_WPS -+ /* According to WPS spec 2.0, disable MAC address filtering -+ * if WPS is enabled on the AP. -+ */ -+ if (hapd->conf->wps_state) -+ return HOSTAPD_ACL_ACCEPT; -+#endif /*CONFIG_WPS */ -+ - if (hostapd_maclist_found(hapd->conf->accept_mac, - hapd->conf->num_accept_mac, addr, vlan_id)) - return HOSTAPD_ACL_ACCEPT; diff --git a/feeds/ipq95xx/hostapd/patches/b00-034-hostapd-Add-max-rate-information-into-STATUS-and-STA.patch b/feeds/ipq95xx/hostapd/patches/b00-034-hostapd-Add-max-rate-information-into-STATUS-and-STA.patch deleted file mode 100644 index ed325e3f..00000000 --- a/feeds/ipq95xx/hostapd/patches/b00-034-hostapd-Add-max-rate-information-into-STATUS-and-STA.patch +++ /dev/null @@ -1,224 +0,0 @@ -commit 2dfbe0feb590dfebaf1e92c4006c1ae22ee482bb -Author: houbao -Date: Thu Dec 6 15:17:46 2018 +0800 - - Subject: [PATCH] hostapd: Add max rate information into STATUS and STA - commands - - These allow external programs to get max MCS, max nss, and rate - information of an interface or a STA. - ---- a/src/ap/ctrl_iface_ap.c -+++ b/src/ap/ctrl_iface_ap.c -@@ -51,6 +51,107 @@ static size_t hostapd_write_ht_mcs_bitma - } - - -+static u8 hostapd_maxnss(struct hostapd_data *hapd, struct sta_info *sta) -+{ -+ u8 *mcs_set = NULL; -+ u16 mcs_map; -+ u8 ht_rx_nss = 0; -+ u8 vht_rx_nss = 1; -+ u8 mcs; -+ u8 ht_supported = 0; -+ u8 vht_supported = 0; -+ int i; -+ -+ if (sta) { -+ if (sta->ht_capabilities && (sta->flags & WLAN_STA_HT)) { -+ mcs_set = sta->ht_capabilities->supported_mcs_set; -+ ht_supported = 1; -+ } -+ if (sta->vht_capabilities && (sta->flags & WLAN_STA_VHT)) { -+ mcs_map = le_to_host16(sta->vht_capabilities-> -+ vht_supported_mcs_set.rx_map); -+ vht_supported = 1; -+ } -+ } else { -+ struct hostapd_config *conf = hapd->iface->conf; -+ struct hostapd_hw_modes *mode = hapd->iface->current_mode; -+ -+ if (mode && conf->ieee80211ac && !hapd->conf->disable_11ac) { -+ mcs_map = mode->vht_mcs_set[4] | \ -+ (mode->vht_mcs_set[5] << 8); -+ vht_supported = 1; -+ } -+ if (mode && conf->ieee80211n && !hapd->conf->disable_11n) { -+ mcs_set = mode->mcs_set; -+ ht_supported = 1; -+ } -+ } -+ if (ht_supported && mcs_set != NULL) { -+ if (mcs_set[0]) -+ ht_rx_nss++; -+ if (mcs_set[1]) -+ ht_rx_nss++; -+ if (mcs_set[2]) -+ ht_rx_nss++; -+ if (mcs_set[3]) -+ ht_rx_nss++; -+ } -+ if (vht_supported) { -+ for (i = 7; i >= 0; i--) { -+ mcs = (mcs_map >> (2 * i)) & 0x03; -+ if (mcs != 0x03) { -+ vht_rx_nss = i + 1; -+ break; -+ } -+ } -+ } -+ -+ return ht_rx_nss > vht_rx_nss ? ht_rx_nss : vht_rx_nss; -+} -+ -+ -+static u8 hostapd_htmaxmcs(const u8 *mcs_set) -+{ -+ u8 rates[WLAN_SUPP_RATES_MAX]; -+ u8 i; -+ u8 j = 0; -+ -+ for (i = 0; i < WLAN_SUPP_HT_RATES_MAX; i++) { -+ if (mcs_set[i / 8] & (1 << (i % 8))) -+ rates[j++] = i; -+ if (j == WLAN_SUPP_RATES_MAX) { -+ wpa_printf(MSG_INFO, -+ "HT extended rate set too large; using only %u rates", -+ j); -+ break; -+ } -+ } -+ if (j <= WLAN_SUPP_RATES_MAX) -+ return rates[j - 1]; -+ -+ return 0; -+} -+ -+ -+static u8 hostapd_vhtmaxmcs(u16 rx_vht_mcs_map, u16 tx_vht_mcs_map) -+{ -+ u8 rx_max_mcs, tx_max_mcs, max_mcs; -+ -+ if (rx_vht_mcs_map && tx_vht_mcs_map) { -+ /* Refer to IEEE P802.11ac/D7.0 Figure 8-401bs -+ * for VHT MCS Map definition -+ */ -+ rx_max_mcs = rx_vht_mcs_map & 0x03; -+ tx_max_mcs = tx_vht_mcs_map & 0x03; -+ max_mcs = rx_max_mcs < tx_max_mcs ? rx_max_mcs : tx_max_mcs; -+ if (max_mcs < 0x03) -+ return 7 + max_mcs; -+ } -+ -+ return 0; -+} -+ -+ - static int hostapd_get_sta_info(struct hostapd_data *hapd, - struct sta_info *sta, - char *buf, size_t buflen) -@@ -161,6 +262,38 @@ static int hostapd_get_sta_info(struct - len += ret; - } - -+ ret = os_snprintf(buf + len, buflen - len, "max_nss=%u\n", -+ hostapd_maxnss(hapd, sta)); -+ if (!os_snprintf_error(buflen - len, ret)) -+ len += ret; -+ -+#ifdef CONFIG_IEEE80211AC -+ if ((sta->flags & WLAN_STA_VHT) && sta->vht_capabilities) { -+ u8 vht_maxmcs = hostapd_vhtmaxmcs( -+ le_to_host16(sta->vht_capabilities-> -+ vht_supported_mcs_set.rx_map), -+ le_to_host16(sta->vht_capabilities-> -+ vht_supported_mcs_set.tx_map)); -+ ret = os_snprintf(buf + len, buflen - len, "max_vhtmcs=%u\n", -+ vht_maxmcs); -+ if (!os_snprintf_error(buflen - len, ret)) -+ len += ret; -+ } -+#endif /* CONFIG_IEEE80211AC */ -+ -+#ifdef CONFIG_IEEE80211N -+ if ((sta->flags & (WLAN_STA_HT | WLAN_STA_VHT)) == WLAN_STA_HT && -+ sta->ht_capabilities) { -+ u8 ht_maxmcs; -+ -+ ht_maxmcs = hostapd_htmaxmcs(sta->ht_capabilities-> -+ supported_mcs_set); -+ ret = os_snprintf(buf + len, buflen - len, "max_mcs=%u\n", -+ ht_maxmcs); -+ if (!os_snprintf_error(buflen - len, ret)) -+ len += ret; -+ } -+#endif /* CONFIG_IEEE80211N */ - return len; - } - -@@ -798,6 +931,20 @@ int hostapd_ctrl_iface_status(struct hos - if (os_snprintf_error(buflen - len, ret)) - return len; - len += ret; -+ -+ if (mode) { -+ u16 rxmap = mode->vht_mcs_set[0] | -+ (mode->vht_mcs_set[1] << 8); -+ u16 txmap = mode->vht_mcs_set[4] | -+ (mode->vht_mcs_set[5] << 8); -+ -+ ret = os_snprintf(buf + len, buflen - len, -+ "vht_max_mcs=%u\n", -+ hostapd_vhtmaxmcs(rxmap, txmap)); -+ if (os_snprintf_error(buflen - len, ret)) -+ return len; -+ len += ret; -+ } - } - - if (iface->conf->ieee80211n && !hapd->conf->disable_11n) { -@@ -832,8 +979,33 @@ int hostapd_ctrl_iface_status(struct hos - if (os_snprintf_error(buflen - len, ret)) - return len; - len += ret; -+ -+ if (mode) { -+ ret = os_snprintf(buf + len, buflen - len, -+ "max_mcs=%u\n", -+ hostapd_htmaxmcs(mode->mcs_set)); -+ if (os_snprintf_error(buflen - len, ret)) -+ return len; -+ len += ret; -+ } - } - -+ if (mode && mode->rates && mode->num_rates && -+ mode->num_rates <= WLAN_SUPP_RATES_MAX) { -+ ret = os_snprintf(buf + len, buflen - len, -+ "max_rate=%u\n", -+ mode->rates[mode->num_rates - 1]); -+ if (os_snprintf_error(buflen - len, ret)) -+ return len; -+ len += ret; -+ } -+ -+ ret = os_snprintf(buf + len, buflen - len, "max_nss=%u\n", -+ hostapd_maxnss(hapd, NULL)); -+ if (os_snprintf_error(buflen - len, ret)) -+ return len; -+ len += ret; -+ - for (j = 0; mode && j < mode->num_channels; j++) { - if (mode->channels[j].freq == iface->freq) { - ret = os_snprintf(buf + len, buflen - len, ---- a/src/ap/sta_info.h -+++ b/src/ap/sta_info.h -@@ -46,6 +46,7 @@ - /* Maximum number of supported rates (from both Supported Rates and Extended - * Supported Rates IEs). */ - #define WLAN_SUPP_RATES_MAX 32 -+#define WLAN_SUPP_HT_RATES_MAX 77 - - struct hostapd_data; - diff --git a/feeds/ipq95xx/hostapd/patches/b00-036-hostapd-disable-40mhz-scan.patch b/feeds/ipq95xx/hostapd/patches/b00-036-hostapd-disable-40mhz-scan.patch deleted file mode 100644 index 3251904f..00000000 --- a/feeds/ipq95xx/hostapd/patches/b00-036-hostapd-disable-40mhz-scan.patch +++ /dev/null @@ -1,41 +0,0 @@ ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -4235,6 +4235,8 @@ static int hostapd_config_fill(struct ho - } else if (os_strcmp(buf, "wowlan_triggers") == 0) { - os_free(bss->wowlan_triggers); - bss->wowlan_triggers = os_strdup(pos); -+ } else if (os_strcmp(buf, "disable_40mhz_scan") == 0) { -+ conf->disable_40mhz_scan = atoi(pos); - #ifdef CONFIG_FST - } else if (os_strcmp(buf, "fst_group_id") == 0) { - size_t len = os_strlen(pos); ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -1018,6 +1018,7 @@ struct hostapd_config { - } *acs_chan_bias; - unsigned int num_acs_chan_bias; - #endif /* CONFIG_ACS */ -+ int disable_40mhz_scan; - - struct wpabuf *lci; - struct wpabuf *civic; ---- a/src/ap/hw_features.c -+++ b/src/ap/hw_features.c -@@ -696,9 +696,14 @@ int hostapd_check_ht_capab(struct hostap - !ieee80211ac_supported_vht_capab(iface)) - return -1; - #endif /* CONFIG_IEEE80211AC */ -- ret = ieee80211n_check_40mhz(iface); -- if (ret) -- return ret; -+ if (!iface->conf->disable_40mhz_scan) { -+ ret = ieee80211n_check_40mhz(iface); -+ if (ret) -+ return ret; -+ } else { -+ wpa_printf(MSG_INFO, "%s:40mhz scan disabled", -+ iface->conf->bss[0]->iface); -+ } - if (!ieee80211n_allowed_ht40_channel_pair(iface)) - return -1; - diff --git a/feeds/ipq95xx/hostapd/patches/c00-002-hostapd-he-update-nl-header.patch b/feeds/ipq95xx/hostapd/patches/c00-002-hostapd-he-update-nl-header.patch deleted file mode 100644 index 8de804a5..00000000 --- a/feeds/ipq95xx/hostapd/patches/c00-002-hostapd-he-update-nl-header.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 1737f5a14528e32df1806471222176e507728fe0 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 3 May 2019 08:16:44 +0200 -Subject: [PATCH] update nl80211.h - -Sync with mac80211-next.git include/uapi/linux/nl80211.h - -This brings in nl80211 definitions as of 2019-06-19. - -Signed-off-by: John Crispin ---- - src/drivers/nl80211_copy.h | 75 +++++++++++++++++++++++----------------------- - 1 file changed, 37 insertions(+), 38 deletions(-) - -Index: hostapd-2021-02-08/src/drivers/nl80211_copy.h -=================================================================== ---- hostapd-2021-02-08.orig/src/drivers/nl80211_copy.h -+++ hostapd-2021-02-08/src/drivers/nl80211_copy.h -@@ -4541,6 +4541,10 @@ enum nl80211_chan_width { - NL80211_CHAN_WIDTH_4, - NL80211_CHAN_WIDTH_8, - NL80211_CHAN_WIDTH_16, -+ -+ /* keep last */ -+ __NL80211_CHAN_WIDTH_NUM, -+ NL80211_CHAN_WIDTH_MAX = __NL80211_CHAN_WIDTH_NUM - 1, - }; - - /** -Index: hostapd-2021-02-08/src/ap/dfs.c -=================================================================== ---- hostapd-2021-02-08.orig/src/ap/dfs.c -+++ hostapd-2021-02-08/src/ap/dfs.c -@@ -1051,13 +1051,17 @@ static int hostapd_dfs_testmode_set_beac - iface->conf->hw_mode, - iface->freq, - iface->conf->channel, -+ iface->conf->enable_edmg, -+ iface->conf->edmg_channel, - iface->conf->ieee80211n, - iface->conf->ieee80211ac, -+ iface->conf->ieee80211ax, - secondary_channel, -- iface->conf->vht_oper_chwidth, -+ hostapd_get_oper_chwidth(iface->conf), - vht_oper_centr_freq_seg0_idx, - vht_oper_centr_freq_seg1_idx, -- iface->current_mode->vht_capab); -+ iface->current_mode->vht_capab, -+ &iface->current_mode->he_capab[IEEE80211_MODE_AP]); - - if (err) { - wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params"); diff --git a/feeds/ipq95xx/hostapd/patches/c00-010-hostapd-fix-enabling-he-in-5G.patch b/feeds/ipq95xx/hostapd/patches/c00-010-hostapd-fix-enabling-he-in-5G.patch deleted file mode 100644 index 8232429c..00000000 --- a/feeds/ipq95xx/hostapd/patches/c00-010-hostapd-fix-enabling-he-in-5G.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -2653,7 +2653,7 @@ skip_ht40: - if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq, - freq->channel, ssid->enable_edmg, - ssid->edmg_channel, freq->ht_enabled, -- vht_freq.vht_enabled, freq->he_enabled, -+ vht_freq.vht_enabled, vht_freq.he_enabled, - freq->sec_channel_offset, - chwidth, seg0, seg1, vht_caps, - &mode->he_capab[ieee80211_mode]) != 0) diff --git a/feeds/ipq95xx/hostapd/patches/c00-011-hostapd-add-mbo-support.patch b/feeds/ipq95xx/hostapd/patches/c00-011-hostapd-add-mbo-support.patch deleted file mode 100644 index 3b10235d..00000000 --- a/feeds/ipq95xx/hostapd/patches/c00-011-hostapd-add-mbo-support.patch +++ /dev/null @@ -1,370 +0,0 @@ ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -4143,10 +4143,12 @@ static int hostapd_config_fill(struct ho - #ifdef CONFIG_MBO - } else if (os_strcmp(buf, "mbo") == 0) { - bss->mbo_enabled = atoi(pos); -- } else if (os_strcmp(buf, "mbo_cell_data_conn_pref") == 0) { -- bss->mbo_cell_data_conn_pref = atoi(pos); -+ } else if (os_strcmp(buf, "mbo_ap_cap_ind") == 0) { -+ bss->mbo_ap_cap_ind = atoi(pos); - } else if (os_strcmp(buf, "oce") == 0) { - bss->oce = atoi(pos); -+ } else if (os_strcmp(buf, "mbo_cell_data_conn_pref") == 0) { -+ bss->mbo_cell_data_conn_pref = atoi(pos); - #endif /* CONFIG_MBO */ - #ifdef CONFIG_TESTING_OPTIONS - #define PARSE_TEST_PROBABILITY(_val) \ ---- a/hostapd/ctrl_iface.c -+++ b/hostapd/ctrl_iface.c -@@ -882,10 +882,11 @@ static int hostapd_ctrl_iface_bss_tm_req - if (pos) { - pos += 10; - req_mode |= WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED; -- /* TODO: TSF configurable/learnable */ -+ /* TODO: TSF learnable */ - bss_term_dur[0] = 4; /* Subelement ID */ - bss_term_dur[1] = 10; /* Length */ -- os_memset(&bss_term_dur[2], 0, 8); -+ bss_term_dur[2] = atoi(pos); /* TSF */ -+ os_memset(&bss_term_dur[3], 0, 7); - end = os_strchr(pos, ','); - if (end == NULL) { - wpa_printf(MSG_DEBUG, "Invalid bss_term data"); -@@ -895,7 +896,7 @@ static int hostapd_ctrl_iface_bss_tm_req - WPA_PUT_LE16(&bss_term_dur[10], atoi(end)); - } - -- nei_len = ieee802_11_parse_candidate_list(cmd, nei_rep, -+ nei_len = ieee802_11_parse_candidate_list(cmd, sta, nei_rep, - sizeof(nei_rep)); - if (nei_len < 0) - return -1; ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -714,6 +714,11 @@ struct hostapd_bss_config { - * - Set BIT(2) to enable OCE in AP mode - */ - unsigned int oce; -+ /** -+ * Set BIT(6) to advertise cellular data aware capability -+ * in AP mode -+ */ -+ unsigned int mbo_ap_cap_ind; - int mbo_cell_data_conn_pref; - #endif /* CONFIG_MBO */ - ---- a/src/ap/gas_serv.c -+++ b/src/ap/gas_serv.c -@@ -19,6 +19,7 @@ - #include "dpp_hostapd.h" - #include "sta_info.h" - #include "gas_serv.h" -+#include "neighbor_db.h" - - - #ifdef CONFIG_DPP -@@ -603,6 +604,28 @@ static void anqp_add_domain_name(struct - } - } - -+static void anqp_add_neighbor_report(struct hostapd_data *hapd, -+ struct wpabuf *buf) -+{ -+ if (anqp_add_override(hapd, buf, ANQP_NEIGHBOR_REPORT)) -+ return; -+ -+ if (hapd->conf->radio_measurements[0] & -+ WLAN_RRM_CAPS_NEIGHBOR_REPORT) { -+ u8* len, *nei_len; -+ len = gas_anqp_add_element(buf, ANQP_NEIGHBOR_REPORT); -+ wpabuf_put_u8(buf, WLAN_EID_NEIGHBOR_REPORT); -+ nei_len = (u8 *)wpabuf_put(buf, 1); -+ -+ if (hostapd_prepare_neighbor_buf(hapd, hapd->own_addr, -+ buf)) { -+ buf->used -= 2; -+ return; -+ } -+ *nei_len = ((u8 *)wpabuf_put(buf, 0) - nei_len - 1); -+ gas_anqp_set_element_len(buf, len); -+ } -+} - - #ifdef CONFIG_FILS - static void anqp_add_fils_realm_info(struct hostapd_data *hapd, -@@ -1028,6 +1051,8 @@ gas_serv_build_gas_resp_payload(struct h - anqp_add_elem(hapd, buf, ANQP_TDLS_CAPABILITY); - if (request & ANQP_REQ_EMERGENCY_NAI) - anqp_add_elem(hapd, buf, ANQP_EMERGENCY_NAI); -+ if (request & ANQP_REQ_NEIGHBOR_REPORT) -+ anqp_add_neighbor_report(hapd, buf); - - for (i = 0; i < num_extra_req; i++) { - #ifdef CONFIG_FILS -@@ -1172,6 +1197,12 @@ static void rx_anqp_query_list_id(struct - "Emergency NAI", - get_anqp_elem(hapd, info_id) != NULL, qi); - break; -+ case ANQP_NEIGHBOR_REPORT: -+ set_anqp_req(ANQP_REQ_NEIGHBOR_REPORT, -+ "Neighbor report", -+ (hapd->conf->radio_measurements[0] & -+ WLAN_RRM_CAPS_NEIGHBOR_REPORT), qi); -+ break; - default: - #ifdef CONFIG_FILS - if (info_id == ANQP_FILS_REALM_INFO && ---- a/src/ap/gas_serv.h -+++ b/src/ap/gas_serv.h -@@ -40,6 +40,8 @@ - (1 << (ANQP_TDLS_CAPABILITY - ANQP_QUERY_LIST)) - #define ANQP_REQ_EMERGENCY_NAI \ - (1 << (ANQP_EMERGENCY_NAI - ANQP_QUERY_LIST)) -+#define ANQP_REQ_NEIGHBOR_REPORT \ -+ (1 << (ANQP_NEIGHBOR_REPORT - ANQP_QUERY_LIST)) - /* - * First 15 Hotspot 2.0 vendor specific ANQP-elements can be included in the - * optimized bitmap. ---- a/src/ap/ieee802_11.h -+++ b/src/ap/ieee802_11.h -@@ -132,6 +132,9 @@ static inline void sae_clear_retransmit_ - } - #endif /* CONFIG_SAE */ - -+u8 * hostapd_eid_rm_enabled_capab(struct hostapd_data *hapd, -+ u8 *eid, size_t len); -+ - #ifdef CONFIG_MBO - - u8 * hostapd_eid_mbo(struct hostapd_data *hapd, u8 *eid, size_t len); ---- a/src/ap/ieee802_11_shared.c -+++ b/src/ap/ieee802_11_shared.c -@@ -801,11 +801,13 @@ u8 * hostapd_eid_mbo(struct hostapd_data - !OCE_STA_CFON_ENABLED(hapd) && !OCE_AP_ENABLED(hapd)) - return eid; - -- if (hapd->conf->mbo_enabled) { -+ if (hapd->conf->mbo_enabled && hapd->conf->oce & OCE_AP) { - *mbo_pos++ = MBO_ATTR_ID_AP_CAPA_IND; - *mbo_pos++ = 1; -- /* Not Cellular aware */ -- *mbo_pos++ = 0; -+ if (hapd->conf->mbo_ap_cap_ind & MBO_AP_CAPA_CELL_AWARE) -+ *mbo_pos++ = MBO_AP_CAPA_CELL_AWARE; -+ else -+ *mbo_pos++ = 0; - } - - if (hapd->conf->mbo_enabled && hapd->mbo_assoc_disallow) { ---- a/src/ap/neighbor_db.c -+++ b/src/ap/neighbor_db.c -@@ -160,6 +160,24 @@ fail: - return -1; - } - -+int hostapd_prepare_neighbor_buf(struct hostapd_data *hapd, -+ const u8 *bssid, struct wpabuf *nrbuf) -+{ -+ struct hostapd_neighbor_entry *nr; -+ -+ nr = hostapd_neighbor_get(hapd, bssid, NULL); -+ if (!nr) -+ return -1; -+ -+ if (wpabuf_tailroom(nrbuf) < wpabuf_len(nr->nr)) { -+ wpa_printf(MSG_ERROR, -+ "Invalid buf size for Neighbor Report\n"); -+ return -1; -+ } -+ -+ wpabuf_put_buf(nrbuf, nr->nr); -+ return 0; -+} - - int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid, - const struct wpa_ssid_value *ssid) ---- a/src/ap/neighbor_db.h -+++ b/src/ap/neighbor_db.h -@@ -19,6 +19,8 @@ int hostapd_neighbor_set(struct hostapd_ - const struct wpabuf *nr, const struct wpabuf *lci, - const struct wpabuf *civic, int stationary); - void hostapd_neighbor_set_own_report(struct hostapd_data *hapd); -+int hostapd_prepare_neighbor_buf(struct hostapd_data *hapd, -+ const u8 *bssid, struct wpabuf *nrbuf); - int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid, - const struct wpa_ssid_value *ssid); - void hostapd_free_neighbor_db(struct hostapd_data *hapd); ---- a/src/ap/wnm_ap.c -+++ b/src/ap/wnm_ap.c -@@ -20,6 +20,7 @@ - #include "ap/wpa_auth.h" - #include "mbo_ap.h" - #include "wnm_ap.h" -+#include "neighbor_db.h" - - #define MAX_TFS_IE_LEN 1024 - -@@ -366,11 +367,27 @@ static int ieee802_11_send_bss_trans_mgm - u8 dialog_token) - { - struct ieee80211_mgmt *mgmt; -- size_t len; -+ size_t len, nr_len = 0; - u8 *pos; -+ u8 req_mode = 0; - int res; - -- mgmt = os_zalloc(sizeof(*mgmt)); -+#ifdef CONFIG_MBO -+ u8 *nr_pos; -+ struct hostapd_neighbor_entry *nr; -+ struct wpabuf *nrbuf = NULL; -+ if (hapd->conf->mbo_enabled) { -+ dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry, -+ list) -+ /* ID and length */ -+ nr_len += wpabuf_len(nr->nr) + 1 + 1; -+ -+ nrbuf = wpabuf_alloc(nr_len); -+ if (nrbuf == NULL) -+ return -1; -+ } -+#endif -+ mgmt = os_zalloc(sizeof(*mgmt) + nr_len); - if (mgmt == NULL) - return -1; - os_memcpy(mgmt->da, addr, ETH_ALEN); -@@ -381,7 +398,11 @@ static int ieee802_11_send_bss_trans_mgm - mgmt->u.action.category = WLAN_ACTION_WNM; - mgmt->u.action.u.bss_tm_req.action = WNM_BSS_TRANS_MGMT_REQ; - mgmt->u.action.u.bss_tm_req.dialog_token = dialog_token; -- mgmt->u.action.u.bss_tm_req.req_mode = 0; -+#ifdef CONFIG_MBO -+ if (hapd->conf->mbo_enabled) -+ req_mode |= WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED; -+#endif -+ mgmt->u.action.u.bss_tm_req.req_mode = req_mode; - mgmt->u.action.u.bss_tm_req.disassoc_timer = host_to_le16(0); - mgmt->u.action.u.bss_tm_req.validity_interval = 1; - pos = mgmt->u.action.u.bss_tm_req.variable; -@@ -394,6 +415,25 @@ static int ieee802_11_send_bss_trans_mgm - le_to_host16(mgmt->u.action.u.bss_tm_req.disassoc_timer), - mgmt->u.action.u.bss_tm_req.validity_interval); - -+#ifdef CONFIG_MBO -+ if (hapd->conf->mbo_enabled) { -+ dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry, -+ list) { -+ wpabuf_put_u8(nrbuf, WLAN_EID_NEIGHBOR_REPORT); -+ /* Length to be filled */ -+ nr_pos = (u8 *)wpabuf_put(nrbuf, 1); -+ if (hostapd_prepare_neighbor_buf(hapd, nr->bssid, -+ nrbuf) < 0) { -+ res = -1; -+ } -+ /* Fill in the length field */ -+ *nr_pos = ((u8 *)wpabuf_put(nrbuf, 0) - nr_pos - 1); -+ } -+ os_memcpy(pos, nrbuf->buf, nr_len); -+ pos += nr_len; -+ wpabuf_free(nrbuf); -+ } -+#endif - len = pos - &mgmt->u.action.category; - res = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, - mgmt->da, &mgmt->u.action.category, len); ---- a/src/common/ieee802_11_common.c -+++ b/src/common/ieee802_11_common.c -@@ -2290,11 +2290,21 @@ bool is_6ghz_psc_frequency(int freq) - } - - --int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep, -- size_t nei_rep_len) -+int ieee802_11_parse_candidate_list(const char *pos, struct sta_info *sta, -+ u8 *nei_rep, size_t nei_rep_len) - { - u8 *nei_pos = nei_rep; - const char *end; -+#ifdef CONFIG_MBO -+ u8 non_pref_chan = 0; -+ u8 *pref_pos = NULL; -+ int i; -+ -+ struct mbo_non_pref_chan_info *info = NULL; -+ -+ if (sta && sta->non_pref_chan) -+ info = sta->non_pref_chan; -+#endif - - /* - * BSS Transition Candidate List Entries - Neighbor Report elements -@@ -2350,6 +2360,9 @@ int ieee802_11_parse_candidate_list(cons - pos++; - - *nei_pos++ = atoi(pos); /* Channel Number */ -+#ifdef CONFIG_MBO -+ non_pref_chan = atoi(pos); -+#endif - pos = os_strchr(pos, ','); - if (pos == NULL) { - wpa_printf(MSG_DEBUG, "Missing PHY Type"); -@@ -2381,6 +2394,25 @@ int ieee802_11_parse_candidate_list(cons - "Invalid neighbor subelement info"); - return -1; - } -+#ifdef CONFIG_MBO -+ if (info) { -+ for (i = 0; i < (len / 2); i++) -+ if (nei_pos[i] == WNM_NEIGHBOR_BSS_TRANSITION_CANDIDATE && -+ nei_pos[i + 1] == 0x1) /* length */ -+ pref_pos = (nei_pos + i + 2); -+ -+ /* If STA had updated MBO non-pref chan report, -+ * use the same candidate preference value in the -+ * BSS Transition Candidate sub-element. -+ */ -+ for ( ; info ; info = info->next) -+ for (i = 0; i < info->num_channels; i++) -+ if (non_pref_chan == info->channels[i]) -+ *pref_pos = info->pref; -+ -+ info = sta->non_pref_chan; -+ } -+#endif - nei_pos += len / 2; - pos = end; - } ---- a/src/common/ieee802_11_common.h -+++ b/src/common/ieee802_11_common.h -@@ -11,6 +11,7 @@ - - #include "defs.h" - #include "ieee802_11_defs.h" -+#include "ap/sta_info.h" - - struct element { - u8 id; -@@ -265,8 +266,8 @@ bool is_6ghz_freq(int freq); - bool is_6ghz_op_class(u8 op_class); - bool is_6ghz_psc_frequency(int freq); - --int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep, -- size_t nei_rep_len); -+int ieee802_11_parse_candidate_list(const char *pos, struct sta_info *sta, -+ u8 *nei_rep, size_t nei_rep_len); - - int ieee802_11_ext_capab(const u8 *ie, unsigned int capab); - int op_class_to_bandwidth(u8 op_class); ---- a/wpa_supplicant/wnm_sta.c -+++ b/wpa_supplicant/wnm_sta.c -@@ -1630,7 +1630,7 @@ int wnm_send_bss_transition_mgmt_query(s - return ret; - } - -- ret = ieee802_11_parse_candidate_list(btm_candidates, -+ ret = ieee802_11_parse_candidate_list(btm_candidates, NULL, - wpabuf_put(buf, 0), - max_len); - if (ret < 0) { diff --git a/feeds/ipq95xx/hostapd/patches/d00-002-set-supp-chan-width-for-40mghz.patch b/feeds/ipq95xx/hostapd/patches/d00-002-set-supp-chan-width-for-40mghz.patch deleted file mode 100644 index b8ee1644..00000000 --- a/feeds/ipq95xx/hostapd/patches/d00-002-set-supp-chan-width-for-40mghz.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 950186814b355d91bcb15ce544eed6f5727da791 Mon Sep 17 00:00:00 2001 -From: Lavanya Suresh -Date: Tue, 17 Nov 2020 19:23:46 +0530 -Subject: [PATCH] hostapd: Add channel width config in htcapab for 40MHz - -HT Support Channel Width field needs to be set in HT capabilities for -40MHz BW operation. - -Signed-off-by: Lavanya Suresh ---- - src/ap/hostapd.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c -index be9ef82..346d83c 100644 ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -3532,6 +3532,9 @@ static int hostapd_fill_csa_settings(struct hostapd_data *hapd, - if (!iface || !iface->freq || hapd->csa_in_progress) - return -1; - -+ if (settings->freq_params.bandwidth != 20) -+ hapd->iconf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET; -+ - switch (settings->freq_params.bandwidth) { - case 80: - if (settings->freq_params.center_freq2) --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/d00-003-wpa-supplicant-override-HE-toVHT-2G.patch b/feeds/ipq95xx/hostapd/patches/d00-003-wpa-supplicant-override-HE-toVHT-2G.patch deleted file mode 100644 index 63e49fa5..00000000 --- a/feeds/ipq95xx/hostapd/patches/d00-003-wpa-supplicant-override-HE-toVHT-2G.patch +++ /dev/null @@ -1,63 +0,0 @@ -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config_ssid.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/config_ssid.h -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config_ssid.h -@@ -1124,7 +1124,6 @@ struct wpa_ssid { - * FT initial mobility domain association. - */ - int ft_eap_pmksa_caching; -- - /** - * beacon_prot - Whether Beacon protection is enabled - * -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/wpa_supplicant.c -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.c -@@ -2578,16 +2578,14 @@ void ibss_mesh_setup_freq(struct wpa_sup - return; - - /* Allow HE on 2.4 GHz without VHT: see nl80211_put_freq_params() */ -- if (is_24ghz) -- freq->he_enabled = mode->he_capab[ieee80211_mode].he_supported; -+ if (is_24ghz) { - #ifdef CONFIG_HE_OVERRIDES -- if (is_24ghz && ssid->disable_he) -- freq->he_enabled = 0; -+ if (ssid->disable_he) -+ freq->he_enabled = 0; -+ else - #endif /* CONFIG_HE_OVERRIDES */ -- -- /* Setup higher BW only for 5 GHz */ -- if (mode->mode != HOSTAPD_MODE_IEEE80211A && !(ssid->noscan)) -- return; -+ freq->he_enabled = mode->he_capab[ieee80211_mode].he_supported; -+ } - - for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) { - pri_chan = &mode->channels[chan_idx]; -@@ -2677,6 +2675,11 @@ void ibss_mesh_setup_freq(struct wpa_sup - - wpa_scan_results_free(scan_res); - } -+#ifdef CONFIG_HE_OVERRIDES -+skip_vht80: -+ if (ssid->disable_he) -+ vht_freq.he_enabled = 0; -+#endif /* CONFIG_HE_OVERRIDES */ - - #ifdef CONFIG_HT_OVERRIDES - skip_ht40: -@@ -2711,6 +2714,11 @@ skip_to_6ghz: - /* Enable HE with VHT for 5 GHz */ - freq->he_enabled = mode->he_capab[ieee80211_mode].he_supported; - -+#ifdef CONFIG_HE_OVERRIDES -+ if (is_24ghz) -+ goto skip_vht80; -+#endif /* CONFIG_HE_OVERRIDES */ -+ - /* setup center_freq1, bandwidth */ - for (j = 0; j < ARRAY_SIZE(bw80); j++) { - if (freq->freq >= bw80[j] && diff --git a/feeds/ipq95xx/hostapd/patches/d00-007-fixing-warning.patch b/feeds/ipq95xx/hostapd/patches/d00-007-fixing-warning.patch deleted file mode 100644 index 814ef7bb..00000000 --- a/feeds/ipq95xx/hostapd/patches/d00-007-fixing-warning.patch +++ /dev/null @@ -1,83 +0,0 @@ -From ed93959f61e103703d04b85351eed7a1c4fe644b Mon Sep 17 00:00:00 2001 -From: Karthikeyan Kathirvel -Date: Fri, 28 Aug 2020 14:16:10 +0530 -Subject: [PATCH] hostapd: Fixed compilation warnings - -Below warnings are fixed - -Uninitialized and redefined macro warnings has been fixed - -../src/crypto/sha1-internal.c:152:0: error: "R3" redefined [-Werror] - #define R3(v,w,x,y,z,i) \ - ^ -In file included from qsdk/staging_dir/toolchain-arm_cortex-a7_gcc-5.2.0_uClibc-1.0.14_eabi/include/signal.h:358:0, -from qsdk/build_dir/target-arm_cortex-a7_uClibc-1.0.14_eabi/hostapd-supplicant-full/hostapd-2021-12-13/src/utils/includes.h:26, -from ../src/crypto/sha1-internal.c:9: -qsdk/staging_dir/toolchain-arm_cortex-a7_gcc-5.2.0_uClibc-1.0.14_eabi/include/sys/ucontext.h:49:0: -note: this is the location of the previous definition -#define R3 R3 - -Signed-off-by: Karthikeyan Kathirvel ---- - src/ap/ieee802_11.c | 2 +- - src/ap/wpa_auth.c | 4 ++++ - src/rsn_supp/wpa.c | 2 +- - 3 files changed, 6 insertions(+), 2 deletions(-) - ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -4859,7 +4859,7 @@ static int wpa_driver_nl80211_sta_add(vo - - if (params->he_capab) { - wpa_hexdump(MSG_DEBUG, " * he_capab", -- params->he_capab, params->he_capab_len); -+ (u8 *) params->he_capab, params->he_capab_len); - if (nla_put(msg, NL80211_ATTR_HE_CAPABILITY, - params->he_capab_len, params->he_capab)) - goto fail; ---- a/src/tls/tlsv1_client_ocsp.c -+++ b/src/tls/tlsv1_client_ocsp.c -@@ -322,7 +322,7 @@ tls_process_ocsp_responses(struct tlsv1_ - { - struct asn1_hdr hdr; - const u8 *pos, *end; -- enum tls_ocsp_result res; -+ enum tls_ocsp_result res = TLS_OCSP_NO_RESPONSE; - - pos = resp; - end = resp + len; ---- a/src/crypto/sha1-internal.c -+++ b/src/crypto/sha1-internal.c -@@ -141,17 +141,32 @@ A million repetitions of "a" - block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1)) - - /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ -+#ifdef R0 -+#undef R0 -+#endif - #define R0(v,w,x,y,z,i) \ - z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \ - w = rol(w, 30); -+#ifdef R1 -+#undef R1 -+#endif - #define R1(v,w,x,y,z,i) \ - z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \ - w = rol(w, 30); -+#ifdef R2 -+#undef R2 -+#endif - #define R2(v,w,x,y,z,i) \ - z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30); -+#ifdef R3 -+#undef R3 -+#endif - #define R3(v,w,x,y,z,i) \ - z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \ - w = rol(w, 30); -+#ifdef R4 -+#undef R4 -+#endif - #define R4(v,w,x,y,z,i) \ - z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \ - w=rol(w, 30); diff --git a/feeds/ipq95xx/hostapd/patches/d00-009-hostapd-update-muedca-params.patch b/feeds/ipq95xx/hostapd/patches/d00-009-hostapd-update-muedca-params.patch deleted file mode 100644 index aaa83bde..00000000 --- a/feeds/ipq95xx/hostapd/patches/d00-009-hostapd-update-muedca-params.patch +++ /dev/null @@ -1,291 +0,0 @@ ---- a/src/ap/drv_callbacks.c -+++ b/src/ap/drv_callbacks.c -@@ -1785,6 +1785,39 @@ static void hostapd_event_wds_sta_interf - ifname, MAC2STR(addr)); - } - -+static void hostapd_event_update_muedca_params(struct hostapd_data *hapd, -+ struct update_muedca *params) -+{ -+ int i; -+ u8 updated_count; -+ -+ /* Update current MU-EDCA parameters */ -+ for (i = 0; i < 3; i++) { -+ hapd->iface->conf->he_mu_edca.he_mu_ac_be_param[i] = -+ params->he_mu_ac_be_param[i]; -+ hapd->iface->conf->he_mu_edca.he_mu_ac_bk_param[i] = -+ params->he_mu_ac_bk_param[i]; -+ hapd->iface->conf->he_mu_edca.he_mu_ac_vo_param[i] = -+ params->he_mu_ac_vo_param[i]; -+ hapd->iface->conf->he_mu_edca.he_mu_ac_vi_param[i] = -+ params->he_mu_ac_vi_param[i]; -+ } -+ -+ /* Increment Parameter Set Update Count for MU-EDCA and WME EDCA only -+ * if any STA is connected -+ */ -+ if (hapd->num_sta) { -+ updated_count = (hapd->iface->conf->he_mu_edca.he_qos_info + 1) & 0xf; -+ hapd->iface->conf->he_mu_edca.he_qos_info &= 0xf0; -+ hapd->iface->conf->he_mu_edca.he_qos_info |= updated_count; -+ hapd->parameter_set_count++; -+ } -+ -+ /* Update beacon with updated MU-EDCA parameters */ -+ if (ieee802_11_update_beacons(hapd->iface)) -+ wpa_printf(MSG_DEBUG, -+ "Failed to update beacons with MU-EDCA parameters"); -+} - - #ifdef CONFIG_OWE - static int hostapd_notif_update_dh_ie(struct hostapd_data *hapd, -@@ -2093,6 +2126,9 @@ void hostapd_wpa_event(void *ctx, enum w - data->wds_sta_interface.ifname, - data->wds_sta_interface.sta_addr); - break; -+ case EVENT_UPDATE_MUEDCA_PARAMS: -+ hostapd_event_update_muedca_params(hapd, &data->update_muedca); -+ break; - default: - wpa_printf(MSG_DEBUG, "Unknown event %d", event); - break; ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -5135,6 +5135,15 @@ enum wpa_event_type { - * is required to provide more details of the frame. - */ - EVENT_UNPROT_BEACON, -+ -+ /** -+ * EVENT_UPDATE_MUEDCA_PARAMS - Updated MU-EDCA parameters received -+ * -+ * This event is emitted when updated MU-EDCA parameters from driver -+ * are received. Updated MU-EDCA parameters need to be updated in -+ * beacon. -+ */ -+ EVENT_UPDATE_MUEDCA_PARAMS, - }; - - -@@ -6027,6 +6036,16 @@ union wpa_event_data { - struct unprot_beacon { - const u8 *sa; - } unprot_beacon; -+ -+ /** -+ * struct update_muedca - Data for EVENT_UPDATE_MU_EDCA_PARAMS -+ */ -+ struct update_muedca { -+ u8 he_mu_ac_be_param[3]; -+ u8 he_mu_ac_bk_param[3]; -+ u8 he_mu_ac_vi_param[3]; -+ u8 he_mu_ac_vo_param[3]; -+ } update_muedca; - }; - - /** ---- a/src/drivers/driver_nl80211_event.c -+++ b/src/drivers/driver_nl80211_event.c -@@ -172,6 +172,8 @@ static const char * nl80211_command_to_s - C2S(NL80211_CMD_UNPROT_BEACON) - C2S(NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS) - C2S(NL80211_CMD_SET_SAR_SPECS) -+ C2S(NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS) -+ C2S(NL80211_CMD_COLOR_CHANGE) - C2S(__NL80211_CMD_AFTER_LAST) - } - #undef C2S -@@ -2797,6 +2799,35 @@ static void nl80211_sta_opmode_change_ev - wpa_supplicant_event(drv->ctx, EVENT_STATION_OPMODE_CHANGED, &ed); - } - -+static void nl80211_update_muedca_params_event(struct wpa_driver_nl80211_data *drv, -+ struct nlattr **tb) -+{ -+ struct host_update_muedca { -+ u8 mu_qos_info; -+ u8 ac_be[3]; -+ u8 ac_bk[3]; -+ u8 ac_vi[3]; -+ u8 ac_vo[3]; -+ }; -+ -+ struct host_update_muedca *rx_muedca_params; -+ union wpa_event_data ed; -+ int i; -+ -+ if (!tb[NL80211_ATTR_HE_MUEDCA_PARAMS]) -+ return; -+ -+ rx_muedca_params = nla_data(tb[NL80211_ATTR_HE_MUEDCA_PARAMS]); -+ -+ for (i = 0; i< 3; i++) { -+ ed.update_muedca.he_mu_ac_be_param[i] = rx_muedca_params->ac_be[i]; -+ ed.update_muedca.he_mu_ac_bk_param[i] = rx_muedca_params->ac_bk[i]; -+ ed.update_muedca.he_mu_ac_vi_param[i] = rx_muedca_params->ac_vi[i]; -+ ed.update_muedca.he_mu_ac_vo_param[i] = rx_muedca_params->ac_vo[i]; -+ } -+ -+ wpa_supplicant_event(drv->ctx, EVENT_UPDATE_MUEDCA_PARAMS, &ed); -+} - - static void nl80211_control_port_frame(struct wpa_driver_nl80211_data *drv, - struct nlattr **tb) -@@ -2854,7 +2885,6 @@ nl80211_control_port_frame_tx_status(str - wpa_supplicant_event(drv->ctx, EVENT_EAPOL_TX_STATUS, &event); - } - -- - static void do_process_drv_event(struct i802_bss *bss, int cmd, - struct nlattr **tb) - { -@@ -3101,6 +3131,9 @@ static void do_process_drv_event(struct - tb[NL80211_ATTR_ACK], - tb[NL80211_ATTR_COOKIE]); - break; -+ case NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS: -+ nl80211_update_muedca_params_event(drv, tb); -+ break; - default: - wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event " - "(cmd=%d)", cmd); ---- a/src/drivers/nl80211_copy.h -+++ b/src/drivers/nl80211_copy.h -@@ -1185,6 +1185,11 @@ - * passed using %NL80211_ATTR_SAR_SPEC. %NL80211_ATTR_WIPHY is used to - * specify the wiphy index to be applied to. - * -+ * @NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS: Updated MU-EDCA parameters from driver. -+ * This event is used to update MU-EDCA parameters in Beacon frame, which -+ * were indicated by driver and now need to be reflected in -+ * Beacon frame. -+ * - * @NL80211_CMD_MAX: highest used command number - * @__NL80211_CMD_AFTER_LAST: internal use - */ -@@ -1417,6 +1422,7 @@ enum nl80211_commands { - - NL80211_CMD_SET_SAR_SPECS, - -+ NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS, - /* add new commands above here */ - - /* used to define NL80211_CMD_MAX below */ -@@ -2560,6 +2566,9 @@ enum nl80211_commands { - * disassoc events to indicate that an immediate reconnect to the AP - * is desired. - * -+ * @NL80211_ATTR_HE_MUEDCA_PARAMS: MU-EDCA AC parameters for the -+ NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS command. -+ * - * @NUM_NL80211_ATTR: total number of nl80211_attrs available - * @NL80211_ATTR_MAX: highest attribute number currently defined - * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -3057,6 +3066,7 @@ enum nl80211_attrs { - - NL80211_ATTR_DISABLE_HE, - -+ NL80211_ATTR_HE_MUEDCA_PARAMS, - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, ---- a/src/drivers/driver_common.c -+++ b/src/drivers/driver_common.c -@@ -90,6 +90,7 @@ const char * event_to_string(enum wpa_ev - E2S(WDS_STA_INTERFACE_STATUS); - E2S(UPDATE_DH); - E2S(UNPROT_BEACON); -+ E2S(UPDATE_MUEDCA_PARAMS); - } - - return "UNKNOWN"; ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -3585,6 +3585,10 @@ static int hostapd_fill_csa_settings(str - hapd->cs_count = settings->cs_count; - hapd->cs_block_tx = settings->block_tx; - -+ /* reset MU-EDCA and WME EDCA parameter set count */ -+ hapd->iface->conf->he_mu_edca.he_qos_info &= 0xfff0; -+ hapd->parameter_set_count = 0; -+ - ret = hostapd_build_beacon_data(hapd, &settings->beacon_csa); - if (ret) { - free_beacon_data(&settings->beacon_after); ---- a/hostapd/ctrl_iface.c -+++ b/hostapd/ctrl_iface.c -@@ -1545,6 +1545,11 @@ static int hostapd_ctrl_iface_set(struct - } else if (os_strncmp(cmd, "wme_ac_", 7) == 0 || - os_strncmp(cmd, "wmm_ac_", 7) == 0) { - hapd->parameter_set_count++; -+ /* Incrementing MU-EDCA Parameter Set Update Count*/ -+ hapd->iface->conf->he_mu_edca.he_qos_info = -+ (hapd->iface->conf->he_mu_edca.he_qos_info & 0xf0) | -+ ((hapd->iface->conf->he_mu_edca.he_qos_info + 1) & -+ 0xf); - if (ieee802_11_update_beacons(hapd->iface)) - wpa_printf(MSG_DEBUG, - "Failed to update beacons with WMM parameters"); ---- a/src/ap/wmm.c -+++ b/src/ap/wmm.c -@@ -68,8 +68,8 @@ wmm_set_regulatory_limit(const struct ho - /* - * Calculate WMM regulatory limit if any. - */ --static void wmm_calc_regulatory_limit(struct hostapd_data *hapd, -- struct hostapd_wmm_ac_params *acp) -+void wmm_calc_regulatory_limit(struct hostapd_data *hapd, -+ struct hostapd_wmm_ac_params *acp) - { - struct hostapd_hw_modes *mode = hapd->iface->current_mode; - int c; -@@ -98,6 +98,10 @@ static void wmm_calc_regulatory_limit(st - os_memcpy(hapd->iface->prev_wmm, acp, - sizeof(hapd->iconf->wmm_ac_params)); - hapd->parameter_set_count++; -+ /* Incrementing MU-EDCA Parameter Set Update Count*/ -+ hapd->iface->conf->he_mu_edca.he_qos_info = -+ (hapd->iface->conf->he_mu_edca.he_qos_info & 0xf0) | -+ ((hapd->iface->conf->he_mu_edca.he_qos_info + 1) & 0xf); - } - } - ---- a/src/ap/ieee802_11_he.c -+++ b/src/ap/ieee802_11_he.c -@@ -18,6 +18,7 @@ - #include "sta_info.h" - #include "ieee802_11.h" - #include "dfs.h" -+#include "wmm.h" - - static u8 ieee80211_he_ppet_size(u8 ppe_thres_hdr, const u8 *phy_cap_info) - { -@@ -266,9 +267,16 @@ u8 * hostapd_eid_he_operation(struct hos - u8 * hostapd_eid_he_mu_edca_parameter_set(struct hostapd_data *hapd, u8 *eid) - { - struct ieee80211_he_mu_edca_parameter_set *edca; -+ struct hostapd_wmm_ac_params wmmp[WMM_AC_NUM]; - u8 *pos; - size_t i; - -+ /* Updating WME Parameter Set Count to avoid mismatch */ -+ os_memset(wmmp, 0, sizeof(wmmp)); -+ -+ if (hapd->conf->wmm_enabled) -+ wmm_calc_regulatory_limit(hapd, wmmp); -+ - pos = (u8 *) &hapd->iface->conf->he_mu_edca; - for (i = 0; i < sizeof(*edca); i++) { - if (pos[i]) ---- a/src/ap/wmm.h -+++ b/src/ap/wmm.h -@@ -13,6 +13,8 @@ - struct ieee80211_mgmt; - struct wmm_tspec_element; - -+void wmm_calc_regulatory_limit(struct hostapd_data *hapd, -+ struct hostapd_wmm_ac_params *acp); - u8 * hostapd_eid_wmm(struct hostapd_data *hapd, u8 *eid); - int hostapd_eid_wmm_valid(struct hostapd_data *hapd, const u8 *eid, - size_t len); diff --git a/feeds/ipq95xx/hostapd/patches/e00-003-hostapd-chan-switch-6ghz.patch b/feeds/ipq95xx/hostapd/patches/e00-003-hostapd-chan-switch-6ghz.patch deleted file mode 100644 index 485f313f..00000000 --- a/feeds/ipq95xx/hostapd/patches/e00-003-hostapd-chan-switch-6ghz.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 917653b0674dfacc976e20956e999fef13c6e6ba Mon Sep 17 00:00:00 2001 -From: Muna Sinada -Date: Wed, 29 Jul 2020 09:41:31 -0700 -Subject: [PATCH] hostapd:remove 11A specific case to allow for 6 GHz - -With 6 GHz utilizing 11A/HE, frequency to channel conversions needed -to accomedate for 6 GHz frequencies in hostapd_event_ch_switch. Removed -5 GHz specific conversions for the 11A case due to incorrect 6 GHz -frequencies being incorrectly being converted in -hostapd_event_ch_switch - -Signed-off-by: Muna Sinada ---- - src/ap/drv_callbacks.c | 14 ++------------ - 1 file changed, 2 insertions(+), 12 deletions(-) - ---- a/src/ap/drv_callbacks.c -+++ b/src/ap/drv_callbacks.c -@@ -876,7 +876,7 @@ void hostapd_event_ch_switch(struct host - { - #ifdef NEED_AP_MLME - int channel, chwidth, is_dfs; -- u8 seg0_idx = 0, seg1_idx = 0; -+ u8 seg0_idx = 0, seg1_idx = 0, op_class; - size_t i; - - hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, -@@ -922,27 +922,8 @@ void hostapd_event_ch_switch(struct host - break; - } - -- switch (hapd->iface->current_mode->mode) { -- case HOSTAPD_MODE_IEEE80211A: -- if (cf1 == 5935) -- seg0_idx = (cf1 - 5925) / 5; -- else if (cf1 > 5950) -- seg0_idx = (cf1 - 5950) / 5; -- else if (cf1 > 5000) -- seg0_idx = (cf1 - 5000) / 5; -- -- if (cf2 == 5935) -- seg1_idx = (cf2 - 5925) / 5; -- else if (cf2 > 5950) -- seg1_idx = (cf2 - 5950) / 5; -- else if (cf2 > 5000) -- seg1_idx = (cf2 - 5000) / 5; -- break; -- default: -- ieee80211_freq_to_chan(cf1, &seg0_idx); -- ieee80211_freq_to_chan(cf2, &seg1_idx); -- break; -- } -+ ieee80211_freq_to_channel_ext(cf1, offset, chwidth, &op_class, &seg0_idx); -+ ieee80211_freq_to_chan(cf2, &seg1_idx); - - hapd->iconf->channel = channel; - hapd->iconf->ieee80211n = ht; -@@ -977,6 +958,7 @@ void hostapd_event_ch_switch(struct host - hostapd_set_oper_chwidth(hapd->iconf, chwidth); - hostapd_set_oper_centr_freq_seg0_idx(hapd->iconf, seg0_idx); - hostapd_set_oper_centr_freq_seg1_idx(hapd->iconf, seg1_idx); -+ hapd->iconf->op_class = op_class; - if (hapd->iconf->ieee80211ac) { - hapd->iconf->vht_capab &= ~VHT_CAP_SUPP_CHAN_WIDTH_MASK; - if (chwidth == CHANWIDTH_160MHZ) diff --git a/feeds/ipq95xx/hostapd/patches/e00-014-hostapd-update-cfs0-and-cfs1-for-160MHz.patch b/feeds/ipq95xx/hostapd/patches/e00-014-hostapd-update-cfs0-and-cfs1-for-160MHz.patch deleted file mode 100644 index 9a03c58c..00000000 --- a/feeds/ipq95xx/hostapd/patches/e00-014-hostapd-update-cfs0-and-cfs1-for-160MHz.patch +++ /dev/null @@ -1,142 +0,0 @@ -From d4c4ef302f98fd6bce173b8636e7e350d8b44981 Mon Sep 17 00:00:00 2001 -From: P Praneesh -Date: Fri, 19 Mar 2021 12:17:27 +0530 -Subject: [PATCH] hostapd: update cfs0 and cfs1 for 160MHz - -As per standard Draft P802.11ax_D8.0,( Table 26-9—Setting -of the VHT Channel Width and VHT NSS at an HE STA -transmitting the OM Control subfield ), center frequency of -160MHz should be published in HT information subset 2 of -HT information when EXT NSS BW field is enabled. - -If the supported number of NSS in 160MHz is at least max NSS -support, then center_freq_seg0 indicates the center frequency of 80MHz and -center_freq_seg1 indicates the center frequency of 160MHz. - -If the supported number of NSS in 160MHz is less than max NSS -support, then center_freq_seg0 indicates the center frequency of 80MHz and -center_freq_seg1 is 0. The center frequency of 160MHz is published in HT -operation information element instead. - -Signed-off-by: P Praneesh ---- - hostapd/config_file.c | 2 ++ - src/ap/ieee802_11_ht.c | 7 +++++++ - src/ap/ieee802_11_vht.c | 16 ++++++++++++++++ - src/common/hw_features_common.c | 1 + - src/common/ieee802_11_defs.h | 1 + - 5 files changed, 27 insertions(+) - ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -1195,6 +1195,8 @@ static int hostapd_config_vht_capab(stru - conf->vht_capab |= VHT_CAP_RX_ANTENNA_PATTERN; - if (os_strstr(capab, "[TX-ANTENNA-PATTERN]")) - conf->vht_capab |= VHT_CAP_TX_ANTENNA_PATTERN; -+ if (os_strstr(capab, "[EXT-NSS-BW-SUPP]")) -+ conf->vht_capab |= VHT_CAP_EXTENDED_NSS_BW_SUPPORT; - return 0; - } - #endif /* CONFIG_IEEE80211AC */ ---- a/src/ap/ieee802_11_ht.c -+++ b/src/ap/ieee802_11_ht.c -@@ -82,7 +82,9 @@ u8 * hostapd_eid_ht_capabilities(struct - u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid) - { - struct ieee80211_ht_operation *oper; -+ le32 vht_capabilities_info; - u8 *pos = eid; -+ u8 chwidth; - - if (!hapd->iconf->ieee80211n || hapd->conf->disable_11n || - is_6ghz_op_class(hapd->iconf->op_class)) -@@ -103,6 +105,13 @@ u8 * hostapd_eid_ht_operation(struct hos - oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW | - HT_INFO_HT_PARAM_STA_CHNL_WIDTH; - -+ vht_capabilities_info = host_to_le32(hapd->iface->current_mode->vht_capab); -+ chwidth = hostapd_get_oper_chwidth(hapd->iconf); -+ if (vht_capabilities_info & VHT_CAP_EXTENDED_NSS_BW_SUPPORT -+ && ((chwidth == CHANWIDTH_160MHZ) || (chwidth == CHANWIDTH_80P80MHZ))) { -+ oper->operation_mode = host_to_le16(hapd->iconf->vht_oper_centr_freq_seg0_idx << 5); -+ } -+ - pos += sizeof(*oper); - - return pos; ---- a/src/ap/ieee802_11_vht.c -+++ b/src/ap/ieee802_11_vht.c -@@ -25,6 +25,7 @@ u8 * hostapd_eid_vht_capabilities(struct - struct ieee80211_vht_capabilities *cap; - struct hostapd_hw_modes *mode = hapd->iface->current_mode; - u8 *pos = eid; -+ u8 chwidth; - - if (!mode || is_6ghz_op_class(hapd->iconf->op_class)) - return eid; -@@ -62,6 +63,17 @@ u8 * hostapd_eid_vht_capabilities(struct - host_to_le32(nsts << VHT_CAP_BEAMFORMEE_STS_OFFSET); - } - -+ chwidth = hostapd_get_oper_chwidth(hapd->iconf); -+ if (((host_to_le32(mode->vht_capab)) & VHT_CAP_EXTENDED_NSS_BW_SUPPORT) -+ && ((chwidth == CHANWIDTH_160MHZ) || (chwidth == CHANWIDTH_80P80MHZ))) { -+ cap->vht_capabilities_info |= VHT_CAP_EXTENDED_NSS_BW_SUPPORT; -+ cap->vht_capabilities_info &= ~(host_to_le32(VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)); -+ cap->vht_capabilities_info &= ~(host_to_le32(VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)); -+ cap->vht_capabilities_info &= ~(host_to_le32(VHT_CAP_SUPP_CHAN_WIDTH_MASK)); -+ } else { -+ cap->vht_capabilities_info &= ~VHT_CAP_EXTENDED_NSS_BW_SUPPORT_MASK; -+ } -+ - /* Supported MCS set comes from hw */ - os_memcpy(&cap->vht_supported_mcs_set, mode->vht_mcs_set, 8); - -@@ -74,6 +86,7 @@ u8 * hostapd_eid_vht_capabilities(struct - u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid) - { - struct ieee80211_vht_operation *oper; -+ le32 vht_capabilities_info; - u8 *pos = eid; - - if (is_6ghz_op_class(hapd->iconf->op_class)) -@@ -96,6 +109,7 @@ u8 * hostapd_eid_vht_operation(struct ho - hapd->iconf->vht_oper_centr_freq_seg1_idx; - - oper->vht_op_info_chwidth = hapd->iconf->vht_oper_chwidth; -+ vht_capabilities_info = host_to_le32(hapd->iface->current_mode->vht_capab); - if (hapd->iconf->vht_oper_chwidth == 2) { - /* - * Convert 160 MHz channel width to new style as interop -@@ -109,6 +123,10 @@ u8 * hostapd_eid_vht_operation(struct ho - oper->vht_op_info_chan_center_freq_seg0_idx -= 8; - else - oper->vht_op_info_chan_center_freq_seg0_idx += 8; -+ -+ if (vht_capabilities_info & VHT_CAP_EXTENDED_NSS_BW_SUPPORT) -+ oper->vht_op_info_chan_center_freq_seg1_idx = 0; -+ - } else if (hapd->iconf->vht_oper_chwidth == 3) { - /* - * Convert 80+80 MHz channel width to new style as interop ---- a/src/common/hw_features_common.c -+++ b/src/common/hw_features_common.c -@@ -740,6 +740,7 @@ int ieee80211ac_cap_check(u32 hw, u32 co - VHT_CAP_CHECK(VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB); - VHT_CAP_CHECK(VHT_CAP_RX_ANTENNA_PATTERN); - VHT_CAP_CHECK(VHT_CAP_TX_ANTENNA_PATTERN); -+ VHT_CAP_CHECK(VHT_CAP_EXTENDED_NSS_BW_SUPPORT); - - #undef VHT_CAP_CHECK - #undef VHT_CAP_CHECK_MAX ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -1304,6 +1304,8 @@ struct ieee80211_ampe_ie { - #define VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB ((u32) BIT(26) | BIT(27)) - #define VHT_CAP_RX_ANTENNA_PATTERN ((u32) BIT(28)) - #define VHT_CAP_TX_ANTENNA_PATTERN ((u32) BIT(29)) -+#define VHT_CAP_EXTENDED_NSS_BW_SUPPORT ((u32) BIT(30)) -+#define VHT_CAP_EXTENDED_NSS_BW_SUPPORT_MASK ((u32) BIT(30) | BIT(31)) - - #define VHT_OPMODE_CHANNEL_WIDTH_MASK ((u8) BIT(0) | BIT(1)) - #define VHT_OPMODE_CHANNEL_RxNSS_MASK ((u8) BIT(4) | BIT(5) | \ diff --git a/feeds/ipq95xx/hostapd/patches/f00-001-bss-coloring-add-support-for-handling-collision-events-and-triggering-CCA.patch b/feeds/ipq95xx/hostapd/patches/f00-001-bss-coloring-add-support-for-handling-collision-events-and-triggering-CCA.patch deleted file mode 100644 index eca54597..00000000 --- a/feeds/ipq95xx/hostapd/patches/f00-001-bss-coloring-add-support-for-handling-collision-events-and-triggering-CCA.patch +++ /dev/null @@ -1,278 +0,0 @@ -From: John Crispin -Subject: [PATCH V4 1/6] bss coloring: add support for handling collision - events and triggering CCA -Date: Wed, 26 Aug 2020 08:22:11 +0200 - -Add the core code for handling bss color collision events and triggering -CCA inside the kernel. - -Signed-off-by: John Crispin ---- - src/ap/ap_drv_ops.h | 12 ++++ - src/ap/hostapd.c | 119 +++++++++++++++++++++++++++++++++++ - src/ap/hostapd.h | 16 +++++ - src/common/ieee802_11_defs.h | 6 ++ - src/drivers/driver.h | 31 +++++++++ - 5 files changed, 184 insertions(+) - ---- a/src/ap/ap_drv_ops.h -+++ b/src/ap/ap_drv_ops.h -@@ -299,6 +299,18 @@ static inline int hostapd_drv_switch_cha - return hapd->driver->switch_channel(hapd->drv_priv, settings); - } - -+#ifdef CONFIG_IEEE80211AX -+static inline int hostapd_drv_switch_color(struct hostapd_data *hapd, -+ struct cca_settings *settings) -+{ -+ if (hapd->driver == NULL || hapd->driver->switch_color == NULL || -+ hapd->drv_priv == NULL) -+ return -1; -+ -+ return hapd->driver->switch_color(hapd->drv_priv, settings); -+} -+#endif -+ - static inline int hostapd_drv_status(struct hostapd_data *hapd, char *buf, - size_t buflen) - { ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -65,6 +65,8 @@ static int setup_interface2(struct hosta - static void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx); - static void hostapd_interface_setup_failure_handler(void *eloop_ctx, - void *timeout_ctx); -+static void -+hostapd_switch_color_timeout_handler(void *eloop_data, void *user_ctx); - - - int hostapd_for_each_interface(struct hapd_interfaces *interfaces, -@@ -476,6 +478,9 @@ static void hostapd_free_hapd_data(struc - } - eloop_cancel_timeout(auth_sae_process_commit, hapd, NULL); - #endif /* CONFIG_SAE */ -+#ifdef CONFIG_IEEE80211AX -+ eloop_cancel_timeout(hostapd_switch_color_timeout_handler, hapd, NULL); -+#endif - } - - -@@ -3713,6 +3718,119 @@ hostapd_switch_channel_fallback(struct h - hostapd_enable_iface(iface); - } - -+ -+#ifdef CONFIG_IEEE80211AX -+void hostapd_cleanup_cca_params(struct hostapd_data *hapd) -+{ -+ hapd->cca_count = 0; -+ hapd->cca_color = 0; -+ hapd->cca_c_off_beacon = 0; -+ hapd->cca_c_off_proberesp = 0; -+ hapd->cca_in_progress = 0; -+} -+ -+ -+static int hostapd_fill_cca_settings(struct hostapd_data *hapd, -+ struct cca_settings *settings) -+{ -+ struct hostapd_iface *iface = hapd->iface; -+ u8 old_color; -+ int ret; -+ -+ if (!iface || iface->conf->he_op.he_bss_color_disabled) -+ return -1; -+ -+ old_color = iface->conf->he_op.he_bss_color; -+ iface->conf->he_op.he_bss_color = hapd->cca_color; -+ ret = hostapd_build_beacon_data(hapd, &settings->beacon_after); -+ iface->conf->he_op.he_bss_color = old_color; -+ -+ settings->cca_count = hapd->cca_count; -+ settings->cca_color = hapd->cca_color, -+ hapd->cca_in_progress = 1; -+ -+ ret = hostapd_build_beacon_data(hapd, &settings->beacon_cca); -+ if (ret) { -+ free_beacon_data(&settings->beacon_after); -+ return ret; -+ } -+ -+ settings->counter_offset_beacon = hapd->cca_c_off_beacon; -+ settings->counter_offset_presp = hapd->cca_c_off_proberesp; -+ -+ return 0; -+} -+ -+ -+static void -+hostapd_switch_color_timeout_handler(void *eloop_data, void *user_ctx) -+{ -+ struct hostapd_data *hapd = (struct hostapd_data *) eloop_data; -+ struct cca_settings settings; -+ struct os_time now; -+ int i, r, b, ret; -+ -+ if (os_get_time(&now)) -+ return; -+ -+ /* check if there has been a recent collision */ -+ if (now.sec - hapd->last_color_collision.sec > 50) -+ return; -+ -+ r = os_random() % HE_OPERATION_BSS_COLOR_MAX; -+ for (i = 0; i < HE_OPERATION_BSS_COLOR_MAX; i++) { -+ if (r && (hapd->color_collision_bitmap & (1 << r)) == 0) -+ break; -+ r = (r + 1) % HE_OPERATION_BSS_COLOR_MAX; -+ } -+ if (i == HE_OPERATION_BSS_COLOR_MAX) { -+ /* there are no free colors so turn bss coloring off */ -+ wpa_printf(MSG_INFO, "no free colors left, turning of BSS coloring"); -+ hapd->iface->conf->he_op.he_bss_color_disabled = 1; -+ for (b = 0; b < hapd->iface->num_bss; b++) -+ ieee802_11_set_beacon(hapd->iface->bss[b]); -+ return; -+ } -+ -+ for (b = 0; b < hapd->iface->num_bss; b++) { -+ struct hostapd_data *bss = hapd->iface->bss[b]; -+ -+ hostapd_cleanup_cca_params(bss); -+ bss->cca_color = r; -+ bss->cca_count = 10; -+ -+ if (hostapd_fill_cca_settings(bss, &settings)) { -+ hostapd_cleanup_cca_params(bss); -+ continue; -+ } -+ -+ ret = hostapd_drv_switch_color(bss, &settings); -+ free_beacon_data(&settings.beacon_cca); -+ free_beacon_data(&settings.beacon_after); -+ -+ if (ret) -+ hostapd_cleanup_cca_params(bss); -+ } -+} -+ -+ -+void -+hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap) -+{ -+ if (hapd->cca_in_progress) -+ return; -+ -+ if (os_get_time(&hapd->last_color_collision)) -+ return; -+ -+ hapd->color_collision_bitmap = bitmap; -+ -+ if (!eloop_is_timeout_registered(hostapd_switch_color_timeout_handler, hapd, NULL)) -+ eloop_register_timeout(DOT11BSS_COLOR_COLLISION_AP_PERIOD, 0, -+ hostapd_switch_color_timeout_handler, hapd, NULL); -+} -+#endif -+ - #endif /* NEED_AP_MLME */ - - ---- a/src/ap/hostapd.h -+++ b/src/ap/hostapd.h -@@ -296,6 +296,16 @@ struct hostapd_data { - unsigned int cs_c_off_ecsa_beacon; - unsigned int cs_c_off_ecsa_proberesp; - -+#ifdef CONFIG_IEEE80211AX -+ int cca_in_progress; -+ u8 cca_count; -+ u8 cca_color; -+ unsigned int cca_c_off_beacon; -+ unsigned int cca_c_off_proberesp; -+ struct os_time last_color_collision; -+ u64 color_collision_bitmap; -+#endif -+ - #ifdef CONFIG_P2P - struct p2p_data *p2p; - struct p2p_group *p2p_group; -@@ -642,6 +652,12 @@ void hostapd_periodic_iface(struct hosta - int hostapd_owe_trans_get_info(struct hostapd_data *hapd); - void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx); - -+ -+#ifdef CONFIG_IEEE80211AX -+void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap); -+void hostapd_cleanup_cca_params(struct hostapd_data *hapd); -+#endif -+ - /* utils.c */ - int hostapd_register_probereq_cb(struct hostapd_data *hapd, - int (*cb)(void *ctx, const u8 *sa, ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -2280,6 +2280,7 @@ struct ieee80211_spatial_reuse { - #define HE_OPERATION_BSS_COLOR_PARTIAL ((u32) BIT(30)) - #define HE_OPERATION_BSS_COLOR_DISABLED ((u32) BIT(31)) - #define HE_OPERATION_BSS_COLOR_OFFSET 24 -+#define HE_OPERATION_BSS_COLOR_MAX 64 - - /* Spatial Reuse defines */ - #define SPATIAL_REUSE_SRP_DISALLOWED BIT(0) -@@ -2430,4 +2431,9 @@ enum mscs_description_subelem { - #define TBTT_BSS_PARAM_CO_LOCATED BIT(6) - #define TBTT_PSD_MAX_TXPOWER 255 /* dBm */ - -+/* IEEE802.11/D6.0 - 26.17.3.5.1 -+ * the minimum default timeout between color collision and color change is defined as 50s -+ */ -+#define DOT11BSS_COLOR_COLLISION_AP_PERIOD 50 -+ - #endif /* IEEE802_11_DEFS_H */ ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -2417,6 +2417,26 @@ struct csa_settings { - u16 counter_offset_presp[2]; - }; - -+/** -+ * struct cca_settings - Settings for color switch command -+ * @cca_count: Count in Beacon frames (TBTT) to perform the switch -+ * @cca_color: The new color that we are switching to -+ * @beacon_cca: Beacon/probe resp/asooc resp info for color switch period -+ * @beacon_after: Next beacon/probe resp/asooc resp info -+ * @counter_offset_beacon: Offset to the count field in beacon's tail -+ * @counter_offset_presp: Offset to the count field in probe resp. -+ */ -+struct cca_settings { -+ u8 cca_count; -+ u8 cca_color; -+ -+ struct beacon_data beacon_cca; -+ struct beacon_data beacon_after; -+ -+ u16 counter_offset_beacon; -+ u16 counter_offset_presp; -+}; -+ - /* TDLS peer capabilities for send_tdls_mgmt() */ - enum tdls_peer_capability { - TDLS_PEER_HT = BIT(0), -@@ -3989,6 +4009,17 @@ struct wpa_driver_ops { - int (*switch_channel)(void *priv, struct csa_settings *settings); - - /** -+ * switch_color - Announce color switch and migrate the BSS to the -+ * given color -+ * @priv: Private driver interface data -+ * @settings: Settings for CCA period and new color -+ * Returns: 0 on success, -1 on failure -+ * -+ * This function is used to move the BSS to its new color. -+ */ -+ int (*switch_color)(void *priv, struct cca_settings *settings); -+ -+ /** - * add_tx_ts - Add traffic stream - * @priv: Private driver interface data - * @tsid: Traffic stream ID diff --git a/feeds/ipq95xx/hostapd/patches/f00-002-bss_coloring-add-the-code-required-to-generate-the-CCA-IE.patch b/feeds/ipq95xx/hostapd/patches/f00-002-bss_coloring-add-the-code-required-to-generate-the-CCA-IE.patch deleted file mode 100644 index 1075b914..00000000 --- a/feeds/ipq95xx/hostapd/patches/f00-002-bss_coloring-add-the-code-required-to-generate-the-CCA-IE.patch +++ /dev/null @@ -1,104 +0,0 @@ -From: John Crispin -Subject: [PATCH V4 2/6] bss_coloring: add the code required to generate the - CCA IE -Date: Wed, 26 Aug 2020 08:22:12 +0200 - - -This IE is similar to the CSA one. It contains a counter and the target -color. Once the counter expired, the change to the new color happens. - -Signed-off-by: John Crispin ---- - src/ap/beacon.c | 12 ++++++++++++ - src/ap/ieee802_11.h | 1 + - src/ap/ieee802_11_he.c | 14 ++++++++++++++ - src/common/ieee802_11_defs.h | 1 + - 4 files changed, 28 insertions(+) - -Index: hostapd-2021-02-08/src/ap/beacon.c -=================================================================== ---- hostapd-2021-02-08.orig/src/ap/beacon.c -+++ hostapd-2021-02-08/src/ap/beacon.c -@@ -592,11 +592,17 @@ static u8 * hostapd_gen_probe_resp(struc - - #ifdef CONFIG_IEEE80211AX - if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) { -+ u8 *cca_pos; -+ - pos = hostapd_eid_he_capab(hapd, pos, IEEE80211_MODE_AP); - pos = hostapd_eid_he_operation(hapd, pos); - pos = hostapd_eid_spatial_reuse(hapd, pos); - pos = hostapd_eid_he_mu_edca_parameter_set(hapd, pos); - pos = hostapd_eid_he_6ghz_band_cap(hapd, pos); -+ cca_pos = hostapd_eid_cca(hapd, pos); -+ if (cca_pos != pos) -+ hapd->cca_c_off_proberesp = cca_pos - (u8 *) resp - 2; -+ pos = cca_pos; - } - #endif /* CONFIG_IEEE80211AX */ - -@@ -1646,12 +1652,18 @@ int ieee802_11_build_ap_params(struct ho - - #ifdef CONFIG_IEEE80211AX - if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) { -+ u8 *cca_pos; -+ - tailpos = hostapd_eid_he_capab(hapd, tailpos, - IEEE80211_MODE_AP); - tailpos = hostapd_eid_he_operation(hapd, tailpos); - tailpos = hostapd_eid_spatial_reuse(hapd, tailpos); - tailpos = hostapd_eid_he_mu_edca_parameter_set(hapd, tailpos); - tailpos = hostapd_eid_he_6ghz_band_cap(hapd, tailpos); -+ cca_pos = hostapd_eid_cca(hapd, tailpos); -+ if (cca_pos != tailpos) -+ hapd->cca_c_off_beacon = cca_pos - tail - 2; -+ tailpos = cca_pos; - } - #endif /* CONFIG_IEEE80211AX */ - -Index: hostapd-2021-02-08/src/ap/ieee802_11.h -=================================================================== ---- hostapd-2021-02-08.orig/src/ap/ieee802_11.h -+++ hostapd-2021-02-08/src/ap/ieee802_11.h -@@ -100,6 +100,7 @@ u16 copy_sta_he_6ghz_capab(struct hostap - const u8 *he_6ghz_capab); - int hostapd_get_he_twt_responder(struct hostapd_data *hapd, - enum ieee80211_op_mode mode); -+u8 * hostapd_eid_cca(struct hostapd_data *hapd, u8 *eid); - void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr, - const u8 *buf, size_t len, int ack); - void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst, -Index: hostapd-2021-02-08/src/ap/ieee802_11_he.c -=================================================================== ---- hostapd-2021-02-08.orig/src/ap/ieee802_11_he.c -+++ hostapd-2021-02-08/src/ap/ieee802_11_he.c -@@ -521,3 +521,17 @@ int hostapd_get_he_twt_responder(struct - - return !!(mac_cap[HE_MAC_CAPAB_0] & HE_MACCAP_TWT_RESPONDER); - } -+ -+ -+u8 * hostapd_eid_cca(struct hostapd_data *hapd, u8 *eid) -+{ -+ if (!hapd->cca_in_progress) -+ return eid; -+ *eid++ = WLAN_EID_EXTENSION; -+ *eid++ = 3; -+ *eid++ = WLAN_EID_EXT_COLOR_CHANGE_ANNOUNCEMENT; -+ *eid++ = hapd->cca_count; -+ *eid++ = hapd->cca_color; -+ -+ return eid; -+} -Index: hostapd-2021-02-08/src/common/ieee802_11_defs.h -=================================================================== ---- hostapd-2021-02-08.orig/src/common/ieee802_11_defs.h -+++ hostapd-2021-02-08/src/common/ieee802_11_defs.h -@@ -480,6 +480,7 @@ - #define WLAN_EID_EXT_HE_OPERATION 36 - #define WLAN_EID_EXT_HE_MU_EDCA_PARAMS 38 - #define WLAN_EID_EXT_SPATIAL_REUSE 39 -+#define WLAN_EID_EXT_COLOR_CHANGE_ANNOUNCEMENT 42 - #define WLAN_EID_EXT_OCV_OCI 54 - #define WLAN_EID_EXT_SHORT_SSID_LIST 58 - #define WLAN_EID_EXT_HE_6GHZ_BAND_CAP 59 diff --git a/feeds/ipq95xx/hostapd/patches/f00-002-hostap-Move-acl-related-code-to-generic-to-be-used-for-mesh.patch b/feeds/ipq95xx/hostapd/patches/f00-002-hostap-Move-acl-related-code-to-generic-to-be-used-for-mesh.patch deleted file mode 100644 index 4f160f28..00000000 --- a/feeds/ipq95xx/hostapd/patches/f00-002-hostap-Move-acl-related-code-to-generic-to-be-used-for-mesh.patch +++ /dev/null @@ -1,603 +0,0 @@ -From 171c96df407c45e94d1fe8afd44ca6cc3a191157 Mon Sep 17 00:00:00 2001 -From: Nishant Pandey -Date: Tue, 22 Sep 2020 14:15:36 +0530 -Subject: [PATCH] hostap: Move ACL configuration callback to generic - -Move ACL configuration support callbacks to generic -place so that it can be utilized for mesh functionality. -No functional change as such made in this patch - -Signed-off-by: Nishant Pandey ---- - hostapd/config_file.c | 119 +----------------------------------- - hostapd/config_file.h | 5 -- - hostapd/ctrl_iface.c | 111 ---------------------------------- - src/ap/ctrl_iface_ap.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++++ - src/ap/ctrl_iface_ap.h | 10 ++++ - src/ap/ieee802_11.c | 81 +++++++++++++++++++++++++ - src/ap/ieee802_11.h | 9 +++ - 7 files changed, 260 insertions(+), 234 deletions(-) - ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -23,6 +23,7 @@ - #include "radius/radius_client.h" - #include "ap/wpa_auth.h" - #include "ap/ap_config.h" -+#include "ap/ieee802_11.h" - #include "config_file.h" - - -@@ -118,124 +119,6 @@ static int hostapd_config_read_vlan_file - #endif /* CONFIG_NO_VLAN */ - - --int hostapd_acl_comp(const void *a, const void *b) --{ -- const struct mac_acl_entry *aa = a; -- const struct mac_acl_entry *bb = b; -- return os_memcmp(aa->addr, bb->addr, sizeof(macaddr)); --} -- -- --int hostapd_add_acl_maclist(struct mac_acl_entry **acl, int *num, -- int vlan_id, const u8 *addr) --{ -- struct mac_acl_entry *newacl; -- -- newacl = os_realloc_array(*acl, *num + 1, sizeof(**acl)); -- if (!newacl) { -- wpa_printf(MSG_ERROR, "MAC list reallocation failed"); -- return -1; -- } -- -- *acl = newacl; -- os_memcpy((*acl)[*num].addr, addr, ETH_ALEN); -- os_memset(&(*acl)[*num].vlan_id, 0, sizeof((*acl)[*num].vlan_id)); -- (*acl)[*num].vlan_id.untagged = vlan_id; -- (*acl)[*num].vlan_id.notempty = !!vlan_id; -- (*num)++; -- -- return 0; --} -- -- --void hostapd_remove_acl_mac(struct mac_acl_entry **acl, int *num, -- const u8 *addr) --{ -- int i = 0; -- -- while (i < *num) { -- if (os_memcmp((*acl)[i].addr, addr, ETH_ALEN) == 0) { -- os_remove_in_array(*acl, *num, sizeof(**acl), i); -- (*num)--; -- } else { -- i++; -- } -- } --} -- -- --static int hostapd_config_read_maclist(const char *fname, -- struct mac_acl_entry **acl, int *num) --{ -- FILE *f; -- char buf[128], *pos; -- int line = 0; -- u8 addr[ETH_ALEN]; -- int vlan_id; -- -- f = fopen(fname, "r"); -- if (!f) { -- wpa_printf(MSG_ERROR, "MAC list file '%s' not found.", fname); -- return -1; -- } -- -- while (fgets(buf, sizeof(buf), f)) { -- int rem = 0; -- -- line++; -- -- if (buf[0] == '#') -- continue; -- pos = buf; -- while (*pos != '\0') { -- if (*pos == '\n') { -- *pos = '\0'; -- break; -- } -- pos++; -- } -- if (buf[0] == '\0') -- continue; -- pos = buf; -- if (buf[0] == '-') { -- rem = 1; -- pos++; -- } -- -- if (hwaddr_aton(pos, addr)) { -- wpa_printf(MSG_ERROR, "Invalid MAC address '%s' at " -- "line %d in '%s'", pos, line, fname); -- fclose(f); -- return -1; -- } -- -- if (rem) { -- hostapd_remove_acl_mac(acl, num, addr); -- continue; -- } -- vlan_id = 0; -- pos = buf; -- while (*pos != '\0' && *pos != ' ' && *pos != '\t') -- pos++; -- while (*pos == ' ' || *pos == '\t') -- pos++; -- if (*pos != '\0') -- vlan_id = atoi(pos); -- -- if (hostapd_add_acl_maclist(acl, num, vlan_id, addr) < 0) { -- fclose(f); -- return -1; -- } -- } -- -- fclose(f); -- -- if (*acl) -- qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp); -- -- return 0; --} -- - - #ifdef EAP_SERVER - ---- a/hostapd/config_file.h -+++ b/hostapd/config_file.h -@@ -13,10 +13,5 @@ struct hostapd_config * hostapd_config_r - int hostapd_set_iface(struct hostapd_config *conf, - struct hostapd_bss_config *bss, const char *field, - char *value); --int hostapd_acl_comp(const void *a, const void *b); --int hostapd_add_acl_maclist(struct mac_acl_entry **acl, int *num, -- int vlan_id, const u8 *addr); --void hostapd_remove_acl_mac(struct mac_acl_entry **acl, int *num, -- const u8 *addr); - - #endif /* CONFIG_FILE_H */ ---- a/hostapd/ctrl_iface.c -+++ b/hostapd/ctrl_iface.c -@@ -1363,42 +1363,6 @@ static int hostapd_ctrl_iface_get_config - } - - --static void hostapd_disassoc_accept_mac(struct hostapd_data *hapd) --{ -- struct sta_info *sta; -- struct vlan_description vlan_id; -- -- if (hapd->conf->macaddr_acl != DENY_UNLESS_ACCEPTED) -- return; -- -- for (sta = hapd->sta_list; sta; sta = sta->next) { -- if (!hostapd_maclist_found(hapd->conf->accept_mac, -- hapd->conf->num_accept_mac, -- sta->addr, &vlan_id) || -- (vlan_id.notempty && -- vlan_compare(&vlan_id, sta->vlan_desc))) -- ap_sta_disconnect(hapd, sta, sta->addr, -- WLAN_REASON_UNSPECIFIED); -- } --} -- -- --static void hostapd_disassoc_deny_mac(struct hostapd_data *hapd) --{ -- struct sta_info *sta; -- struct vlan_description vlan_id; -- -- for (sta = hapd->sta_list; sta; sta = sta->next) { -- if (hostapd_maclist_found(hapd->conf->deny_mac, -- hapd->conf->num_deny_mac, sta->addr, -- &vlan_id) && -- (!vlan_id.notempty || -- !vlan_compare(&vlan_id, sta->vlan_desc))) -- ap_sta_disconnect(hapd, sta, sta->addr, -- WLAN_REASON_UNSPECIFIED); -- } --} -- - - static int hostapd_ctrl_iface_set_band(struct hostapd_data *hapd, - const char *bands) -@@ -3470,81 +3434,6 @@ static int hostapd_ctrl_driver_flags2(st - return pos - buf; - } - -- --static int hostapd_ctrl_iface_acl_del_mac(struct mac_acl_entry **acl, int *num, -- const char *txtaddr) --{ -- u8 addr[ETH_ALEN]; -- struct vlan_description vlan_id; -- -- if (!(*num)) -- return 0; -- -- if (hwaddr_aton(txtaddr, addr)) -- return -1; -- -- if (hostapd_maclist_found(*acl, *num, addr, &vlan_id)) -- hostapd_remove_acl_mac(acl, num, addr); -- -- return 0; --} -- -- --static void hostapd_ctrl_iface_acl_clear_list(struct mac_acl_entry **acl, -- int *num) --{ -- while (*num) -- hostapd_remove_acl_mac(acl, num, (*acl)[0].addr); --} -- -- --static int hostapd_ctrl_iface_acl_show_mac(struct mac_acl_entry *acl, int num, -- char *buf, size_t buflen) --{ -- int i = 0, len = 0, ret = 0; -- -- if (!acl) -- return 0; -- -- while (i < num) { -- ret = os_snprintf(buf + len, buflen - len, -- MACSTR " VLAN_ID=%d\n", -- MAC2STR(acl[i].addr), -- acl[i].vlan_id.untagged); -- if (ret < 0 || (size_t) ret >= buflen - len) -- return len; -- i++; -- len += ret; -- } -- return len; --} -- -- --static int hostapd_ctrl_iface_acl_add_mac(struct mac_acl_entry **acl, int *num, -- const char *cmd) --{ -- u8 addr[ETH_ALEN]; -- struct vlan_description vlan_id; -- int ret = 0, vlanid = 0; -- const char *pos; -- -- if (hwaddr_aton(cmd, addr)) -- return -1; -- -- pos = os_strstr(cmd, "VLAN_ID="); -- if (pos) -- vlanid = atoi(pos + 8); -- -- if (!hostapd_maclist_found(*acl, *num, addr, &vlan_id)) { -- ret = hostapd_add_acl_maclist(acl, num, vlanid, addr); -- if (ret != -1 && *acl) -- qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp); -- } -- -- return ret < 0 ? -1 : 0; --} -- -- - static int hostapd_ctrl_iface_get_capability(struct hostapd_data *hapd, - const char *field, char *buf, - size_t buflen) ---- a/src/ap/ctrl_iface_ap.c -+++ b/src/ap/ctrl_iface_ap.c -@@ -24,6 +24,7 @@ - #include "ap_drv_ops.h" - #include "mbo_ap.h" - #include "taxonomy.h" -+#include "ap/vlan.h" - - #ifdef CONFIG_CTRL_IFACE_MIB - -@@ -645,6 +646,164 @@ static int p2p_manager_disconnect(struct - #endif /* CONFIG_P2P_MANAGER */ - - -+int hostapd_add_acl_maclist(struct mac_acl_entry **acl, int *num, -+ int vlan_id, const u8 *addr) -+{ -+ struct mac_acl_entry *newacl; -+ -+ newacl = os_realloc_array(*acl, *num + 1, sizeof(**acl)); -+ if (!newacl) { -+ wpa_printf(MSG_ERROR, "MAC list reallocation failed"); -+ return -1; -+ } -+ -+ *acl = newacl; -+ os_memcpy((*acl)[*num].addr, addr, ETH_ALEN); -+ os_memset(&(*acl)[*num].vlan_id, 0, sizeof((*acl)[*num].vlan_id)); -+ (*acl)[*num].vlan_id.untagged = vlan_id; -+ (*acl)[*num].vlan_id.notempty = !!vlan_id; -+ (*num)++; -+ -+ return 0; -+} -+ -+ -+void hostapd_remove_acl_mac(struct mac_acl_entry **acl, int *num, -+ const u8 *addr) -+{ -+ int i = 0; -+ -+ while (i < *num) { -+ if (os_memcmp((*acl)[i].addr, addr, ETH_ALEN) == 0) { -+ os_remove_in_array(*acl, *num, sizeof(**acl), i); -+ (*num)--; -+ } else { -+ i++; -+ } -+ } -+} -+ -+int hostapd_disassoc_accept_mac(struct hostapd_data *hapd) -+{ -+ struct sta_info *sta; -+ struct vlan_description vlan_id; -+ -+ if (hapd->conf->macaddr_acl != DENY_UNLESS_ACCEPTED) -+ return 0; -+ -+ for (sta = hapd->sta_list; sta; sta = sta->next) { -+ if (!hostapd_maclist_found(hapd->conf->accept_mac, -+ hapd->conf->num_accept_mac, -+ sta->addr, &vlan_id) || -+ (vlan_id.notempty && -+ vlan_compare(&vlan_id, sta->vlan_desc))) { -+#ifdef CONFIG_MESH -+ if (hapd->iface->mconf) -+ return 1; -+#endif /* CONFIG_MESH */ -+ ap_sta_disconnect(hapd, sta, sta->addr, -+ WLAN_REASON_UNSPECIFIED); -+ } -+ } -+ return 0; -+} -+ -+int hostapd_disassoc_deny_mac(struct hostapd_data *hapd) -+{ -+ struct sta_info *sta; -+ struct vlan_description vlan_id; -+ -+ for (sta = hapd->sta_list; sta; sta = sta->next) { -+ if (hostapd_maclist_found(hapd->conf->deny_mac, -+ hapd->conf->num_deny_mac, sta->addr, -+ &vlan_id) && -+ (!vlan_id.notempty || -+ !vlan_compare(&vlan_id, sta->vlan_desc))) { -+#ifdef CONFIG_MESH -+ if (hapd->iface->mconf) -+ return 1; -+#endif /* CONFIG_MESH */ -+ ap_sta_disconnect(hapd, sta, sta->addr, -+ WLAN_REASON_UNSPECIFIED); -+ } -+ } -+ -+ return 0; -+} -+ -+int hostapd_ctrl_iface_acl_del_mac(struct mac_acl_entry **acl, int *num, -+ const char *txtaddr) -+{ -+ u8 addr[ETH_ALEN]; -+ struct vlan_description vlan_id; -+ -+ if (!(*num)) -+ return 0; -+ -+ if (hwaddr_aton(txtaddr, addr)) -+ return -1; -+ -+ if (hostapd_maclist_found(*acl, *num, addr, &vlan_id)) -+ hostapd_remove_acl_mac(acl, num, addr); -+ -+ return 0; -+} -+ -+ -+void hostapd_ctrl_iface_acl_clear_list(struct mac_acl_entry **acl, -+ int *num) -+{ -+ while (*num) -+ hostapd_remove_acl_mac(acl, num, (*acl)[0].addr); -+} -+ -+ -+int hostapd_ctrl_iface_acl_show_mac(struct mac_acl_entry *acl, int num, -+ char *buf, size_t buflen) -+{ -+ int i = 0, len = 0, ret = 0; -+ -+ if (!acl) -+ return 0; -+ -+ while (i < num) { -+ ret = os_snprintf(buf + len, buflen - len, -+ MACSTR " VLAN_ID=%d\n", -+ MAC2STR(acl[i].addr), -+ acl[i].vlan_id.untagged); -+ if (ret < 0 || (size_t) ret >= buflen - len) -+ return len; -+ i++; -+ len += ret; -+ } -+ return len; -+} -+ -+ -+int hostapd_ctrl_iface_acl_add_mac(struct mac_acl_entry **acl, int *num, -+ const char *cmd) -+{ -+ u8 addr[ETH_ALEN]; -+ struct vlan_description vlan_id; -+ int ret = 0, vlanid = 0; -+ const char *pos; -+ -+ if (hwaddr_aton(cmd, addr)) -+ return -1; -+ -+ pos = os_strstr(cmd, "VLAN_ID="); -+ if (pos) -+ vlanid = atoi(pos + 8); -+ -+ if (!hostapd_maclist_found(*acl, *num, addr, &vlan_id)) { -+ ret = hostapd_add_acl_maclist(acl, num, vlanid, addr); -+ if (ret != -1 && *acl) -+ qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp); -+ } -+ -+ return ret < 0 ? -1 : 0; -+} -+ - int hostapd_ctrl_iface_deauthenticate(struct hostapd_data *hapd, - const char *txtaddr) - { ---- a/src/ap/ctrl_iface_ap.h -+++ b/src/ap/ctrl_iface_ap.h -@@ -36,5 +36,15 @@ int hostapd_ctrl_iface_pmksa_add(struct - int hostapd_ctrl_iface_pmksa_list_mesh(struct hostapd_data *hapd, - const u8 *addr, char *buf, size_t len); - void * hostapd_ctrl_iface_pmksa_create_entry(const u8 *aa, char *cmd); -+int hostapd_ctrl_iface_acl_add_mac(struct mac_acl_entry **acl, int *num, -+ const char *cmd); -+int hostapd_ctrl_iface_acl_show_mac(struct mac_acl_entry *acl, int num, -+ char *buf, size_t buflen); -+void hostapd_ctrl_iface_acl_clear_list(struct mac_acl_entry **acl, -+ int *num); -+int hostapd_ctrl_iface_acl_del_mac(struct mac_acl_entry **acl, int *num, -+ const char *txtaddr); -+int hostapd_disassoc_accept_mac(struct hostapd_data *hapd); -+int hostapd_disassoc_deny_mac(struct hostapd_data *hapd); - - #endif /* CTRL_IFACE_AP_H */ ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -7099,6 +7099,87 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct - } - - -+int hostapd_acl_comp(const void *a, const void *b) -+{ -+ const struct mac_acl_entry *aa = a; -+ const struct mac_acl_entry *bb = b; -+ -+ return os_memcmp(aa->addr, bb->addr, sizeof(macaddr)); -+} -+ -+int hostapd_config_read_maclist(const char *fname, -+ struct mac_acl_entry **acl, int *num) -+{ -+ FILE *f; -+ char buf[128], *pos; -+ int line = 0; -+ u8 addr[ETH_ALEN]; -+ int vlan_id; -+ -+ f = fopen(fname, "r"); -+ if (!f) { -+ wpa_printf(MSG_ERROR, "MAC list file '%s' not found.", fname); -+ return -1; -+ } -+ -+ while (fgets(buf, sizeof(buf), f)) { -+ int rem = 0; -+ -+ line++; -+ -+ if (buf[0] == '#') -+ continue; -+ pos = buf; -+ while (*pos != '\0') { -+ if (*pos == '\n') { -+ *pos = '\0'; -+ break; -+ } -+ pos++; -+ } -+ if (buf[0] == '\0') -+ continue; -+ pos = buf; -+ if (buf[0] == '-') { -+ rem = 1; -+ pos++; -+ } -+ -+ if (hwaddr_aton(pos, addr)) { -+ wpa_printf(MSG_ERROR, "Invalid MAC address '%s' at " -+ "line %d in '%s'", pos, line, fname); -+ fclose(f); -+ return -1; -+ } -+ -+ if (rem) { -+ hostapd_remove_acl_mac(acl, num, addr); -+ continue; -+ } -+ vlan_id = 0; -+ pos = buf; -+ while (*pos != '\0' && *pos != ' ' && *pos != '\t') -+ pos++; -+ while (*pos == ' ' || *pos == '\t') -+ pos++; -+ if (*pos != '\0') -+ vlan_id = atoi(pos); -+ -+ if (hostapd_add_acl_maclist(acl, num, vlan_id, addr) < 0) { -+ fclose(f); -+ return -1; -+ } -+ } -+ -+ fclose(f); -+ -+ if (*acl) -+ qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp); -+ -+ return 0; -+} -+ -+ - static size_t hostapd_eid_nr_db_len(struct hostapd_data *hapd, - size_t *current_len) - { ---- a/src/ap/ieee802_11.h -+++ b/src/ap/ieee802_11.h -@@ -18,6 +18,7 @@ struct ieee80211_vht_capabilities; - struct ieee80211_mgmt; - struct radius_sta; - enum ieee80211_op_mode; -+struct mac_acl_entry; - - int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len, - struct hostapd_frame_info *fi); -@@ -25,6 +26,14 @@ void ieee802_11_mgmt_cb(struct hostapd_d - u16 stype, int ok); - void hostapd_2040_coex_action(struct hostapd_data *hapd, - const struct ieee80211_mgmt *mgmt, size_t len); -+ -+int hostapd_config_read_maclist(const char *fname, -+ struct mac_acl_entry **acl, int *num); -+int hostapd_acl_comp(const void *a, const void *b); -+int hostapd_add_acl_maclist(struct mac_acl_entry **acl, int *num, -+ int vlan_id, const u8 *addr); -+void hostapd_remove_acl_mac(struct mac_acl_entry **acl, int *num, -+ const u8 *addr); - #ifdef NEED_AP_MLME - int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen); - int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta, diff --git a/feeds/ipq95xx/hostapd/patches/f00-003-Extend-acl-config-support-to-mesh.patch b/feeds/ipq95xx/hostapd/patches/f00-003-Extend-acl-config-support-to-mesh.patch deleted file mode 100644 index 567e0d7a..00000000 --- a/feeds/ipq95xx/hostapd/patches/f00-003-Extend-acl-config-support-to-mesh.patch +++ /dev/null @@ -1,229 +0,0 @@ -From d3447cf20a26072d294cd74a8b3e5c676a7421e7 Mon Sep 17 00:00:00 2001 -From: Nishant Pandey -Date: Tue, 22 Sep 2020 14:19:41 +0530 -Subject: [PATCH] mesh: Add ACL logic support to mesh configuration - -Extend AP-STA accept and deny acl list support to -mesh peer connection as well. Here mesh node uses -macaddr_acl value either ACCEPT_UNLESS_DENIED or -DENY_UNLESS_ACCEPTED. - -Signed-off-by: Nishant Pandey ---- - wpa_supplicant/config.c | 21 ++++++++++++++++++++- - wpa_supplicant/config_file.c | 6 ++++++ - wpa_supplicant/config_ssid.h | 5 +++++ - wpa_supplicant/mesh.c | 22 ++++++++++++++++++++++ - wpa_supplicant/mesh_mpm.c | 15 +++++++++++++++ - wpa_supplicant/wpa_supplicant.conf | 14 ++++++++++++++ - 6 files changed, 82 insertions(+), 1 deletion(-) - -Index: hostapd-2021-02-08/wpa_supplicant/config.c -=================================================================== ---- hostapd-2021-02-08.orig/wpa_supplicant/config.c -+++ hostapd-2021-02-08/wpa_supplicant/config.c -@@ -20,7 +20,9 @@ - #include "drivers/nl80211_copy.h" - #include "fst/fst.h" - #include "config.h" -- -+#ifdef CONFIG_MESH -+#include "ap/ap_config.h" -+#endif - - #if !defined(CONFIG_CTRL_IFACE) && defined(CONFIG_NO_CONFIG_WRITE) - #define NO_CONFIG_WRITE -@@ -2710,6 +2712,9 @@ static const struct parse_data ssid_fiel - { INT(dot11MeshRetryTimeout) }, - { INT(dot11MeshConfirmTimeout) }, - { INT(dot11MeshHoldingTimeout) }, -+ { STR(accept_mac_file) }, -+ { STR(deny_mac_file) }, -+ { INT(macaddr_acl) }, - #endif /* CONFIG_MESH */ - { INT(wpa_ptk_rekey) }, - { INT_RANGE(wpa_deny_ptk0_rekey, 0, 2) }, -@@ -2980,6 +2985,8 @@ void wpa_config_free_ssid(struct wpa_ssi - os_free(ssid->p2p_client_list); - os_free(ssid->bssid_ignore); - os_free(ssid->bssid_accept); -+ os_free(ssid->accept_mac_file); -+ os_free(ssid->deny_mac_file); - #ifdef CONFIG_HT_OVERRIDES - os_free(ssid->ht_mcs); - #endif /* CONFIG_HT_OVERRIDES */ -@@ -3344,6 +3351,18 @@ int wpa_config_set(struct wpa_ssid *ssid - } - ret = -1; - } -+#ifdef CONFIG_MESH -+ if (os_strcmp(var, "macaddr_acl") == 0) { -+ if (ssid->macaddr_acl != ACCEPT_UNLESS_DENIED && -+ ssid->macaddr_acl != DENY_UNLESS_ACCEPTED) { -+ wpa_printf(MSG_ERROR, -+ "Line %d: unknown macaddr_acl %d", -+ line, ssid->macaddr_acl); -+ ret = -1; -+ } -+ } -+#endif -+ - #ifdef CONFIG_SAE - if (os_strcmp(var, "ssid") == 0 || - os_strcmp(var, "psk") == 0 || -Index: hostapd-2021-02-08/wpa_supplicant/config_file.c -=================================================================== ---- hostapd-2021-02-08.orig/wpa_supplicant/config_file.c -+++ hostapd-2021-02-08/wpa_supplicant/config_file.c -@@ -18,6 +18,9 @@ - #include "common.h" - #include "config.h" - #include "base64.h" -+#ifdef CONFIG_MESH -+#include "ap/ap_config.h" -+#endif - #include "uuid.h" - #include "common/ieee802_1x_defs.h" - #include "p2p/p2p.h" -@@ -914,6 +917,9 @@ static void wpa_config_write_network(FIL - write_int(f, "mac_addr", ssid->mac_addr, -1); - #ifdef CONFIG_MESH - STR(mesh_basic_rates); -+ STR(accept_mac_file); -+ STR(deny_mac_file); -+ INT_DEF(macaddr_acl, ACCEPT_UNLESS_DENIED); - INT_DEF(dot11MeshMaxRetries, DEFAULT_MESH_MAX_RETRIES); - INT_DEF(dot11MeshRetryTimeout, DEFAULT_MESH_RETRY_TIMEOUT); - INT_DEF(dot11MeshConfirmTimeout, DEFAULT_MESH_CONFIRM_TIMEOUT); -Index: hostapd-2021-02-08/wpa_supplicant/config_ssid.h -=================================================================== ---- hostapd-2021-02-08.orig/wpa_supplicant/config_ssid.h -+++ hostapd-2021-02-08/wpa_supplicant/config_ssid.h -@@ -546,6 +546,11 @@ struct wpa_ssid { - int dot11MeshConfirmTimeout; /* msec */ - int dot11MeshHoldingTimeout; /* msec */ - -+ char *accept_mac_file; -+ char *deny_mac_file; -+ int macaddr_acl; -+ -+ - int ht; - int ht40; - -Index: hostapd-2021-02-08/wpa_supplicant/mesh.c -=================================================================== ---- hostapd-2021-02-08.orig/wpa_supplicant/mesh.c -+++ hostapd-2021-02-08/wpa_supplicant/mesh.c -@@ -16,6 +16,7 @@ - #include "common/hw_features_common.h" - #include "ap/sta_info.h" - #include "ap/hostapd.h" -+#include "ap/ieee802_11_auth.h" - #include "ap/ieee802_11.h" - #include "config_ssid.h" - #include "config.h" -@@ -459,6 +460,17 @@ static int wpa_supplicant_mesh_init(stru - ifmsh->bss[0]->dot11RSNASAERetransPeriod = - wpa_s->conf->dot11RSNASAERetransPeriod; - os_strlcpy(bss->conf->iface, wpa_s->ifname, sizeof(bss->conf->iface)); -+ bss->conf->macaddr_acl = ssid->macaddr_acl; -+ -+ if (ssid->accept_mac_file) -+ hostapd_config_read_maclist(ssid->accept_mac_file, -+ &bss->conf->accept_mac, -+ &bss->conf->num_accept_mac); -+ -+ if (ssid->deny_mac_file) -+ hostapd_config_read_maclist(ssid->deny_mac_file, -+ &bss->conf->deny_mac, -+ &bss->conf->num_deny_mac); - - mconf = mesh_config_create(wpa_s, ssid); - if (!mconf) -@@ -555,6 +567,16 @@ void wpa_mesh_notify_peer(struct wpa_sup - const u8 *ies, size_t ie_len) - { - struct ieee802_11_elems elems; -+ int acl_res; -+ struct hostapd_data *data = wpa_s->ifmsh->bss[0]; -+ struct radius_sta rad_info; -+ -+ acl_res = hostapd_allowed_address(data, addr, NULL, 0, &rad_info, 0); -+ if (acl_res == HOSTAPD_ACL_REJECT) { -+ wpa_printf(MSG_ERROR, "Ignore new peer notification\n"); -+ return; -+ -+ } - - wpa_msg(wpa_s, MSG_INFO, - "new peer notification for " MACSTR, MAC2STR(addr)); -Index: hostapd-2021-02-08/wpa_supplicant/mesh_mpm.c -=================================================================== ---- hostapd-2021-02-08.orig/wpa_supplicant/mesh_mpm.c -+++ hostapd-2021-02-08/wpa_supplicant/mesh_mpm.c -@@ -16,6 +16,7 @@ - #include "ap/hostapd.h" - #include "ap/sta_info.h" - #include "ap/ieee802_11.h" -+#include "ap/ieee802_11_auth.h" - #include "ap/wpa_auth.h" - #include "wpa_supplicant_i.h" - #include "driver_i.h" -@@ -1128,10 +1129,12 @@ void mesh_mpm_action_rx(struct wpa_suppl - enum plink_event event; - struct ieee802_11_elems elems; - struct mesh_peer_mgmt_ie peer_mgmt_ie; -+ struct radius_sta rad_info; - const u8 *ies; - size_t ie_len; - int ret; - u16 reason = 0; -+ int acl_res; - - if (mgmt->u.action.category != WLAN_ACTION_SELF_PROTECTED) - return; -@@ -1179,6 +1182,18 @@ void mesh_mpm_action_rx(struct wpa_suppl - return; - } - if (action_field != PLINK_CLOSE) { -+ if (action_field != PLINK_CLOSE) { -+ acl_res = hostapd_allowed_address(hapd, mgmt->sa, -+ (const u8 *) mgmt, -+ len, &rad_info, 0); -+ if (acl_res == HOSTAPD_ACL_REJECT) { -+ wpa_printf(MSG_DEBUG, -+ "MPM: Ignore action frame\n"); -+ return; -+ -+ } -+ } -+ - if (!elems.mesh_id || !elems.mesh_config) { - wpa_printf(MSG_DEBUG, - "MPM: No Mesh ID or Mesh Configuration element"); -Index: hostapd-2021-02-08/wpa_supplicant/wpa_supplicant.conf -=================================================================== ---- hostapd-2021-02-08.orig/wpa_supplicant/wpa_supplicant.conf -+++ hostapd-2021-02-08/wpa_supplicant/wpa_supplicant.conf -@@ -150,6 +150,20 @@ ap_scan=1 - # This timeout value is used in mesh STA to clean up inactive stations. - #mesh_max_inactivity=300 - -+# Mesh node address -based authentication -+# Please note that this kind of access control requires a driver that uses -+# wpa_supplicant to take care of management frame and mesh PLINK connection -+# processing and as such. -+# 0 = accept unless in deny list -+# 1 = deny unless in accept list -+macaddr_acl=0 -+ -+# Accept/deny lists are read from separate files (containing list of -+# MAC addresses, one per line). Use absolute path name to make sure that the -+# files can be read on SIGHUP configuration reloads. -+#accept_mac_file=/etc/hostapd.accept -+#deny_mac_file=/etc/hostapd.deny -+ - # cert_in_cb - Whether to include a peer certificate dump in events - # This controls whether peer certificates for authentication server and - # its certificate chain are included in EAP peer certificate events. This is diff --git a/feeds/ipq95xx/hostapd/patches/f00-003-bss-coloring-disable-BSS-color-during-CCA.patch b/feeds/ipq95xx/hostapd/patches/f00-003-bss-coloring-disable-BSS-color-during-CCA.patch deleted file mode 100644 index d0b401f3..00000000 --- a/feeds/ipq95xx/hostapd/patches/f00-003-bss-coloring-disable-BSS-color-during-CCA.patch +++ /dev/null @@ -1,24 +0,0 @@ -From: John Crispin -Subject: [PATCH V4 3/6] bss coloring: disable BSS color during CCA -Date: Wed, 26 Aug 2020 08:22:13 +0200 - - -While we are doing CCA the bss color disable bit inside the he oper field -needs to be set. - -Signed-off-by: John Crispin ---- - src/ap/ieee802_11_he.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/src/ap/ieee802_11_he.c -+++ b/src/ap/ieee802_11_he.c -@@ -198,7 +198,7 @@ u8 * hostapd_eid_he_operation(struct hos - params |= (hapd->iface->conf->he_op.he_rts_threshold << - HE_OPERATION_RTS_THRESHOLD_OFFSET); - -- if (hapd->iface->conf->he_op.he_bss_color_disabled) -+ if (hapd->iface->conf->he_op.he_bss_color_disabled || hapd->cca_in_progress) - params |= HE_OPERATION_BSS_COLOR_DISABLED; - if (hapd->iface->conf->he_op.he_bss_color_partial) - params |= HE_OPERATION_BSS_COLOR_PARTIAL; diff --git a/feeds/ipq95xx/hostapd/patches/f00-004-bss-coloring-add-the-switch_color-handler-to-the-nl80211-driver.patch b/feeds/ipq95xx/hostapd/patches/f00-004-bss-coloring-add-the-switch_color-handler-to-the-nl80211-driver.patch deleted file mode 100644 index 7debeddb..00000000 --- a/feeds/ipq95xx/hostapd/patches/f00-004-bss-coloring-add-the-switch_color-handler-to-the-nl80211-driver.patch +++ /dev/null @@ -1,156 +0,0 @@ -From 2113291e2fb20d82ac9f9740fed13abea2193a35 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Tue, 3 Nov 2020 20:15:08 -0800 -Subject: [PATCH V4 4/6] bss coloring: add the switch_color handler to the - nl80211 driver - -In order to start the CCA process we need to send NL80211_CMD_COLOR_CHANGE -to the kernel. This patch adds the required code. - -Signed-off-by: John Crispin ---- - src/drivers/driver_nl80211.c | 79 ++++++++++++++++++++++++++++++++++++ - src/drivers/nl80211_copy.h | 18 +++++++- - 2 files changed, 95 insertions(+), 2 deletions(-) - ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -9977,6 +9977,82 @@ error: - } - - -+#ifdef CONFIG_IEEE80211AX -+static int nl80211_switch_color(void *priv, struct cca_settings *settings) -+{ -+ struct nl_msg *msg; -+ struct i802_bss *bss = priv; -+ struct wpa_driver_nl80211_data *drv = bss->drv; -+ struct nlattr *beacon_cca; -+ int ret = -ENOBUFS; -+ -+ wpa_printf(MSG_DEBUG, "nl80211: Color change request (cca_count=%u color=%d)", -+ settings->cca_count, settings->cca_color); -+ -+ if (drv->nlmode != NL80211_IFTYPE_AP) -+ return -EOPNOTSUPP; -+ -+ if (!settings->beacon_cca.tail) -+ return -EINVAL; -+ -+ if ((settings->beacon_cca.tail_len <= settings->counter_offset_beacon) || -+ (settings->beacon_cca.tail[settings->counter_offset_beacon] != -+ settings->cca_count)) -+ return -EINVAL; -+ -+ if (settings->beacon_cca.probe_resp && -+ ((settings->beacon_cca.probe_resp_len <= -+ settings->counter_offset_presp) || -+ (settings->beacon_cca.probe_resp[settings->counter_offset_presp] != -+ settings->cca_count))) -+ return -EINVAL; -+ -+ if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_COLOR_CHANGE)) || -+ nla_put_u8(msg, NL80211_ATTR_COLOR_CHANGE_ANNOUNCEMENT_COUNT, -+ settings->cca_count) || -+ nla_put_u8(msg, NL80211_ATTR_COLOR_CHANGE_ANNOUNCEMENT_COLOR, -+ settings->cca_color)) -+ goto error; -+ -+ /* beacon_after params */ -+ ret = set_beacon_data(msg, &settings->beacon_after); -+ if (ret) -+ goto error; -+ -+ /* beacon_csa params */ -+ beacon_cca = nla_nest_start(msg, NL80211_ATTR_COLOR_CHANGE_ANNOUNCEMENT_IES); -+ if (!beacon_cca) -+ goto fail; -+ -+ ret = set_beacon_data(msg, &settings->beacon_cca); -+ if (ret) -+ goto error; -+ -+ if (nla_put_u16(msg, NL80211_ATTR_CNTDWN_OFFS_BEACON, -+ settings->counter_offset_beacon) || -+ (settings->beacon_cca.probe_resp && -+ nla_put_u16(msg, NL80211_ATTR_CNTDWN_OFFS_PRESP, -+ settings->counter_offset_presp))) -+ goto fail; -+ -+ nla_nest_end(msg, beacon_cca); -+ ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL); -+ if (ret) { -+ wpa_printf(MSG_DEBUG, "nl80211: switch_color failed err=%d (%s)", -+ ret, strerror(-ret)); -+ } -+ return ret; -+ -+fail: -+ ret = -ENOBUFS; -+error: -+ nlmsg_free(msg); -+ wpa_printf(MSG_DEBUG, "nl80211: Could not build color switch request"); -+ return ret; -+} -+#endif -+ -+ - static int nl80211_add_ts(void *priv, u8 tsid, const u8 *addr, - u8 user_priority, u16 admitted_time) - { -@@ -12242,6 +12318,9 @@ const struct wpa_driver_ops wpa_driver_n - .get_survey = wpa_driver_nl80211_get_survey, - .status = wpa_driver_nl80211_status, - .switch_channel = nl80211_switch_channel, -+#ifdef CONFIG_IEEE80211AX -+ .switch_color = nl80211_switch_color, -+#endif - #ifdef ANDROID_P2P - .set_noa = wpa_driver_set_p2p_noa, - .get_noa = wpa_driver_get_p2p_noa, ---- a/src/drivers/nl80211_copy.h -+++ b/src/drivers/nl80211_copy.h -@@ -1423,6 +1423,16 @@ enum nl80211_commands { - NL80211_CMD_SET_SAR_SPECS, - - NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS, -+ -+ NL80211_CMD_OBSS_COLOR_COLLISION, -+ -+ NL80211_CMD_COLOR_CHANGE, -+ NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_STARTED, -+ NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_ABORTED, -+ NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_COMPLETED, -+ -+ NL80211_CMD_SET_FILS_AAD, -+ - /* add new commands above here */ - - /* used to define NL80211_CMD_MAX below */ -@@ -3067,6 +3077,16 @@ enum nl80211_attrs { - NL80211_ATTR_DISABLE_HE, - - NL80211_ATTR_HE_MUEDCA_PARAMS, -+ -+ NL80211_ATTR_OBSS_COLOR_BITMAP, -+ -+ NL80211_ATTR_COLOR_CHANGE_ANNOUNCEMENT_COUNT, -+ NL80211_ATTR_COLOR_CHANGE_ANNOUNCEMENT_COLOR, -+ NL80211_ATTR_COLOR_CHANGE_ANNOUNCEMENT_IES, -+ -+ NL80211_ATTR_MBSSID_CONFIG, -+ NL80211_ATTR_MBSSID_ELEMS, -+ - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, ---- a/src/drivers/driver_nl80211_event.c -+++ b/src/drivers/driver_nl80211_event.c -@@ -172,6 +172,7 @@ static const char * nl80211_command_to_s - C2S(NL80211_CMD_UNPROT_BEACON) - C2S(NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS) - C2S(NL80211_CMD_SET_SAR_SPECS) -+ C2S(NL80211_CMD_SET_FILS_AAD) - C2S(NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS) - C2S(NL80211_CMD_COLOR_CHANGE) - C2S(__NL80211_CMD_AFTER_LAST) diff --git a/feeds/ipq95xx/hostapd/patches/f00-004-mesh-Dynamic-MAC-ACL-management-over-control-interface.patch b/feeds/ipq95xx/hostapd/patches/f00-004-mesh-Dynamic-MAC-ACL-management-over-control-interface.patch deleted file mode 100644 index 976a23a8..00000000 --- a/feeds/ipq95xx/hostapd/patches/f00-004-mesh-Dynamic-MAC-ACL-management-over-control-interface.patch +++ /dev/null @@ -1,299 +0,0 @@ -From 2173e65aa098ab130bfdbc9b9cfe8ac2fc2ae086 Mon Sep 17 00:00:00 2001 -From: Nishant Pandey -Date: Tue, 22 Sep 2020 14:23:08 +0530 -Subject: [PATCH] mesh: Dynamic MAC ACL management over control interface - -Extend support to modify MAC ACL and displayed it through -new control interface - -commands: - -ACCEPT_ACL [argument] -DENY_ACL [argument] -subcmd: ADD_MAC |DEL_MAC |SHOW|CLEAR - -Signed-off-by: Nishant Pandey ---- - wpa_supplicant/ap.c | 68 +++++++++++++++++++++++++++++++++++++++++ - wpa_supplicant/ap.h | 5 +++ - wpa_supplicant/ctrl_iface.c | 45 +++++++++++++++++++++++++++ - wpa_supplicant/events.c | 1 + - wpa_supplicant/mesh.c | 1 + - wpa_supplicant/wpa_cli.c | 19 ++++++++++++ - wpa_supplicant/wpa_supplicant.c | 3 +- - wpa_supplicant/wps_supplicant.c | 2 ++ - 8 files changed, 143 insertions(+), 1 deletion(-) - ---- a/wpa_supplicant/ap.c -+++ b/wpa_supplicant/ap.c -@@ -6,6 +6,7 @@ - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ -+#include - - #include "utils/includes.h" - -@@ -1616,6 +1617,73 @@ void wpas_ap_pmksa_cache_flush(struct wp - hostapd_ctrl_iface_pmksa_flush(wpa_s->ifmsh->bss[0]); - } - -+#ifdef CONFIG_MESH -+ -+int wpas_ap_acl_del_mac(struct wpa_supplicant *wpa_s, char *buf, bool accept) -+{ -+ struct hostapd_data *hapd = wpa_s->ifmsh->bss[0]; -+ -+ if (accept) { -+ if (!hostapd_ctrl_iface_acl_del_mac(&hapd->conf->accept_mac, -+ &hapd->conf->num_accept_mac, -+ buf)) -+ if (hostapd_disassoc_accept_mac(hapd)) -+ return 1; -+ } -+ -+ return hostapd_ctrl_iface_acl_del_mac(&hapd->conf->deny_mac, -+ &hapd->conf->num_deny_mac, -+ buf); -+} -+ -+int wpas_ap_acl_add_mac(struct wpa_supplicant *wpa_s, char *buf, bool accept) -+{ -+ struct hostapd_data *hapd = wpa_s->ifmsh->bss[0]; -+ -+ if (accept) { -+ return hostapd_ctrl_iface_acl_add_mac(&hapd->conf->accept_mac, -+ &hapd->conf->num_accept_mac, -+ buf); -+ } else { -+ if (!hostapd_ctrl_iface_acl_add_mac(&hapd->conf->deny_mac, -+ &hapd->conf->num_deny_mac, buf)) { -+ if (hostapd_disassoc_deny_mac(hapd)) -+ return 1; -+ return 0; -+ } -+ } -+ -+ return -1; -+} -+ -+int wpas_ap_acl_show_mac(struct wpa_supplicant *wpa_s, char *reply, -+ const int reply_size, bool accept) -+{ -+ struct hostapd_data *hapd = wpa_s->ifmsh->bss[0]; -+ -+ if (accept) -+ return hostapd_ctrl_iface_acl_show_mac( -+ hapd->conf->accept_mac, -+ hapd->conf->num_accept_mac, -+ reply, reply_size); -+ -+ return hostapd_ctrl_iface_acl_show_mac( -+ hapd->conf->deny_mac, -+ hapd->conf->num_deny_mac, -+ reply, reply_size); -+} -+ -+void wpas_ap_deny_acl_clear_list(struct wpa_supplicant *wpa_s) -+{ -+ struct hostapd_data *hapd = wpa_s->ifmsh->bss[0]; -+ -+ -+ return hostapd_ctrl_iface_acl_clear_list(&hapd->conf->deny_mac, -+ &hapd->conf->num_deny_mac); -+} -+ -+#endif /* CONFIG_MESH */ -+ - - #ifdef CONFIG_PMKSA_CACHE_EXTERNAL - #ifdef CONFIG_MESH ---- a/wpa_supplicant/ap.h -+++ b/wpa_supplicant/ap.h -@@ -99,6 +99,11 @@ void wpas_ap_event_dfs_cac_aborted(struc - struct dfs_event *radar); - void wpas_ap_event_dfs_cac_nop_finished(struct wpa_supplicant *wpa_s, - struct dfs_event *radar); -+int wpas_ap_acl_del_mac(struct wpa_supplicant *wpa_s, char *buf, bool accept); -+int wpas_ap_acl_add_mac(struct wpa_supplicant *wpa_s, char *buf, bool accept); -+int wpas_ap_acl_show_mac(struct wpa_supplicant *wpa_s, char *reply, -+ const int reply_size, bool accept); -+void wpas_ap_deny_acl_clear_list(struct wpa_supplicant *wpa_s); - - void ap_periodic(struct wpa_supplicant *wpa_s); - ---- a/wpa_supplicant/ctrl_iface.c -+++ b/wpa_supplicant/ctrl_iface.c -@@ -5,6 +5,7 @@ - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ -+#include - - #include "utils/includes.h" - #ifdef CONFIG_TESTING_OPTIONS -@@ -56,6 +57,7 @@ - #include "mesh.h" - #include "dpp_supplicant.h" - #include "sme.h" -+#include "ap/ieee802_11.h" - - #ifdef __NetBSD__ - #include -@@ -3284,6 +3286,18 @@ static int wpa_supplicant_ctrl_iface_mes - return wpas_mesh_peer_remove(wpa_s, addr); - } - -+static void wpas_ap_accept_acl_clear_list(struct wpa_supplicant *wpa_s) -+{ -+ struct hostapd_data *hapd = wpa_s->ifmsh->bss[0]; -+ struct mac_acl_entry **acl = &hapd->conf->accept_mac; -+ int *num = &hapd->conf->num_accept_mac; -+ -+ while (*num) { -+ wpas_mesh_peer_remove(wpa_s, (*acl)[0].addr); -+ hostapd_remove_acl_mac(acl, num, (*acl)[0].addr); -+ } -+} -+ - - static int wpa_supplicant_ctrl_iface_mesh_peer_add( - struct wpa_supplicant *wpa_s, char *cmd) -@@ -10655,6 +10669,38 @@ char * wpa_supplicant_ctrl_iface_process - reply_len = -1; - #endif /* CONFIG_IBSS_RSN */ - #ifdef CONFIG_MESH -+ } else if (os_strncmp(buf, "ACCEPT_ACL ", 11) == 0) { -+ if (os_strncmp(buf + 11, "ADD_MAC ", 8) == 0) { -+ wpas_ap_acl_add_mac(wpa_s, buf + 19, 1); -+ } else if (os_strncmp((buf + 11), "DEL_MAC ", 8) == 0) { -+ reply_len = wpas_ap_acl_del_mac(wpa_s, buf + 19, 1); -+ if (reply_len == 1) -+ wpa_supplicant_ctrl_iface_mesh_peer_remove( -+ wpa_s, buf + 19); -+ else if (reply_len) -+ reply_len = -1; -+ } else if (os_strcmp(buf + 11, "SHOW") == 0) { -+ reply_len = wpas_ap_acl_show_mac(wpa_s, reply, -+ reply_size, 1); -+ } else if (os_strcmp(buf + 11, "CLEAR") == 0) { -+ wpas_ap_accept_acl_clear_list(wpa_s); -+ } -+ } else if (os_strncmp(buf, "DENY_ACL ", 9) == 0) { -+ if (os_strncmp(buf + 9, "ADD_MAC ", 8) == 0) { -+ reply_len = wpas_ap_acl_add_mac(wpa_s, buf + 17, 0); -+ if (reply_len == 1) -+ wpa_supplicant_ctrl_iface_mesh_peer_remove( -+ wpa_s, buf + 17); -+ else if (reply_len) -+ reply_len = -1; -+ } else if (os_strncmp(buf + 9, "DEL_MAC ", 8) == 0) { -+ wpas_ap_acl_del_mac(wpa_s, buf + 17, 0); -+ } else if (os_strcmp(buf + 9, "SHOW") == 0) { -+ reply_len = wpas_ap_acl_show_mac(wpa_s, reply, -+ reply_size, 0); -+ } else if (os_strcmp(buf + 9, "CLEAR") == 0) { -+ wpas_ap_deny_acl_clear_list(wpa_s); -+ } - } else if (os_strncmp(buf, "MESH_INTERFACE_ADD ", 19) == 0) { - reply_len = wpa_supplicant_ctrl_iface_mesh_interface_add( - wpa_s, buf + 19, reply, reply_size); ---- a/wpa_supplicant/events.c -+++ b/wpa_supplicant/events.c -@@ -5,6 +5,7 @@ - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ -+#include - - #include "includes.h" - ---- a/wpa_supplicant/mesh.c -+++ b/wpa_supplicant/mesh.c -@@ -5,6 +5,7 @@ - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ -+#include - - #include "utils/includes.h" - ---- a/wpa_supplicant/wpa_cli.c -+++ b/wpa_supplicant/wpa_cli.c -@@ -2113,6 +2113,19 @@ static int wpa_cli_cmd_mesh_link_probe(s - return wpa_cli_cmd(ctrl, "MESH_LINK_PROBE", 1, argc, argv); - } - -+static int wpa_cli_cmd_accept_macacl(struct wpa_ctrl *ctrl, int argc, -+ char *argv[]) -+{ -+ return wpa_cli_cmd(ctrl, "ACCEPT_ACL", 1, argc, argv); -+} -+ -+ -+static int wpa_cli_cmd_deny_macacl(struct wpa_ctrl *ctrl, int argc, -+ char *argv[]) -+{ -+ return wpa_cli_cmd(ctrl, "DENY_ACL", 1, argc, argv); -+} -+ - #endif /* CONFIG_MESH */ - - -@@ -3532,6 +3545,12 @@ static const struct wpa_cli_cmd wpa_cli_ - { "mesh_link_probe", wpa_cli_cmd_mesh_link_probe, NULL, - cli_cmd_flag_none, - " [payload=] = Probe a mesh link for a given peer by injecting a frame." }, -+ { "accept_acl", wpa_cli_cmd_accept_macacl, NULL, -+ cli_cmd_flag_none, -+ "=Add/Delete/Show/Clear accept MAC ACL" }, -+ { "deny_acl", wpa_cli_cmd_deny_macacl, NULL, -+ cli_cmd_flag_none, -+ "=Add/Delete/Show/Clear deny MAC ACL" }, - #endif /* CONFIG_MESH */ - #ifdef CONFIG_P2P - { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find, ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -9,6 +9,7 @@ - * %wpa_supplicant interfaces. In addition, this file contains number of - * functions for managing network connections. - */ -+#include - - #include "includes.h" - #ifdef CONFIG_MATCH_IFACE -@@ -49,7 +50,6 @@ - #include "ibss_rsn.h" - #include "sme.h" - #include "gas_query.h" --#include "ap.h" - #include "p2p_supplicant.h" - #include "wifi_display.h" - #include "notify.h" -@@ -67,6 +67,7 @@ - #include "ap/ap_config.h" - #include "ap/hostapd.h" - #endif /* CONFIG_MESH */ -+#include "ap.h" - - const char *const wpa_supplicant_version = - "wpa_supplicant v" VERSION_STR "\n" ---- a/wpa_supplicant/wps_supplicant.c -+++ b/wpa_supplicant/wps_supplicant.c -@@ -5,6 +5,7 @@ - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ -+#include - - #include "includes.h" - -@@ -21,6 +22,7 @@ - #include "eap_peer/eap.h" - #include "eapol_supp/eapol_supp_sm.h" - #include "rsn_supp/wpa.h" -+#include "ap/hostapd.h" - #include "wps/wps_attr_parse.h" - #include "config.h" - #include "wpa_supplicant_i.h" diff --git a/feeds/ipq95xx/hostapd/patches/f00-005-bss-coloring-handle-the-collision-and-CCA-events-coming-from-the-kernel.patch b/feeds/ipq95xx/hostapd/patches/f00-005-bss-coloring-handle-the-collision-and-CCA-events-coming-from-the-kernel.patch deleted file mode 100644 index eb7a91e8..00000000 --- a/feeds/ipq95xx/hostapd/patches/f00-005-bss-coloring-handle-the-collision-and-CCA-events-coming-from-the-kernel.patch +++ /dev/null @@ -1,227 +0,0 @@ -From: John Crispin -Subject: [PATCH V4 5/6] bss coloring: handle the collision and CCA events - coming from the kernel -Date: Wed, 26 Aug 2020 08:22:15 +0200 - - -This patch activates the functionality of the previous patches by handling -the actual events that will trigger the CCA process. - -Signed-off-by: John Crispin ---- - src/ap/drv_callbacks.c | 45 ++++++++++++++++++++- - src/drivers/driver.h | 27 +++++++++++++ - src/drivers/driver_common.c | 4 ++ - src/drivers/driver_nl80211_event.c | 64 +++++++++++++++++++++++++++++- - 4 files changed, 138 insertions(+), 2 deletions(-) - ---- a/src/ap/drv_callbacks.c -+++ b/src/ap/drv_callbacks.c -@@ -44,7 +44,6 @@ - #include "fils_hlp.h" - #include "neighbor_db.h" - -- - #ifdef CONFIG_FILS - void hostapd_notify_assoc_fils_finish(struct hostapd_data *hapd, - struct sta_info *sta) -@@ -1801,6 +1800,39 @@ static void hostapd_event_update_muedca_ - "Failed to update beacons with MU-EDCA parameters"); - } - -+#ifdef CONFIG_IEEE80211AX -+static void hostapd_event_bss_color_collision(struct hostapd_data *hapd, -+ u64 bitmap) -+{ -+ /* the bss color is shared amongst all BBSs on a specific phy. -+ * therefore we always start the color change on the primary BSS -+ */ -+ wpa_printf(MSG_DEBUG, "BSS color collision on %s", hapd->conf->iface); -+ hostapd_switch_color(hapd->iface->bss[0], bitmap); -+} -+ -+static void hostapd_event_cca(struct hostapd_data *hapd, enum wpa_event_type event) -+{ -+ switch (event) { -+ case EVENT_CCA_STARTED_NOTIFY: -+ wpa_printf(MSG_DEBUG, "CCA started on %s", hapd->conf->iface); -+ break; -+ case EVENT_CCA_NOTIFY: -+ wpa_printf(MSG_DEBUG, "CCA finished on %s (new color: %d)", hapd->conf->iface, hapd->cca_color); -+ hapd->iface->conf->he_op.he_bss_color = hapd->cca_color; -+ hostapd_cleanup_cca_params(hapd); -+ break; -+ case EVENT_CCA_ABORTED_NOTIFY: -+ wpa_printf(MSG_DEBUG, "CCA aborted on %s for cca_color: %d", hapd->conf->iface, hapd->cca_color); -+ hostapd_cleanup_cca_params(hapd); -+ break; -+ default: -+ break; -+ } -+} -+#endif -+ -+ - #ifdef CONFIG_OWE - static int hostapd_notif_update_dh_ie(struct hostapd_data *hapd, - const u8 *peer, const u8 *ie, -@@ -2111,6 +2143,17 @@ void hostapd_wpa_event(void *ctx, enum w - case EVENT_UPDATE_MUEDCA_PARAMS: - hostapd_event_update_muedca_params(hapd, &data->update_muedca); - break; -+#ifdef CONFIG_IEEE80211AX -+ case EVENT_BSS_COLOR_COLLISION: -+ hostapd_event_bss_color_collision(hapd, -+ data->bss_color_collision.bitmap); -+ break; -+ case EVENT_CCA_STARTED_NOTIFY: -+ case EVENT_CCA_ABORTED_NOTIFY: -+ case EVENT_CCA_NOTIFY: -+ hostapd_event_cca(hapd, event); -+ break; -+#endif - default: - wpa_printf(MSG_DEBUG, "Unknown event %d", event); - break; ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -5175,6 +5175,26 @@ enum wpa_event_type { - * beacon. - */ - EVENT_UPDATE_MUEDCA_PARAMS, -+ -+ /** -+ * EVENT_BSS_COLOR_COLLISION - Notification of a BSS color collision -+ */ -+ EVENT_BSS_COLOR_COLLISION, -+ -+ /** -+ * EVENT_CCA_STARTED_NOTIFY - Notification that CCA has started -+ */ -+ EVENT_CCA_STARTED_NOTIFY, -+ -+ /** -+ * EVENT_CCA_ABORTED_NOTIFY - Notification that CCA has aborted -+ */ -+ EVENT_CCA_ABORTED_NOTIFY, -+ -+ /** -+ * EVENT_CCA_NOTIFY - Notification that CCA has completed -+ */ -+ EVENT_CCA_NOTIFY, - }; - - -@@ -6077,6 +6097,13 @@ union wpa_event_data { - u8 he_mu_ac_vi_param[3]; - u8 he_mu_ac_vo_param[3]; - } update_muedca; -+ -+ /** -+ * struct bss_color_collision - Data for EVENT_BSS_COLOR_COLLISION -+ */ -+ struct bss_color_collision { -+ u64 bitmap; -+ } bss_color_collision; - }; - - /** ---- a/src/drivers/driver_common.c -+++ b/src/drivers/driver_common.c -@@ -91,6 +91,10 @@ const char * event_to_string(enum wpa_ev - E2S(UPDATE_DH); - E2S(UNPROT_BEACON); - E2S(UPDATE_MUEDCA_PARAMS); -+ E2S(BSS_COLOR_COLLISION); -+ E2S(CCA_STARTED_NOTIFY); -+ E2S(CCA_ABORTED_NOTIFY); -+ E2S(CCA_NOTIFY); - } - - return "UNKNOWN"; ---- a/src/drivers/driver_nl80211_event.c -+++ b/src/drivers/driver_nl80211_event.c -@@ -175,6 +175,10 @@ static const char * nl80211_command_to_s - C2S(NL80211_CMD_SET_FILS_AAD) - C2S(NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS) - C2S(NL80211_CMD_COLOR_CHANGE) -+ C2S(NL80211_CMD_OBSS_COLOR_COLLISION) -+ C2S(NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_STARTED) -+ C2S(NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_ABORTED) -+ C2S(NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_COMPLETED) - C2S(__NL80211_CMD_AFTER_LAST) - } - #undef C2S -@@ -2863,6 +2867,51 @@ static void nl80211_control_port_frame(s - } - } - -+#ifdef CONFIG_IEEE80211AX -+static void mlme_event_obss_color_collision(struct wpa_driver_nl80211_data *drv, -+ struct nlattr *tb[]) -+{ -+ union wpa_event_data data; -+ -+ if (!tb[NL80211_ATTR_OBSS_COLOR_BITMAP]) -+ return; -+ -+ os_memset(&data, 0, sizeof(data)); -+ data.bss_color_collision.bitmap = nla_get_u64(tb[NL80211_ATTR_OBSS_COLOR_BITMAP]); -+ -+ wpa_printf(MSG_DEBUG, "nl80211: BSS color collision - bitmap %08llx", -+ (long long unsigned int)data.bss_color_collision.bitmap); -+ -+ wpa_supplicant_event(drv->ctx, EVENT_BSS_COLOR_COLLISION, &data); -+} -+ -+static void mlme_event_color_change_announcement_started(struct wpa_driver_nl80211_data *drv) -+{ -+ union wpa_event_data data = {}; -+ -+ wpa_printf(MSG_DEBUG, "nl80211: CCA started"); -+ -+ wpa_supplicant_event(drv->ctx, EVENT_CCA_STARTED_NOTIFY, &data); -+} -+ -+static void mlme_event_color_change_announcement_aborted(struct wpa_driver_nl80211_data *drv) -+{ -+ union wpa_event_data data = {}; -+ -+ wpa_printf(MSG_DEBUG, "nl80211: CCA aborted"); -+ -+ wpa_supplicant_event(drv->ctx, EVENT_CCA_ABORTED_NOTIFY, &data); -+} -+ -+static void mlme_event_color_change_announcement_completed(struct wpa_driver_nl80211_data *drv) -+{ -+ union wpa_event_data data = {}; -+ -+ wpa_printf(MSG_DEBUG, "nl80211: CCA completed"); -+ -+ wpa_supplicant_event(drv->ctx, EVENT_CCA_NOTIFY, &data); -+} -+#endif - - static void - nl80211_control_port_frame_tx_status(struct wpa_driver_nl80211_data *drv, -@@ -3135,6 +3184,20 @@ static void do_process_drv_event(struct - case NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS: - nl80211_update_muedca_params_event(drv, tb); - break; -+#ifdef CONFIG_IEEE80211AX -+ case NL80211_CMD_OBSS_COLOR_COLLISION: -+ mlme_event_obss_color_collision(drv, tb); -+ break; -+ case NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_STARTED: -+ mlme_event_color_change_announcement_started(drv); -+ break; -+ case NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_ABORTED: -+ mlme_event_color_change_announcement_aborted(drv); -+ break; -+ case NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_COMPLETED: -+ mlme_event_color_change_announcement_completed(drv); -+ break; -+#endif - default: - wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event " - "(cmd=%d)", cmd); diff --git a/feeds/ipq95xx/hostapd/patches/f00-006-bss_coloring-allow-using-a-random-starting-color.patch b/feeds/ipq95xx/hostapd/patches/f00-006-bss_coloring-allow-using-a-random-starting-color.patch deleted file mode 100644 index 685aa6aa..00000000 --- a/feeds/ipq95xx/hostapd/patches/f00-006-bss_coloring-allow-using-a-random-starting-color.patch +++ /dev/null @@ -1,44 +0,0 @@ -From: John Crispin -Subject: [PATCH V4 6/6] bss_coloring: allow using a random starting color -Date: Wed, 26 Aug 2020 08:22:16 +0200 - - -Enhance the possible values for he_bss_color. Anything greater than 63 will -make hostapd choose a random color. - -Signed-off-by: John Crispin ---- - hostapd/config_file.c | 7 +++++-- - hostapd/hostapd.conf | 5 ++++- - 2 files changed, 9 insertions(+), 3 deletions(-) - ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -3367,8 +3367,11 @@ static int hostapd_config_fill(struct ho - } else if (os_strcmp(buf, "he_ul_mumimo") == 0) { - conf->he_phy_capab.he_ul_mumimo = atoi(pos); - } else if (os_strcmp(buf, "he_bss_color") == 0) { -- conf->he_op.he_bss_color = atoi(pos) & 0x3f; -- conf->he_op.he_bss_color_disabled = 0; -+ conf->he_op.he_bss_color = atoi(pos); -+ if (conf->he_op.he_bss_color > 63) -+ conf->he_op.he_bss_color = (os_random() % 63) + 1; -+ if (conf->he_op.he_bss_color) -+ conf->he_op.he_bss_color_disabled = 0; - } else if (os_strcmp(buf, "he_bss_color_partial") == 0) { - conf->he_op.he_bss_color_partial = atoi(pos); - } else if (os_strcmp(buf, "he_default_pe_duration") == 0) { ---- a/hostapd/hostapd.conf -+++ b/hostapd/hostapd.conf -@@ -810,7 +810,10 @@ wmm_ac_vo_acm=0 - # 1 = supported - #he_mu_beamformer=1 - --# he_bss_color: BSS color (1-63) -+# he_bss_color: -+# 0 = disable -+# 1-63 = pre-defined color -+# 64+ = random color - #he_bss_color=1 - - # he_bss_color_partial: BSS color AID equation diff --git a/feeds/ipq95xx/hostapd/patches/f00-007-bss_coloring-add-intelligence-color-choose-in-CCA.patch b/feeds/ipq95xx/hostapd/patches/f00-007-bss_coloring-add-intelligence-color-choose-in-CCA.patch deleted file mode 100644 index 4bfdb381..00000000 --- a/feeds/ipq95xx/hostapd/patches/f00-007-bss_coloring-add-intelligence-color-choose-in-CCA.patch +++ /dev/null @@ -1,126 +0,0 @@ -From d0d7cc4647ecad26b7bf04e39a4e9403cab68a48 Mon Sep 17 00:00:00 2001 -From: Karthikeyan Periyasamy -Date: Sat, 15 Aug 2020 18:47:26 +0530 -Subject: [PATCH] hostapd: Add intelligence color choose in CCA - -Gather color information of the neighbor APs and choose available -free color after go through the neighbor colors to minimise the color collision - -Signed-off-by: Karthikeyan Periyasamy ---- - src/ap/ap_list.c | 29 +++++++++++++++++++++++++ - src/ap/ap_list.h | 7 ++++++ - src/ap/hostapd.c | 66 +++++++++++++++++++++++++++++--------------------------- - 3 files changed, 70 insertions(+), 32 deletions(-) - ---- a/src/ap/ap_list.c -+++ b/src/ap/ap_list.c -@@ -174,6 +174,7 @@ void ap_list_process_beacon(struct hosta - struct ap_info *ap; - int new_ap = 0; - int set_beacon = 0; -+ u32 he_operation; - - if (iface->conf->ap_table_max_size < 1) - return; -@@ -210,6 +211,17 @@ void ap_list_process_beacon(struct hosta - else - ap->ht_support = 0; - -+ if (iface->conf->ieee80211ax && -+ elems->he_operation) { -+ he_operation = *(u32 *)elems->he_operation; -+ -+ if (!(he_operation & HE_OPERATION_BSS_COLOR_DISABLED)) -+ ap->color = (he_operation & HE_OPERATION_BSS_COLOR_MASK) >> -+ HE_OPERATION_BSS_COLOR_OFFSET; -+ else -+ ap->color = 0; -+ } -+ - os_get_reltime(&ap->last_beacon); - - if (!new_ap && ap != iface->ap_list) { -@@ -295,6 +307,21 @@ void ap_list_timer(struct hostapd_iface - ieee802_11_update_beacons(iface); - } - -+u64 ap_list_get_color(struct hostapd_iface *iface) -+{ -+ u64 used_color_bitmap = 0; -+ struct ap_info *ap; -+ -+ if (!iface->ap_list) -+ return used_color_bitmap; -+ -+ ap = iface->ap_list; -+ while (ap != NULL) { -+ used_color_bitmap |= (u64)1 << ap->color; -+ ap = ap->next; -+ } -+ return used_color_bitmap; -+} - - int ap_list_init(struct hostapd_iface *iface) - { ---- a/src/ap/ap_list.h -+++ b/src/ap/ap_list.h -@@ -25,6 +25,7 @@ struct ap_info { - int channel; - - int ht_support; -+ u8 color; - - struct os_reltime last_beacon; - }; -@@ -40,6 +41,7 @@ void ap_list_process_beacon(struct hosta - int ap_list_init(struct hostapd_iface *iface); - void ap_list_deinit(struct hostapd_iface *iface); - void ap_list_timer(struct hostapd_iface *iface); -+u64 ap_list_get_color(struct hostapd_iface *iface); - #else /* NEED_AP_MLME */ - static inline int ap_list_init(struct hostapd_iface *iface) - { -@@ -53,6 +55,11 @@ static inline void ap_list_deinit(struct - static inline void ap_list_timer(struct hostapd_iface *iface) - { - } -+ -+static u64 ap_list_get_color(struct hostapd_iface *iface) -+{ -+ return 0; -+} - #endif /* NEED_AP_MLME */ - - #endif /* AP_LIST_H */ ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -3769,6 +3769,7 @@ hostapd_switch_color_timeout_handler(voi - struct cca_settings settings; - struct os_time now; - int i, r, b, ret; -+ u64 neighbor_color; - - if (os_get_time(&now)) - return; -@@ -3777,11 +3778,16 @@ hostapd_switch_color_timeout_handler(voi - if (now.sec - hapd->last_color_collision.sec > 50) - return; - -- r = os_random() % HE_OPERATION_BSS_COLOR_MAX; -- for (i = 0; i < HE_OPERATION_BSS_COLOR_MAX; i++) { -- if (r && (hapd->color_collision_bitmap & (1 << r)) == 0) -+ neighbor_color = ap_list_get_color(hapd->iface); -+ neighbor_color |= hapd->color_collision_bitmap; -+ -+ r = os_random() % HE_OPERATION_BSS_COLOR_MAX - 1; -+ r++; -+ for (i = 1; i < HE_OPERATION_BSS_COLOR_MAX; i++) { -+ if ((neighbor_color & (1 << r)) == 0) - break; -- r = (r + 1) % HE_OPERATION_BSS_COLOR_MAX; -+ r = r % HE_OPERATION_BSS_COLOR_MAX - 1; -+ r++; - } - if (i == HE_OPERATION_BSS_COLOR_MAX) { - /* there are no free colors so turn bss coloring off */ diff --git a/feeds/ipq95xx/hostapd/patches/f00-008-bss_coloring_add_support_to_change_bss_color_by_user.patch b/feeds/ipq95xx/hostapd/patches/f00-008-bss_coloring_add_support_to_change_bss_color_by_user.patch deleted file mode 100644 index d2982dc0..00000000 --- a/feeds/ipq95xx/hostapd/patches/f00-008-bss_coloring_add_support_to_change_bss_color_by_user.patch +++ /dev/null @@ -1,194 +0,0 @@ -From baf3a982caee59ec08602a9e981d6742abc4fc7b Mon Sep 17 00:00:00 2001 -From: Lavanya Suresh -Date: Mon, 28 Sep 2020 23:21:43 +0530 -Subject: [PATCH] hostapd: Add support to change bss color by user - - -hostpad_cli command is added to change bss color in runtime, -for testing purpose. hostapd_cli status can be used to check -updated color. - -Usage: hostapd_cli color_change - -Signed-off-by: Lavanya Suresh ---- - hostapd/ctrl_iface.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ - hostapd/hostapd_cli.c | 23 +++++++++++++++++++++++ - src/ap/ctrl_iface_ap.c | 6 ++++-- - src/ap/hostapd.c | 4 ++-- - src/ap/hostapd.h | 3 ++- - 5 files changed, 76 insertions(+), 5 deletions(-) - -Index: hostapd-2021-12-13-b26f5c0f/hostapd/ctrl_iface.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/hostapd/ctrl_iface.c -+++ hostapd-2021-12-13-b26f5c0f/hostapd/ctrl_iface.c -@@ -2781,6 +2781,59 @@ static int hostapd_ctrl_check_freq_param - } - #endif /* NEED_AP_MLME */ - -+static int hostapd_ctrl_iface_color_change(struct hostapd_iface *iface, -+ char *pos) -+{ -+#ifdef NEED_AP_MLME -+ struct cca_settings settings; -+ struct hostapd_data *hapd = iface->bss[0]; -+ int ret, color; -+ unsigned int i; -+ char *end; -+ -+ os_memset(&settings, 0, sizeof(settings)); -+ color = strtol(pos, &end, 10); -+ if (pos == end || color < 0 || color > 63) { -+ wpa_printf(MSG_ERROR, "colorchange: invalid color provided"); -+ return -1; -+ } -+ -+ if (color == iface->conf->he_op.he_bss_color) { -+ wpa_printf(MSG_ERROR, "colorchange: provided color is already set"); -+ return -1; -+ } -+ -+ if (hapd->cca_in_progress) { -+ wpa_printf(MSG_ERROR, "colorchange: cca is in progress, so color change is now allowed"); -+ return -1; -+ } -+ -+ for (i = 0; i < iface->num_bss; i++) { -+ struct hostapd_data *bss = iface->bss[i]; -+ hostapd_cleanup_cca_params(bss); -+ bss->cca_color = color; -+ bss->cca_count = 10; -+ -+ if (hostapd_fill_cca_settings(bss, &settings)) { -+ wpa_printf(MSG_DEBUG, "hostapd fill cca settings failed for color: %d\n", color); -+ hostapd_cleanup_cca_params(bss); -+ continue; -+ } -+ -+ wpa_printf(MSG_DEBUG, "Setting user selected color: %d\n", color); -+ ret = hostapd_drv_switch_color(bss, &settings); -+ free_beacon_data(&settings.beacon_cca); -+ free_beacon_data(&settings.beacon_after); -+ -+ if (ret) -+ hostapd_cleanup_cca_params(bss); -+ } -+ -+ return 0; -+#else /* NEED_AP_MLME */ -+ return -1; -+#endif /* NEED_AP_MLME */ -+} - - static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface, - char *pos) -@@ -3813,6 +3866,9 @@ static int hostapd_ctrl_iface_receive_pr - } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) { - if (hostapd_ctrl_iface_chan_switch(hapd->iface, buf + 12)) - reply_len = -1; -+ } else if (os_strncmp(buf, "COLOR_CHANGE ", 12) == 0) { -+ if (hostapd_ctrl_iface_color_change(hapd->iface, buf + 12)) -+ reply_len = -1; - } else if (os_strncmp(buf, "VENDOR ", 7) == 0) { - reply_len = hostapd_ctrl_iface_vendor(hapd, buf + 7, reply, - reply_size); -Index: hostapd-2021-12-13-b26f5c0f/hostapd/hostapd_cli.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/hostapd/hostapd_cli.c -+++ hostapd-2021-12-13-b26f5c0f/hostapd/hostapd_cli.c -@@ -1150,6 +1150,27 @@ static int hostapd_cli_cmd_fst(struct wp - } - #endif /* CONFIG_FST */ - -+static int hostapd_cli_cmd_color_change(struct wpa_ctrl *ctrl, -+ int argc, char *argv[]) -+{ -+ char cmd[256]; -+ int res; -+ -+ if (argc < 1) { -+ printf("Invalid color_change command: no argument given \n" -+ "usage: \n"); -+ return -1; -+ } -+ -+ res = os_snprintf(cmd, sizeof(cmd), "COLOR_CHANGE %s", -+ argv[0]); -+ if (os_snprintf_error(sizeof(cmd), res)) { -+ printf("Too long CHAN_CHANGE command\n"); -+ return -1; -+ } -+ -+ return wpa_ctrl_command(ctrl, cmd); -+} - - static int hostapd_cli_cmd_chan_switch(struct wpa_ctrl *ctrl, - int argc, char *argv[]) -@@ -1646,6 +1667,8 @@ static const struct hostapd_cli_cmd host - " [sec_channel_offset=] [center_freq1=]\n" - " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]\n" - " = initiate channel switch announcement" }, -+ { "color_change", hostapd_cli_cmd_color_change, NULL, -+ " = initiate bss color change to set user color\n" }, - { "hs20_wnm_notif", hostapd_cli_cmd_hs20_wnm_notif, NULL, - " \n" - " = send WNM-Notification Subscription Remediation Request" }, -Index: hostapd-2021-12-13-b26f5c0f/src/ap/ctrl_iface_ap.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/ctrl_iface_ap.c -+++ hostapd-2021-12-13-b26f5c0f/src/ap/ctrl_iface_ap.c -@@ -1063,10 +1063,12 @@ int hostapd_ctrl_iface_status(struct hos - ret = os_snprintf(buf + len, buflen - len, - "he_oper_chwidth=%d\n" - "he_oper_centr_freq_seg0_idx=%d\n" -- "he_oper_centr_freq_seg1_idx=%d\n", -+ "he_oper_centr_freq_seg1_idx=%d\n" -+ "he_bss_color=%d\n", - iface->conf->he_oper_chwidth, - iface->conf->he_oper_centr_freq_seg0_idx, -- iface->conf->he_oper_centr_freq_seg1_idx); -+ iface->conf->he_oper_centr_freq_seg1_idx, -+ iface->conf->he_op.he_bss_color); - if (os_snprintf_error(buflen - len, ret)) - return len; - len += ret; -Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/hostapd.c -+++ hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.c -@@ -3429,7 +3429,7 @@ int hostapd_csa_in_progress(struct hosta - - #ifdef NEED_AP_MLME - --static void free_beacon_data(struct beacon_data *beacon) -+void free_beacon_data(struct beacon_data *beacon) - { - os_free(beacon->head); - beacon->head = NULL; -@@ -3834,7 +3834,7 @@ void hostapd_cleanup_cca_params(struct h - } - - --static int hostapd_fill_cca_settings(struct hostapd_data *hapd, -+int hostapd_fill_cca_settings(struct hostapd_data *hapd, - struct cca_settings *settings) - { - struct hostapd_iface *iface = hapd->iface; -Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/hostapd.h -+++ hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.h -@@ -680,10 +680,12 @@ int hostapd_owe_trans_get_info(struct ho - void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx); - int hostapd_check_max_sta(struct hostapd_data *hapd); - -+void free_beacon_data(struct beacon_data *beacon); - - #ifdef CONFIG_IEEE80211AX - void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap); - void hostapd_cleanup_cca_params(struct hostapd_data *hapd); -+int hostapd_fill_cca_settings(struct hostapd_data *hapd, struct cca_settings *settings); - #endif - - /* utils.c */ diff --git a/feeds/ipq95xx/hostapd/patches/f00-009-add-bcca-IE-with-countdown-zero-in-color-change-beacon.patch b/feeds/ipq95xx/hostapd/patches/f00-009-add-bcca-IE-with-countdown-zero-in-color-change-beacon.patch deleted file mode 100644 index 59cbc2d8..00000000 --- a/feeds/ipq95xx/hostapd/patches/f00-009-add-bcca-IE-with-countdown-zero-in-color-change-beacon.patch +++ /dev/null @@ -1,96 +0,0 @@ -From f2cc86f874e09b0b1d1247de98f1720aa51080d8 Mon Sep 17 00:00:00 2001 -From: Lavanya Suresh -Date: Tue, 6 Oct 2020 21:37:04 +0530 -Subject: [PATCH] hostapd: Add BCCA IE with countdown zero - -During BCCA, BCCA IE with countdown zero has to be added -in the beacon in which new color is updated. Remove BCCA -IE in the beacon template after color change is -completed. - -Signed-off-by: Lavanya Suresh ---- - src/ap/drv_callbacks.c | 6 ++++++ - src/ap/hostapd.c | 10 ++++++++-- - src/ap/hostapd.h | 1 + - src/ap/ieee802_11_he.c | 2 +- - 4 files changed, 16 insertions(+), 3 deletions(-) - ---- a/src/ap/drv_callbacks.c -+++ b/src/ap/drv_callbacks.c -@@ -1802,14 +1802,29 @@ static void hostapd_event_bss_color_coll - - static void hostapd_event_cca(struct hostapd_data *hapd, enum wpa_event_type event) - { -+ int b, err; -+ - switch (event) { - case EVENT_CCA_STARTED_NOTIFY: - wpa_printf(MSG_DEBUG, "CCA started on %s", hapd->conf->iface); - break; - case EVENT_CCA_NOTIFY: - wpa_printf(MSG_DEBUG, "CCA finished on %s (new color: %d)", hapd->conf->iface, hapd->cca_color); -- hapd->iface->conf->he_op.he_bss_color = hapd->cca_color; -- hostapd_cleanup_cca_params(hapd); -+ -+ for (b = 0; b < hapd->iface->num_bss; b++) { -+ if (hapd->iface->bss[b]->cca_color != 0) { -+ hapd->iface->conf->he_op.he_bss_color = hapd->iface->bss[b]->cca_color; -+ hapd->iface->bss[b]->cca_in_progress = 0; -+ err = ieee802_11_set_beacon(hapd->iface->bss[b]); -+ if (err) { -+ wpa_printf(MSG_ERROR, "Failed to remove BCCA IE"); -+ hapd->iface->bss[b]->cca_in_progress = 1; -+ } -+ else -+ hostapd_cleanup_cca_params(hapd->iface->bss[b]); -+ } -+ } -+ - break; - case EVENT_CCA_ABORTED_NOTIFY: - wpa_printf(MSG_DEBUG, "CCA aborted on %s for cca_color: %d", hapd->conf->iface, hapd->cca_color); ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -3742,12 +3742,18 @@ int hostapd_fill_cca_settings(struct hos - - old_color = iface->conf->he_op.he_bss_color; - iface->conf->he_op.he_bss_color = hapd->cca_color; -+ -+ settings->cca_count = hapd->cca_count; -+ settings->cca_color = hapd->cca_color; -+ hapd->cca_count = 0; -+ hapd->cca_zero_count = 1; -+ - ret = hostapd_build_beacon_data(hapd, &settings->beacon_after); - iface->conf->he_op.he_bss_color = old_color; - -- settings->cca_count = hapd->cca_count; -- settings->cca_color = hapd->cca_color, -+ hapd->cca_count = settings->cca_count; - hapd->cca_in_progress = 1; -+ hapd->cca_zero_count = 0; - - ret = hostapd_build_beacon_data(hapd, &settings->beacon_cca); - if (ret) { ---- a/src/ap/hostapd.h -+++ b/src/ap/hostapd.h -@@ -298,6 +298,7 @@ struct hostapd_data { - - #ifdef CONFIG_IEEE80211AX - int cca_in_progress; -+ int cca_zero_count; - u8 cca_count; - u8 cca_color; - unsigned int cca_c_off_beacon; ---- a/src/ap/ieee802_11_he.c -+++ b/src/ap/ieee802_11_he.c -@@ -496,7 +496,7 @@ int hostapd_get_he_twt_responder(struct - - u8 * hostapd_eid_cca(struct hostapd_data *hapd, u8 *eid) - { -- if (!hapd->cca_in_progress) -+ if (!hapd->cca_in_progress && !hapd->cca_zero_count) - return eid; - *eid++ = WLAN_EID_EXTENSION; - *eid++ = 3; diff --git a/feeds/ipq95xx/hostapd/patches/f00-010-bss_coloring-check-free-color-periodically.patch b/feeds/ipq95xx/hostapd/patches/f00-010-bss_coloring-check-free-color-periodically.patch deleted file mode 100644 index 87b767a0..00000000 --- a/feeds/ipq95xx/hostapd/patches/f00-010-bss_coloring-check-free-color-periodically.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 7c0383bf8883e2bad9c7beb47712105be38b5427 Mon Sep 17 00:00:00 2001 -From: Lavanya Suresh -Date: Wed, 7 Oct 2020 13:29:03 +0530 -Subject: [PATCH] hostapd: Check free colors periodically if no new color is - available - -In case of collision, if all the colors are in use, start dot11APcollision -timer(50s) and check for new color after timeout. - -Signed-off-by: Lavanya Suresh ---- - src/ap/hostapd.c | 20 +++++++++++++++++--- - src/ap/hostapd.h | 1 + - 2 files changed, 18 insertions(+), 3 deletions(-) - ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -3781,11 +3781,12 @@ hostapd_switch_color_timeout_handler(voi - return; - - /* check if there has been a recent collision */ -- if (now.sec - hapd->last_color_collision.sec > 50) -+ if (now.sec - hapd->last_color_collision.sec > 50 && !hapd->no_free_color) - return; - - neighbor_color = ap_list_get_color(hapd->iface); -- neighbor_color |= hapd->color_collision_bitmap; -+ if (!hapd->no_free_color) -+ neighbor_color |= hapd->color_collision_bitmap; - - r = os_random() % HE_OPERATION_BSS_COLOR_MAX - 1; - r++; -@@ -3797,13 +3798,26 @@ hostapd_switch_color_timeout_handler(voi - } - if (i == HE_OPERATION_BSS_COLOR_MAX) { - /* there are no free colors so turn bss coloring off */ -- wpa_printf(MSG_INFO, "no free colors left, turning of BSS coloring"); -+ wpa_printf(MSG_INFO, "no free colors left, turning off BSS coloring"); - hapd->iface->conf->he_op.he_bss_color_disabled = 1; -+ hapd->no_free_color = 1; - for (b = 0; b < hapd->iface->num_bss; b++) - ieee802_11_set_beacon(hapd->iface->bss[b]); -+ -+ /* Enabling for next check after timeout*/ -+ hapd->iface->conf->he_op.he_bss_color_disabled = 0; -+ -+ /* start timer for DOT11BSS_COLOR_COLLISION_AP_PERIOD, and check free color on timeout */ -+ if (!eloop_is_timeout_registered(hostapd_switch_color_timeout_handler, hapd, NULL)) -+ eloop_register_timeout(DOT11BSS_COLOR_COLLISION_AP_PERIOD, 0, -+ hostapd_switch_color_timeout_handler, hapd, NULL); -+ - return; - } - -+ if (hapd->no_free_color) -+ hapd->no_free_color = 0; -+ - for (b = 0; b < hapd->iface->num_bss; b++) { - struct hostapd_data *bss = hapd->iface->bss[b]; - ---- a/src/ap/hostapd.h -+++ b/src/ap/hostapd.h -@@ -299,6 +299,7 @@ struct hostapd_data { - #ifdef CONFIG_IEEE80211AX - int cca_in_progress; - int cca_zero_count; -+ int no_free_color; - u8 cca_count; - u8 cca_color; - unsigned int cca_c_off_beacon; diff --git a/feeds/ipq95xx/hostapd/patches/g00-003-hostapd-fix-int-in-bool-context-Werror.patch b/feeds/ipq95xx/hostapd/patches/g00-003-hostapd-fix-int-in-bool-context-Werror.patch deleted file mode 100644 index 277cd1e1..00000000 --- a/feeds/ipq95xx/hostapd/patches/g00-003-hostapd-fix-int-in-bool-context-Werror.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 93f695bfe52dd725841fcca71ed4e14e9a90e1dc Mon Sep 17 00:00:00 2001 -From: Abinaya Kalaiselvan -Date: Wed, 25 Nov 2020 19:58:58 +0530 -Subject: [PATCH] hostapd: fix int-in-bool-context Werror - -Add changes to fix the below compilation error. - -./src/rsn_supp/wpa.c:621:35: error: ?: using integer constants -in boolean context, the expression will always evaluate -to 'true' [-Werror=int-in-bool-context] - -Signed-off-by: Abinaya Kalaiselvan ---- - src/rsn_supp/wpa.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c -index 3205527..88c1e3e 100644 ---- a/src/rsn_supp/wpa.c -+++ b/src/rsn_supp/wpa.c -@@ -615,10 +615,11 @@ static int wpa_handle_ext_key_id(struct wpa_sm *sm, - { - if (sm->ext_key_id) { - u16 key_id; -+ u8 use_ext_key_id; - - if (!kde->key_id) { -- wpa_msg(sm->ctx->msg_ctx, -- sm->use_ext_key_id ? MSG_INFO : MSG_DEBUG, -+ use_ext_key_id = sm->use_ext_key_id ? MSG_INFO : MSG_DEBUG; -+ wpa_msg(sm->ctx->msg_ctx, use_ext_key_id, - "RSN: No Key ID in Extended Key ID handshake"); - sm->keyidx_active = 0; - return sm->use_ext_key_id ? -1 : 0; --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/g00-004-hostapd-Initilize-chan-for-second-80-mhz-to-zero.patch b/feeds/ipq95xx/hostapd/patches/g00-004-hostapd-Initilize-chan-for-second-80-mhz-to-zero.patch deleted file mode 100644 index 0efa99e5..00000000 --- a/feeds/ipq95xx/hostapd/patches/g00-004-hostapd-Initilize-chan-for-second-80-mhz-to-zero.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 789bc909ea59671e43fa89e539cca3b8970275fb Mon Sep 17 00:00:00 2001 -From: Muna Sinada -Date: Mon, 30 Nov 2020 20:37:14 -0800 -Subject: [PATCH] hostapd: Initilize chan for second 80 mhz to zero - -CSA updates freq for CSA beacons and after CSA beacons utilizing -hostapd_change_config_freq(). In the case of 80+80 MHz, there are two -channels store, one for the 80 MHz and the second 80 MHz. In non -80+80 cases, the second channel needs to be initialized to zero or -else garbage values are stored in place. - -Signed-off-by: Muna Sinada ---- - src/ap/hostapd.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c -index 346d83cfda91..fa46667017f4 100644 ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -3455,7 +3455,7 @@ static int hostapd_change_config_freq(struct hostapd_data *hapd, - struct hostapd_freq_params *old_params) - { - int channel; -- u8 seg0, seg1; -+ u8 seg0, seg1 = 0; - struct hostapd_hw_modes *mode; - - if (!params->channel) { --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/h00-001-wpa_supplicant-add-mesh-ID-IE-only-for-mesh-mode.patch b/feeds/ipq95xx/hostapd/patches/h00-001-wpa_supplicant-add-mesh-ID-IE-only-for-mesh-mode.patch deleted file mode 100644 index a8df9409..00000000 --- a/feeds/ipq95xx/hostapd/patches/h00-001-wpa_supplicant-add-mesh-ID-IE-only-for-mesh-mode.patch +++ /dev/null @@ -1,33 +0,0 @@ -From ed96951a0e08771570c950f42ebfd49ff0511756 Mon Sep 17 00:00:00 2001 -From: Lavanya Suresh -Date: Thu, 3 Dec 2020 18:58:19 +0530 -Subject: [PATCH] wpa_supplicant: add mesh ID IE only for mesh mode - -Mesh ID IE is added in probe request frame irrespective -of mode. Added check to avoid adding this IE for non-mesh -modes. - -Signed-off-by: Lavanya Suresh ---- - wpa_supplicant/scan.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c -index b9e4162..9992e42 100644 ---- a/wpa_supplicant/scan.c -+++ b/wpa_supplicant/scan.c -@@ -611,7 +611,10 @@ static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s) - } - #endif /* CONFIG_P2P */ - -- wpa_supplicant_mesh_add_scan_ie(wpa_s, &extra_ie); -+#ifdef CONFIG_MESH -+ if (wpa_s->conf->ssid && wpa_s->conf->ssid->mode == WPAS_MODE_MESH) -+ wpa_supplicant_mesh_add_scan_ie(wpa_s, &extra_ie); -+#endif /* CONFIG_MESH */ - - #endif /* CONFIG_WPS */ - --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/h00-002-hostapd-Enable-HE40-support-in-2G-11s-mesh.patch b/feeds/ipq95xx/hostapd/patches/h00-002-hostapd-Enable-HE40-support-in-2G-11s-mesh.patch deleted file mode 100644 index 2cabb040..00000000 --- a/feeds/ipq95xx/hostapd/patches/h00-002-hostapd-Enable-HE40-support-in-2G-11s-mesh.patch +++ /dev/null @@ -1,189 +0,0 @@ -From 42bd9677183c6a71c56c9f36d32e2fb626fdb535 Mon Sep 17 00:00:00 2001 -From: P Praneesh -Date: Tue, 8 Dec 2020 00:28:00 +0530 -Subject: [PATCH] hostapd: Enable HE40 support in 2G 11s mesh - -This patch adds support for HE40 in 2G 11s mesh if -the driver advertise HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G -support in HE capability. - -Signed-off-by: P Praneesh ---- - wpa_supplicant/wpa_supplicant.c | 30 ++++++++++++++++++++++++++++++ - 1 file changed, 30 insertions(+) - -Index: hostapd-2021-02-18/wpa_supplicant/wpa_supplicant.c -=================================================================== ---- hostapd-2021-02-18.orig/wpa_supplicant/wpa_supplicant.c -+++ hostapd-2021-02-18/wpa_supplicant/wpa_supplicant.c -@@ -2378,6 +2378,57 @@ static int drv_supports_vht(struct wpa_s - return mode->vht_capab != 0; - } - -+static void ibss_mesh_setup_2G_he40(struct hostapd_freq_params *freq, -+ struct hostapd_hw_modes *mode, -+ struct wpa_supplicant *wpa_s, -+ const struct wpa_ssid *ssid, -+ int ieee80211_mode) -+{ -+ struct wpa_scan_results *scan_res; -+ int he40plus2G[] = { 2412, 2417, 2422, 2427, 2432, 2437}; -+ int i, res; -+ u8 pri_chan, sec_chan; -+ -+ freq->vht_enabled = vht_supported(mode); -+ freq->sec_channel_offset = -1; -+ -+ if (mode->he_capab[ieee80211_mode].phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] & -+ HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G) -+ freq->bandwidth = 40; -+ -+ /* Setting channel offset as 1 for channel 1 to 6 and -1 for -+ * channel 7 to 11 -+ */ -+ for (i = 0; i < ARRAY_SIZE(he40plus2G); i++) { -+ if (freq->freq == he40plus2G[i]) -+ freq->sec_channel_offset = 1; -+ } -+ -+ freq->center_freq1 = freq->freq + freq->sec_channel_offset * 10; -+ freq->center_freq2 = 0; -+ -+ if (ssid->disable_40mhz_scan) { -+ wpa_printf(MSG_DEBUG, "IBSSS: 40MHz Coex scan disabled"); -+ return; -+ } -+ -+ scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0); -+ if (scan_res == NULL) -+ goto HE20; -+ -+ pri_chan = freq->channel; -+ sec_chan = pri_chan + freq->sec_channel_offset * 4; -+ res = check_40mhz_2g4(mode, scan_res, pri_chan, sec_chan); -+ wpa_scan_results_free(scan_res); -+ if (!res) -+ goto HE20; -+ return; -+HE20: -+ freq->sec_channel_offset = 0; -+ freq->bandwidth = 20; -+ freq->center_freq1 = freq->freq + freq->sec_channel_offset * 10; -+} -+ - static bool ibss_mesh_is_80mhz_avail(int channel, struct hostapd_hw_modes *mode) - { - int i; -@@ -2498,6 +2549,11 @@ void ibss_mesh_setup_freq(struct wpa_sup - else - #endif /* CONFIG_HE_OVERRIDES */ - freq->he_enabled = mode->he_capab[ieee80211_mode].he_supported; -+ -+ if (freq->he_enabled) -+ ibss_mesh_setup_2G_he40(freq, mode, wpa_s, -+ ssid, ieee80211_mode); -+ return; - } - - for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) { -Index: hostapd-2021-02-18/src/drivers/driver.h -=================================================================== ---- hostapd-2021-02-18.orig/src/drivers/driver.h -+++ hostapd-2021-02-18/src/drivers/driver.h -@@ -1203,6 +1203,11 @@ struct wpa_driver_associate_params { - * 2 = both hunting-and-pecking loop and hash-to-element enabled - */ - int sae_pwe; -+ -+ /** -+ * Disable HE40MHz coexistence scan -+ */ -+ int disable_40mhz_scan; - }; - - enum hide_ssid { -Index: hostapd-2021-02-18/wpa_supplicant/config.c -=================================================================== ---- hostapd-2021-02-18.orig/wpa_supplicant/config.c -+++ hostapd-2021-02-18/wpa_supplicant/config.c -@@ -2804,6 +2804,7 @@ static const struct parse_data ssid_fiel - { INT_RANGE(beacon_prot, 0, 1) }, - { INT_RANGE(transition_disable, 0, 255) }, - { INT_RANGE(sae_pk, 0, 2) }, -+ { INT_RANGE(disable_40mhz_scan, 0, 1)}, - }; - - #undef OFFSET -Index: hostapd-2021-02-18/wpa_supplicant/config_file.c -=================================================================== ---- hostapd-2021-02-18.orig/wpa_supplicant/config_file.c -+++ hostapd-2021-02-18/wpa_supplicant/config_file.c -@@ -885,7 +885,7 @@ static void wpa_config_write_network(FIL - #ifdef CONFIG_HE_OVERRIDES - INT(disable_he); - #endif /* CONFIG_HE_OVERRIDES */ -- -+ INT(disable_40mhz_scan); - #undef STR - #undef INT - #undef INT_DEF -Index: hostapd-2021-02-18/wpa_supplicant/config_ssid.h -=================================================================== ---- hostapd-2021-02-18.orig/wpa_supplicant/config_ssid.h -+++ hostapd-2021-02-18/wpa_supplicant/config_ssid.h -@@ -1165,6 +1165,11 @@ struct wpa_ssid { - * 2 = both hunting-and-pecking loop and hash-to-element enabled - */ - int sae_pwe; -+ -+ /** -+ * disable_40mhz_scan - Disable 40MHz coex scan -+ */ -+ int disable_40mhz_scan; - }; - - #endif /* CONFIG_SSID_H */ -Index: hostapd-2021-02-18/wpa_supplicant/wpa_cli.c -=================================================================== ---- hostapd-2021-02-18.orig/wpa_supplicant/wpa_cli.c -+++ hostapd-2021-02-18/wpa_supplicant/wpa_cli.c -@@ -1482,7 +1482,8 @@ static const char *network_fields[] = { - #ifdef CONFIG_HS20 - "update_identifier", - #endif /* CONFIG_HS20 */ -- "mac_addr", "pbss", "wps_disabled" -+ "mac_addr", "pbss", "wps_disabled", -+ "disable_40mhz_scan", - }; - - -Index: hostapd-2021-02-18/wpa_supplicant/wpa_supplicant.conf -=================================================================== ---- hostapd-2021-02-18.orig/wpa_supplicant/wpa_supplicant.conf -+++ hostapd-2021-02-18/wpa_supplicant/wpa_supplicant.conf -@@ -158,6 +158,9 @@ ap_scan=1 - # 1 = deny unless in accept list - macaddr_acl=0 - -+# Disable 40MHz co-existence scan in Mesh -+#disable_40mhz_scan=1 -+ - # Accept/deny lists are read from separate files (containing list of - # MAC addresses, one per line). Use absolute path name to make sure that the - # files can be read on SIGHUP configuration reloads. -@@ -1983,6 +1986,15 @@ network={ - psk="very secret passphrase" - } - -+# Disable 40MHz Co-existence scan in mesh -+network={ -+ ssid="OpenWrt" -+ key_mgmt=SAE -+ mode=5 -+ frequency=2437 -+ psk="1234567890" -+ disable_40mhz_scan=1 -+} - - # Catch all example that allows more or less all configuration modes - network={ diff --git a/feeds/ipq95xx/hostapd/patches/h00-003-hostapd-allow-AP_VLAN-creation-for-dynamic-VLAN.patch b/feeds/ipq95xx/hostapd/patches/h00-003-hostapd-allow-AP_VLAN-creation-for-dynamic-VLAN.patch deleted file mode 100644 index 293d39e9..00000000 --- a/feeds/ipq95xx/hostapd/patches/h00-003-hostapd-allow-AP_VLAN-creation-for-dynamic-VLAN.patch +++ /dev/null @@ -1,95 +0,0 @@ -commit 120f4976cdb83e421459242db7a1b41c16b772f6 -Author: Sathishkumar Muruganandam -Date: Wed Jan 13 16:51:07 2021 +0530 - - hostapd: allow AP_VLAN creation with wpa_psk_file having vlan_id - - When WPA_DRIVER_FLAGS_VLAN_OFFLOAD is advertised from driver during - NSS offload enabled case, vlan_id is sent to mac80211 which is stored - in key_conf for dynamic VLAN support on NSS offload case. - - This flag blocks the AP_VLAN creation when using wpa_psk_file with - vlan_id which is needed for dynamic VLAN support on NSS offload case. - - Hence removing the check associated with _VLAN_OFFLOAD flag which is - advertised only when NSS offload is enabled to allow AP_VLAN creation. - - Signed-off-by: Sathishkumar Muruganandam - ---- a/src/ap/sta_info.c -+++ b/src/ap/sta_info.c -@@ -1060,8 +1060,7 @@ int ap_sta_bind_vlan(struct hostapd_data - if (sta->vlan_id == old_vlanid) - goto skip_counting; - -- if (sta->vlan_id > 0 && !vlan && -- !(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_VLAN_OFFLOAD)) { -+ if (sta->vlan_id > 0 && !vlan) { - hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, - HOSTAPD_LEVEL_DEBUG, "could not find VLAN for " - "binding station to (vlan_id=%d)", ---- a/src/ap/wpa_auth_glue.c -+++ b/src/ap/wpa_auth_glue.c -@@ -437,12 +437,8 @@ static int hostapd_wpa_auth_set_key(void - - if (vlan_id > 0) { - ifname = hostapd_get_vlan_id_ifname(hapd->conf->vlan, vlan_id); -- if (!ifname) { -- if (!(hapd->iface->drv_flags & -- WPA_DRIVER_FLAGS_VLAN_OFFLOAD)) -- return -1; -- ifname = hapd->conf->iface; -- } -+ if (!ifname) -+ return -1; - } - - #ifdef CONFIG_TESTING_OPTIONS -@@ -917,32 +913,27 @@ static int hostapd_wpa_auth_update_vlan( - #ifndef CONFIG_NO_VLAN - struct hostapd_data *hapd = ctx; - struct sta_info *sta; -+ struct vlan_description vlan_desc; - - sta = ap_get_sta(hapd, addr); - if (!sta) - return -1; - -- if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_VLAN_OFFLOAD)) { -- struct vlan_description vlan_desc; -- -- os_memset(&vlan_desc, 0, sizeof(vlan_desc)); -- vlan_desc.notempty = 1; -- vlan_desc.untagged = vlan_id; -- if (!hostapd_vlan_valid(hapd->conf->vlan, &vlan_desc)) { -- wpa_printf(MSG_INFO, -- "Invalid VLAN ID %d in wpa_psk_file", -- vlan_id); -- return -1; -- } -+ os_memset(&vlan_desc, 0, sizeof(vlan_desc)); -+ vlan_desc.notempty = 1; -+ vlan_desc.untagged = vlan_id; -+ if (!hostapd_vlan_valid(hapd->conf->vlan, &vlan_desc)) { -+ wpa_printf(MSG_INFO, -+ "Invalid VLAN ID %d in wpa_psk_file", -+ vlan_id); -+ return -1; -+ } - -- if (ap_sta_set_vlan(hapd, sta, &vlan_desc) < 0) { -- wpa_printf(MSG_INFO, -- "Failed to assign VLAN ID %d from wpa_psk_file to " -- MACSTR, vlan_id, MAC2STR(sta->addr)); -- return -1; -- } -- } else { -- sta->vlan_id = vlan_id; -+ if (ap_sta_set_vlan(hapd, sta, &vlan_desc) < 0) { -+ wpa_printf(MSG_INFO, -+ "Failed to assign VLAN ID %d from wpa_psk_file to " -+ MACSTR, vlan_id, MAC2STR(sta->addr)); -+ return -1; - } - - wpa_printf(MSG_INFO, diff --git a/feeds/ipq95xx/hostapd/patches/h00-004-hostapd-Add-support-for-beacon-tx-mode.patch b/feeds/ipq95xx/hostapd/patches/h00-004-hostapd-Add-support-for-beacon-tx-mode.patch deleted file mode 100644 index 09065f12..00000000 --- a/feeds/ipq95xx/hostapd/patches/h00-004-hostapd-Add-support-for-beacon-tx-mode.patch +++ /dev/null @@ -1,279 +0,0 @@ -From a1d4da59739c2054eb46cf634320c8bd323a8069 Mon Sep 17 00:00:00 2001 -From: Maharaja Kennadyrajan -Date: Tue, 12 Jan 2021 18:12:37 +0530 -Subject: [PATCH] hostapd: Add support for beacon tx mode - -User can configure the beacon tx mode while bring-up the -AP via hostapd configuration and while bring-up MESH via -wpa_supplicant configuration. - -Use the below configuration in the hostapd/wpa_supplicant -to configure the beacon tx mode. - -"beacon_tx_mode=N", where N = 1 for STAGGERED beacon mode -and N = 2 for BURST beacon mode. - -Signed-off-by: Maharaja Kennadyrajan ---- - hostapd/config_file.c | 9 +++++++++ - src/ap/ap_config.c | 2 ++ - src/ap/ap_config.h | 1 + - src/ap/beacon.c | 2 ++ - src/ap/ctrl_iface_ap.c | 6 ++++-- - src/drivers/driver.h | 5 +++++ - src/drivers/driver_nl80211.c | 16 +++++++++++++++- - src/drivers/nl80211_copy.h | 4 ++++ - 8 files changed, 42 insertions(+), 3 deletions(-) - -Index: hostapd-2021-12-13-b26f5c0f/hostapd/config_file.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/hostapd/config_file.c -+++ hostapd-2021-12-13-b26f5c0f/hostapd/config_file.c -@@ -4621,6 +4621,15 @@ static int hostapd_config_fill(struct ho - bss->disable_11ac = !!atoi(pos); - } else if (os_strcmp(buf, "disable_11ax") == 0) { - bss->disable_11ax = !!atoi(pos); -+ } else if (os_strcmp(buf, "beacon_tx_mode") == 0) { -+ int val = atoi(pos); -+ -+ if (val < 0 || val > 2) { -+ wpa_printf(MSG_ERROR, "Line %d: invalid beacon_tx_mode %d", -+ line, val); -+ return 1; -+ } -+ bss->beacon_tx_mode = val; - #ifdef CONFIG_PASN - #ifdef CONFIG_TESTING_OPTIONS - } else if (os_strcmp(buf, "force_kdk_derivation") == 0) { -Index: hostapd-2021-12-13-b26f5c0f/src/ap/ap_config.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/ap_config.h -+++ hostapd-2021-12-13-b26f5c0f/src/ap/ap_config.h -@@ -911,6 +911,7 @@ struct hostapd_bss_config { - u8 ext_capa[EXT_CAPA_MAX_LEN]; - - u8 rnr; -+ int beacon_tx_mode; - }; - - /** -Index: hostapd-2021-12-13-b26f5c0f/src/ap/beacon.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/beacon.c -+++ hostapd-2021-12-13-b26f5c0f/src/ap/beacon.c -@@ -1779,6 +1779,8 @@ int ieee802_11_build_ap_params(struct ho - } - } - -+ params->beacon_tx_mode = hapd->conf->beacon_tx_mode; -+ - return 0; - } - -Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/drivers/driver.h -+++ hostapd-2021-12-13-b26f5c0f/src/drivers/driver.h -@@ -1213,6 +1213,12 @@ struct wpa_driver_associate_params { - * Disable HE40MHz coexistence scan - */ - int disable_40mhz_scan; -+ /** -+ * Beacon Tx mode - To configure STAGGERED or BURST mode -+ * 1 = STAGGERED beacon tx mode -+ * 2 = BURST beacon tx mode -+ */ -+ int beacon_tx_mode; - }; - - enum hide_ssid { -@@ -1592,6 +1598,13 @@ struct wpa_driver_ap_params { - * Unsolicited broadcast Probe Response template length - */ - size_t unsol_bcast_probe_resp_tmpl_len; -+ -+ /** -+ * Beacon Tx mode - To configure STAGGERED or BURST mode -+ * 1 = STAGGERED beacon tx mode -+ * 2 = BURST beacon tx mode -+ */ -+ int beacon_tx_mode; - }; - - struct wpa_driver_mesh_bss_params { -@@ -1631,6 +1644,7 @@ struct wpa_driver_mesh_join_params { - unsigned int flags; - bool handle_dfs; - int mcast_rate; -+ int beacon_tx_mode; - }; - - struct wpa_driver_set_key_params { -Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/drivers/driver_nl80211.c -+++ hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211.c -@@ -4573,6 +4573,7 @@ static int wpa_driver_nl80211_set_ap(voi - wpa_printf(MSG_DEBUG, "nl80211: beacon_rate=%u", params->beacon_rate); - wpa_printf(MSG_DEBUG, "nl80211: rate_type=%d", params->rate_type); - wpa_printf(MSG_DEBUG, "nl80211: dtim_period=%d", params->dtim_period); -+ wpa_printf(MSG_DEBUG, "nl80211: beacon_tx_mode=%d", params->beacon_tx_mode); - wpa_printf(MSG_DEBUG, "nl80211: ssid=%s", - wpa_ssid_txt(params->ssid, params->ssid_len)); - if (!(msg = nl80211_bss_msg(bss, 0, cmd)) || -@@ -4584,7 +4585,9 @@ static int wpa_driver_nl80211_set_ap(voi - nl80211_put_beacon_rate(msg, drv->capa.flags, drv->capa.flags2, - params) || - nl80211_put_dtim_period(msg, params->dtim_period) || -- nla_put(msg, NL80211_ATTR_SSID, params->ssid_len, params->ssid)) -+ nla_put(msg, NL80211_ATTR_SSID, params->ssid_len, params->ssid) || -+ (params->beacon_tx_mode && -+ nla_put_u32(msg, NL80211_ATTR_BEACON_TX_MODE, params->beacon_tx_mode))) - goto fail; - if (params->proberesp && params->proberesp_len) { - wpa_hexdump(MSG_DEBUG, "nl80211: proberesp (offload)", -@@ -10648,7 +10651,9 @@ static int nl80211_join_mesh(struct i802 - nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) || - nl80211_put_beacon_int(msg, params->beacon_int) || - nl80211_put_mcast_rate(msg, params->mcast_rate) || -- nl80211_put_dtim_period(msg, params->dtim_period)) -+ nl80211_put_dtim_period(msg, params->dtim_period) || -+ (params->beacon_tx_mode && -+ nla_put_u32(msg, NL80211_ATTR_BEACON_TX_MODE, params->beacon_tx_mode))) - goto fail; - - wpa_printf(MSG_DEBUG, " * flags=%08X", params->flags); -Index: hostapd-2021-12-13-b26f5c0f/src/drivers/nl80211_copy.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/drivers/nl80211_copy.h -+++ hostapd-2021-12-13-b26f5c0f/src/drivers/nl80211_copy.h -@@ -2579,6 +2579,10 @@ enum nl80211_commands { - * @NL80211_ATTR_HE_MUEDCA_PARAMS: MU-EDCA AC parameters for the - NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS command. - * -+ * @NL80211_ATTR_BEACON_TX_MODE: used to configure the beacon tx mode as -+ * staggered mode or burst mode in %NL80211_CMD_START_AP from -+ * user-space. -+ * - * @NUM_NL80211_ATTR: total number of nl80211_attrs available - * @NL80211_ATTR_MAX: highest attribute number currently defined - * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -3087,6 +3091,8 @@ enum nl80211_attrs { - NL80211_ATTR_MBSSID_CONFIG, - NL80211_ATTR_MBSSID_ELEMS, - -+ NL80211_ATTR_BEACON_TX_MODE, -+ - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, -@@ -7333,4 +7339,13 @@ enum nl80211_sar_specs_attrs { - NL80211_SAR_ATTR_SPECS_MAX = __NL80211_SAR_ATTR_SPECS_LAST - 1, - }; - -+ -+/** -+ * enum nl80211_beacon_tx_mode - Beacon Tx Mode enum. -+ * Used to configure beacon staggered mode or beacon burst mode. -+ */ -+enum nl80211_beacon_tx_mode { -+ NL80211_BEACON_STAGGERED_MODE = 1, -+ NL80211_BEACON_BURST_MODE = 2, -+}; - #endif /* __LINUX_NL80211_H */ -Index: hostapd-2021-12-13-b26f5c0f/hostapd/hostapd.conf -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/hostapd/hostapd.conf -+++ hostapd-2021-12-13-b26f5c0f/hostapd/hostapd.conf -@@ -254,6 +254,9 @@ rts_threshold=-1 - # it. - fragm_threshold=-1 - -+# Beacon Tx mode; 1 = STAGGERED beacon tx mode; 2 = BURST beacon tx mode. -+beacon_tx_mode=1 -+ - # Rate configuration - # Default is to enable all rates supported by the hardware. This configuration - # item allows this list be filtered so that only the listed rates will be left -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/config.c -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config.c -@@ -2740,6 +2740,7 @@ static const struct parse_data ssid_fiel - { INT_RANGE(transition_disable, 0, 255) }, - { INT_RANGE(sae_pk, 0, 2) }, - { INT_RANGE(disable_40mhz_scan, 0, 1)}, -+ { INT_RANGE(beacon_tx_mode, 1, 2)}, - }; - - #undef OFFSET -@@ -3255,6 +3256,7 @@ void wpa_config_set_network_defaults(str - #endif /* CONFIG_MACSEC */ - ssid->mac_addr = -1; - ssid->max_oper_chwidth = DEFAULT_MAX_OPER_CHWIDTH; -+ ssid->beacon_tx_mode = DEFAULT_BEACON_TX_MODE; - } - - -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config_file.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/config_file.c -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config_file.c -@@ -889,6 +889,7 @@ static void wpa_config_write_network(FIL - INT(disable_he); - #endif /* CONFIG_HE_OVERRIDES */ - INT(disable_40mhz_scan); -+ INT(beacon_tx_mode); - #undef STR - #undef INT - #undef INT_DEF -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config_ssid.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/config_ssid.h -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config_ssid.h -@@ -47,6 +47,7 @@ - #define DEFAULT_AMPDU_DENSITY -1 /* no change */ - #define DEFAULT_USER_SELECTED_SIM 1 - #define DEFAULT_MAX_OPER_CHWIDTH -1 -+#define DEFAULT_BEACON_TX_MODE 0 - - /* Consider global sae_pwe for SAE mechanism for PWE derivation */ - #define DEFAULT_SAE_PWE 4 -@@ -1193,6 +1194,13 @@ struct wpa_ssid { - * disable_40mhz_scan - Disable 40MHz coex scan - */ - int disable_40mhz_scan; -+ -+ /** -+ * beacon_tx_mode - Beacon Tx mode -+ * 1 = STAGGERED MODE -+ * 2 = BURST MODE -+ */ -+ int beacon_tx_mode; - }; - - #endif /* CONFIG_SSID_H */ -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/mesh.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/mesh.c -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/mesh.c -@@ -693,6 +693,7 @@ int wpa_supplicant_join_mesh(struct wpa_ - params->dtim_period = ssid->dtim_period; - else if (wpa_s->conf->dtim_period > 0) - params->dtim_period = wpa_s->conf->dtim_period; -+ params->beacon_tx_mode = ssid->beacon_tx_mode; - params->conf.max_peer_links = wpa_s->conf->max_peer_links; - if (ssid->mesh_rssi_threshold < DEFAULT_MESH_RSSI_THRESHOLD) { - params->conf.rssi_threshold = ssid->mesh_rssi_threshold; -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_cli.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/wpa_cli.c -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_cli.c -@@ -1490,6 +1490,7 @@ static const char *network_fields[] = { - #endif /* CONFIG_HS20 */ - "mac_addr", "pbss", "wps_disabled", - "disable_40mhz_scan", -+ "beacon_tx_mode", - }; - - diff --git a/feeds/ipq95xx/hostapd/patches/h00-007-b-hostapd-Fix-HE-chan-switch-command-to-use-proper-BW.patch b/feeds/ipq95xx/hostapd/patches/h00-007-b-hostapd-Fix-HE-chan-switch-command-to-use-proper-BW.patch deleted file mode 100644 index 5f0b455f..00000000 --- a/feeds/ipq95xx/hostapd/patches/h00-007-b-hostapd-Fix-HE-chan-switch-command-to-use-proper-BW.patch +++ /dev/null @@ -1,91 +0,0 @@ -From ebcd20553b63eb899b6983b5b205e374aba85e73 Mon Sep 17 00:00:00 2001 -From: Lavanya Suresh -Date: Tue, 18 May 2021 12:56:15 +0530 -Subject: [PATCH] hostapd: Fix HE chan switch command to use proper BW - -VHT is not enabled when HE mode is indicated in channel -switch command, due to which VHT operation IE is missing -in beacon causing STA to connect in HT40 mode. - -HE support for channel switch command patch is modified in -upstream commit causing this issue. It is reverted to the -previous version for fixing the same. - -Fixes: I4bd28058adbc27 (hostap: upgrade hostapd to 59e9794c7d7e) - -Signed-off-by: Lavanya Suresh ---- - src/ap/drv_callbacks.c | 38 ++++++++++++++++++++++---------------- - 1 file changed, 22 insertions(+), 16 deletions(-) - ---- a/src/ap/drv_callbacks.c -+++ b/src/ap/drv_callbacks.c -@@ -928,22 +928,30 @@ void hostapd_event_ch_switch(struct host - hapd->iconf->ieee80211n = ht; - if (!ht) { - hapd->iconf->ieee80211ac = 0; -- } else if (hapd->iconf->ch_switch_vht_config) { -- /* CHAN_SWITCH VHT config */ -- if (hapd->iconf->ch_switch_vht_config & -- CH_SWITCH_VHT_ENABLED) -- hapd->iconf->ieee80211ac = 1; -- else if (hapd->iconf->ch_switch_vht_config & -- CH_SWITCH_VHT_DISABLED) -- hapd->iconf->ieee80211ac = 0; -- } else if (hapd->iconf->ch_switch_he_config) { -- /* CHAN_SWITCH HE config */ -- if (hapd->iconf->ch_switch_he_config & -- CH_SWITCH_HE_ENABLED) -- hapd->iconf->ieee80211ax = 1; -- else if (hapd->iconf->ch_switch_he_config & -- CH_SWITCH_HE_DISABLED) -+ if (!is_6ghz_freq(hapd->iface->freq)) - hapd->iconf->ieee80211ax = 0; -+ } else { -+ if (hapd->iconf->ch_switch_vht_config) { -+ /* CHAN_SWITCH VHT config */ -+ if (hapd->iconf->ch_switch_vht_config & -+ CH_SWITCH_VHT_ENABLED) -+ hapd->iconf->ieee80211ac = 1; -+ else if (hapd->iconf->ch_switch_vht_config & -+ CH_SWITCH_VHT_DISABLED) -+ hapd->iconf->ieee80211ac = 0; -+ } -+ if (hapd->iconf->ch_switch_he_config) { -+ /* CHAN_SWITCH HE config */ -+ if (hapd->iconf->ch_switch_he_config & -+ CH_SWITCH_HE_ENABLED) { -+ hapd->iconf->ieee80211ax = 1; -+ if (!is_6ghz_freq(hapd->iface->freq)) -+ hapd->iconf->ieee80211ac = 1; -+ } -+ else if (hapd->iconf->ch_switch_he_config & -+ CH_SWITCH_HE_DISABLED) -+ hapd->iconf->ieee80211ax = 0; -+ } - } - hapd->iconf->ch_switch_vht_config = 0; - hapd->iconf->ch_switch_he_config = 0; ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -3727,12 +3727,17 @@ hostapd_switch_channel_fallback(struct h - iface->freq = freq_params->freq; - iface->conf->channel = freq_params->channel; - iface->conf->secondary_channel = freq_params->sec_channel_offset; -- hostapd_set_oper_centr_freq_seg0_idx(iface->conf, seg0_idx); -- hostapd_set_oper_centr_freq_seg1_idx(iface->conf, seg1_idx); -- hostapd_set_oper_chwidth(iface->conf, bw); - iface->conf->ieee80211n = freq_params->ht_enabled; - iface->conf->ieee80211ac = freq_params->vht_enabled; - iface->conf->ieee80211ax = freq_params->he_enabled; -+ hostapd_set_oper_centr_freq_seg0_idx(iface->conf, seg0_idx); -+ hostapd_set_oper_centr_freq_seg1_idx(iface->conf, seg1_idx); -+ hostapd_set_oper_chwidth(iface->conf, bw); -+ -+ /* -+ * Resetting operating class to avoid referring previous values -+ */ -+ iface->conf->op_class = 0; - - /* - * cs_params must not be cleared earlier because the freq_params diff --git a/feeds/ipq95xx/hostapd/patches/h00-007-hostapd-Setting-Spectrum-Management-bit-for-chan-swi.patch b/feeds/ipq95xx/hostapd/patches/h00-007-hostapd-Setting-Spectrum-Management-bit-for-chan-swi.patch deleted file mode 100644 index c38e7912..00000000 --- a/feeds/ipq95xx/hostapd/patches/h00-007-hostapd-Setting-Spectrum-Management-bit-for-chan-swi.patch +++ /dev/null @@ -1,67 +0,0 @@ -From d2b5a9ed668829c04a8c86e8712cc045a9aaac5f Mon Sep 17 00:00:00 2001 -From: Muna Sinada -Date: Mon, 11 Jan 2021 17:30:34 -0800 -Subject: [PATCH] hostapd: Setting Spectrum Management bit for chan switch - -When CSA IEs are adversied by AP when CSA is initiated, spectrum -management bit in capability information located in management frame's -fixed field shoud be set. Therfore when channel switch is supported, -the spectrum management bit is set. - -Signed-off-by: Muna Sinada ---- - src/ap/ap_config.c | 4 +++- - src/ap/ieee802_11.c | 15 +++++++++------ - 2 files changed, 12 insertions(+), 7 deletions(-) - -Index: hostapd-2021-02-18/src/ap/ap_config.c -=================================================================== ---- hostapd-2021-02-18.orig/src/ap/ap_config.c -+++ hostapd-2021-02-18/src/ap/ap_config.c -@@ -229,6 +229,8 @@ struct hostapd_config * hostapd_config_d - conf->fragm_threshold = -2; /* user driver default: 2346 */ - /* Set to invalid value means do not add Power Constraint IE */ - conf->local_pwr_constraint = -1; -+ /* Set to invalid value means that user did not set this value */ -+ conf->spectrum_mgmt_required = -1; - - conf->wmm_ac_params[0] = ac_be; - conf->wmm_ac_params[1] = ac_bk; -@@ -1471,7 +1473,7 @@ int hostapd_config_check(struct hostapd_ - return -1; - } - -- if (full_config && conf->spectrum_mgmt_required && -+ if (full_config && conf->spectrum_mgmt_required != -1 && - conf->local_pwr_constraint == -1) { - wpa_printf(MSG_ERROR, "Cannot set Spectrum Management bit without Country and Power Constraint elements"); - return -1; -Index: hostapd-2021-02-18/src/ap/ieee802_11.c -=================================================================== ---- hostapd-2021-02-18.orig/src/ap/ieee802_11.c -+++ hostapd-2021-02-18/src/ap/ieee802_11.c -@@ -300,15 +300,18 @@ u16 hostapd_own_capab_info(struct hostap - capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME; - - /* -- * Currently, Spectrum Management capability bit is set when directly -- * requested in configuration by spectrum_mgmt_required or when AP is -- * running on DFS channel. -+ * Currently, Spectrum Management capability bit is set by default when -+ * channel switch is supported. When CSA is not supported, then Spectrum -+ * Management capability bit is set when directly requested in -+ * configuration by spectrum_mgmt_required or when AP is running on DFS -+ * channel. - * TODO: Also consider driver support for TPC to set Spectrum Mgmt bit - */ - if (hapd->iface->current_mode && -- hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A && -- (hapd->iconf->spectrum_mgmt_required || dfs)) -- capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; -+ hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A) -+ if (!(hapd->iconf->spectrum_mgmt_required == 0 && !dfs) && -+ (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA || dfs)) -+ capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; - - for (i = 0; i < RRM_CAPABILITIES_IE_LEN; i++) { - if (hapd->conf->radio_measurements[i]) { diff --git a/feeds/ipq95xx/hostapd/patches/h00-008-a-add-support-for-6ghz-tpc.patch b/feeds/ipq95xx/hostapd/patches/h00-008-a-add-support-for-6ghz-tpc.patch deleted file mode 100644 index 46805106..00000000 --- a/feeds/ipq95xx/hostapd/patches/h00-008-a-add-support-for-6ghz-tpc.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 2974dde2aa3273451b6a51c33a30fc98cee10b25 Mon Sep 17 00:00:00 2001 -From: Pradeep Kumar Chitrapu -Date: Sat, 30 Jan 2021 10:15:52 -0800 -Subject: [PATCH 1/4] hostapd: Add country Information element support for 6Ghz - -Signed-off-by: Pradeep Kumar Chitrapu ---- - src/ap/beacon.c | 66 +++++++++++++++++++++++++----------- - src/common/ieee802_11_defs.h | 10 ++++++ - 2 files changed, 56 insertions(+), 20 deletions(-) - ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -187,7 +187,8 @@ static u8 * hostapd_eid_pwr_constraint(s - } - - --static u8 * hostapd_eid_country_add(u8 *pos, u8 *end, int chan_spacing, -+static u8 * hostapd_eid_country_add(struct hostapd_data *hapd, u8 *pos, -+ u8 *end, int chan_spacing, - struct hostapd_channel_data *start, - struct hostapd_channel_data *prev) - { -@@ -199,30 +200,20 @@ static u8 * hostapd_eid_country_add(u8 * - /* number of channels */ - *pos++ = (prev->chan - start->chan) / chan_spacing + 1; - /* maximum transmit power level */ -- *pos++ = start->max_tx_power; -+ if (!is_6ghz_op_class(hapd->iconf->op_class)) -+ *pos++ = start->max_tx_power; -+ else -+ *pos++ = 0; /* Reserved for 6GHz Band */ - - return pos; - } - -- --static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid, -- int max_len) -+static u8 * hostapd_fill_triplets(struct hostapd_data *hapd, u8 *pos, -+ u8 *end) - { -- u8 *pos = eid; -- u8 *end = eid + max_len; -- int i; - struct hostapd_hw_modes *mode; - struct hostapd_channel_data *start, *prev; -- int chan_spacing = 1; -- -- if (!hapd->iconf->ieee80211d || max_len < 6 || -- hapd->iface->current_mode == NULL) -- return eid; -- -- *pos++ = WLAN_EID_COUNTRY; -- pos++; /* length will be set later */ -- os_memcpy(pos, hapd->iconf->country, 3); /* e.g., 'US ' */ -- pos += 3; -+ int i, chan_spacing = 1; - - mode = hapd->iface->current_mode; - if (mode->mode == HOSTAPD_MODE_IEEE80211A) -@@ -233,6 +224,7 @@ static u8 * hostapd_eid_country(struct h - struct hostapd_channel_data *chan = &mode->channels[i]; - if (chan->flag & HOSTAPD_CHAN_DISABLED) - continue; -+ - if (start && prev && - prev->chan + chan_spacing == chan->chan && - start->max_tx_power == chan->max_tx_power) { -@@ -241,7 +233,8 @@ static u8 * hostapd_eid_country(struct h - } - - if (start && prev) { -- pos = hostapd_eid_country_add(pos, end, chan_spacing, -+ pos = hostapd_eid_country_add(hapd, pos, end, -+ chan_spacing, - start, prev); - start = NULL; - } -@@ -251,10 +244,48 @@ static u8 * hostapd_eid_country(struct h - } - - if (start) { -- pos = hostapd_eid_country_add(pos, end, chan_spacing, -+ pos = hostapd_eid_country_add(hapd, pos, end, -+ chan_spacing, - start, prev); - } - -+ return pos; -+} -+ -+static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid, -+ int max_len) -+{ -+ u8 *pos = eid; -+ u8 *end = eid + max_len; -+ -+ if (!hapd->iconf->ieee80211d || max_len < 6 || -+ hapd->iface->current_mode == NULL) -+ return eid; -+ -+ *pos++ = WLAN_EID_COUNTRY; -+ pos++; /* length will be set later */ -+ os_memcpy(pos, hapd->iconf->country, 3); /* e.g., 'US ' */ -+ pos += 3; -+ -+ if (is_6ghz_op_class(hapd->iconf->op_class)) { -+ /* Third octet of the country string to indicate -+ * Global Operating Class -+ */ -+ eid[4] = 0x4; -+ -+ *pos++ = WLAN_EID_EXT_OPERATING_TRIPLET; -+ /* Operating class*/ -+ *pos++ = hapd->iconf->op_class; -+ /* Coverage Class */ -+ *pos++ = 0; -+ /* Subband Triplets are required only for 20MHz case */ -+ if (hapd->iconf->op_class == 131 || -+ hapd->iconf->op_class == 136) -+ pos = hostapd_fill_triplets(hapd, pos, end); -+ } else { -+ pos = hostapd_fill_triplets(hapd, pos, end); -+ } -+ - if ((pos - eid) & 1) { - if (end - pos < 1) - return eid; ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -494,6 +494,16 @@ - #define WLAN_EID_EXT_ANTI_CLOGGING_TOKEN 93 - #define WLAN_EID_EXT_PASN_PARAMS 100 - -+/* Operating Triplet can be any integer >= 201 -+ * From IEEE P802.11-REVmd/D4.0: The first octet in each Subband -+ * Triplet field or Operating Triplet field contains an unsigned -+ * integer and identifies the type of field. If the integer has -+ * a value less than or equal to 200, then the field is a -+ * Subband Triplet field. If the integer has a value of 201 or -+ * greater, then the field is an Operating Triplet field. -+ */ -+#define WLAN_EID_EXT_OPERATING_TRIPLET 201 -+ - /* Extended Capabilities field */ - #define WLAN_EXT_CAPAB_20_40_COEX 0 - #define WLAN_EXT_CAPAB_GLK 1 diff --git a/feeds/ipq95xx/hostapd/patches/h00-008-b-add-support-for-6ghz-tpc.patch b/feeds/ipq95xx/hostapd/patches/h00-008-b-add-support-for-6ghz-tpc.patch deleted file mode 100644 index 5937579b..00000000 --- a/feeds/ipq95xx/hostapd/patches/h00-008-b-add-support-for-6ghz-tpc.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 5b23a6f5fba606cb76fe50e2fc73285caf935b32 Mon Sep 17 00:00:00 2001 -From: Pradeep Kumar Chitrapu -Date: Mon, 1 Feb 2021 11:16:07 -0800 -Subject: [PATCH 2/4] ieee80211: Regulatory info field definition for HE 6GHz - operation IE - -Regulatory info subfield is added per specification -IEEE P802.11ax/D7.0. - -Signed-off-by: Pradeep Kumar Chitrapu ---- - src/ap/ieee802_11_he.c | 9 ++++++++- - src/common/ieee802_11_defs.h | 1 + - 2 files changed, 9 insertions(+), 1 deletion(-) - -diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c -index 18436a6b336b..a78ed01a54b6 100644 ---- a/src/ap/ieee802_11_he.c -+++ b/src/ap/ieee802_11_he.c -@@ -226,7 +226,14 @@ u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid) - /* 6 GHz Operation Information field */ - *pos++ = hapd->iconf->channel; /* Primary Channel */ - -- /* Control: Channel Width */ -+ /* Control: -+ * bits 0-1: Channel Width -+ * bits 2-2: Duplicate Beacon -+ * bits 3-5: Regulatory Info -+ * - 0 (Indoor Access Point) -+ * - 1 (Standard Power Access Point) -+ * - Reserved in 5GHz and 2Ghz bands -+ */ - if (seg1) - *pos++ = 3; - else -diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h -index be37c9323ae2..3c065ab27f51 100644 ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -2188,6 +2188,7 @@ struct ieee80211_he_6ghz_oper_info { - - #define HE_6GHZ_OPER_INFO_CTRL_CHAN_WIDTH_MASK (BIT(0) | BIT(1)) - #define HE_6GHZ_OPER_INFO_CTRL_DUP_BEACON BIT(2) -+#define HE_6GHZ_OPER_INFO_CTRL_REG_INFO_MASK (BIT(3) | BIT(4) | BIT(5)) - - /* IEEE P802.11ax/D6.0, 9.4.2.261 HE 6 GHz Band Capabilities element */ - struct ieee80211_he_6ghz_band_cap { --- -2.17.1 - diff --git a/feeds/ipq95xx/hostapd/patches/h00-008-c-add-support-for-6ghz-tpc.patch b/feeds/ipq95xx/hostapd/patches/h00-008-c-add-support-for-6ghz-tpc.patch deleted file mode 100644 index c9218ec0..00000000 --- a/feeds/ipq95xx/hostapd/patches/h00-008-c-add-support-for-6ghz-tpc.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 6ab1c08908767246cf0550787adb75371ab00c96 Mon Sep 17 00:00:00 2001 -From: Pradeep Kumar Chitrapu -Date: Tue, 2 Mar 2021 23:03:03 -0800 -Subject: [PATCH 3/4] hostapd: add config option to specify 6Ghz AP type - -IEEE P802.11ax/D7.0 introduces Regulatory info subfield which -is interpreted to 6Ghz ap type. - -When not specified, Indoor AP type is selected for 6GHz AP by -default. - -Signed-off-by: Pradeep Kumar Chitrapu ---- - hostapd/config_file.c | 2 ++ - hostapd/hostapd.conf | 7 +++++++ - src/ap/ap_config.h | 12 ++++++++++++ - 3 files changed, 21 insertions(+) - ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -3536,6 +3536,8 @@ static int hostapd_config_fill(struct ho - line, pos); - return 1; - } -+ } else if (os_strcmp(buf, "he_6ghz_reg_pwr_type") == 0) { -+ conf->he_6ghz_reg_pwr_type = atoi(pos); - } else if (os_strcmp(buf, "he_oper_chwidth") == 0) { - conf->he_oper_chwidth = atoi(pos); - } else if (os_strcmp(buf, "he_oper_centr_freq_seg0_idx") == 0) { ---- a/hostapd/hostapd.conf -+++ b/hostapd/hostapd.conf -@@ -584,6 +584,13 @@ wmm_ac_vo_acm=0 - # Default: 0 (disabled) - #notify_mgmt_frames=0 - -+# 6GHz regulatory AP type -+# This config is to set 6GHz access point type. Possible options -+# are 0 = Indoor AP, 1 = Standard Power AP -+# If not specified Indoor AP is selected by default. -+# option is no operation for non 6GHz band. -+#he_6ghz_reg_pwr_type=0 -+ - ##### IEEE 802.11n related configuration ###################################### - - # ieee80211n: Whether IEEE 802.11n (HT) is enabled ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -1083,6 +1083,9 @@ struct hostapd_config { - u8 he_6ghz_max_ampdu_len_exp; - u8 he_6ghz_rx_ant_pat; - u8 he_6ghz_tx_ant_pat; -+#define AP_TYPE_6GHZ_INDOOR_AP 0 -+#define AP_TYPE_6GHZ_STANDARD_POWER_AP 1 -+ u8 he_6ghz_reg_pwr_type; - #endif /* CONFIG_IEEE80211AX */ - - /* VHT enable/disable config from CHAN_SWITCH */ -@@ -1112,6 +1115,15 @@ struct hostapd_config { - #endif /* CONFIG_AIRTIME_POLICY */ - }; - -+static inline u8 hostapd_get_he_6ghz_reg_pwr_type(struct hostapd_config *conf) -+{ -+#ifdef CONFIG_IEEE80211AX -+ if (conf->ieee80211ax) -+ return conf->he_6ghz_reg_pwr_type; -+#endif /* CONFIG_IEEE80211AX */ -+ return 0; -+} -+ - - static inline u8 hostapd_get_oper_chwidth(struct hostapd_config *conf) - { diff --git a/feeds/ipq95xx/hostapd/patches/h00-008-d-add-support-for-6ghz-tpc.patch b/feeds/ipq95xx/hostapd/patches/h00-008-d-add-support-for-6ghz-tpc.patch deleted file mode 100644 index 5287cc44..00000000 --- a/feeds/ipq95xx/hostapd/patches/h00-008-d-add-support-for-6ghz-tpc.patch +++ /dev/null @@ -1,229 +0,0 @@ -From 7c79ef90001929dfa9f150135d672e7105a5ef44 Mon Sep 17 00:00:00 2001 -From: Pradeep Kumar Chitrapu -Date: Tue, 9 Feb 2021 16:51:13 -0800 -Subject: [PATCH 4/4] 6G: add TX power envelope IE in 6GHz - -Add power envelope element for 6GHz Indoor AP as per the -spec IEEE P802.11ax/D7.0. - -Currently uses fixed values for maximum transmit power limits -which are applicable to 6GHz operation in United states, Japan -and Korea. Support to extract the AP operation type and country -or channel specific power contraints will be added later on. - -Signed-off-by: Pradeep Kumar Chitrapu ---- - src/ap/beacon.c | 26 +++++++++++- - src/ap/ieee802_11_vht.c | 81 ++++++++++++++++++++++++++++-------- - src/common/ieee802_11_defs.h | 32 ++++++++++++++ - 3 files changed, 119 insertions(+), 20 deletions(-) - ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -498,9 +498,14 @@ static u8 * hostapd_gen_probe_resp(struc - 3 + sizeof(struct ieee80211_he_operation) + - 3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) + - 3 + sizeof(struct ieee80211_spatial_reuse); -- if (is_6ghz_op_class(hapd->iconf->op_class)) -+ if (is_6ghz_op_class(hapd->iconf->op_class)) { - buflen += sizeof(struct ieee80211_he_6ghz_oper_info) + - 3 + sizeof(struct ieee80211_he_6ghz_band_cap); -+ /* Additional TX Power envelope for subordinate client */ -+ if (hostapd_get_he_6ghz_reg_pwr_type(hapd->iconf) == -+ AP_TYPE_6GHZ_INDOOR_AP) -+ buflen += 4; -+ } - } - #endif /* CONFIG_IEEE80211AX */ - -@@ -1388,6 +1393,15 @@ static u8 * hostapd_gen_fils_discovery(s - buf_len = pos - buf; - total_len += buf_len; - -+ /* TX Power Envelopes */ -+ if (is_6ghz_op_class(hapd->iconf->op_class)) { -+ if (hostapd_get_he_6ghz_reg_pwr_type(hapd->iconf) == -+ AP_TYPE_6GHZ_INDOOR_AP) -+ total_len = total_len + 8; -+ else -+ total_len = total_len + 4; -+ } -+ - head = os_zalloc(total_len); - if (!head) - return NULL; -@@ -1460,6 +1474,9 @@ static u8 * hostapd_gen_fils_discovery(s - pos += buf_len; - } - -+ if (is_6ghz_op_class(hapd->iconf->op_class)) -+ pos = hostapd_eid_txpower_envelope(hapd, pos); -+ - *len = pos - (u8 *) head; - wpa_hexdump(MSG_DEBUG, "FILS Discovery frame template", - (u8 *) head, pos - (u8 *) head); -@@ -1534,9 +1551,14 @@ int ieee802_11_build_ap_params(struct ho - 3 + sizeof(struct ieee80211_he_operation) + - 3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) + - 3 + sizeof(struct ieee80211_spatial_reuse); -- if (is_6ghz_op_class(hapd->iconf->op_class)) -+ if (is_6ghz_op_class(hapd->iconf->op_class)) { - tail_len += sizeof(struct ieee80211_he_6ghz_oper_info) + - 3 + sizeof(struct ieee80211_he_6ghz_band_cap); -+ /* Additional TX Power envelope for subordinate client */ -+ if (hostapd_get_he_6ghz_reg_pwr_type(hapd->iconf) == -+ AP_TYPE_6GHZ_INDOOR_AP) -+ tail_len += 4; -+ } - } - #endif /* CONFIG_IEEE80211AX */ - ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -1938,8 +1938,40 @@ struct tpc_report { - u8 link_margin; - } STRUCT_PACKED; - -+ -+/* -+ * IEEE P802.11ax/D7.0, Table 9-275a—Maximum Transmit Power Interpretation -+ * subfield encoding. -+ */ -+enum max_tx_pwr_interpretation { -+ LOCAL_EIRP = 0, -+ LOCAL_EIRP_PSD = 1, -+ REGULATORY_CLIENT_EIRP = 2, -+ REGULATORY_CLIENT_EIRP_PSD = 3, -+}; -+ -+/* -+ * IEEE P802.11ax/D7.0,Table E-13 — Maximum Transmit Power -+ * Category subfield encoding in the United States. -+ */ -+enum reg_6g_client_type { -+ REG_DEFAULT_CLIENT = 0, -+ REG_SUBORDINATE_CLIENT = 1, -+}; -+ -+/* same Max Tx Pwr for all 20MHz bands */ -+#define DEFAULT_MAX_TX_POWER_COUNT_6G 0 -+/* -+ * These tx-power macros are present till the 6G regdomains are defined to -+ * support tx-power values for various client types. -+ */ -+#define REG_PSD_MAX_TXPOWER_FOR_DEFAULT_CLIENT (-1) /* dBm/MHz */ -+#define REG_PSD_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT 5 /* dBm/MHz */ -+#define REG_EIRP_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT 24 /* dBm */ -+ - #define RRM_CAPABILITIES_IE_LEN 5 - -+ - /* IEEE Std 802.11-2012, 8.5.7.4 - Link Measurement Request frame format */ - struct rrm_link_measurement_request { - u8 dialog_token; ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -6817,6 +6817,30 @@ void ieee802_11_rx_from_unknown(struct h - WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); - } - -+static u8 * hostapd_add_tpe_info(u8 *eid, u8 tx_pwr_count, -+ u8 tx_pwr_intrpn, u8 tx_pwr_cat, -+ u8 tx_pwr) -+{ -+ int i; -+ -+ *eid++ = WLAN_EID_TRANSMIT_POWER_ENVELOPE; -+ /* length */ -+ *eid++ = 2 + tx_pwr_count; -+ -+ /* -+ * Transmit Power Information -+ * bits 0-2 : Maximum Transmit Power Count -+ * bits 3-5 : Maximum Transmit Power Interpretation -+ * bits 6-7 : Maximum Transmit Power Category -+ */ -+ *eid++ = tx_pwr_count | ( tx_pwr_intrpn << 3) | (tx_pwr_cat << 6); -+ -+ /* Maximum transmit Power field */ -+ for (i = 0; i <= tx_pwr_count; i++) -+ *eid++ = tx_pwr; -+ -+ return eid; -+} - - u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid) - { -@@ -6826,8 +6850,8 @@ u8 * hostapd_eid_txpower_envelope(struct - struct hostapd_channel_data *chan; - int dfs, i; - u8 channel, tx_pwr_count, local_pwr_constraint; -+ u8 tx_pwr, tx_pwr_intrpn, tx_pwr_cat, ap_type; - int max_tx_power; -- u8 tx_pwr; - - if (!mode) - return eid; -@@ -6842,6 +6866,41 @@ u8 * hostapd_eid_txpower_envelope(struct - if (i == mode->num_channels) - return eid; - -+ /* For now, 6GHz has only support for Indoor AP type -+ * From IEEE P802.11ax/D7.0: An AP that is an -+ * Indoor Access Point per regulatory rules shall send at least -+ * two Transmit Power Envelope elements in Beacon and Probe -+ * Response frames as follows: -+ * - Maximum Transmit Power Category subfield = Default; -+ * Unit interpretation = Regulatory client EIRP PSD -+ * - Maximum Transmit Power Category subfield = Subordinate Device; -+ * Unit interpretation = Regulatory client EIRP PSD -+ */ -+ if (is_6ghz_op_class(iconf->op_class)) { -+ ap_type = hostapd_get_he_6ghz_reg_pwr_type(iconf); -+ -+ tx_pwr_count = DEFAULT_MAX_TX_POWER_COUNT_6G; -+ tx_pwr_intrpn = REGULATORY_CLIENT_EIRP_PSD; -+ -+ /* Indoor access point must include additional -+ * TPE for subordinate device -+ */ -+ if (ap_type == AP_TYPE_6GHZ_INDOOR_AP) { -+ tx_pwr_cat = REG_SUBORDINATE_CLIENT; -+ /* TODO: extract psd limits from channel data */ -+ tx_pwr = REG_PSD_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT * 2; -+ eid = hostapd_add_tpe_info(eid, tx_pwr_count, tx_pwr_intrpn, -+ tx_pwr_cat, tx_pwr); -+ } -+ -+ /* Default Tx Power envelope for Global Operating class */ -+ tx_pwr_cat = REG_DEFAULT_CLIENT; -+ tx_pwr = REG_PSD_MAX_TXPOWER_FOR_DEFAULT_CLIENT * 2; -+ eid = hostapd_add_tpe_info(eid, tx_pwr_count, tx_pwr_intrpn, tx_pwr_cat, tx_pwr); -+ -+ return eid; -+ } -+ - switch (hostapd_get_oper_chwidth(iconf)) { - case CHANWIDTH_USE_HT: - if (iconf->secondary_channel == 0) { -@@ -6914,17 +6973,9 @@ u8 * hostapd_eid_txpower_envelope(struct - else - tx_pwr = max_tx_power; - -- *eid++ = WLAN_EID_TRANSMIT_POWER_ENVELOPE; -- *eid++ = 2 + tx_pwr_count; -- -- /* -- * Max Transmit Power count and -- * Max Transmit Power units = 0 (EIRP) -- */ -- *eid++ = tx_pwr_count; -- -- for (i = 0; i <= tx_pwr_count; i++) -- *eid++ = tx_pwr; -+ tx_pwr_intrpn = LOCAL_EIRP; -+ tx_pwr_cat = 0; /* Reserved for non 6GHz */ -+ eid = hostapd_add_tpe_info(eid, tx_pwr_count, tx_pwr_intrpn, tx_pwr_cat, tx_pwr); - - return eid; - } diff --git a/feeds/ipq95xx/hostapd/patches/h00-008-e-Fill-6G-TPE-IE-for-non-US-countries.patch b/feeds/ipq95xx/hostapd/patches/h00-008-e-Fill-6G-TPE-IE-for-non-US-countries.patch deleted file mode 100644 index 8f59f45f..00000000 --- a/feeds/ipq95xx/hostapd/patches/h00-008-e-Fill-6G-TPE-IE-for-non-US-countries.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 575b68536cb4e44a42de2d76b5702f13f8557d36 Mon Sep 17 00:00:00 2001 -From: Lavanya Suresh -Date: Fri, 26 Mar 2021 12:59:10 +0530 -Subject: [PATCH] hostapd: Fill 6G TPE IE for non-US countries - -Currently PSD power limits for 6GHz Regular and subordinate -clients in 6G TPE IE are hardcoded with the values defined -for country US, by default. - -It is extended to hardcode proper PSD values for all 6G countries -and supported AP power modes. - -PSD values will be fetched from kernel data instead of hardcoded -values, after complete regulatory support is added for 6G. - -Signed-off-by: Lavanya Suresh ---- - src/ap/ap_config.h | 1 + - src/ap/ieee802_11.c | 43 +++++++++++++++++++++++++++++++++++++++++-- - src/common/ieee802_11_defs.h | 25 ++++++++++++++++++++++--- - 3 files changed, 64 insertions(+), 5 deletions(-) - ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -1085,6 +1085,7 @@ struct hostapd_config { - u8 he_6ghz_tx_ant_pat; - #define AP_TYPE_6GHZ_INDOOR_AP 0 - #define AP_TYPE_6GHZ_STANDARD_POWER_AP 1 -+#define AP_TYPE_6GHZ_VERY_LOW_POWER_AP 2 - u8 he_6ghz_reg_pwr_type; - #endif /* CONFIG_IEEE80211AX */ - ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -6935,6 +6935,47 @@ void ieee802_11_rx_from_unknown(struct h - WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); - } - -+u8 hostapd_get_6g_tx_power(struct hostapd_data *hapd, u8 ap_type, u8 tx_pwr_cat) -+{ -+ char country[3]; -+ -+ if (hapd->iconf->country[0] != '\0' && hapd->iconf->country[1] != '\0') -+ memcpy(country, hapd->iconf->country, 3); -+ else -+ hostapd_get_country(hapd, country); -+ -+ if ((memcmp(country, "US", 2) == 0) || (memcmp(country, "CL", 2) == 0)) { -+ /* FCC Regdomain */ -+ if (ap_type == AP_TYPE_6GHZ_INDOOR_AP && tx_pwr_cat == REG_DEFAULT_CLIENT) -+ return REG_FCC_PSD_MAX_TXPOWER_FOR_DEFAULT_CLIENT_LPI; -+ else if (ap_type == AP_TYPE_6GHZ_INDOOR_AP) -+ return REG_FCC_PSD_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT_LPI; -+ else if (ap_type == AP_TYPE_6GHZ_STANDARD_POWER_AP) -+ return REG_FCC_PSD_MAX_TXPOWER_SP; -+ -+ } else if (memcmp(country, "GB", 2) == 0) { -+ /* ETSI2 Regdomain */ -+ if (ap_type == AP_TYPE_6GHZ_INDOOR_AP) -+ return REG_ETSI2_PSD_MAX_TXPOWER_DEFAULT_SUBORDINATE_CLIENT_LPI; -+ else if (ap_type == AP_TYPE_6GHZ_VERY_LOW_POWER_AP) -+ return REG_ETSI2_PSD_MAX_TXPOWER_DEFAULT_SUBORDINATE_CLIENT_VLP; -+ -+ } else if (memcmp(country, "KR", 2) == 0) { -+ /* APL1 Regdomain */ -+ if (ap_type == AP_TYPE_6GHZ_INDOOR_AP) -+ return REG_APL1_PSD_MAX_TXPOWER_DEFAULT_SUBORDINATE_CLIENT_LPI; -+ else if (ap_type == AP_TYPE_6GHZ_VERY_LOW_POWER_AP) -+ return REG_APL1_PSD_MAX_TXPOWER_DEFAULT_SUBORDINATE_CLIENT_VLP; -+ } else { -+ wpa_printf(MSG_DEBUG, "Invalid 6g regdomain/country(%s)", country); -+ return 0; -+ } -+ -+ wpa_printf(MSG_DEBUG, "Configured AP type(%d) is not supported for the country(%s) currently set", -+ ap_type, country); -+ return 0; -+} -+ - static u8 * hostapd_add_tpe_info(u8 *eid, u8 tx_pwr_count, - u8 tx_pwr_intrpn, u8 tx_pwr_cat, - u8 tx_pwr) -@@ -7006,14 +7047,14 @@ u8 * hostapd_eid_txpower_envelope(struct - if (ap_type == AP_TYPE_6GHZ_INDOOR_AP) { - tx_pwr_cat = REG_SUBORDINATE_CLIENT; - /* TODO: extract psd limits from channel data */ -- tx_pwr = REG_PSD_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT * 2; -+ tx_pwr = (hostapd_get_6g_tx_power(hapd, ap_type, tx_pwr_cat) * 2); - eid = hostapd_add_tpe_info(eid, tx_pwr_count, tx_pwr_intrpn, - tx_pwr_cat, tx_pwr); - } - - /* Default Tx Power envelope for Global Operating class */ - tx_pwr_cat = REG_DEFAULT_CLIENT; -- tx_pwr = REG_PSD_MAX_TXPOWER_FOR_DEFAULT_CLIENT * 2; -+ tx_pwr = (hostapd_get_6g_tx_power(hapd, ap_type, tx_pwr_cat) * 2); - eid = hostapd_add_tpe_info(eid, tx_pwr_count, tx_pwr_intrpn, tx_pwr_cat, tx_pwr); - - return eid; ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -1987,9 +1987,15 @@ enum reg_6g_client_type { - * These tx-power macros are present till the 6G regdomains are defined to - * support tx-power values for various client types. - */ --#define REG_PSD_MAX_TXPOWER_FOR_DEFAULT_CLIENT (-1) /* dBm/MHz */ --#define REG_PSD_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT 5 /* dBm/MHz */ --#define REG_EIRP_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT 24 /* dBm */ -+#define REG_FCC_PSD_MAX_TXPOWER_FOR_DEFAULT_CLIENT_LPI (-1) /* dBm/MHz */ -+#define REG_FCC_PSD_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT_LPI 5 /* dBm/MHz */ -+#define REG_FCC_PSD_MAX_TXPOWER_SP 17 /* dBm/MHz */ -+ -+#define REG_ETSI2_PSD_MAX_TXPOWER_DEFAULT_SUBORDINATE_CLIENT_LPI 11 /* dBm/MHz */ -+#define REG_ETSI2_PSD_MAX_TXPOWER_DEFAULT_SUBORDINATE_CLIENT_VLP 11 /* dBm/MHz */ -+ -+#define REG_APL1_PSD_MAX_TXPOWER_DEFAULT_SUBORDINATE_CLIENT_LPI 2 /* dBm/MHz */ -+#define REG_APL1_PSD_MAX_TXPOWER_DEFAULT_SUBORDINATE_CLIENT_VLP 1 /* dBm/MHz */ - - #define RRM_CAPABILITIES_IE_LEN 5 - ---- a/hostapd/hostapd.conf -+++ b/hostapd/hostapd.conf -@@ -586,7 +586,7 @@ wmm_ac_vo_acm=0 - - # 6GHz regulatory AP type - # This config is to set 6GHz access point type. Possible options --# are 0 = Indoor AP, 1 = Standard Power AP -+# are 0 = Indoor AP, 1 = Standard Power AP, 2 = Very Low Power AP - # If not specified Indoor AP is selected by default. - # option is no operation for non 6GHz band. - #he_6ghz_reg_pwr_type=0 diff --git a/feeds/ipq95xx/hostapd/patches/i00-001-compile-fix.patch b/feeds/ipq95xx/hostapd/patches/i00-001-compile-fix.patch deleted file mode 100644 index 1d2cbd8b..00000000 --- a/feeds/ipq95xx/hostapd/patches/i00-001-compile-fix.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 66f270e4bbf8ffcd645721042ffef36c9df54297 Mon Sep 17 00:00:00 2001 -From: Tamizh Chelvam -Date: Tue, 9 Mar 2021 10:20:47 +0530 -Subject: [PATCH] hostap: Add changes to fix compilation errors - -Signed-off-by: Tamizh Chelvam ---- - src/ap/beacon.c | 2 +- - src/drivers/driver_nl80211.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/ap/beacon.c b/src/ap/beacon.c -index 7296f23f0d85..c56aff1b915d 100644 ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -1459,7 +1459,7 @@ static u8 * hostapd_gen_fils_discovery(struct hostapd_data *hapd, size_t *len) - - *len = pos - (u8 *) head; - wpa_hexdump(MSG_DEBUG, "FILS Discovery frame template", -- head, pos - (u8 *) head); -+ (u8 *) head, pos - (u8 *) head); - return (u8 *) head; - } - -diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c -index ab6c4281f366..bd56c6471630 100644 ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -5135,7 +5135,7 @@ static int wpa_driver_nl80211_sta_add(void *priv, - - if (params->he_6ghz_capab) { - wpa_hexdump(MSG_DEBUG, " * he_6ghz_capab", -- params->he_6ghz_capab, -+ (u8 *) params->he_6ghz_capab, - sizeof(*params->he_6ghz_capab)); - if (nla_put(msg, NL80211_ATTR_HE_6GHZ_CAPABILITY, - sizeof(*params->he_6ghz_capab), --- -2.31.1 - diff --git a/feeds/ipq95xx/hostapd/patches/j00-001-hostapd-update-missing-5.9GHz-channels.patch b/feeds/ipq95xx/hostapd/patches/j00-001-hostapd-update-missing-5.9GHz-channels.patch deleted file mode 100644 index 843b297a..00000000 --- a/feeds/ipq95xx/hostapd/patches/j00-001-hostapd-update-missing-5.9GHz-channels.patch +++ /dev/null @@ -1,61 +0,0 @@ -From b6bb46ef161e1c3890f517fdb04f081926fc1a08 Mon Sep 17 00:00:00 2001 -From: Seevalamuthu Mariappan -Date: Tue, 23 Mar 2021 19:57:43 +0530 -Subject: [PATCH] hostapd: update missing 5.9GHz channels - -Update channel 165 and 173 in allowed channel. -This fixes below upstream commit, -833cdbe - "Add support for new 5 GHz channels 173 and 177" - -Signed-off-by: Seevalamuthu Mariappan ---- - src/common/hw_features_common.c | 2 +- - wpa_supplicant/wpa_supplicant.c | 4 ++-- - 2 files changed, 3 insertions(+), 3 deletions(-) - -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/wpa_supplicant.c -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.c -@@ -2540,8 +2540,8 @@ void ibss_mesh_setup_freq(struct wpa_sup - enum hostapd_hw_mode hw_mode; - struct hostapd_hw_modes *mode = NULL; - int ht40plus[] = { 1, 2, 3, 4, 5, 6, 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157, -- 184, 192 }; -- int bw80[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5955, -+ 165, 173, 184, 192 }; -+ int bw80[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5825, 5955, - 6035, 6115, 6195, 6275, 6355, 6435, 6515, - 6595, 6675, 6755, 6835, 6915, 6995 }; - int bw160[] = { 5955, 6115, 6275, 6435, 6595, 6755, 6915 }; -Index: hostapd-2021-12-13-b26f5c0f/src/ap/acs.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/acs.c -+++ hostapd-2021-12-13-b26f5c0f/src/ap/acs.c -@@ -369,7 +369,7 @@ acs_survey_chan_interference_factor(stru - static int acs_usable_bw40_chan(const struct hostapd_channel_data *chan) - { - const int allowed[] = { 5180, 5220, 5260, 5300, 5500, 5540, 5580, 5620, -- 5660, 5745, 5785, 4920, 4960, 5955, 5995, 6035, -+ 5660, 5745, 5785, 5825, 5865, 4920, 4960, 5955, 5995, 6035, - 6075, 6115, 6155, 6195, 6235, 6275, 6315, 6355, - 6395, 6435, 6475, 6515, 6555, 6595, 6635, 6675, - 6715, 6755, 6795, 6835, 6875, 6915, 6955, 6995, -@@ -386,7 +386,7 @@ static int acs_usable_bw40_chan(const st - - static int acs_usable_bw80_chan(const struct hostapd_channel_data *chan) - { -- const int allowed[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5955, 6035, -+ const int allowed[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5825, 5955, 6035, - 6115, 6195, 6275, 6355, 6435, 6515, 6595, 6675, - 6755, 6835, 6915, 6995 }; - unsigned int i; -@@ -401,7 +401,7 @@ static int acs_usable_bw80_chan(const st - - static int acs_usable_bw160_chan(const struct hostapd_channel_data *chan) - { -- const int allowed[] = { 5180, 5500, 5955, 6115, 6275, 6435, 6595, 6755, -+ const int allowed[] = { 5180, 5500, 5745, 5955, 6115, 6275, 6435, 6595, 6755, - 6915 }; - unsigned int i; - diff --git a/feeds/ipq95xx/hostapd/patches/k00-001-hostapd-cli-allowed-bw-on-each-channel.patch b/feeds/ipq95xx/hostapd/patches/k00-001-hostapd-cli-allowed-bw-on-each-channel.patch deleted file mode 100644 index 2731032d..00000000 --- a/feeds/ipq95xx/hostapd/patches/k00-001-hostapd-cli-allowed-bw-on-each-channel.patch +++ /dev/null @@ -1,329 +0,0 @@ -From 6cbf57cd8899d8a531706c9f85393f602cd08219 Mon Sep 17 00:00:00 2001 -From: Hari Chandrakanthan -Date: Tue, 4 May 2021 12:35:55 +0530 -Subject: [PATCH] hostapd cli cmd to display allowed bw on each channel - -Signed-off-by: Hari Chandrakanthan ---- - hostapd/ctrl_iface.c | 235 ++++++++++++++++++++++++++++++++++++++------------ - hostapd/hostapd_cli.c | 10 +-- - 2 files changed, 185 insertions(+), 60 deletions(-) - -diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c -index bbe49aa..ea1a156 100644 ---- a/hostapd/ctrl_iface.c -+++ b/hostapd/ctrl_iface.c -@@ -3215,75 +3215,202 @@ set: - return ret; - } - --static int hostapd_2ghz_ht40_allow_map(struct hostapd_hw_modes *mode, -- char *buf, size_t buflen) -+static int hostapd_2ghz_channel_bw(struct hostapd_hw_modes *mode, char *buf, -+ size_t buflen) - { -- int j, ret, len = 0; -+ int ch, ret, len = 0; -+ char temp_buf[30] = {0}; - -- for (j = 0; j < mode->num_channels; j++) { -- struct hostapd_channel_data *chan = &mode->channels[j]; -- if (!(chan->flag & HOSTAPD_CHAN_DISABLED)) { -- ret = os_snprintf(buf + len, buflen - len, -- "Channel: %d : %d HT40%c%c\n", -- chan->chan, chan->freq, -- (chan->flag & HOSTAPD_CHAN_HT40MINUS) ? -- '-' : ' ', -- (chan->flag & HOSTAPD_CHAN_HT40PLUS) ? -- '+' : ' '); -- if (os_snprintf_error(buflen - len, ret)) -- return len; -- len += ret; -- } -+ for (ch = 0; ch < mode->num_channels; ch++) { -+ struct hostapd_channel_data *chan = &mode->channels[ch]; -+ if (chan->flag & HOSTAPD_CHAN_DISABLED) -+ continue; -+ ret = os_snprintf(temp_buf, 30, "Channel[%d]", chan->chan); -+ if (os_snprintf_error(30, ret)) -+ return len; -+ ret = os_snprintf(buf + len, buflen - len, -+ "%-13s : %d - 20MHz HT40%c%c\n", -+ temp_buf, chan->freq, -+ (chan->flag & HOSTAPD_CHAN_HT40MINUS)?'-':' ', -+ (chan->flag & HOSTAPD_CHAN_HT40PLUS)?'+':' '); -+ if (os_snprintf_error(buflen - len, ret)) -+ return len; -+ len += ret; - } - return len; - } - --static int hostapd_5ghz_ht40_allow_map(struct hostapd_hw_modes *mode, -- char *buf, size_t buflen) -+static int hostapd_get_channel_idx(struct hostapd_hw_modes *mode, -+ int channel_num) - { -- int j, k, ok, ret, len = 0, allowed[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 140, -- 149, 157, 184, 192 }; -+ int j=0; - -- for (j = 0; j < mode->num_channels; j++) { -+ for(j = 0; j < mode->num_channels; j++) { - struct hostapd_channel_data *chan = &mode->channels[j]; -+ if(chan->chan == channel_num) -+ return j; -+ } -+ return -1; -+} - -- if ((chan->flag & HOSTAPD_CHAN_HT40MINUS) || -- (chan->flag & HOSTAPD_CHAN_HT40PLUS)) { -- ok = 0; -- for (k = 0; k < ARRAY_SIZE(allowed); k++) { -- if (chan->chan < allowed[k]) -- break; -- if (chan->chan == allowed[k]) { -- ok = 1; -- break; -- } -+static int hostapd_5ghz_vht_80_channel_bw(struct hostapd_hw_modes *mode, -+ int channel_idx) -+{ -+ int k, m, ok, allowed[][4] = {{36, 40, 44, 48}, {52, 56, 60, 64}, -+ {100, 104, 108, 112}, {116, 120, 124, 128}, -+ {132, 136, 140, 144}, {149, 153, 157, 161}}; -+ struct hostapd_channel_data *chan = &mode->channels[channel_idx]; -+ -+ ok = 0; -+ for (k = 0; k < ARRAY_SIZE(allowed); k++) { -+ for(m = 0; m < ARRAY_SIZE(allowed[0]); m++) { -+ if (chan->chan == allowed[k][m]) { -+ ok = 1; -+ break; - } -+ } -+ if(ok == 1) -+ break; -+ } - -- if (!ok && chan->chan != (allowed[k - 1] + 4)) -- ok = -1; -- -- if (ok == 1 && (mode->channels[j + 1].flag & -- HOSTAPD_CHAN_DISABLED)) -- ok = -1; -+ if (ok == 0) -+ return false; - -- if (ok != -1) { -- ret = os_snprintf(buf + len, buflen - len, -- "Channel: %d : %d HT40%s\n", -- chan->chan, chan->freq, -- ok == 1 ? "+" : "-"); -+ for(m = 0; m < ARRAY_SIZE(allowed[0]); m++) { -+ channel_idx = hostapd_get_channel_idx(mode, allowed[k][m]); -+ if((channel_idx == -1) || (mode->channels[channel_idx].flag & -+ HOSTAPD_CHAN_DISABLED)) -+ return false; -+ } - -- if (os_snprintf_error(buflen - len, ret)) -- return len; -+ return true; -+} - -- len += ret; -+static bool hostapd_5ghz_vht_160_channel_bw(struct hostapd_hw_modes *mode, -+ int channel_idx) -+{ -+ int k, m, ok, allowed[][8] = {{36, 40, 44, 48, 52, 56, 60, 64}, -+ {100, 104, 108, 112, 116, 120, 124, 128}}; -+ struct hostapd_channel_data *chan = &mode->channels[channel_idx]; -+ -+ ok = 0; -+ for (k = 0; k < ARRAY_SIZE(allowed); k++) { -+ for(m = 0; m < ARRAY_SIZE(allowed[0]); m++) { -+ if (chan->chan == allowed[k][m]) { -+ ok = 1; -+ break; - } - } -+ if(ok == 1) -+ break; -+ } -+ -+ if (ok == 0) -+ return false; -+ -+ for(m = 0; m < ARRAY_SIZE(allowed[0]); m++) { -+ channel_idx = hostapd_get_channel_idx(mode, allowed[k][m]); -+ if (channel_idx == -1 || (mode->channels[channel_idx].flag & -+ HOSTAPD_CHAN_DISABLED)) -+ return false; -+ } -+ return true; -+} -+ -+static int hostapd_5ghz_ht_40_channel_bw(struct hostapd_hw_modes *mode, -+ int channel_idx) -+{ -+ -+ int k, ok, allowed[] = {36, 44, 52, 60, 100, 108, 116, 124, 132, 140, -+ 149, 157, 184, 192}; -+ struct hostapd_channel_data *chan = &mode->channels[channel_idx]; -+ -+ if (!((chan->flag & HOSTAPD_CHAN_HT40MINUS) || -+ (chan->flag & HOSTAPD_CHAN_HT40PLUS))) -+ return 0; -+ -+ ok = 0; -+ for (k = 0; k < ARRAY_SIZE(allowed); k++) { -+ if (chan->chan < allowed[k]) -+ break; -+ if (chan->chan == allowed[k]) { -+ ok = 1; -+ break; -+ } -+ } -+ -+ if (!ok && chan->chan != (allowed[k - 1] + 4)) -+ ok = -1; -+ -+ if (ok == 1 && (mode->channels[channel_idx + 1].flag & -+ HOSTAPD_CHAN_DISABLED)) -+ ok = -1; -+ -+ if (ok != -1) { -+ if( ok == 1) -+ return HOSTAPD_CHAN_HT40PLUS; -+ else -+ return HOSTAPD_CHAN_HT40MINUS; -+ } -+ return 0; -+} -+ -+static int hostapd_5ghz_channel_bw(struct hostapd_hw_modes *mode, -+ char *buf, size_t buflen) -+{ -+ int j, ret, ret_val, len = 0; -+ char temp_buf[30] = {0}; -+ -+ for (j = 0; j < mode->num_channels; j++) { -+ struct hostapd_channel_data *chan = &mode->channels[j]; -+ if (chan->flag & HOSTAPD_CHAN_DISABLED) -+ continue; -+ -+ ret = os_snprintf(temp_buf, 30, "Channel[%d]", chan->chan); -+ if (os_snprintf_error(30, ret)) -+ return len; -+ -+ ret = os_snprintf(buf + len, buflen - len, "%-13s : %d - 20MHz ", -+ temp_buf, chan->freq); -+ if (os_snprintf_error(buflen - len, ret)) -+ return len; -+ len += ret; -+ -+ ret_val = hostapd_5ghz_ht_40_channel_bw(mode, j); -+ if(ret_val) { -+ ret = os_snprintf(buf + len, buflen - len, "HT40%s ", -+ ret_val == HOSTAPD_CHAN_HT40PLUS? "+":"-"); -+ if (os_snprintf_error(buflen - len, ret)) -+ return len; -+ len += ret; -+ } -+ -+ if(hostapd_5ghz_vht_80_channel_bw(mode, j)) { -+ ret = os_snprintf(buf + len, buflen - len, "80MHz "); -+ if (os_snprintf_error(buflen - len, ret)) -+ return len; -+ len += ret; -+ } -+ -+ if((mode->vht_capab & (VHT_CAP_SUPP_CHAN_WIDTH_160MHZ | -+ VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)) && -+ hostapd_5ghz_vht_160_channel_bw(mode, j)) { -+ ret = os_snprintf(buf + len, buflen - len, "160MHz "); -+ if (os_snprintf_error(buflen - len, ret)) -+ return len; -+ len += ret; -+ } -+ -+ ret = os_snprintf(buf + len, buflen - len,"\n"); -+ if (os_snprintf_error(buflen - len, ret)) -+ return len; -+ len += ret; - } - return len; - } - --static int hostapd_ctrl_iface_ht40_allow_map(struct hostapd_iface *iface, -- char *buf, size_t buflen) -+static int hostapd_ctrl_iface_channel_bw(struct hostapd_iface *iface, -+ char *buf, size_t buflen) - { - struct hostapd_data *hapd = iface->bss[0]; - struct hostapd_hw_modes *mode; -@@ -3295,11 +3422,12 @@ static int hostapd_ctrl_iface_ht40_allow_map(struct hostapd_iface *iface, - &dfs_domain); - - if (mode->mode != HOSTAPD_MODE_IEEE80211A) -- len = hostapd_2ghz_ht40_allow_map(mode, buf, buflen); -+ len = hostapd_2ghz_channel_bw(mode, buf, buflen); - else -- len = hostapd_5ghz_ht40_allow_map(mode, buf, buflen); -+ len = hostapd_5ghz_channel_bw(mode, buf, buflen); - - return len; -+ - } - - static int hostapd_ctrl_iface_remove_neighbor(struct hostapd_data *hapd, -@@ -3912,10 +4040,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd, - if (radius_server_dac_request(hapd->radius_srv, buf + 12) < 0) - reply_len = -1; - #endif /* RADIUS_SERVER */ -- } else if (os_strcmp(buf, "HT40_ALLOW_MAP") == 0) { -- reply_len = hostapd_ctrl_iface_ht40_allow_map(hapd->iface, -- reply, -- reply_size); -+ } else if(os_strcmp(buf, "CHANNEL_BW") == 0) { -+ reply_len = hostapd_ctrl_iface_channel_bw(hapd->iface, reply, -+ reply_size); - } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) { - reply_len = hostapd_ctrl_iface_get_capability( - hapd, buf + 15, reply, reply_size); -diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c -index 6ee8d96..14317f5 100644 ---- a/hostapd/hostapd_cli.c -+++ b/hostapd/hostapd_cli.c -@@ -1384,13 +1384,11 @@ static int hostapd_cli_cmd_driver_flags(struct wpa_ctrl *ctrl, int argc, - return wpa_ctrl_command(ctrl, "DRIVER_FLAGS"); - } - --static int hostapd_cli_cmd_ht40_allow_map(struct wpa_ctrl *ctrl, -+static int hostapd_cli_cmd_channel_bw(struct wpa_ctrl *ctrl, - int argc, char *argv[]) - { -- return wpa_ctrl_command(ctrl, "HT40_ALLOW_MAP"); -+ return wpa_ctrl_command(ctrl, "CHANNEL_BW"); - } -- -- - #ifdef CONFIG_DPP - - static int hostapd_cli_cmd_dpp_qr_code(struct wpa_ctrl *ctrl, int argc, -@@ -1753,8 +1751,8 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = { - "=Add/Delete/Show/Clear deny MAC ACL" }, - { "poll_sta", hostapd_cli_cmd_poll_sta, hostapd_complete_stations, - " = poll a STA to check connectivity with a QoS null frame" }, -- { "ht40_allow_map", hostapd_cli_cmd_ht40_allow_map, NULL, -- "= show ht40 allow map status" }, -+ { "channel_bw", hostapd_cli_cmd_channel_bw, NULL, -+ "= show allowed bandwidth on each channel"}, - { "req_beacon", hostapd_cli_cmd_req_beacon, NULL, - " [req_mode=] = send a Beacon report request to a station" }, - { "reload_wpa_psk", hostapd_cli_cmd_reload_wpa_psk, NULL, --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/k00-001-hostapd-macsec-support-gcmaes256-cipher-suite-when-participant-act-as-key-server.patch b/feeds/ipq95xx/hostapd/patches/k00-001-hostapd-macsec-support-gcmaes256-cipher-suite-when-participant-act-as-key-server.patch deleted file mode 100644 index 91fcbccc..00000000 --- a/feeds/ipq95xx/hostapd/patches/k00-001-hostapd-macsec-support-gcmaes256-cipher-suite-when-participant-act-as-key-server.patch +++ /dev/null @@ -1,195 +0,0 @@ -From cd028d950808096de588d99ef5a082a33d4965db Mon Sep 17 00:00:00 2001 -From: leiwei -Date: Fri, 23 Apr 2021 19:54:24 +0800 -Subject: [PATCH] hostap:Support GCM-AES-256 cipher suite select when - participant act as key server - -Signed-off-by: leiwei ---- - hostapd/config_file.c | 10 ++++++++++ - src/ap/ap_config.h | 7 +++++++ - src/ap/wpa_auth_kay.c | 3 ++- - src/pae/ieee802_1x_cp.c | 6 +++--- - src/pae/ieee802_1x_kay.c | 13 ++++++++++--- - src/pae/ieee802_1x_kay.h | 2 +- - wpa_supplicant/config.c | 1 + - wpa_supplicant/config_ssid.h | 7 +++++++ - wpa_supplicant/wpas_kay.c | 4 ++-- - 9 files changed, 43 insertions(+), 10 deletions(-) - -diff --git a/hostapd/config_file.c b/hostapd/config_file.c -index 08a5bcd..39ea156 100644 ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -4530,6 +4530,16 @@ static int hostapd_config_fill(struct hostapd_config *conf, - return 1; - } - bss->mka_priority = mka_priority; -+ } else if (os_strcmp(buf, "macsec_csindex") == 0) { -+ int macsec_csindex = atoi(pos); -+ -+ if (macsec_csindex < 0 || macsec_csindex > 1) { -+ wpa_printf(MSG_ERROR, -+ "Line %d: invalid macsec_csindex (%d): '%s'.", -+ line, macsec_csindex, pos); -+ return 1; -+ } -+ bss->macsec_csindex = macsec_csindex; - } else if (os_strcmp(buf, "mka_cak") == 0) { - size_t len = os_strlen(pos); - -diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h -index 05f3c7d..ad37222 100644 ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -850,6 +850,13 @@ struct hostapd_bss_config { - int mka_priority; - - /** -+ * macsec_csindex - chipher suite index of macsec -+ * -+ * Range: 0-1 (default: 0) -+ */ -+ int macsec_csindex; -+ -+ /** - * mka_ckn - MKA pre-shared CKN - */ - #define MACSEC_CKN_MAX_LEN 32 -diff --git a/src/ap/wpa_auth_kay.c b/src/ap/wpa_auth_kay.c -index 46d94b4..d5341e2 100644 ---- a/src/ap/wpa_auth_kay.c -+++ b/src/ap/wpa_auth_kay.c -@@ -329,7 +329,8 @@ int ieee802_1x_alloc_kay_sm_hapd(struct hostapd_data *hapd, - hapd->conf->macsec_replay_protect, - hapd->conf->macsec_replay_window, - hapd->conf->macsec_port, -- hapd->conf->mka_priority, hapd->conf->iface, -+ hapd->conf->mka_priority, -+ hapd->conf->macsec_csindex, hapd->conf->iface, - hapd->own_addr); - /* ieee802_1x_kay_init() frees kay_ctx on failure */ - if (!res) -diff --git a/src/pae/ieee802_1x_cp.c b/src/pae/ieee802_1x_cp.c -index cf41d8d..f0527fd 100644 ---- a/src/pae/ieee802_1x_cp.c -+++ b/src/pae/ieee802_1x_cp.c -@@ -20,7 +20,7 @@ - #define STATE_MACHINE_DATA struct ieee802_1x_cp_sm - #define STATE_MACHINE_DEBUG_PREFIX "CP" - --static u64 default_cs_id = CS_ID_GCM_AES_128; -+static u64 cs_id[]={CS_ID_GCM_AES_128, CS_ID_GCM_AES_256}; - - /* The variable defined in clause 12 in IEEE Std 802.1X-2010 */ - enum connect_type { PENDING, UNAUTHENTICATED, AUTHENTICATED, SECURE }; -@@ -473,8 +473,8 @@ struct ieee802_1x_cp_sm * ieee802_1x_cp_sm_init(struct ieee802_1x_kay *kay) - sm->orx = false; - sm->otx = false; - -- sm->current_cipher_suite = default_cs_id; -- sm->cipher_suite = default_cs_id; -+ sm->current_cipher_suite = cs_id[kay->macsec_csindex]; -+ sm->cipher_suite = cs_id[kay->macsec_csindex]; - sm->cipher_offset = CONFIDENTIALITY_OFFSET_0; - sm->confidentiality_offset = sm->cipher_offset; - sm->transmit_delay = MKA_LIFE_TIME; -diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c -index ad5a34b..04a7e93 100644 ---- a/src/pae/ieee802_1x_kay.c -+++ b/src/pae/ieee802_1x_kay.c -@@ -222,7 +222,14 @@ ieee802_1x_mka_dump_dist_sak_body(struct ieee802_1x_mka_dist_sak_body *body) - wpa_printf(MSG_DEBUG, "\tKey Number............: %d", - be_to_host32(body->kn)); - /* TODO: Other than GCM-AES-128 case: MACsec Cipher Suite */ -- wpa_hexdump(MSG_DEBUG, "\tAES Key Wrap of SAK...:", body->sak, 24); -+ if(body_len == 28){ -+ wpa_hexdump(MSG_INFO, "\tAES Key Wrap of SAK...:", body->sak, 24); -+ } -+ else{ -+ wpa_hexdump(MSG_INFO, "\tMacsec Cipher Suite...:", body->sak, CS_ID_LEN); -+ wpa_hexdump(MSG_INFO, "\tAES Key Wrap of SAK...:", body->sak + CS_ID_LEN, -+ body_len - CS_ID_LEN - sizeof(body->kn)); -+ } - } - - -@@ -3458,7 +3465,7 @@ static void kay_l2_receive(void *ctx, const u8 *src_addr, const u8 *buf, - struct ieee802_1x_kay * - ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, - bool macsec_replay_protect, u32 macsec_replay_window, -- u16 port, u8 priority, const char *ifname, const u8 *addr) -+ u16 port, u8 priority, u32 macsec_csindex, const char *ifname, const u8 *addr) - { - struct ieee802_1x_kay *kay; - -@@ -3495,7 +3502,7 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, - kay->dist_time = 0; - - kay->pn_exhaustion = PENDING_PN_EXHAUSTION; -- kay->macsec_csindex = DEFAULT_CS_INDEX; -+ kay->macsec_csindex = macsec_csindex; - kay->mka_algindex = DEFAULT_MKA_ALG_INDEX; - kay->mka_version = MKA_VERSION_ID; - -diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h -index 1d3c2ac..a3cf964 100644 ---- a/src/pae/ieee802_1x_kay.h -+++ b/src/pae/ieee802_1x_kay.h -@@ -240,7 +240,7 @@ u64 mka_sci_u64(struct ieee802_1x_mka_sci *sci); - struct ieee802_1x_kay * - ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, - bool macsec_replay_protect, u32 macsec_replay_window, -- u16 port, u8 priority, const char *ifname, const u8 *addr); -+ u16 port, u8 priority, u32 macsec_csindex, const char *ifname, const u8 *addr); - void ieee802_1x_kay_deinit(struct ieee802_1x_kay *kay); - - struct ieee802_1x_mka_participant * -diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c -index 7e7d9bb..f723b70 100644 ---- a/wpa_supplicant/config.c -+++ b/wpa_supplicant/config.c -@@ -2777,6 +2777,7 @@ static const struct parse_data ssid_fields[] = { - { INT(macsec_replay_window) }, - { INT_RANGE(macsec_port, 1, 65534) }, - { INT_RANGE(mka_priority, 0, 255) }, -+ { INT_RANGE(macsec_csindex, 0, 1) }, - { FUNC_KEY(mka_cak) }, - { FUNC_KEY(mka_ckn) }, - #endif /* CONFIG_MACSEC */ -diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h -index b655e39..747e4d0 100644 ---- a/wpa_supplicant/config_ssid.h -+++ b/wpa_supplicant/config_ssid.h -@@ -915,6 +915,13 @@ struct wpa_ssid { - int mka_priority; - - /** -+ * macsec_csindex - chipher suite index of macsec -+ * -+ * Range: 0-1 (default: 0) -+ */ -+ int macsec_csindex; -+ -+ /** - * mka_ckn - MKA pre-shared CKN - */ - #define MACSEC_CKN_MAX_LEN 32 -diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c -index defd0f2..4d1ce02 100644 ---- a/wpa_supplicant/wpas_kay.c -+++ b/wpa_supplicant/wpas_kay.c -@@ -241,8 +241,8 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) - - res = ieee802_1x_kay_init(kay_ctx, policy, ssid->macsec_replay_protect, - ssid->macsec_replay_window, ssid->macsec_port, -- ssid->mka_priority, wpa_s->ifname, -- wpa_s->own_addr); -+ ssid->mka_priority, ssid->macsec_csindex, -+ wpa_s->ifname, wpa_s->own_addr); - /* ieee802_1x_kay_init() frees kay_ctx on failure */ - if (res == NULL) - return -1; --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/k00-002-hostapd-Fix-channel-switch-on-6g.patch b/feeds/ipq95xx/hostapd/patches/k00-002-hostapd-Fix-channel-switch-on-6g.patch deleted file mode 100644 index 09518d95..00000000 --- a/feeds/ipq95xx/hostapd/patches/k00-002-hostapd-Fix-channel-switch-on-6g.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 6e1348ac1eaa8a4a62dccce588aa9306f876b068 Mon Sep 17 00:00:00 2001 -From: Anilkumar Kolli -Date: Mon, 24 May 2021 22:18:11 +0530 -Subject: [PATCH] hostapd: Fix channel switch on 6g - -Below cmd does not return fail, but fails to update beacon. -Center frequency used in command is not valid for 80M bandwidth. - - hostapd_cli -i wlan0 chan_switch 5 6315 sec_channel_offset=1 - center_freq1=6345 bandwidth=80 he - -This patch adds condition check to validate the center frequency. - -Signed-off-by: Anilkumar Kolli ---- - hostapd/ctrl_iface.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c -index ea1a1567278c..664711d5bd87 100644 ---- a/hostapd/ctrl_iface.c -+++ b/hostapd/ctrl_iface.c -@@ -2528,6 +2528,16 @@ static int hostapd_ctrl_get_pmk(struct hostapd_data *hapd, const char *cmd, - #ifdef NEED_AP_MLME - static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params) - { -+ int idx, bw, bw_idx[] = { 20, 40, 80, 160 }; -+ -+ if (is_6ghz_freq(params->freq) && params->center_freq1) { -+ idx = (params->center_freq1 - 5950) / 5; -+ bw = center_idx_to_bw_6ghz(idx); -+ -+ if (bw < 0 || (bw_idx[bw] != params->bandwidth)) -+ return -1; -+ } -+ - switch (params->bandwidth) { - case 0: - /* bandwidth not specified: use 20 MHz by default */ --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/l00-001-hostapd-avoid-filling-group-mgmt-cipher-type-in-FD-R.patch b/feeds/ipq95xx/hostapd/patches/l00-001-hostapd-avoid-filling-group-mgmt-cipher-type-in-FD-R.patch deleted file mode 100644 index 0afd8654..00000000 --- a/feeds/ipq95xx/hostapd/patches/l00-001-hostapd-avoid-filling-group-mgmt-cipher-type-in-FD-R.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 2149e44c4a1767645c889de3e1712465b7fe5137 Mon Sep 17 00:00:00 2001 -From: Sriram R -Date: Wed, 12 May 2021 20:03:07 +0530 -Subject: [PATCH] hostapd: avoid filling group mgmt cipher type in FD RSN to - reflect beacon RSN IE - -Currently we don’t advertise Group Management cipher suite -in beacons if management frame protection is not enabled or -if the group management cipher is default (WPA_CIPHER_AES_128_CMAC) -but we advertise the suite type in FD RSN IE. - -Hence set it to 63, if management frame protection is disabled or when -default cipher is used. - -Signed-off-by: Sriram R ---- - src/ap/wpa_auth_ie.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/src/ap/wpa_auth_ie.c -+++ b/src/ap/wpa_auth_ie.c -@@ -1177,11 +1177,9 @@ bool wpa_auth_write_fd_rsn_info(struct w - - /* Group Management Cipher Suite Selector (B22..B27) */ - cipher = 63; /* Default to no cipher suite selected */ -- if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) { -+ if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION && -+ conf->group_mgmt_cipher != WPA_CIPHER_AES_128_CMAC) { - switch (conf->group_mgmt_cipher) { -- case WPA_CIPHER_AES_128_CMAC: -- cipher = RSN_CIPHER_SUITE_AES_128_CMAC & 0xff; -- break; - case WPA_CIPHER_BIP_GMAC_128: - cipher = RSN_CIPHER_SUITE_BIP_GMAC_128 & 0xff; - break; diff --git a/feeds/ipq95xx/hostapd/patches/l00-002-hostapd-fix-enabling-HE-thru-cli-in-2ghz.patch b/feeds/ipq95xx/hostapd/patches/l00-002-hostapd-fix-enabling-HE-thru-cli-in-2ghz.patch deleted file mode 100644 index 2fbdebd3..00000000 --- a/feeds/ipq95xx/hostapd/patches/l00-002-hostapd-fix-enabling-HE-thru-cli-in-2ghz.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 994bff7d74eba00244b481a7d164a44412908ad6 Mon Sep 17 00:00:00 2001 -From: Karthikeyan Kathirvel -Date: Fri, 4 Jun 2021 22:19:27 +0530 -Subject: [PATCH] hostapd: unable to set HE mode on 2.4Ghz - -Channel switch through hostapd_cli is not able to operate in HE mode in -2.4Ghz. This is because since the he mode is not enabled for 2ghz the -channel type is set to 20Mhz NO_HT. - -Enabled he for 2Ghz radio on 20Mhz bandwidth for channel switch. - -Signed-off-by: Karthikeyan Kathirvel ---- - src/drivers/driver_nl80211.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c -index cbf41c6..a0dd827 100644 ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -4979,7 +4979,7 @@ static int nl80211_put_freq_params(struct nl_msg *msg, - nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, - freq->center_freq2))) - return -ENOBUFS; -- } else if (freq->ht_enabled) { -+ } else if (freq->ht_enabled || (freq->he_enabled && is_24ghz)) { - enum nl80211_channel_type ct; - - wpa_printf(MSG_DEBUG, " * sec_channel_offset=%d", --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/m00-001-hostap-Avoid-adjacent-channel-selection-in-DFS-for-q.patch b/feeds/ipq95xx/hostapd/patches/m00-001-hostap-Avoid-adjacent-channel-selection-in-DFS-for-q.patch deleted file mode 100644 index af0b01c7..00000000 --- a/feeds/ipq95xx/hostapd/patches/m00-001-hostap-Avoid-adjacent-channel-selection-in-DFS-for-q.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 420852ff044c804a6487ccc060f85c12bbdaac31 Mon Sep 17 00:00:00 2001 -From: Seevalamuthu Mariappan -Date: Thu, 1 Jul 2021 10:15:29 +0530 -Subject: [PATCH] hostap: Avoid selecting UNII-1 channel after DFS switch - -Avoid UNII-1 band channel from getting selected after DFS when primary -channel is UNII-2 band with 80Mhz configuration. - -To enable this, 'skip_unii1_dfs_switch' config should be enabled -in hostapd config. - -Signed-off-by: Seevalamuthu Mariappan ---- - hostapd/config_file.c | 2 ++ - src/ap/ap_config.h | 1 + - src/ap/dfs.c | 25 +++++++++++++++++++++++++ - 3 files changed, 28 insertions(+) - ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -3377,6 +3377,8 @@ static int hostapd_config_fill(struct ho - conf->require_ht = atoi(pos); - } else if (os_strcmp(buf, "obss_interval") == 0) { - conf->obss_interval = atoi(pos); -+ } else if (os_strcmp(buf, "skip_unii1_dfs_switch") == 0) { -+ conf->skip_unii1_dfs_switch = atoi(pos); - #ifdef CONFIG_IEEE80211AC - } else if (os_strcmp(buf, "ieee80211ac") == 0) { - conf->ieee80211ac = atoi(pos); ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -1045,6 +1045,7 @@ struct hostapd_config { - - /* Use driver-generated interface addresses when adding multiple BSSs */ - u8 use_driver_iface_addr; -+ u8 skip_unii1_dfs_switch; - - #ifdef CONFIG_FST - struct fst_iface_cfg fst_cfg; ---- a/src/ap/dfs.c -+++ b/src/ap/dfs.c -@@ -199,6 +199,64 @@ static int is_in_chanlist(struct hostapd - return freq_range_list_includes(&iface->conf->acs_ch_list, chan->chan); - } - -+#define HOSTAPD_DFS_UNII2_CHANNELS(chan) (chan >= 52 && chan <= 64) -+ -+static bool is_skip_unii1_dfs_switch_applicable(struct hostapd_iface *iface, -+ struct hostapd_channel_data *chan) -+{ -+ if (!iface->conf->skip_unii1_dfs_switch) -+ return false; -+ -+ /* skip if the selected channel is 52/56/60/64 */ -+ if (HOSTAPD_DFS_UNII2_CHANNELS(iface->conf->channel) && -+ HOSTAPD_DFS_UNII2_CHANNELS(chan->chan)) -+ return true; -+ -+ /* Skip below mentioned adjacent channels if one of the following -+ * conditions is true -+ * i) The primary channel of the AP is 52/56/60/64 in 80MHz mode and -+ * moves to adjacent channel 36/44/48 in 80MHz -+ * ii) The primary channel of the AP is 36/44/48/52/56/60/64 in 160MHz -+ * and moves to 36/44/48 in 80MHz mode -+ * iii) The primary channel of the AP is 52/56/60/64 in 20MHz or 40MHz mode -+ * and moves to the adjacent channels 40/44/48 in 20MHz mode or 36/40/44/48 -+ * in 40MHz mode -+ */ -+ switch(hostapd_get_oper_chwidth(iface->conf)) -+ { -+ case CHANWIDTH_160MHZ: -+ if ((iface->conf->channel >= 36) && -+ (iface->conf->channel <= 64) && -+ (iface->conf->channel != 40) && -+ (chan->chan >= 36) && (chan->chan <= 48) && -+ (chan->chan != 40)) -+ return true; -+ break; -+ case CHANWIDTH_80MHZ: -+ if ((iface->conf->channel >= 52) && -+ (iface->conf->channel <= 64) && -+ (chan->chan >= 36) && (chan->chan <= 48) && -+ (chan->chan != 40)) -+ return true; -+ break; -+ case CHANWIDTH_USE_HT: -+ if ((iface->conf->channel >= 52) && -+ (iface->conf->channel <= 64)) { -+ if (iface->conf->secondary_channel) { -+ if ((chan->chan >= 36) && (chan->chan <= 48)) -+ return true; -+ } else { -+ if ((chan->chan >= 40) && (chan->chan <= 48)) -+ return true; -+ } -+ } -+ break; -+ default: -+ break; -+ } -+ -+ return false; -+} - - /* - * The function assumes HT40+ operation. -@@ -248,6 +306,13 @@ static int dfs_find_channel(struct hosta - continue; - } - -+ if (is_skip_unii1_dfs_switch_applicable(iface, chan)) { -+ wpa_printf(MSG_DEBUG, -+ "DFS: skip_unii1_dfs_switch enabled, skip adjacent channel: %d (%d)", -+ chan->freq, chan->chan); -+ continue; -+ } -+ - if (chan->max_tx_power < iface->conf->min_tx_power) - continue; - -@@ -963,8 +1028,15 @@ dfs_downgrade_bandwidth(struct hostapd_i - int oper_chwidth; - - oper_chwidth = hostapd_get_oper_chwidth(iface->conf); -- if (oper_chwidth == CHANWIDTH_USE_HT) -- break; -+ if (oper_chwidth == CHANWIDTH_USE_HT) { -+ /* try finding 20MHz channels if skip_unii1_dfs_switch is enabled */ -+ if (!iface->conf->skip_unii1_dfs_switch || -+ !iface->conf->secondary_channel) -+ break; -+ iface->conf->secondary_channel = 0; -+ *skip_radar = 1; -+ continue; -+ } - *skip_radar = 1; - hostapd_set_oper_chwidth(iface->conf, oper_chwidth - 1); - } diff --git a/feeds/ipq95xx/hostapd/patches/n00-001-hostapd-Add-support-to-awgn-mitigation-for-6Ghz.patch b/feeds/ipq95xx/hostapd/patches/n00-001-hostapd-Add-support-to-awgn-mitigation-for-6Ghz.patch deleted file mode 100644 index 2cc4539f..00000000 --- a/feeds/ipq95xx/hostapd/patches/n00-001-hostapd-Add-support-to-awgn-mitigation-for-6Ghz.patch +++ /dev/null @@ -1,760 +0,0 @@ -From b581d1e5d5ef4adc4d60bca087942cc45fc653f1 Mon Sep 17 00:00:00 2001 -From: Hari Chandrakanthan -Date: Wed, 1 Dec 2021 21:27:36 +0530 -Subject: [PATCH] hostapd : Add support to awgn mitigation for 6Ghz - -when awgn interference is detected on operating channel, -AP is supposed to stop transmitting in that channel. -AP can reduce it's operating bandwidth or -completely move to another channel based on the -interference segment. - -hostapd receives awgn notification through NL80211_CMD_AWGN_DETECT -cmd and the NL attribute NL80211_ATTR_AWGN_INTERFERENCE_BITMAP -provides the channel interference information. - -Eg: For 80Mhz operating bandwidth, the chan bw interference -bitmap can be as follows. -segment chan_bw_interference_bitmap -0 0x01 -1 0x02 -2 0x04 -3 0x08 - -segment 0 - primary 20Mhz -segment 1 - secondary 20Mhz -segment 2 - secondary 40Mhz lower -segment 3 - secondary 40Mhz upper - -Signed-off-by: Hari Chandrakanthan ---- - hostapd/Makefile | 1 + - hostapd/config_file.c | 2 + - src/ap/Makefile | 1 + - src/ap/ap_config.c | 1 + - src/ap/ap_config.h | 1 + - src/ap/drv_callbacks.c | 13 + - src/ap/interference.c | 393 +++++++++++++++++++++++++++++ - src/ap/interference.h | 41 +++ - src/drivers/driver.h | 13 + - src/drivers/driver_common.c | 1 + - src/drivers/driver_nl80211_event.c | 30 +++ - src/drivers/nl80211_copy.h | 16 +- - wpa_supplicant/Makefile | 1 + - 13 files changed, 513 insertions(+), 1 deletion(-) - create mode 100644 src/ap/interference.c - create mode 100644 src/ap/interference.h - -diff --git a/hostapd/Makefile b/hostapd/Makefile -index 50f75bf2876a..002d68833c46 100644 ---- a/hostapd/Makefile -+++ b/hostapd/Makefile -@@ -1189,6 +1189,7 @@ OBJS += ../src/ap/ap_list.o - OBJS += ../src/ap/ieee802_11.o - OBJS += ../src/ap/hw_features.o - OBJS += ../src/ap/dfs.o -+OBJS += ../src/ap/interference.o - CFLAGS += -DNEED_AP_MLME - endif - OBJS += ../src/ap/ieee802_11_ht.o -diff --git a/hostapd/config_file.c b/hostapd/config_file.c -index afa07ef28f99..9f55bcd6ed2b 100644 ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -3564,6 +3564,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, - return 1; - } - bss->unsol_bcast_probe_resp_interval = val; -+ } else if (os_strcmp(buf, "discard_6g_awgn_event") == 0) { -+ conf->discard_6g_awgn_event = atoi(pos); - #endif /* CONFIG_IEEE80211AX */ - } else if (os_strcmp(buf, "max_listen_interval") == 0) { - bss->max_listen_interval = atoi(pos); -diff --git a/src/ap/Makefile b/src/ap/Makefile -index a1e9b7c44d2f..22a21d31eda6 100644 ---- a/src/ap/Makefile -+++ b/src/ap/Makefile -@@ -36,6 +36,7 @@ LIB_OBJS= \ - ieee802_11_shared.o \ - ieee802_11_vht.o \ - ieee802_1x.o \ -+ interference.o \ - neighbor_db.o \ - ndisc_snoop.o \ - p2p_hostapd.o \ -diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c -index 9f86a4701ed4..1e27cb3d9416 100644 ---- a/src/ap/ap_config.c -+++ b/src/ap/ap_config.c -@@ -281,6 +281,7 @@ struct hostapd_config * hostapd_config_defaults(void) - conf->he_6ghz_max_ampdu_len_exp = 7; - conf->he_6ghz_rx_ant_pat = 1; - conf->he_6ghz_tx_ant_pat = 1; -+ conf->discard_6g_awgn_event = 0; - #endif /* CONFIG_IEEE80211AX */ - - /* The third octet of the country string uses an ASCII space character -diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h -index 32107f15bab8..261b1fafd74d 100644 ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -1095,6 +1095,7 @@ struct hostapd_config { - #define AP_TYPE_6GHZ_STANDARD_POWER_AP 1 - #define AP_TYPE_6GHZ_VERY_LOW_POWER_AP 2 - u8 he_6ghz_reg_pwr_type; -+ bool discard_6g_awgn_event; - #endif /* CONFIG_IEEE80211AX */ - - /* VHT enable/disable config from CHAN_SWITCH */ -diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c -index 2c945b6d3f92..bf143beac9ac 100644 ---- a/src/ap/drv_callbacks.c -+++ b/src/ap/drv_callbacks.c -@@ -43,6 +43,7 @@ - #include "dpp_hostapd.h" - #include "fils_hlp.h" - #include "neighbor_db.h" -+#include "interference.h" - - #ifdef CONFIG_FILS - void hostapd_notify_assoc_fils_finish(struct hostapd_data *hapd, -@@ -1700,6 +1701,13 @@ static void hostapd_event_dfs_radar_detected(struct hostapd_data *hapd, - radar->cf1, radar->cf2); - } - -+static void hostapd_event_awgn_detected(struct hostapd_data *hapd, -+ struct awgn_event *awgn_info) -+{ -+ hostapd_intf_awgn_detected(hapd->iface, awgn_info->freq, awgn_info->chan_width, -+ awgn_info->cf1, awgn_info->cf2, -+ awgn_info->chan_bw_interference_bitmap); -+} - - static void hostapd_event_dfs_pre_cac_expired(struct hostapd_data *hapd, - struct dfs_event *radar) -@@ -2084,6 +2092,11 @@ void hostapd_wpa_event(void *ctx, enum wpa_event_type event, - break; - hostapd_event_dfs_radar_detected(hapd, &data->dfs_event); - break; -+ case EVENT_AWGN_DETECTED: -+ if (!data) -+ break; -+ hostapd_event_awgn_detected(hapd, &data->awgn_event); -+ break; - case EVENT_DFS_PRE_CAC_EXPIRED: - if (!data) - break; -diff --git a/src/ap/interference.c b/src/ap/interference.c -new file mode 100644 -index 000000000000..c51a4bfe9e30 ---- /dev/null -+++ b/src/ap/interference.c -@@ -0,0 +1,393 @@ -+/* -+ * AWGN - Additive white Gaussian Noise -+ * Copyright (c) 2002-2013, Jouni Malinen -+ * Copyright (c) 2013-2017, Qualcomm Atheros, Inc. -+ * -+ * This software may be distributed under the terms of the BSD license. -+ * See README for more details. -+ */ -+ -+/* -+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without modification, -+ * are permitted (subject to the limitations in the disclaimer below) provided that -+ * the following conditions are met: -+ * * Redistributions of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation and/or -+ * other materials provided with the distribution. -+ * * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its contributors -+ * may be used to endorse or promote products derived from this software without specific -+ * prior written permission. -+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS -+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "utils/includes.h" -+ -+#include "utils/common.h" -+#include "common/ieee802_11_defs.h" -+#include "common/hw_features_common.h" -+#include "common/wpa_ctrl.h" -+#include "hostapd.h" -+#include "ap_drv_ops.h" -+#include "drivers/driver.h" -+#include "beacon.h" -+#include "eloop.h" -+#include "hw_features.h" -+ -+/* -+ * intf_awgn_chan_range_available - check whether the channel can operate -+ * in the given bandwidth in 6Ghz -+ * @first_chan_idx - channel index of the first 20Mhz channel in a segment -+ * @num_chans - number of 20Mhz channels needed for the operating bandwidth -+ */ -+static int intf_awgn_chan_range_available(struct hostapd_hw_modes *mode, -+ int first_chan_idx, int num_chans) -+{ -+ struct hostapd_channel_data *first_chan = NULL; -+ int allowed_40_6g[] = {1, 9, 17, 25, 33, 41, 49, 57, 65, 73, 81, 89, 97, 105, -+ 113, 121, 129, 137, 145, 153, 161, 169, 177, 185, 193, -+ 201, 209, 217, 225, 233}; -+ int allowed_80_6g[] = {1, 17, 33, 49, 65, 81, 97, 113, 129, 145, 161, 177, -+ 193, 209}; -+ int allowed_160_6g[] = {1, 33, 65, 97, 129, 161, 193}; -+ int chan_idx_match = 0; -+ int i; -+ -+ first_chan = &mode->channels[first_chan_idx]; -+ -+ if (!first_chan || !chan_pri_allowed(first_chan)) { -+ wpa_printf(MSG_DEBUG, "AWGN: primary channel not allowed"); -+ return 0; -+ } -+ -+ /* 20Mhz channel, so no need to check the range */ -+ if (num_chans == 1) -+ return 1; -+ -+ if (num_chans == 2) { /* 40Mhz channel */ -+ for (i = 0; i < ARRAY_SIZE(allowed_40_6g); i++) { -+ if (first_chan->chan == allowed_40_6g[i]) { -+ chan_idx_match = 1; -+ break; -+ } -+ } -+ } else if (num_chans == 4) { /* 80Mhz channel */ -+ for (i = 0; i < ARRAY_SIZE(allowed_80_6g); i++) { -+ if (first_chan->chan == allowed_80_6g[i]) { -+ chan_idx_match = 1; -+ break; -+ } -+ } -+ } else if (num_chans == 8) { /* 160Mhz channel */ -+ for (i = 0; i < ARRAY_SIZE(allowed_160_6g); i++) { -+ if (first_chan->chan == allowed_160_6g[i]) { -+ chan_idx_match = 1; -+ break; -+ } -+ } -+ } -+ -+ if (chan_idx_match == 1) -+ return 1; -+ -+ return 0; -+} -+ -+static int is_in_chanlist(struct hostapd_iface *iface, -+ struct hostapd_channel_data *chan) -+{ -+ if (!iface->conf->acs_ch_list.num) -+ return 1; -+ -+ return freq_range_list_includes(&iface->conf->acs_ch_list, chan->chan); -+} -+ -+/* -+ *intf_awgn_find_channel - find the channel that can operate with bandwidth chan_width. -+ If idx doesn't match with index of any of the existing channel, then the api -+ returns the total number of available chandefs that supports the provided bandwidth -+ * @idx - index of the channel -+ * @chan_width - bandwidth of the channel -+ */ -+static int intf_awgn_find_channel(struct hostapd_iface *iface, -+ struct hostapd_channel_data **ret_chan, -+ int idx, int chan_width) -+{ -+ struct hostapd_hw_modes *mode = iface->current_mode; -+ struct hostapd_channel_data *chan; -+ int i, channel_idx = 0, n_chans; -+ -+ switch (chan_width) { -+ case CHAN_WIDTH_20_NOHT: -+ case CHAN_WIDTH_20: -+ n_chans = 1; -+ break; -+ case CHAN_WIDTH_40: -+ n_chans = 2; -+ break; -+ case CHAN_WIDTH_80: -+ n_chans = 4; -+ break; -+ case CHAN_WIDTH_80P80: -+ case CHAN_WIDTH_160: -+ n_chans = 8; -+ break; -+ default: -+ n_chans = 1; -+ break; -+ } -+ -+ for (i = 0; i < mode->num_channels; i++) { -+ chan = &mode->channels[i]; -+ -+ /* Skip incompatible chandefs */ -+ if (!intf_awgn_chan_range_available(mode, i, n_chans)) { -+ wpa_printf(MSG_DEBUG, -+ "AWGN: range not available for %d (%d)", -+ chan->freq, chan->chan); -+ continue; -+ } -+ -+ if (!is_in_chanlist(iface, chan)) { -+ wpa_printf(MSG_DEBUG, -+ "AWGN: channel %d (%d) not in chanlist", -+ chan->freq, chan->chan); -+ continue; -+ } -+ -+ if (ret_chan && idx == channel_idx) { -+ wpa_printf(MSG_DEBUG, "AWGN: Selected channel %d (%d)", -+ chan->freq, chan->chan); -+ *ret_chan = chan; -+ return idx; -+ } -+ -+ wpa_printf(MSG_DEBUG, "AWGN: Adding channel %d (%d)", -+ chan->freq, chan->chan); -+ channel_idx++; -+ } -+ return channel_idx; -+} -+ -+enum chan_seg { -+ SEG_PRI20 = 0x1, -+ SEG_SEC20 = 0x2, -+ SEG_SEC40_LOWER = 0x4, -+ SEG_SEC40_UPPER = 0x8, -+ SEG_SEC40 = 0xC, -+ SEG_SEC80_LOWER = 0x10, -+ SEG_SEC80_LOWER_UPPER = 0x20, -+ SEG_SEC80_UPPER_LOWER = 0x40, -+ SEG_SEC80_UPPER = 0x80, -+ SEG_SEC80 = 0xF0, -+}; -+ -+#define BASE_6G_FREQ 5950 -+ -+int get_centre_freq_6g(int chan_idx, int chan_width, int *centre_freq) -+{ -+ if (!centre_freq) -+ return -1; -+ -+ *centre_freq = 0; -+ -+ switch (chan_width) { -+ case CHAN_WIDTH_40: -+ if (chan_idx >= 1 && chan_idx <= 229) -+ *centre_freq = ((chan_idx / 8) * 8 + 3) * 5 + BASE_6G_FREQ; -+ break; -+ case CHAN_WIDTH_80: -+ if (chan_idx >= 1 && chan_idx <= 221) -+ *centre_freq = ((chan_idx / 16) * 16 + 7) * 5 + BASE_6G_FREQ; -+ break; -+ case CHAN_WIDTH_160: -+ if (chan_idx >= 1 && chan_idx <= 221) -+ *centre_freq = ((chan_idx / 32) * 32 + 15) * 5 + BASE_6G_FREQ; -+ break; -+ default: -+ break; -+ } -+ -+ if (*centre_freq == 0) -+ return -1; -+ -+ return 0; -+} -+ -+/* -+ * hostapd_intf_awgn_detected - awgn interference is detected in the operating channel. -+ * The interference channel information is available as a -+ * bitmap(chan_bw_interference_bitmap). If interference has occurred in the -+ * primary channel, do a complete channel switch to a different channel else -+ * reduce the operating bandwidth and continue ap operation in the same channel. -+ */ -+int hostapd_intf_awgn_detected(struct hostapd_iface *iface, int freq, int chan_width, -+ int cf1, int cf2, u32 chan_bw_interference_bitmap) -+{ -+ struct csa_settings settings; -+ struct hostapd_channel_data *chan_data = NULL; -+ struct hostapd_channel_data *chan_temp = NULL; -+ int ret; -+ unsigned int i; -+ u32 _rand; -+ u32 chan_idx; -+ int num_available_chandefs; -+ u8 channel_switch = 0; -+ int new_chan_width; -+ int new_centre_freq; -+ struct hostapd_hw_modes *mode = iface->current_mode; -+ -+ wpa_printf(MSG_DEBUG, -+ "input freq=%d, chan_width=%d, cf1=%d cf2=%d" -+ " chan_bw_interference_bitmap=0x%x", -+ freq, -+ chan_width, -+ cf1, cf2, chan_bw_interference_bitmap); -+ -+ if (iface->conf->discard_6g_awgn_event) { -+ wpa_printf(MSG_DEBUG, "discard_6g_awgn_event set ignoring" -+ "AWGN DETECT event from driver"); -+ return 0; -+ } -+ -+ /* check whether interference has occurred in primary 20Mhz channel */ -+ if (!chan_bw_interference_bitmap || (chan_bw_interference_bitmap & SEG_PRI20)) -+ channel_switch = 1; -+ -+ if (channel_switch) { -+ /* Find a random channel to be switched */ -+ num_available_chandefs = intf_awgn_find_channel(iface, NULL, 0, -+ chan_width); -+ if (num_available_chandefs == 0) { -+ wpa_printf(MSG_ERROR, "AWGN: no available_chandefs"); -+ return 0; -+ } -+ -+ if (os_get_random((u8 *)&_rand, sizeof(_rand)) < 0) { -+ wpa_printf(MSG_ERROR, "AWGN: couldn't get random number"); -+ return 0; -+ } -+ -+ chan_idx = _rand % num_available_chandefs; -+ intf_awgn_find_channel(iface, &chan_data, chan_idx, chan_width); -+ -+ if (!chan_data) { -+ wpa_printf(MSG_ERROR, "AWGN: no random channel found, chan idx : %d", -+ chan_idx); -+ return 0; -+ } -+ -+ if(chan_data->freq == freq) { -+ /* New random channel is same as operating channel -+ * so choose another channel -+ */ -+ chan_data = NULL; -+ chan_idx = (chan_idx + 1) % num_available_chandefs; -+ intf_awgn_find_channel(iface, &chan_data, chan_idx, chan_width); -+ if (!chan_data) { -+ wpa_printf(MSG_ERROR, -+ "AWGN: random channel not found, chan idx : %d", -+ chan_idx); -+ return 0; -+ } -+ } -+ -+ wpa_printf(MSG_DEBUG, "AWGN: got random channel %d (%d)", -+ chan_data->freq, chan_data->chan); -+ new_chan_width = chan_width; -+ } else { -+ /* interference is not present in the primary 20Mhz, so reduce bandwidth*/ -+ for (i = 0; i < mode->num_channels; i++) { -+ chan_temp = &mode->channels[i]; -+ if (chan_temp->freq == freq) -+ chan_data = chan_temp; -+ } -+ if (!chan_data) { -+ wpa_printf(MSG_ERROR, "AWGN : no channel found"); -+ return 0; -+ } -+ -+ if ((chan_width > CHAN_WIDTH_80) && -+ !(chan_bw_interference_bitmap & SEG_SEC40) && -+ !(chan_bw_interference_bitmap & SEG_SEC20)) -+ new_chan_width = CHAN_WIDTH_80; -+ else if (chan_width > CHAN_WIDTH_40 && -+ !(chan_bw_interference_bitmap & SEG_SEC20)) -+ new_chan_width = CHAN_WIDTH_40; -+ else -+ new_chan_width = CHAN_WIDTH_20; -+ } -+ -+ if (new_chan_width > CHAN_WIDTH_20) { -+ ret = get_centre_freq_6g(chan_data->chan, new_chan_width, -+ &new_centre_freq); -+ if (ret) { -+ wpa_printf(MSG_ERROR, -+ "AWGN : couldn't find centre freq for chan : %d" -+ " chan_width : %d", chan_data->chan, new_chan_width); -+ return 0; -+ } -+ } else { -+ new_centre_freq = chan_data->freq; -+ } -+ -+ os_memset(&settings, 0, sizeof(settings)); -+ settings.cs_count = 5; -+ settings.freq_params.freq = chan_data->freq; -+ -+ switch (new_chan_width) { -+ case CHAN_WIDTH_40: -+ settings.freq_params.bandwidth = 40; -+ break; -+ case CHAN_WIDTH_80P80: -+ case CHAN_WIDTH_80: -+ settings.freq_params.bandwidth = 80; -+ break; -+ case CHAN_WIDTH_160: -+ settings.freq_params.bandwidth = 160; -+ break; -+ default: -+ settings.freq_params.bandwidth = 20; -+ break; -+ } -+ -+ settings.freq_params.center_freq1 = new_centre_freq; -+ settings.freq_params.ht_enabled = iface->conf->ieee80211n; -+ settings.freq_params.vht_enabled = iface->conf->ieee80211ac; -+ settings.freq_params.he_enabled = iface->conf->ieee80211ax; -+ -+ for (i = 0; i < iface->num_bss; i++) { -+ /* Save CHAN_SWITCH VHT and HE config */ -+ hostapd_chan_switch_config(iface->bss[i], -+ &settings.freq_params); -+ -+ wpa_printf(MSG_DEBUG, -+ "channel=%u, freq=%d, bw=%d, center_freq1=%d", -+ settings.freq_params.channel, -+ settings.freq_params.freq, -+ settings.freq_params.bandwidth, -+ settings.freq_params.center_freq1); -+ -+ ret = hostapd_switch_channel(iface->bss[i], &settings); -+ if (ret) { -+ /* FIX: What do we do if CSA fails in the middle of -+ * submitting multi-BSS CSA requests? -+ */ -+ return ret; -+ } -+ } -+ -+ return 0; -+} -diff --git a/src/ap/interference.h b/src/ap/interference.h -new file mode 100644 -index 000000000000..047818c0b2f6 ---- /dev/null -+++ b/src/ap/interference.h -@@ -0,0 +1,41 @@ -+/* -+ * INTF - Interference -+ * AWGN - Additive white Gaussian Noise -+ * Copyright (c) 2002-2013, Jouni Malinen -+ * Copyright (c) 2013-2017, Qualcomm Atheros, Inc. -+ * -+ * This software may be distributed under the terms of the BSD license. -+ * See README for more details. -+ */ -+ -+/* -+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without modification, -+ * are permitted (subject to the limitations in the disclaimer below) provided that -+ * the following conditions are met: -+ * * Redistributions of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation and/or -+ * other materials provided with the distribution. -+ * * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its contributors -+ * may be used to endorse or promote products derived from this software without specific -+ * prior written permission. -+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS -+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+int hostapd_intf_awgn_detected(struct hostapd_iface *iface, int freq, -+ int chan_width, -+ int cf1, int cf2, -+ u32 chan_bw_interference_bitmap); -+ -diff --git a/src/drivers/driver.h b/src/drivers/driver.h -index 01f1bc4091ab..57cfac622db5 100644 ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -5214,6 +5214,7 @@ enum wpa_event_type { - * EVENT_CCA_NOTIFY - Notification that CCA has completed - */ - EVENT_CCA_NOTIFY, -+ EVENT_AWGN_DETECTED, - }; - - -@@ -6123,6 +6124,18 @@ union wpa_event_data { - struct bss_color_collision { - u64 bitmap; - } bss_color_collision; -+ -+ /** -+ * Data for EVENT_AWGN -+ */ -+ struct awgn_event { -+ int freq; -+ enum chan_width chan_width; -+ int cf1; -+ int cf2; -+ u32 chan_bw_interference_bitmap; -+ } awgn_event; -+ - }; - - /** -diff --git a/src/drivers/driver_common.c b/src/drivers/driver_common.c -index b06e7062d25c..198c2713b91e 100644 ---- a/src/drivers/driver_common.c -+++ b/src/drivers/driver_common.c -@@ -95,6 +95,7 @@ const char * event_to_string(enum wpa_event_type event) - E2S(CCA_STARTED_NOTIFY); - E2S(CCA_ABORTED_NOTIFY); - E2S(CCA_NOTIFY); -+ E2S(AWGN_DETECTED); - } - - return "UNKNOWN"; -diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c -index 7a357c07340f..9a32b7a0e0ca 100644 ---- a/src/drivers/driver_nl80211_event.c -+++ b/src/drivers/driver_nl80211_event.c -@@ -179,6 +179,7 @@ static const char * nl80211_command_to_string(enum nl80211_commands cmd) - C2S(NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_STARTED) - C2S(NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_ABORTED) - C2S(NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_COMPLETED) -+ C2S(NL80211_CMD_AWGN_DETECT) - C2S(__NL80211_CMD_AFTER_LAST) - } - #undef C2S -@@ -1856,6 +1857,32 @@ static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv, - } - } - -+static void nl80211_awgn_event(struct wpa_driver_nl80211_data *drv, -+ struct nlattr **tb) -+{ -+ union wpa_event_data data; -+ -+ os_memset(&data, 0, sizeof(data)); -+ -+ if (tb[NL80211_ATTR_WIPHY_FREQ]) -+ data.awgn_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]); -+ -+ if (tb[NL80211_ATTR_CHANNEL_WIDTH]) -+ data.awgn_event.chan_width = -+ convert2width(nla_get_u32(tb[NL80211_ATTR_CHANNEL_WIDTH])); -+ -+ if (tb[NL80211_ATTR_CENTER_FREQ1]) -+ data.awgn_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]); -+ -+ if (tb[NL80211_ATTR_CENTER_FREQ2]) -+ data.awgn_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]); -+ -+ if (tb[NL80211_ATTR_AWGN_INTERFERENCE_BITMAP]) -+ data.awgn_event.chan_bw_interference_bitmap = -+ nla_get_u32(tb[NL80211_ATTR_AWGN_INTERFERENCE_BITMAP]); -+ -+ wpa_supplicant_event(drv->ctx, EVENT_AWGN_DETECTED, &data); -+} - - static void nl80211_spurious_frame(struct i802_bss *bss, struct nlattr **tb, - int wds) -@@ -3198,6 +3225,9 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, - mlme_event_color_change_announcement_completed(drv); - break; - #endif -+ case NL80211_CMD_AWGN_DETECT: -+ nl80211_awgn_event(drv, tb); -+ break; - default: - wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event " - "(cmd=%d)", cmd); -diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h -index 85fe14ba9093..ea5fd565bb43 100644 ---- a/src/drivers/nl80211_copy.h -+++ b/src/drivers/nl80211_copy.h -@@ -1190,6 +1190,10 @@ - * were indicated by driver and now need to be reflected in - * Beacon frame. - * -+ * @NL80211_CMD_AWGN_DETECT: Once AWGN interference is detected on the operating -+ * channel, userspace is notified with the interference bitmap using -+ * %NL80211_ATTR_AWGN_INTERFERENCE_BITMAP -+ * - * @NL80211_CMD_MAX: highest used command number - * @__NL80211_CMD_AFTER_LAST: internal use - */ -@@ -1431,6 +1435,8 @@ enum nl80211_commands { - NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_ABORTED, - NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_COMPLETED, - -+ NL80211_CMD_AWGN_DETECT, -+ - NL80211_CMD_SET_FILS_AAD, - - /* add new commands above here */ -@@ -2583,6 +2589,9 @@ enum nl80211_commands { - * staggered mode or burst mode in %NL80211_CMD_START_AP from - * user-space. - * -+ * @NL80211_ATTR_AWGN_INTERFERENCE_BITMAP: u32 attribute specifying the -+ * interference bitmap of operating bandwidth for %NL80211_CMD_AWGN_DETECT -+ * - * @NUM_NL80211_ATTR: total number of nl80211_attrs available - * @NL80211_ATTR_MAX: highest attribute number currently defined - * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -2678,7 +2687,6 @@ enum nl80211_attrs { - - NL80211_ATTR_FREQ_FIXED, - -- - NL80211_ATTR_WIPHY_RETRY_SHORT, - NL80211_ATTR_WIPHY_RETRY_LONG, - NL80211_ATTR_WIPHY_FRAG_THRESHOLD, -@@ -3093,6 +3101,12 @@ enum nl80211_attrs { - - NL80211_ATTR_BEACON_TX_MODE, - -+ NL80211_ATTR_WIPHY_ANTENNA_GAIN, -+ -+ NL80211_ATTR_STA_MGMT_RTS_CTS_CONFIG, -+ -+ NL80211_ATTR_AWGN_INTERFERENCE_BITMAP, -+ - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, -diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile -index 9ff1e8d51568..4c6592b62f5b 100644 ---- a/wpa_supplicant/Makefile -+++ b/wpa_supplicant/Makefile -@@ -977,6 +977,7 @@ OBJS += ../src/ap/ap_list.o - OBJS += ../src/ap/ieee802_11.o - OBJS += ../src/ap/hw_features.o - OBJS += ../src/ap/dfs.o -+OBJS += ../src/ap/interference.o - CFLAGS += -DNEED_AP_MLME - endif - ifdef CONFIG_WPS --- -2.31.1 - diff --git a/feeds/ipq95xx/hostapd/patches/n00-001-hostapd-add-support-for-6GHz-operation.patch b/feeds/ipq95xx/hostapd/patches/n00-001-hostapd-add-support-for-6GHz-operation.patch deleted file mode 100644 index 82e90e09..00000000 --- a/feeds/ipq95xx/hostapd/patches/n00-001-hostapd-add-support-for-6GHz-operation.patch +++ /dev/null @@ -1,564 +0,0 @@ -From 404211da041eef5ddfc52515048b04c70ef8579c Mon Sep 17 00:00:00 2001 -From: Aditya Kumar Singh -Date: Thu, 21 Oct 2021 12:51:38 +0530 -Subject: [PATCH] hostapd: add support for 6GHz operation - -6 GHz gives users ability to select the AP mode from LPI, SP and -VLP modes. This mode needs to be passed on to the cfg80211 -for further processing during AP bring up. Also, the regulatory -rules received by hostapd contains psd values for 6G rules. -Hostapd needs to store these values in order to later advertise -it in the tx power element in the beacon. - -This patch adds the support to send the user configured 6g power -type during set_channel command and as well to get and store the -psd values from reg rules which will be later on used in tpe -advertisement during beacon formation. - -Signed-off-by: Aditya Kumar Singh ---- - src/ap/ap_drv_ops.c | 9 ++++++--- - src/ap/beacon.c | 9 +++++++-- - src/ap/dfs.c | 6 ++++-- - src/ap/hostapd.c | 2 +- - src/ap/ieee802_11.c | 13 ++++++++++++- - src/ap/ieee802_11_he.c | 10 ++++++++-- - src/common/hw_features_common.c | 4 +++- - src/common/hw_features_common.h | 2 +- - src/common/ieee802_11_defs.h | 14 ++++++++++++++ - src/drivers/driver.h | 20 +++++++++++++++++++- - src/drivers/driver_hostap.c | 3 ++- - src/drivers/driver_nl80211.c | 15 ++++++++++++++- - src/drivers/driver_nl80211.h | 2 +- - src/drivers/driver_nl80211_capa.c | 28 +++++++++++++++++++++++----- - src/drivers/driver_nl80211_event.c | 2 +- - src/drivers/nl80211_copy.h | 19 +++++++++++++++++++ - wpa_supplicant/driver_i.h | 2 +- - wpa_supplicant/mesh.c | 2 +- - wpa_supplicant/wpa_supplicant.c | 2 +- - 19 files changed, 138 insertions(+), 26 deletions(-) - ---- a/src/ap/ap_drv_ops.c -+++ b/src/ap/ap_drv_ops.c -@@ -563,7 +563,8 @@ int hostapd_set_freq(struct hostapd_data - center_segment0, center_segment1, - cmode ? cmode->vht_capab : 0, - cmode ? -- &cmode->he_capab[IEEE80211_MODE_AP] : NULL)) -+ &cmode->he_capab[IEEE80211_MODE_AP] : NULL, -+ hapd->iconf->he_6ghz_reg_pwr_type)) - return -1; - - if (hapd->driver == NULL) -@@ -636,7 +637,8 @@ hostapd_get_hw_feature_data(struct hosta - hapd->driver->get_hw_feature_data == NULL) - return NULL; - return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes, -- flags, dfs_domain); -+ flags, dfs_domain, -+ hapd->iconf->he_6ghz_reg_pwr_type); - } - - -@@ -836,7 +838,8 @@ int hostapd_start_dfs_cac(struct hostapd - oper_chwidth, center_segment0, - center_segment1, - cmode->vht_capab, -- &cmode->he_capab[IEEE80211_MODE_AP])) { -+ &cmode->he_capab[IEEE80211_MODE_AP], -+ hapd->iconf->he_6ghz_reg_pwr_type)) { - wpa_printf(MSG_ERROR, "Can't set freq params"); - return -1; - } ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -1563,7 +1563,11 @@ int ieee802_11_build_ap_params(struct ho - if (is_6ghz_op_class(hapd->iconf->op_class)) { - tail_len += sizeof(struct ieee80211_he_6ghz_oper_info) + - 3 + sizeof(struct ieee80211_he_6ghz_band_cap); -- /* Additional TX Power envelope for subordinate client */ -+ /* Additional TX Power envelope for subordinate client -+ * Currently as per the spec, only AP LP mode should send -+ * the tpe for subordinate client. SP mode should not and -+ * no standard set yet for VLP mode. -+ */ - if (hostapd_get_he_6ghz_reg_pwr_type(hapd->iconf) == - AP_TYPE_6GHZ_INDOOR_AP) - tail_len += 4; -@@ -1988,7 +1992,8 @@ static int __ieee802_11_set_beacon(struc - hostapd_get_oper_centr_freq_seg0_idx(iconf), - hostapd_get_oper_centr_freq_seg1_idx(iconf), - cmode->vht_capab, -- &cmode->he_capab[IEEE80211_MODE_AP]) == 0) -+ &cmode->he_capab[IEEE80211_MODE_AP], -+ iconf->he_6ghz_reg_pwr_type) == 0) - params.freq = &freq; - - res = hostapd_drv_set_ap(hapd, ¶ms); ---- a/src/ap/dfs.c -+++ b/src/ap/dfs.c -@@ -1089,7 +1089,8 @@ static int hostapd_dfs_testmode_set_beac - vht_oper_centr_freq_seg0_idx, - vht_oper_centr_freq_seg1_idx, - iface->current_mode->vht_capab, -- &iface->current_mode->he_capab[IEEE80211_MODE_AP]); -+ &iface->current_mode->he_capab[IEEE80211_MODE_AP], -+ hapd->iconf->he_6ghz_reg_pwr_type); - - if (err) { - wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params"); -@@ -1230,7 +1231,8 @@ static int hostapd_dfs_start_channel_swi - oper_centr_freq_seg0_idx, - oper_centr_freq_seg1_idx, - cmode->vht_capab, -- &cmode->he_capab[ieee80211_mode]); -+ &cmode->he_capab[ieee80211_mode], -+ iface->conf->he_6ghz_reg_pwr_type); - - if (err) { - wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params"); ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -3534,7 +3534,7 @@ static int hostapd_change_config_freq(st - hostapd_get_oper_centr_freq_seg1_idx(conf), - conf->vht_capab, - mode ? &mode->he_capab[IEEE80211_MODE_AP] : -- NULL)) -+ NULL, hapd->iconf->he_6ghz_reg_pwr_type)) - return -1; - - switch (params->bandwidth) { ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -7017,6 +7017,8 @@ u8 * hostapd_eid_txpower_envelope(struct - int dfs, i; - u8 channel, tx_pwr_count, local_pwr_constraint; - u8 tx_pwr, tx_pwr_intrpn, tx_pwr_cat, ap_type; -+ s8 psd; -+ - int max_tx_power; - - if (!mode) -@@ -7053,15 +7055,24 @@ u8 * hostapd_eid_txpower_envelope(struct - */ - if (ap_type == AP_TYPE_6GHZ_INDOOR_AP) { - tx_pwr_cat = REG_SUBORDINATE_CLIENT; -- /* TODO: extract psd limits from channel data */ -+ psd = mode->psd_values[NL80211_REG_SUBORDINATE_CLIENT_LPI + ap_type]; -+#ifdef REG_DOM_SUPPORT_TX_POWER -+ tx_pwr = psd * 2; -+#else - tx_pwr = (hostapd_get_6g_tx_power(hapd, ap_type, tx_pwr_cat) * 2); -+#endif /* REG_DOM_SUPPORT_TX_POWER */ - eid = hostapd_add_tpe_info(eid, tx_pwr_count, tx_pwr_intrpn, - tx_pwr_cat, tx_pwr); - } - - /* Default Tx Power envelope for Global Operating class */ - tx_pwr_cat = REG_DEFAULT_CLIENT; -+ psd = mode->psd_values[NL80211_REG_REGULAR_CLIENT_LPI + ap_type]; -+#ifdef REG_DOM_SUPPORT_TX_POWER -+ tx_pwr = psd * 2; -+#else - tx_pwr = (hostapd_get_6g_tx_power(hapd, ap_type, tx_pwr_cat) * 2); -+#endif /* REG_DOM_SUPPORT_TX_POWER */ - eid = hostapd_add_tpe_info(eid, tx_pwr_count, tx_pwr_intrpn, tx_pwr_cat, tx_pwr); - - return eid; ---- a/src/ap/ieee802_11_he.c -+++ b/src/ap/ieee802_11_he.c -@@ -241,10 +241,16 @@ u8 * hostapd_eid_he_operation(struct hos - * - 1 (Standard Power Access Point) - * - Reserved in 5GHz and 2Ghz bands - */ -+ -+ u8 ap_type = hostapd_get_he_6ghz_reg_pwr_type(hapd->iconf); -+ - if (seg1) -- *pos++ = 3; -+ *pos++ = 3 | (IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO & -+ (ap_type << IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO_LSB)); - else -- *pos++ = center_idx_to_bw_6ghz(seg0); -+ *pos++ = center_idx_to_bw_6ghz(seg0) | -+ (IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO & -+ (ap_type << IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO_LSB)); - - /* Channel Center Freq Seg0/Seg1 */ - if (hapd->iconf->he_oper_chwidth == 2) { ---- a/src/common/hw_features_common.c -+++ b/src/common/hw_features_common.c -@@ -386,7 +386,7 @@ int hostapd_set_freq_params(struct hosta - int sec_channel_offset, - int oper_chwidth, int center_segment0, - int center_segment1, u32 vht_caps, -- struct he_capabilities *he_cap) -+ struct he_capabilities *he_cap, u8 reg_6g_pwr_mode) - { - if (!he_cap || !he_cap->he_supported) - he_enabled = 0; -@@ -477,6 +477,8 @@ int hostapd_set_freq_params(struct hosta - data->ht_enabled = 0; - data->vht_enabled = 0; - -+ /* Append 6G reg power info */ -+ data->he_6ghz_reg_pwr_type = reg_6g_pwr_mode; - return 0; - } - ---- a/src/common/hw_features_common.h -+++ b/src/common/hw_features_common.h -@@ -43,7 +43,7 @@ int hostapd_set_freq_params(struct hosta - int sec_channel_offset, - int oper_chwidth, int center_segment0, - int center_segment1, u32 vht_caps, -- struct he_capabilities *he_caps); -+ struct he_capabilities *he_caps, u8 reg_6g_pwr_mode); - void set_disable_ht40(struct ieee80211_ht_capabilities *htcaps, - int disabled); - int ieee80211ac_cap_check(u32 hw, u32 conf); ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -1986,6 +1986,17 @@ enum reg_6g_client_type { - - /* same Max Tx Pwr for all 20MHz bands */ - #define DEFAULT_MAX_TX_POWER_COUNT_6G 0 -+ -+/* -+ * REG_DOM_SUPPORT_TX_POWER - regulatory domain -+ * supports tx power values or not. -+ * -+ * If this macro is undefined, tx-power macros will be used to -+ * get the tx-power, otherwise psd values from regulatory domain -+ * will be taken -+ */ -+#define REG_DOM_SUPPORT_TX_POWER 1 -+ - /* - * These tx-power macros are present till the 6G regdomains are defined to - * support tx-power values for various client types. -@@ -2372,6 +2383,9 @@ struct ieee80211_spatial_reuse { - #define HE_OPERATION_BSS_COLOR_OFFSET 24 - #define HE_OPERATION_BSS_COLOR_MAX 64 - -+#define IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO 0x38 -+#define IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO_LSB 3 -+ - /* Spatial Reuse defines */ - #define SPATIAL_REUSE_SRP_DISALLOWED BIT(0) - #define SPATIAL_REUSE_NON_SRG_OBSS_PD_SR_DISALLOWED BIT(1) ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -299,6 +299,12 @@ struct hostapd_hw_modes { - * for IEEE 802.11ay EDMG configuration. - */ - struct ieee80211_edmg_config edmg; -+ -+ /** -+ * This array is used to store the psd value of each power mode -+ * supported in 6G band. -+ */ -+ s8 psd_values[NL80211_REG_NUM_POWER_MODES]; - }; - - -@@ -783,6 +789,17 @@ struct hostapd_freq_params { - * for IEEE 802.11ay EDMG configuration. - */ - struct ieee80211_edmg_config edmg; -+ -+ /** -+ * he_6ghz_reg_pwr_type - 6G regulatory power mode -+ * Since many operation related to channel for 6G depends on the -+ * power mode, this parameter is added here. -+ * -+ * 0 - LPI_AP -+ * 1 - SP_AP -+ * 2 - VLP_AP -+ */ -+ u8 he_6ghz_reg_pwr_type; - }; - - /** -@@ -2926,12 +2943,13 @@ struct wpa_driver_ops { - * @num_modes: Variable for returning the number of returned modes - * flags: Variable for returning hardware feature flags - * @dfs: Variable for returning DFS region (HOSTAPD_DFS_REGION_*) -+ * @pwr_mode: Variable required for processing the support data for 6G - * Returns: Pointer to allocated hardware data on success or %NULL on - * failure. Caller is responsible for freeing this. - */ - struct hostapd_hw_modes * (*get_hw_feature_data)(void *priv, - u16 *num_modes, -- u16 *flags, u8 *dfs); -+ u16 *flags, u8 *dfs, u8 pwr_mode); - - /** - * send_mlme - Send management frame from MLME ---- a/src/drivers/driver_hostap.c -+++ b/src/drivers/driver_hostap.c -@@ -1099,7 +1099,8 @@ static int hostap_sta_disassoc(void *pri - - static struct hostapd_hw_modes * hostap_get_hw_feature_data(void *priv, - u16 *num_modes, -- u16 *flags, u8 *dfs) -+ u16 *flags, u8 *dfs, -+ u8 pwr_mode) - { - struct hostapd_hw_modes *mode; - int i, clen, rlen; ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -5074,6 +5074,19 @@ static int nl80211_set_channel(struct i8 - return -1; - } - -+#ifdef CONFIG_IEEE80211AX -+ if (freq->freq && is_6ghz_freq(freq->freq)) { -+ wpa_printf(MSG_DEBUG, "%s: 6g_reg_pwr_mode=%d", -+ __func__, freq->he_6ghz_reg_pwr_type); -+ if (nla_put_u8(msg, NL80211_ATTR_6G_REG_POWER_MODE, -+ freq->he_6ghz_reg_pwr_type)) { -+ wpa_printf(MSG_ERROR, -+ "%s: Failed to put 6g_reg_pwr_mode", __func__); -+ nlmsg_free(msg); -+ return -1; -+ } -+ } -+#endif /* CONFIG_IEEE80211AX */ - ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL); - if (ret == 0) { - bss->freq = freq->freq; -@@ -8353,7 +8366,7 @@ static int wpa_driver_nl80211_send_actio - int i; - - modes = nl80211_get_hw_feature_data(bss, &num_modes, -- &flags, &dfs_domain); -+ &flags, &dfs_domain, 0); - if (dfs_domain != HOSTAPD_DFS_REGION_ETSI && - ieee80211_is_dfs(bss->freq, modes, num_modes)) - offchanok = 0; ---- a/src/drivers/driver_nl80211.h -+++ b/src/drivers/driver_nl80211.h -@@ -288,7 +288,7 @@ int nl80211_send_monitor(struct wpa_driv - int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv); - struct hostapd_hw_modes * - nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags, -- u8 *dfs_domain); -+ u8 *dfs_domain, u8 pwr_mode); - - int process_global_event(struct nl_msg *msg, void *arg); - int process_bss_event(struct nl_msg *msg, void *arg); ---- a/src/drivers/driver_nl80211_capa.c -+++ b/src/drivers/driver_nl80211_capa.c -@@ -1468,6 +1468,7 @@ struct phy_info_arg { - int last_mode, last_chan_idx; - int failed; - u8 dfs_domain; -+ u8 pwr_mode; - }; - - static void phy_info_ht_capa(struct hostapd_hw_modes *mode, struct nlattr *capa, -@@ -2116,7 +2117,9 @@ static void nl80211_set_ht40_mode_sec(st - - - static void nl80211_reg_rule_max_eirp(u32 start, u32 end, u32 max_eirp, -- struct phy_info_arg *results) -+ struct phy_info_arg *results, -+ u8 config_pwr_mode, u8 pwr_mode, -+ s8 psd) - { - u16 m; - -@@ -2126,10 +2129,16 @@ static void nl80211_reg_rule_max_eirp(u3 - - for (c = 0; c < mode->num_channels; c++) { - struct hostapd_channel_data *chan = &mode->channels[c]; -+ -+ if (is_6ghz_freq(chan->freq) && config_pwr_mode != pwr_mode) -+ continue; -+ - if ((u32) chan->freq - 10 >= start && - (u32) chan->freq + 10 <= end) - chan->max_tx_power = max_eirp; - } -+ /* Update the psd rules */ -+ mode->psd_values[pwr_mode] = psd; - } - } - -@@ -2302,6 +2311,7 @@ static int nl80211_get_reg(struct nl_msg - [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 }, - }; - -+ u8 config_pwr_mode = results->pwr_mode; - nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), - genlmsg_attrlen(gnlh, 0), NULL); - if (!tb_msg[NL80211_ATTR_REG_ALPHA2] || -@@ -2326,6 +2336,8 @@ static int nl80211_get_reg(struct nl_msg - nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule) - { - u32 start, end, max_eirp = 0, max_bw = 0, flags = 0; -+ u8 pwr_mode = 0; -+ s8 psd = 0; - nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX, - nla_data(nl_rule), nla_len(nl_rule), reg_policy); - if (tb_rule[NL80211_ATTR_FREQ_RANGE_START] == NULL || -@@ -2339,9 +2351,13 @@ static int nl80211_get_reg(struct nl_msg - max_bw = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000; - if (tb_rule[NL80211_ATTR_REG_RULE_FLAGS]) - flags = nla_get_u32(tb_rule[NL80211_ATTR_REG_RULE_FLAGS]); -+ if (tb_rule[NL80211_ATTR_REG_POWER_MODE]) -+ pwr_mode = nla_get_u8(tb_rule[NL80211_ATTR_REG_POWER_MODE]); -+ if (tb_rule[NL80211_ATTR_POWER_RULE_PSD]) -+ psd = (s8) nla_get_u8(tb_rule[NL80211_ATTR_POWER_RULE_PSD]); - -- wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz %u mBm%s%s%s%s%s%s%s%s", -- start, end, max_bw, max_eirp, -+ wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz %u mBm pwr_mode: %u psd: %d%s%s%s%s%s%s%s%s", -+ start, end, max_bw, max_eirp, pwr_mode, psd, - flags & NL80211_RRF_NO_OFDM ? " (no OFDM)" : "", - flags & NL80211_RRF_NO_CCK ? " (no CCK)" : "", - flags & NL80211_RRF_NO_INDOOR ? " (no indoor)" : "", -@@ -2355,7 +2371,8 @@ static int nl80211_get_reg(struct nl_msg - nl80211_reg_rule_ht40(start, end, results); - if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP]) - nl80211_reg_rule_max_eirp(start, end, max_eirp, -- results); -+ results, config_pwr_mode, -+ pwr_mode, psd); - } - - nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule) -@@ -2455,7 +2472,7 @@ static void nl80211_dump_chan_list(struc - - struct hostapd_hw_modes * - nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags, -- u8 *dfs_domain) -+ u8 *dfs_domain, u8 pwr_mode) - { - u32 feat; - struct i802_bss *bss = priv; -@@ -2468,6 +2485,7 @@ nl80211_get_hw_feature_data(void *priv, - .last_mode = -1, - .failed = 0, - .dfs_domain = 0, -+ .pwr_mode = pwr_mode - }; - - *num_modes = 0; ---- a/src/drivers/driver_nl80211_event.c -+++ b/src/drivers/driver_nl80211_event.c -@@ -1982,7 +1982,7 @@ static unsigned int chan_to_freq(struct - int i; - - modes = nl80211_get_hw_feature_data(drv->first_bss, &num_modes, -- &flags, &dfs_domain); -+ &flags, &dfs_domain, 0); - if (!modes) { - wpa_printf(MSG_DEBUG, - "nl80211: Fetching hardware mode failed"); ---- a/src/drivers/nl80211_copy.h -+++ b/src/drivers/nl80211_copy.h -@@ -3135,6 +3136,8 @@ enum nl80211_attrs { - - NL80211_ATTR_AWGN_INTERFERENCE_BITMAP, - -+ NL80211_ATTR_6G_REG_POWER_MODE, -+ - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, -@@ -3799,6 +3802,20 @@ enum nl80211_band_attr { - - #define NL80211_BAND_ATTR_HT_CAPA NL80211_BAND_ATTR_HT_CAPA - -+enum nl80211_regulatory_power_modes { -+ NL80211_REG_AP_LPI, -+ NL80211_REG_AP_SP, -+ NL80211_REG_AP_VLP, -+ NL80211_REG_REGULAR_CLIENT_LPI, -+ NL80211_REG_REGULAR_CLIENT_SP, -+ NL80211_REG_REGULAR_CLIENT_VLP, -+ NL80211_REG_SUBORDINATE_CLIENT_LPI, -+ NL80211_REG_SUBORDINATE_CLIENT_SP, -+ NL80211_REG_SUBORDINATE_CLIENT_VLP, -+ -+ NL80211_REG_NUM_POWER_MODES, -+}; -+ - /** - * enum nl80211_wmm_rule - regulatory wmm rule - * -@@ -4023,6 +4040,9 @@ enum nl80211_reg_type { - * a given frequency range. The value is in mBm (100 * dBm). - * @NL80211_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds. - * If not present or 0 default CAC time will be used. -+ * @NL80211_ATTR_POWER_RULE_PSD: power spectral density (in dBm). -+ * This could be negative. -+ * @NL80211_ATTR_REG_POWER_MODE: the regulatory power mode for 6G rules - * @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number - * currently defined - * @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use -@@ -4040,6 +4060,10 @@ enum nl80211_reg_rule_attr { - - NL80211_ATTR_DFS_CAC_TIME, - -+ NL80211_ATTR_POWER_RULE_PSD, -+ -+ NL80211_ATTR_REG_POWER_MODE, -+ - /* keep last */ - __NL80211_REG_RULE_ATTR_AFTER_LAST, - NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1 ---- a/wpa_supplicant/driver_i.h -+++ b/wpa_supplicant/driver_i.h -@@ -305,7 +305,7 @@ wpa_drv_get_hw_feature_data(struct wpa_s - if (wpa_s->driver->get_hw_feature_data) - return wpa_s->driver->get_hw_feature_data(wpa_s->drv_priv, - num_modes, flags, -- dfs_domain); -+ dfs_domain, 0); - return NULL; - } - ---- a/wpa_supplicant/mesh.c -+++ b/wpa_supplicant/mesh.c -@@ -232,7 +232,7 @@ static int wpas_mesh_update_freq_params( - hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf), - hostapd_get_oper_centr_freq_seg1_idx(ifmsh->conf), - ifmsh->conf->vht_capab, -- he_capab)) { -+ he_capab, ifmsh->conf->he_6ghz_reg_pwr_type)) { - wpa_printf(MSG_ERROR, "Error updating mesh frequency params"); - wpa_supplicant_mesh_deinit(wpa_s, true); - return -1; ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -2824,7 +2824,7 @@ skip_to_6ghz: - vht_freq.vht_enabled, vht_freq.he_enabled, - freq->sec_channel_offset, - chwidth, seg0, seg1, vht_caps, -- &mode->he_capab[ieee80211_mode]) != 0) -+ &mode->he_capab[ieee80211_mode], 0) != 0) - return; - - *freq = vht_freq; ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -3542,6 +3542,15 @@ static int hostapd_config_fill(struct ho - } - } else if (os_strcmp(buf, "he_6ghz_reg_pwr_type") == 0) { - conf->he_6ghz_reg_pwr_type = atoi(pos); -+ if (conf->he_6ghz_reg_pwr_type > AP_TYPE_6GHZ_VERY_LOW_POWER_AP || -+ conf->he_6ghz_reg_pwr_type < AP_TYPE_6GHZ_INDOOR_AP) { -+ wpa_printf(MSG_ERROR, -+ "Line %d: Invalid 6ghz regulatory power type('%s') " -+ "[min: %d and max: %d]", -+ line, pos, AP_TYPE_6GHZ_INDOOR_AP, -+ AP_TYPE_6GHZ_VERY_LOW_POWER_AP); -+ return 1; -+ } - } else if (os_strcmp(buf, "he_oper_chwidth") == 0) { - conf->he_oper_chwidth = atoi(pos); - } else if (os_strcmp(buf, "he_oper_centr_freq_seg0_idx") == 0) { diff --git a/feeds/ipq95xx/hostapd/patches/n00-002-hostapd-add-support-for-6g-client-type.patch b/feeds/ipq95xx/hostapd/patches/n00-002-hostapd-add-support-for-6g-client-type.patch deleted file mode 100644 index b48c74bf..00000000 --- a/feeds/ipq95xx/hostapd/patches/n00-002-hostapd-add-support-for-6g-client-type.patch +++ /dev/null @@ -1,171 +0,0 @@ -From 2a556ebff47bebcda6a1c7c8cd760bd38de54ff4 Mon Sep 17 00:00:00 2001 -From: Aditya Kumar Singh -Date: Fri, 22 Oct 2021 22:50:37 +0530 -Subject: [PATCH] hostapd: add support for 6g client type - -IEEE Std 802.11ax™‐2021 introduces two types of client -namely DEFAULT and SUBORDINATE client for 6GHz device. - -This patch - - * add u8 he_6ghz_reg_client_type member in struct wpa_config - to store the 6g configured mode. - * add new nl80211 ops - set_6gclient_type, which will be used - to send the 6G client type via existing NL80211_CMD_SET_INTERFACE - command. - -Signed-off-by: Aditya Kumar Singh ---- - src/drivers/driver.h | 8 ++++++++ - src/drivers/driver_nl80211.c | 26 ++++++++++++++++++++++++++ - wpa_supplicant/config.c | 2 ++ - wpa_supplicant/config.h | 11 +++++++++++ - wpa_supplicant/driver_i.h | 8 ++++++++ - wpa_supplicant/wpa_supplicant.c | 9 +++++++++ - 6 files changed, 64 insertions(+) - ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -4694,6 +4694,14 @@ struct wpa_driver_ops { - * explicitly allow reception of broadcast Public Action frames. - */ - int (*dpp_listen)(void *priv, bool enable); -+ -+ /** -+ * set_6gclient_type - Set the client type for 6G interface -+ * @priv: Private driver interface data -+ * @client_type_6g: 0 - Default Client, 1 - Subordinate Client -+ * Returns: 0 on success, < 0 on failure -+ */ -+ int (*set_6gclient_type)(void *priv, u8 client_type_6g); - - #ifdef CONFIG_TESTING_OPTIONS - int (*register_frame)(void *priv, u16 type, ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -12173,6 +12173,31 @@ static int nl80211_dpp_listen(void *priv - } - #endif /* CONFIG_DPP */ - -+static int nl80211_set_6gclient_type(void *priv, u8 client_type_6g) -+{ -+ struct i802_bss *bss = priv; -+ struct wpa_driver_nl80211_data *drv = bss->drv; -+ struct nl_msg *msg; -+ int ret = -ENOBUFS; -+ -+ wpa_printf(MSG_DEBUG, "nl80211: 6g client type: %d", -+ client_type_6g); -+ -+ msg = nl80211_cmd_msg(drv->first_bss, 0, NL80211_CMD_SET_INTERFACE); -+ if (!msg || nla_put_u8(msg, NL80211_ATTR_6G_REG_POWER_MODE, -+ client_type_6g)) -+ goto fail; -+ -+ ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL); -+ -+ if(ret) -+ wpa_printf(MSG_DEBUG, "nl80211: 6g client type could not be set (%d)", -+ ret); -+ return ret; -+fail: -+ nlmsg_free(msg); -+ return ret; -+} - - const struct wpa_driver_ops wpa_driver_nl80211_ops = { - .name = "nl80211", -@@ -12315,4 +12340,5 @@ const struct wpa_driver_ops wpa_driver_n - #ifdef CONFIG_TESTING_OPTIONS - .register_frame = testing_nl80211_register_frame, - #endif /* CONFIG_TESTING_OPTIONS */ -+ .set_6gclient_type = nl80211_set_6gclient_type, - }; ---- a/wpa_supplicant/config.c -+++ b/wpa_supplicant/config.c -@@ -5394,6 +5394,8 @@ static const struct global_parse_data gl - { INT_RANGE(force_kdk_derivation, 0, 1), 0 }, - #endif /* CONFIG_TESTING_OPTIONS */ - #endif /* CONFIG_PASN */ -+ { INT_RANGE(he_6ghz_reg_client_type, 1, 2), -+ CFG_CHANGED_HE_6GHZ_CLIENT_TYPE}, - }; - - #undef FUNC ---- a/wpa_supplicant/config.h -+++ b/wpa_supplicant/config.h -@@ -378,6 +378,7 @@ struct wpa_cred { - #define CFG_CHANGED_WOWLAN_TRIGGERS BIT(18) - #define CFG_CHANGED_DISABLE_BTM BIT(19) - #define CFG_CHANGED_BGSCAN BIT(20) -+#define CFG_CHANGED_HE_6GHZ_CLIENT_TYPE BIT(21) - - /** - * struct wpa_config - wpa_supplicant configuration data -@@ -1650,6 +1651,16 @@ struct wpa_config { - int force_kdk_derivation; - #endif /* CONFIG_TESTING_OPTIONS */ - #endif /* CONFIG_PASN*/ -+ -+ /** -+ * he_6ghz_reg_client_type - Type of client in 6GHz band -+ * -+ * IEEE Std 802.11ax™‐2021 allows two kinds of client -+ * -+ * 1 = DEFAULT or REGULAR CLIENT -+ * 2 = SUBORDINATE CLIENT -+ */ -+ u8 he_6ghz_reg_client_type; - }; - - ---- a/wpa_supplicant/driver_i.h -+++ b/wpa_supplicant/driver_i.h -@@ -1117,4 +1117,12 @@ static inline int wpa_drv_dpp_listen(str - return wpa_s->driver->dpp_listen(wpa_s->drv_priv, enable); - } - -+static inline int wpa_drv_set_6gclient_type(struct wpa_supplicant *wpa_s, -+ u8 he_6ghz_reg_client_type) -+{ -+ if (!wpa_s->driver->set_6gclient_type) -+ return -1; -+ return wpa_s->driver->set_6gclient_type(wpa_s->drv_priv, -+ he_6ghz_reg_client_type); -+} - #endif /* DRIVER_I_H */ ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -5212,6 +5212,15 @@ int wpa_supplicant_driver_init(struct wp - wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver"); - wpa_drv_flush_pmkid(wpa_s); - -+ /* Before starting scan, for 6g interface, set the client type */ -+ if (wpa_s->conf->changed_parameters & CFG_CHANGED_HE_6GHZ_CLIENT_TYPE) { -+ u8 he_6ghz_reg_client_type = wpa_s->conf->he_6ghz_reg_client_type; -+ /** -+ * Subtract 1 to map the client type with 0 indexing -+ */ -+ wpa_drv_set_6gclient_type(wpa_s, he_6ghz_reg_client_type - 1); -+ } -+ - wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; - wpa_s->prev_scan_wildcard = 0; - ---- a/wpa_supplicant/wpa_supplicant.conf -+++ b/wpa_supplicant/wpa_supplicant.conf -@@ -589,6 +589,15 @@ fast_reauth=1 - # 1 = Publish - #ftm_initiator=0 - -+# 6GHz regulatory client type -+# This sets the 6GHz client type. Possible options are -+# 1 = Default Client -+# 2 = Subordinate Client -+# Note that value 0 is reserved and can not be used. For 6GHz operation -+# user has to choose from either 1 or 2. If not mentioned, no type will -+# be set from user side. Wireless stack will handle its own default case. -+#he_6ghz_reg_client_type=1 -+ - # credential block - # - # Each credential used for automatic network selection is configured as a set diff --git a/feeds/ipq95xx/hostapd/patches/o00-001-hostapd-fix-6GHz-chan-switch-issue.patch b/feeds/ipq95xx/hostapd/patches/o00-001-hostapd-fix-6GHz-chan-switch-issue.patch deleted file mode 100644 index 87c73a22..00000000 --- a/feeds/ipq95xx/hostapd/patches/o00-001-hostapd-fix-6GHz-chan-switch-issue.patch +++ /dev/null @@ -1,53 +0,0 @@ -From bd267ee2e6c1ce5165bf8be9411b398709f83a8f Mon Sep 17 00:00:00 2001 -From: Aditya Kumar Singh -Date: Fri, 19 Nov 2021 19:51:04 +0530 -Subject: [PATCH] hostapd: fix 6GHz chan switch issue - -If user doesnt provide HE parameter in the hostapd_cli chan_switch -command, by default HE should be enabled for 6 GHz frequency range. -This is because, 6 GHz does not support legacy mode. Similarly, if -bandwidth isnt provided, 20 MHz should be taken as default bandwidth. - -Signed-off-by: Aditya Kumar Singh ---- - hostapd/ctrl_iface.c | 24 ++++++++++++++++++------ - 1 file changed, 18 insertions(+), 6 deletions(-) - -diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c -index 664711d..3c2d51c 100644 ---- a/hostapd/ctrl_iface.c -+++ b/hostapd/ctrl_iface.c -@@ -2530,12 +2530,24 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params) - { - int idx, bw, bw_idx[] = { 20, 40, 80, 160 }; - -- if (is_6ghz_freq(params->freq) && params->center_freq1) { -- idx = (params->center_freq1 - 5950) / 5; -- bw = center_idx_to_bw_6ghz(idx); -- -- if (bw < 0 || (bw_idx[bw] != params->bandwidth)) -- return -1; -+ if (is_6ghz_freq(params->freq)) { -+ /* Verify if HE was enabled by user or not. 6 GHz does not -+ * support legacy mode. Hence, enable HE if not given */ -+ if (!params->he_enabled) -+ params->he_enabled = 1; -+ -+ /* By default in 6 GHz, HE 20 mode should be selected */ -+ if (!params->center_freq1 && params->bandwidth == 0) { -+ params->center_freq1 = params->freq; -+ /* If bw is not given by user, by default assuming 20 */ -+ params->bandwidth = 20; -+ } else { -+ idx = (params->center_freq1 - 5950) / 5; -+ bw = center_idx_to_bw_6ghz(idx); -+ -+ if (bw < 0 || (bw_idx[bw] != params->bandwidth)) -+ return -1; -+ } - } - - switch (params->bandwidth) { --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/p00-001-wpa-supplicant-support-5dot9-channels-in-mesh-160mhz.patch b/feeds/ipq95xx/hostapd/patches/p00-001-wpa-supplicant-support-5dot9-channels-in-mesh-160mhz.patch deleted file mode 100644 index 80620f88..00000000 --- a/feeds/ipq95xx/hostapd/patches/p00-001-wpa-supplicant-support-5dot9-channels-in-mesh-160mhz.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 473175ab3030092aa75c9e4e3daf81eb50da0278 Mon Sep 17 00:00:00 2001 -From: Thiraviyam Mariyappan -Date: Tue, 4 Jan 2022 13:22:18 +0530 -Subject: [PATCH] wpa_supplicant: support 5.9 channels in mesh 160mhz - -currently, mesh supported 5.9 channels on 80Mhz. This patch supports -5.9 channels to bring up at 160mhz based on channel availability. - -Signed-off-by: Thiraviyam Mariyappan ---- - wpa_supplicant/wpa_supplicant.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/wpa_supplicant.c -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.c -@@ -2544,7 +2544,7 @@ void ibss_mesh_setup_freq(struct wpa_sup - int bw80[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5825, 5955, - 6035, 6115, 6195, 6275, 6355, 6435, 6515, - 6595, 6675, 6755, 6835, 6915, 6995 }; -- int bw160[] = { 5955, 6115, 6275, 6435, 6595, 6755, 6915 }; -+ int bw160[] = { 5745, 5955, 6115, 6275, 6435, 6595, 6755, 6915 }; - struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL; - u8 channel; - int i, chan_idx, ht40 = -1, res, obss_scan = !(ssid->noscan); -@@ -2797,13 +2797,13 @@ skip_to_6ghz: - - if ((mode->he_capab[ieee80211_mode].phy_cap[ - HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] & -- HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) && is_6ghz) { -+ HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G)) { - /* In 160 MHz, the initial four 20 MHz channels were validated - * above; check the remaining four 20 MHz channels for the total - * of 160 MHz bandwidth. - */ - if (!ibss_mesh_is_80mhz_avail(channel + 16, mode)) -- return; -+ break; - - for (j = 0; j < ARRAY_SIZE(bw160); j++) { - if (freq->freq == bw160[j]) { diff --git a/feeds/ipq95xx/hostapd/patches/p00-002-mesh-enable-more-160MHz-channels-in-6GHz.patch b/feeds/ipq95xx/hostapd/patches/p00-002-mesh-enable-more-160MHz-channels-in-6GHz.patch deleted file mode 100644 index f1599ded..00000000 --- a/feeds/ipq95xx/hostapd/patches/p00-002-mesh-enable-more-160MHz-channels-in-6GHz.patch +++ /dev/null @@ -1,263 +0,0 @@ -From d6e52c4ef2bb8e915cae088564c412583f1794c9 Mon Sep 17 00:00:00 2001 -From: P Praneesh -Date: Fri, 21 Jan 2022 09:44:15 +0530 -Subject: [PATCH] mesh: enable more 160MHz channels in 6GHz - -Current 160MHz implementation supports mesh bringup in limited channels. -Allow all the 6GHz 80MHz channels to support 160MHz if the secondary 80MHz -is available. - -Ex: User can bringup 160MHz in 49th channel (primary 80MHz) based on 33rd -channel(secondary 80MHz) availablity. - -Signed-off-by: P Praneesh ---- - wpa_supplicant/wpa_supplicant.c | 21 ++++++++++++++++++--- - 1 file changed, 18 insertions(+), 3 deletions(-) - -Index: hostapd-2021-12-13-b26f5c0f/hostapd/config_file.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/hostapd/config_file.c -+++ hostapd-2021-12-13-b26f5c0f/hostapd/config_file.c -@@ -4280,6 +4280,8 @@ static int hostapd_config_fill(struct ho - } else if (os_strcmp(buf, "wowlan_triggers") == 0) { - os_free(bss->wowlan_triggers); - bss->wowlan_triggers = os_strdup(pos); -+ } else if (os_strcmp(buf, "enable_160mhz_bw") == 0) { -+ conf->enable_160mhz_bw = atoi(pos); - } else if (os_strcmp(buf, "disable_40mhz_scan") == 0) { - conf->disable_40mhz_scan = atoi(pos); - #ifdef CONFIG_FST -Index: hostapd-2021-12-13-b26f5c0f/src/ap/ap_config.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/ap_config.h -+++ hostapd-2021-12-13-b26f5c0f/src/ap/ap_config.h -@@ -1083,6 +1083,7 @@ struct hostapd_config { - } *acs_chan_bias; - unsigned int num_acs_chan_bias; - #endif /* CONFIG_ACS */ -+ int enable_160mhz_bw; - int disable_40mhz_scan; - - struct wpabuf *lci; -Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/drivers/driver.h -+++ hostapd-2021-12-13-b26f5c0f/src/drivers/driver.h -@@ -1236,6 +1236,10 @@ struct wpa_driver_associate_params { - * 2 = BURST beacon tx mode - */ - int beacon_tx_mode; -+ /** -+ * Enable 160MHz BW - set it 1 to enable mesh 160MHz 6G -+ */ -+ int enable_160mhz_bw; - }; - - enum hide_ssid { -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/config.c -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config.c -@@ -2742,6 +2742,7 @@ static const struct parse_data ssid_fiel - { INT_RANGE(sae_pk, 0, 2) }, - { INT_RANGE(disable_40mhz_scan, 0, 1)}, - { INT_RANGE(beacon_tx_mode, 1, 2)}, -+ { INT_RANGE(enable_160mhz_bw, 0, 1)}, - }; - - #undef OFFSET -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config_file.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/config_file.c -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config_file.c -@@ -890,6 +890,7 @@ static void wpa_config_write_network(FIL - #endif /* CONFIG_HE_OVERRIDES */ - INT(disable_40mhz_scan); - INT(beacon_tx_mode); -+ INT(enable_160mhz_bw); - #undef STR - #undef INT - #undef INT_DEF -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config_ssid.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/config_ssid.h -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/config_ssid.h -@@ -1208,6 +1208,11 @@ struct wpa_ssid { - * 2 = BURST MODE - */ - int beacon_tx_mode; -+ -+ /** -+ * Enable 160MHz BW - set it 1 to enable mesh 160MHz 6G -+ */ -+ int enable_160mhz_bw; - }; - - #endif /* CONFIG_SSID_H */ -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_cli.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/wpa_cli.c -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_cli.c -@@ -1491,6 +1491,7 @@ static const char *network_fields[] = { - "mac_addr", "pbss", "wps_disabled", - "disable_40mhz_scan", - "beacon_tx_mode", -+ "enable_160mhz_bw", - }; - - -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.conf -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/wpa_supplicant.conf -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.conf -@@ -1699,6 +1699,11 @@ fast_reauth=1 - # In STA mode it defines the EDMG channel for connection (if supported by AP). - #edmg_channel=9 - -+#To configure 80MHz and 160MHz in Mesh mode. -+#Set 0 to enable 80MHz in Mesh mode -+#Set 1 to enable 160MHz in Mesh mode -+#enable_160mhz_bw=1 -+ - # Example blocks: - - # Simple case: WPA-PSK, PSK as an ASCII passphrase, allow all valid ciphers -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/wpa_supplicant.c -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/wpa_supplicant.c -@@ -2541,12 +2541,20 @@ void ibss_mesh_setup_freq(struct wpa_sup - struct hostapd_hw_modes *mode = NULL; - int ht40plus[] = { 1, 2, 3, 4, 5, 6, 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157, - 165, 173, 184, 192 }; -- int bw80[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5825, 5955, -- 6035, 6115, 6195, 6275, 6355, 6435, 6515, -- 6595, 6675, 6755, 6835, 6915, 6995 }; -- int bw160[] = { 5745, 5955, 6115, 6275, 6435, 6595, 6755, 6915 }; -+ /* bw_80_160 array members are 80MHz start freq, 80MHz end freq and so on -+ */ -+ unsigned int bw_80_160[] = { 5180, 5240, 5260, 5320, -+ 5500, 5560, 5580, 5660, -+ 5745, 5805, 5825, 5885, -+ 5955, 6015, 6035, 6095, -+ 6115, 6175, 6195, 6255, -+ 6275, 6335, 6355, 6415, -+ 6435, 6495, 6515, 6575, -+ 6595, 6655, 6675, 6735, -+ 6755, 6815, 6835, 6895, -+ 6915, 6975, 6995, 7055 }; - struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL; -- u8 channel; -+ u8 channel, chan_80mhz; - int i, chan_idx, ht40 = -1, res, obss_scan = !(ssid->noscan); - unsigned int j, k; - struct hostapd_freq_params vht_freq; -@@ -2769,60 +2777,79 @@ skip_to_6ghz: - return; - - /* Enable HE with VHT for 5 GHz */ -- freq->he_enabled = mode->he_capab[ieee80211_mode].he_supported; -+ vht_freq.he_enabled = mode->he_capab[ieee80211_mode].he_supported; - - #ifdef CONFIG_HE_OVERRIDES - if (is_24ghz) - goto skip_vht80; - #endif /* CONFIG_HE_OVERRIDES */ - -- /* setup center_freq1, bandwidth */ -- for (j = 0; j < ARRAY_SIZE(bw80); j++) { -- if (freq->freq >= bw80[j] && -- freq->freq < bw80[j] + 80) -+ for (j = 0; j < ARRAY_SIZE(bw_80_160); j+=2) { -+ /* If the config provided freq available between any of two indices -+ * get the starting range of the channel to check chan availability -+ */ -+ if (freq->freq >= bw_80_160[j] && freq->freq <= bw_80_160[j+1]) { -+ ieee80211_freq_to_chan(bw_80_160[j], &chan_80mhz); -+ seg0 = chan_80mhz + 6; - break; -+ } - } - -- if (j == ARRAY_SIZE(bw80) || -- ieee80211_freq_to_chan(bw80[j], &channel) == NUM_HOSTAPD_MODES) -+ if (j == ARRAY_SIZE(bw_80_160)) - return; - - /* Back to HT configuration if channel not usable */ -- if (!ibss_mesh_is_80mhz_avail(channel, mode)) -+ if (!ibss_mesh_is_80mhz_avail(chan_80mhz, mode)) - return; - - chwidth = CHANWIDTH_80MHZ; -- seg0 = channel + 6; - seg1 = 0; - - if ((mode->he_capab[ieee80211_mode].phy_cap[ - HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] & -- HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G)) { -- /* In 160 MHz, the initial four 20 MHz channels were validated -- * above; check the remaining four 20 MHz channels for the total -- * of 160 MHz bandwidth. -- */ -- if (!ibss_mesh_is_80mhz_avail(channel + 16, mode)) -- break; -- -- for (j = 0; j < ARRAY_SIZE(bw160); j++) { -- if (freq->freq == bw160[j]) { -- chwidth = CHANWIDTH_160MHZ; -- seg0 = channel + 14; -+ HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) && (ssid->enable_160mhz_bw)) { -+ chan_80mhz = freq->channel + 16; -+ for (j = 0; j < ARRAY_SIZE(bw_80_160); j+=2) { -+ if (freq->freq >= bw_80_160[j] && freq->freq <= bw_80_160[j+1]) { -+ if (j % 4 == 0) { -+ ieee80211_freq_to_chan(bw_80_160[j], -+ &chan_80mhz); -+ seg0 = chan_80mhz + 14; -+ -+ /* Get secondary 80MHz channel using freq by -+ * adding 16*5 ie., 80MHz. -+ */ -+ ieee80211_freq_to_chan((bw_80_160[j] + 16*5), -+ &chan_80mhz); -+ } else { -+ ieee80211_freq_to_chan(bw_80_160[j], -+ &chan_80mhz); -+ seg0 = chan_80mhz - 2; -+ /* Get secondary 80MHz channel using freq by -+ * subtracting 16*5 ie., 80MHz. -+ */ -+ ieee80211_freq_to_chan((bw_80_160[j] - 16*5), -+ &chan_80mhz); -+ } -+ -+ if (!ibss_mesh_is_80mhz_avail(chan_80mhz, mode)) -+ seg0 = freq->channel + 6; -+ else -+ chwidth = CHANWIDTH_160MHZ; - break; -- } -- } -- } -+ } -+ } -+ } - - if (ssid->max_oper_chwidth == CHANWIDTH_80P80MHZ) { - /* setup center_freq2, bandwidth */ -- for (k = 0; k < ARRAY_SIZE(bw80); k++) { -+ for (k = 0; k < ARRAY_SIZE(bw_80_160); k++) { - /* Only accept 80 MHz segments separated by a gap */ -- if (j == k || abs(bw80[j] - bw80[k]) == 80) -+ if (j == k || abs(bw_80_160[j] - bw_80_160[k]) == 80) - continue; - -- if (ieee80211_freq_to_chan(bw80[k], &channel) == -- NUM_HOSTAPD_MODES) -+ if (ieee80211_freq_to_chan(bw_80_160[k], -+ &channel) == NUM_HOSTAPD_MODES) - return; - - for (i = channel; i < channel + 16; i += 4) { diff --git a/feeds/ipq95xx/hostapd/patches/p00-003-hostapd-add-acs_exclude_6ghz_non_psc-option-for-acs-.patch b/feeds/ipq95xx/hostapd/patches/p00-003-hostapd-add-acs_exclude_6ghz_non_psc-option-for-acs-.patch deleted file mode 100644 index 501fe032..00000000 --- a/feeds/ipq95xx/hostapd/patches/p00-003-hostapd-add-acs_exclude_6ghz_non_psc-option-for-acs-.patch +++ /dev/null @@ -1,369 +0,0 @@ -From daf67e765bcfa6ff6affb1a916696271014303b2 Mon Sep 17 00:00:00 2001 -From: P Praneesh -Date: Mon, 21 Feb 2022 11:49:50 +0530 -Subject: [PATCH] hostapd: add acs_exclude_6ghz_non_psc option for acs non - offload driver - -Hostapd configuration "acs_exclude_6ghz_non_psc" is supported for ACS -offloaded driver alone. Extend the support to ACS non offload driver -by adding 6G Preferred Scan Channel check and hostapd config flag -during scan and survey dump. - -Signed-off-by: P Praneesh ---- - src/ap/acs.c | 141 ++++++++++++++++++++++++++++++++++++++++--- - src/ap/ap_drv_ops.h | 6 +- - src/ap/bss_load.c | 3 +- - src/drivers/driver.h | 4 +- - src/drivers/driver_nl80211.c | 30 ++++++--- - 5 files changed, 166 insertions(+), 18 deletions(-) - ---- a/src/ap/acs.c -+++ b/src/ap/acs.c -@@ -641,6 +641,112 @@ static int is_common_24ghz_chan(int chan - #endif /* ACS_24GHZ_PREFER_1_6_11 */ - - static void -+acs_find_6g_psc_chan_mode(struct hostapd_iface *iface, -+ struct hostapd_hw_modes *mode, -+ int n_chans, u32 bw, -+ struct hostapd_channel_data **rand_chan, -+ struct hostapd_channel_data **ideal_chan, -+ long double *ideal_factor) -+{ -+ struct hostapd_channel_data *chan, *adj_chan = NULL; -+ long double factor; -+ int i, j; -+ unsigned int k; -+ -+ for (i = 0; i < mode->num_channels; i++) { -+ double total_weight; -+ struct acs_bias *bias; -+ -+ chan = &mode->channels[i]; -+ if (!chan_pri_allowed(chan)) -+ continue; -+ -+ if (!is_in_chanlist(iface, chan)) -+ continue; -+ -+ if (!is_in_freqlist(iface, chan)) -+ continue; -+ -+ if (!is_6ghz_psc_frequency(chan->freq)) -+ continue; -+ -+ if (!chan_bw_allowed(chan, bw, 1, 1)) { -+ wpa_printf(MSG_DEBUG, -+ "ACS: Channel %d: BW %u is not supported", -+ chan->chan, bw); -+ continue; -+ } -+ -+ factor = 0; -+ if (acs_usable_chan(chan)) -+ factor = chan->interference_factor; -+ total_weight = 1; -+ -+ /* Start index from -1 because all the PSC channels are located in -+ * secondary 20MHz of primary 40MHz. Ex: CH33 - CH61 has 160MHz BW, PSC -+ * CH37 which is secondary 20MHz of primary 40MHz. -+ */ -+ -+ for (j = -1; j < n_chans; j++) { -+ adj_chan = acs_find_chan(iface, chan->freq + (j * 20)); -+ if (!adj_chan) -+ break; -+ -+ if (!chan_bw_allowed(adj_chan, bw, 1, 0)) { -+ wpa_printf(MSG_DEBUG, -+ "ACS: PRI Channel %d: secondary channel %d BW %u is not supported", -+ chan->chan, adj_chan->chan, bw); -+ break; -+ } -+ -+ if (acs_usable_chan(adj_chan)) { -+ factor += adj_chan->interference_factor; -+ total_weight += 1; -+ } -+ } -+ -+ if (j != n_chans) { -+ wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth", -+ chan->chan); -+ continue; -+ } -+ -+ factor /= total_weight; -+ -+ bias = NULL; -+ if (iface->conf->acs_chan_bias) { -+ for (k = 0; k < iface->conf->num_acs_chan_bias; k++) { -+ bias = &iface->conf->acs_chan_bias[k]; -+ if (bias->channel == chan->chan) -+ break; -+ bias = NULL; -+ } -+ } -+ -+ if (bias) { -+ factor *= bias->bias; -+ wpa_printf(MSG_DEBUG, -+ "ACS: * channel %d: total interference = %Lg (%f bias)", -+ chan->chan, factor, bias->bias); -+ } else { -+ wpa_printf(MSG_DEBUG, -+ "ACS: * channel %d: total interference = %Lg", -+ chan->chan, factor); -+ } -+ -+ if (acs_usable_chan(chan) && -+ (!*ideal_chan || factor < *ideal_factor)) { -+ *ideal_factor = factor; -+ *ideal_chan = chan; -+ } -+ -+ /* This channel would at least be usable */ -+ if (!(*rand_chan)) -+ *rand_chan = chan; -+ } -+} -+ -+static void - acs_find_ideal_chan_mode(struct hostapd_iface *iface, - struct hostapd_hw_modes *mode, - int n_chans, u32 bw, -@@ -874,10 +980,17 @@ bw_selected: - - for (i = 0; i < iface->num_hw_features; i++) { - mode = &iface->hw_features[i]; -- if (!hostapd_hw_skip_mode(iface, mode)) -- acs_find_ideal_chan_mode(iface, mode, n_chans, bw, -- &rand_chan, &ideal_chan, -- &ideal_factor); -+ if (!hostapd_hw_skip_mode(iface, mode)) { -+ if (iface->conf->acs_exclude_6ghz_non_psc) { -+ acs_find_6g_psc_chan_mode(iface, mode, n_chans, bw, -+ &rand_chan, &ideal_chan, -+ &ideal_factor); -+ } else { -+ acs_find_ideal_chan_mode(iface, mode, n_chans, bw, -+ &rand_chan, &ideal_chan, -+ &ideal_factor); -+ } -+ } - } - - if (ideal_chan) { -@@ -892,19 +1005,42 @@ bw_selected: - - static void acs_adjust_center_freq(struct hostapd_iface *iface) - { -- int offset; -+ int psc_chan[] = {37, 53, 69, 85, 101, 117, -+ 133, 149, 165, 181, 197, 213} ; -+ int offset, i; -+ u8 bw = hostapd_get_oper_chwidth(iface->conf); -+ bool acs_exclude_6ghz_non_psc = iface->conf->acs_exclude_6ghz_non_psc; -+ bool is_sec_psc_chan = false; - - wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency"); - -- switch (hostapd_get_oper_chwidth(iface->conf)) { -+ if (acs_exclude_6ghz_non_psc && (bw == CHANWIDTH_160MHZ)) { -+ for (i = 0; i < ARRAY_SIZE(psc_chan); i++) { -+ if (psc_chan[i] == iface->conf->channel) { -+ is_sec_psc_chan = (i%2) ? true : false; -+ break; -+ } -+ } -+ } -+ -+ switch (bw) { - case CHANWIDTH_USE_HT: - offset = 2 * iface->conf->secondary_channel; - break; - case CHANWIDTH_80MHZ: -- offset = 6; -+ if (acs_exclude_6ghz_non_psc) -+ offset = 2; -+ else -+ offset = 6; - break; - case CHANWIDTH_160MHZ: -- offset = 14; -+ /* In 160MHz, if primary 20MHz present in secondary 80MHz, then -+ * subtract with -6 to find the center frequency of the 160MHz -+ */ -+ if (acs_exclude_6ghz_non_psc) -+ offset = is_sec_psc_chan ? -6 : 10; -+ else -+ offset = 14; - break; - default: - /* TODO: How can this be calculated? Adjust -@@ -1001,7 +1137,8 @@ static void acs_scan_complete(struct hos - wpa_printf(MSG_DEBUG, "ACS: Using survey based algorithm (acs_num_scans=%d)", - iface->conf->acs_num_scans); - -- err = hostapd_drv_get_survey(iface->bss[0], 0); -+ err = hostapd_drv_get_survey(iface->bss[0], 0, -+ iface->conf->acs_exclude_6ghz_non_psc); - if (err) { - wpa_printf(MSG_ERROR, "ACS: Failed to get survey data"); - goto fail; -@@ -1043,6 +1180,11 @@ static int * acs_request_scan_add_freqs( - if (!is_in_freqlist(iface, chan)) - continue; - -+ if (is_6ghz_freq(chan->freq) && -+ iface->conf->acs_exclude_6ghz_non_psc && -+ !is_6ghz_psc_frequency(chan->freq)) -+ continue; -+ - *freq++ = chan->freq; - } - ---- a/src/ap/ap_drv_ops.h -+++ b/src/ap/ap_drv_ops.h -@@ -266,13 +266,15 @@ static inline void hostapd_drv_poll_clie - } - - static inline int hostapd_drv_get_survey(struct hostapd_data *hapd, -- unsigned int freq) -+ unsigned int freq, -+ bool acs_exclude_6ghz_non_psc) - { - if (hapd->driver == NULL) - return -1; - if (!hapd->driver->get_survey) - return -1; -- return hapd->driver->get_survey(hapd->drv_priv, freq); -+ return hapd->driver->get_survey(hapd->drv_priv, freq, -+ acs_exclude_6ghz_non_psc); - } - - static inline int hostapd_get_country(struct hostapd_data *hapd, char *alpha2) ---- a/src/ap/bss_load.c -+++ b/src/ap/bss_load.c -@@ -49,7 +49,8 @@ static void update_channel_utilization(v - if (!(hapd->beacon_set_done && hapd->started)) - return; - -- err = hostapd_drv_get_survey(hapd, hapd->iface->freq); -+ err = hostapd_drv_get_survey(hapd, hapd->iface->freq, -+ hapd->iface->conf->acs_exclude_6ghz_non_psc); - if (err) { - wpa_printf(MSG_ERROR, "BSS Load: Failed to get survey data"); - return; ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -4186,6 +4186,8 @@ struct wpa_driver_ops { - * @priv: Private driver interface data - * @freq: If set, survey data for the specified frequency is only - * being requested. If not set, all survey data is requested. -+ * @acs_exclude_6ghz_non_psc: If set Include only preferred scan -+ * channels from 6 GHz band for ACS - * Returns: 0 on success, -1 on failure - * - * Use this to retrieve: -@@ -4204,7 +4206,7 @@ struct wpa_driver_ops { - * for each survey. The min_nf of the channel is updated for each - * survey. - */ -- int (*get_survey)(void *priv, unsigned int freq); -+ int (*get_survey)(void *priv, unsigned int freq, bool acs_exclude_6ghz_non_psc); - - /** - * status - Get driver interface status information ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -9033,6 +9033,10 @@ static int check_survey_ok(struct nlattr - return freq_filter == surveyed_freq; - } - -+struct nl80211_get_survey_arg { -+ struct survey_results *survey_results; -+ bool acs_exclude_6ghz_non_psc; -+}; - - static int survey_handler(struct nl_msg *msg, void *arg) - { -@@ -9040,15 +9044,19 @@ static int survey_handler(struct nl_msg - struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); - struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1]; - struct survey_results *survey_results; -+ struct nl80211_get_survey_arg *arg_survey = -+ (struct nl80211_get_survey_arg *)arg; - u32 surveyed_freq = 0; - u32 ifidx; -+ bool acs_exclude_6ghz_non_psc; - - static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = { - [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 }, - [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 }, - }; - -- survey_results = (struct survey_results *) arg; -+ survey_results = arg_survey->survey_results; -+ acs_exclude_6ghz_non_psc = arg_survey->acs_exclude_6ghz_non_psc; - - nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), - genlmsg_attrlen(gnlh, 0), NULL); -@@ -9077,6 +9085,11 @@ static int survey_handler(struct nl_msg - survey_results->freq_filter)) - return NL_SKIP; - -+ if (is_6ghz_freq(surveyed_freq) && -+ acs_exclude_6ghz_non_psc && -+ !is_6ghz_psc_frequency(surveyed_freq)) -+ return NL_SKIP; -+ - if (survey_results->freq_filter && - survey_results->freq_filter != surveyed_freq) { - wpa_printf(MSG_EXCESSIVE, "nl80211: Ignoring survey data for freq %d MHz", -@@ -9090,19 +9103,22 @@ static int survey_handler(struct nl_msg - } - - --static int wpa_driver_nl80211_get_survey(void *priv, unsigned int freq) -+static int wpa_driver_nl80211_get_survey(void *priv, unsigned int freq, -+ bool acs_exclude_6ghz_non_psc) - { - struct i802_bss *bss = priv; - struct wpa_driver_nl80211_data *drv = bss->drv; - struct nl_msg *msg; - int err; - union wpa_event_data data; -- struct survey_results *survey_results; -+ struct nl80211_get_survey_arg arg; - - os_memset(&data, 0, sizeof(data)); -- survey_results = &data.survey_results; -+ os_memset(&arg, 0, sizeof(arg)); -+ arg.survey_results = &data.survey_results; -+ arg.acs_exclude_6ghz_non_psc = acs_exclude_6ghz_non_psc; - -- dl_list_init(&survey_results->survey_list); -+ dl_list_init(&arg.survey_results->survey_list); - - msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SURVEY); - if (!msg) -@@ -9114,7 +9130,7 @@ static int wpa_driver_nl80211_get_survey - do { - wpa_printf(MSG_DEBUG, "nl80211: Fetch survey data"); - err = send_and_recv_msgs(drv, msg, survey_handler, -- survey_results, NULL, NULL); -+ &arg, NULL, NULL); - } while (err > 0); - - if (err) -@@ -9122,7 +9138,7 @@ static int wpa_driver_nl80211_get_survey - else - wpa_supplicant_event(drv->ctx, EVENT_SURVEY, &data); - -- clean_survey_results(survey_results); -+ clean_survey_results(arg.survey_results); - return err; - } - diff --git a/feeds/ipq95xx/hostapd/patches/q00-001-crypto-Remove-unused-crypto_ec_point_solve_y_coord.patch b/feeds/ipq95xx/hostapd/patches/q00-001-crypto-Remove-unused-crypto_ec_point_solve_y_coord.patch deleted file mode 100644 index b6868f21..00000000 --- a/feeds/ipq95xx/hostapd/patches/q00-001-crypto-Remove-unused-crypto_ec_point_solve_y_coord.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 1dc7e10a10275b8921e1417acc209ee8ee904c81 Mon Sep 17 00:00:00 2001 -From: Jouni Malinen -Date: Fri, 7 Jan 2022 19:44:10 +0200 -Subject: [PATCH 1/5] crypto: Remove unused crypto_ec_point_solve_y_coord() - -This wrapper function is not used anymore, so remove it. - -Signed-off-by: Jouni Malinen -Signed-off-by: Rameshkumar Sundaram -(cherry picked from commit 9b14aed90887e1ec35830d60eea9ebde6a2cf814) ---- - src/crypto/crypto.h | 12 ------------ - src/crypto/crypto_openssl.c | 15 --------------- - src/crypto/crypto_wolfssl.c | 24 ------------------------ - 3 files changed, 51 deletions(-) - -diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h -index 7d2ebd6..6ec4284 100644 ---- a/src/crypto/crypto.h -+++ b/src/crypto/crypto.h -@@ -858,18 +858,6 @@ int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p, - int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p); - - /** -- * crypto_ec_point_solve_y_coord - Solve y coordinate for an x coordinate -- * @e: EC context from crypto_ec_init() -- * @p: EC point to use for the returning the result -- * @x: x coordinate -- * @y_bit: y-bit (0 or 1) for selecting the y value to use -- * Returns: 0 on success, -1 on failure -- */ --int crypto_ec_point_solve_y_coord(struct crypto_ec *e, -- struct crypto_ec_point *p, -- const struct crypto_bignum *x, int y_bit); -- --/** - * crypto_ec_point_compute_y_sqr - Compute y^2 = x^3 + ax + b - * @e: EC context from crypto_ec_init() - * @x: x coordinate -diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c -index 72f93c1..55a62bc 100644 ---- a/src/crypto/crypto_openssl.c -+++ b/src/crypto/crypto_openssl.c -@@ -1880,21 +1880,6 @@ int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p) - } - - --int crypto_ec_point_solve_y_coord(struct crypto_ec *e, -- struct crypto_ec_point *p, -- const struct crypto_bignum *x, int y_bit) --{ -- if (TEST_FAIL()) -- return -1; -- if (!EC_POINT_set_compressed_coordinates_GFp(e->group, (EC_POINT *) p, -- (const BIGNUM *) x, y_bit, -- e->bnctx) || -- !EC_POINT_is_on_curve(e->group, (EC_POINT *) p, e->bnctx)) -- return -1; -- return 0; --} -- -- - struct crypto_bignum * - crypto_ec_point_compute_y_sqr(struct crypto_ec *e, - const struct crypto_bignum *x) -diff --git a/src/crypto/crypto_wolfssl.c b/src/crypto/crypto_wolfssl.c -index 2e4bf89..efe693b 100644 ---- a/src/crypto/crypto_wolfssl.c -+++ b/src/crypto/crypto_wolfssl.c -@@ -1626,30 +1626,6 @@ int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p) - } - - --int crypto_ec_point_solve_y_coord(struct crypto_ec *e, -- struct crypto_ec_point *p, -- const struct crypto_bignum *x, int y_bit) --{ -- byte buf[1 + 2 * MAX_ECC_BYTES]; -- int ret; -- int prime_len = crypto_ec_prime_len(e); -- -- if (TEST_FAIL()) -- return -1; -- -- buf[0] = y_bit ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN; -- ret = crypto_bignum_to_bin(x, buf + 1, prime_len, prime_len); -- if (ret <= 0) -- return -1; -- ret = wc_ecc_import_point_der(buf, 1 + 2 * ret, e->key.idx, -- (ecc_point *) p); -- if (ret != 0) -- return -1; -- -- return 0; --} -- -- - struct crypto_bignum * - crypto_ec_point_compute_y_sqr(struct crypto_ec *e, - const struct crypto_bignum *x) --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q00-002-EAP-pwd-Derive-the-y-coordinate-for-PWE-with-own-imp.patch b/feeds/ipq95xx/hostapd/patches/q00-002-EAP-pwd-Derive-the-y-coordinate-for-PWE-with-own-imp.patch deleted file mode 100644 index 0b2b7523..00000000 --- a/feeds/ipq95xx/hostapd/patches/q00-002-EAP-pwd-Derive-the-y-coordinate-for-PWE-with-own-imp.patch +++ /dev/null @@ -1,115 +0,0 @@ -From bd64d44e25795bfaf6232c0720fd6fe8f3674c7d Mon Sep 17 00:00:00 2001 -From: Jouni Malinen -Date: Fri, 7 Jan 2022 18:52:27 +0200 -Subject: [PATCH 2/5] EAP-pwd: Derive the y coordinate for PWE with own - implementation - -The crypto_ec_point_solve_y_coord() wrapper function might not use -constant time operations in the crypto library and as such, could leak -side channel information about the password that is used to generate the -PWE in the hunting and pecking loop. As such, calculate the two possible -y coordinate values and pick the correct one to use with constant time -selection. - -Signed-off-by: Jouni Malinen -Signed-off-by: Rameshkumar Sundaram -(cherry picked from commit 8c502336d40cdb8d211e4f8b8d59d7d282253733) ---- - src/eap_common/eap_pwd_common.c | 46 ++++++++++++++++++++++++++++++++--------- - 1 file changed, 36 insertions(+), 10 deletions(-) - -diff --git a/src/eap_common/eap_pwd_common.c b/src/eap_common/eap_pwd_common.c -index 2b2b8ef..ff22b29 100644 ---- a/src/eap_common/eap_pwd_common.c -+++ b/src/eap_common/eap_pwd_common.c -@@ -127,7 +127,8 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, - u8 qr_or_qnr_bin[MAX_ECC_PRIME_LEN]; - u8 x_bin[MAX_ECC_PRIME_LEN]; - u8 prime_bin[MAX_ECC_PRIME_LEN]; -- struct crypto_bignum *tmp2 = NULL; -+ u8 x_y[2 * MAX_ECC_PRIME_LEN]; -+ struct crypto_bignum *tmp2 = NULL, *y = NULL; - struct crypto_hash *hash; - unsigned char pwe_digest[SHA256_MAC_LEN], *prfbuf = NULL, ctr; - int ret = 0, res; -@@ -139,6 +140,7 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, - u8 found_ctr = 0, is_odd = 0; - int cmp_prime; - unsigned int in_range; -+ unsigned int is_eq; - - if (grp->pwe) - return -1; -@@ -151,11 +153,6 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, - if (crypto_bignum_to_bin(prime, prime_bin, sizeof(prime_bin), - primebytelen) < 0) - return -1; -- grp->pwe = crypto_ec_point_init(grp->group); -- if (!grp->pwe) { -- wpa_printf(MSG_INFO, "EAP-pwd: unable to create bignums"); -- goto fail; -- } - - if ((prfbuf = os_malloc(primebytelen)) == NULL) { - wpa_printf(MSG_INFO, "EAP-pwd: unable to malloc space for prf " -@@ -261,10 +258,37 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, - */ - crypto_bignum_deinit(x_candidate, 1); - x_candidate = crypto_bignum_init_set(x_bin, primebytelen); -- if (!x_candidate || -- crypto_ec_point_solve_y_coord(grp->group, grp->pwe, x_candidate, -- is_odd) != 0) { -- wpa_printf(MSG_INFO, "EAP-pwd: Could not solve for y"); -+ if (!x_candidate) -+ goto fail; -+ -+ /* y = sqrt(x^3 + ax + b) mod p -+ * if LSB(y) == LSB(pwd-seed): PWE = (x, y) -+ * else: PWE = (x, p - y) -+ * -+ * Calculate y and the two possible values for PWE and after that, -+ * use constant time selection to copy the correct alternative. -+ */ -+ y = crypto_ec_point_compute_y_sqr(grp->group, x_candidate); -+ if (!y || -+ dragonfly_sqrt(grp->group, y, y) < 0 || -+ crypto_bignum_to_bin(y, x_y, MAX_ECC_PRIME_LEN, primebytelen) < 0 || -+ crypto_bignum_sub(prime, y, y) < 0 || -+ crypto_bignum_to_bin(y, x_y + MAX_ECC_PRIME_LEN, -+ MAX_ECC_PRIME_LEN, primebytelen) < 0) { -+ wpa_printf(MSG_DEBUG, "SAE: Could not solve y"); -+ goto fail; -+ } -+ -+ /* Constant time selection of the y coordinate from the two -+ * options */ -+ is_eq = const_time_eq(is_odd, x_y[primebytelen - 1] & 0x01); -+ const_time_select_bin(is_eq, x_y, x_y + MAX_ECC_PRIME_LEN, -+ primebytelen, x_y + primebytelen); -+ os_memcpy(x_y, x_bin, primebytelen); -+ wpa_hexdump_key(MSG_DEBUG, "EAP-pwd: PWE", x_y, 2 * primebytelen); -+ grp->pwe = crypto_ec_point_from_bin(grp->group, x_y); -+ if (!grp->pwe) { -+ wpa_printf(MSG_DEBUG, "EAP-pwd: Could not generate PWE"); - goto fail; - } - -@@ -289,6 +313,7 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, - /* cleanliness and order.... */ - crypto_bignum_deinit(x_candidate, 1); - crypto_bignum_deinit(tmp2, 1); -+ crypto_bignum_deinit(y, 1); - crypto_bignum_deinit(qr, 1); - crypto_bignum_deinit(qnr, 1); - bin_clear_free(prfbuf, primebytelen); -@@ -296,6 +321,7 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, - os_memset(qnr_bin, 0, sizeof(qnr_bin)); - os_memset(qr_or_qnr_bin, 0, sizeof(qr_or_qnr_bin)); - os_memset(pwe_digest, 0, sizeof(pwe_digest)); -+ forced_memzero(x_y, sizeof(x_y)); - - return ret; - } --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q00-003-SAE-Derive-the-y-coordinate-for-PWE-with-own-impleme.patch b/feeds/ipq95xx/hostapd/patches/q00-003-SAE-Derive-the-y-coordinate-for-PWE-with-own-impleme.patch deleted file mode 100644 index 38843a47..00000000 --- a/feeds/ipq95xx/hostapd/patches/q00-003-SAE-Derive-the-y-coordinate-for-PWE-with-own-impleme.patch +++ /dev/null @@ -1,101 +0,0 @@ -From e900f6d2db719f18bd831dee0232ab485fafd740 Mon Sep 17 00:00:00 2001 -From: Jouni Malinen -Date: Fri, 7 Jan 2022 13:47:16 +0200 -Subject: [PATCH 3/5] SAE: Derive the y coordinate for PWE with own - implementation - -The crypto_ec_point_solve_y_coord() wrapper function might not use -constant time operations in the crypto library and as such, could leak -side channel information about the password that is used to generate the -PWE in the hunting and pecking loop. As such, calculate the two possible -y coordinate values and pick the correct one to use with constant time -selection. - -Signed-off-by: Jouni Malinen -Signed-off-by: Rameshkumar Sundaram -(cherry picked from commit 6c380f4c87fbda0bc1a2c8d522412cf1fc01d477) ---- - src/common/sae.c | 47 +++++++++++++++++++++++++++++++++-------------- - 1 file changed, 33 insertions(+), 14 deletions(-) - -diff --git a/src/common/sae.c b/src/common/sae.c -index b768c22..2440156 100644 ---- a/src/common/sae.c -+++ b/src/common/sae.c -@@ -290,14 +290,16 @@ static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1, - int pwd_seed_odd = 0; - u8 prime[SAE_MAX_ECC_PRIME_LEN]; - size_t prime_len; -- struct crypto_bignum *x = NULL, *qr = NULL, *qnr = NULL; -+ struct crypto_bignum *x = NULL, *y = NULL, *qr = NULL, *qnr = NULL; - u8 x_bin[SAE_MAX_ECC_PRIME_LEN]; - u8 x_cand_bin[SAE_MAX_ECC_PRIME_LEN]; - u8 qr_bin[SAE_MAX_ECC_PRIME_LEN]; - u8 qnr_bin[SAE_MAX_ECC_PRIME_LEN]; -+ u8 x_y[2 * SAE_MAX_ECC_PRIME_LEN]; - int res = -1; - u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_* - * mask */ -+ unsigned int is_eq; - - os_memset(x_bin, 0, sizeof(x_bin)); - -@@ -396,25 +398,42 @@ static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1, - goto fail; - } - -- if (!sae->tmp->pwe_ecc) -- sae->tmp->pwe_ecc = crypto_ec_point_init(sae->tmp->ec); -- if (!sae->tmp->pwe_ecc) -- res = -1; -- else -- res = crypto_ec_point_solve_y_coord(sae->tmp->ec, -- sae->tmp->pwe_ecc, x, -- pwd_seed_odd); -- if (res < 0) { -- /* -- * This should not happen since we already checked that there -- * is a result. -- */ -+ /* y = sqrt(x^3 + ax + b) mod p -+ * if LSB(save) == LSB(y): PWE = (x, y) -+ * else: PWE = (x, p - y) -+ * -+ * Calculate y and the two possible values for PWE and after that, -+ * use constant time selection to copy the correct alternative. -+ */ -+ y = crypto_ec_point_compute_y_sqr(sae->tmp->ec, x); -+ if (!y || -+ dragonfly_sqrt(sae->tmp->ec, y, y) < 0 || -+ crypto_bignum_to_bin(y, x_y, SAE_MAX_ECC_PRIME_LEN, -+ prime_len) < 0 || -+ crypto_bignum_sub(sae->tmp->prime, y, y) < 0 || -+ crypto_bignum_to_bin(y, x_y + SAE_MAX_ECC_PRIME_LEN, -+ SAE_MAX_ECC_PRIME_LEN, prime_len) < 0) { - wpa_printf(MSG_DEBUG, "SAE: Could not solve y"); -+ goto fail; -+ } -+ -+ is_eq = const_time_eq(pwd_seed_odd, x_y[prime_len - 1] & 0x01); -+ const_time_select_bin(is_eq, x_y, x_y + SAE_MAX_ECC_PRIME_LEN, -+ prime_len, x_y + prime_len); -+ os_memcpy(x_y, x_bin, prime_len); -+ wpa_hexdump_key(MSG_DEBUG, "SAE: PWE", x_y, 2 * prime_len); -+ crypto_ec_point_deinit(sae->tmp->pwe_ecc, 1); -+ sae->tmp->pwe_ecc = crypto_ec_point_from_bin(sae->tmp->ec, x_y); -+ if (!sae->tmp->pwe_ecc) { -+ wpa_printf(MSG_DEBUG, "SAE: Could not generate PWE"); -+ res = -1; - } - - fail: -+ forced_memzero(x_y, sizeof(x_y)); - crypto_bignum_deinit(qr, 0); - crypto_bignum_deinit(qnr, 0); -+ crypto_bignum_deinit(y, 1); - os_free(stub_password); - bin_clear_free(tmp_password, password_len); - crypto_bignum_deinit(x, 1); --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q00-004-SAE-Move-sqrt-implementation-into-a-helper-function.patch b/feeds/ipq95xx/hostapd/patches/q00-004-SAE-Move-sqrt-implementation-into-a-helper-function.patch deleted file mode 100644 index 90f8a0e3..00000000 --- a/feeds/ipq95xx/hostapd/patches/q00-004-SAE-Move-sqrt-implementation-into-a-helper-function.patch +++ /dev/null @@ -1,100 +0,0 @@ -From e04120904221ac4c69a409451d53de04180ae4a3 Mon Sep 17 00:00:00 2001 -From: Jouni Malinen -Date: Fri, 7 Jan 2022 13:47:16 +0200 -Subject: [PATCH 4/5] SAE: Move sqrt() implementation into a helper function - -This implementation within SSWU can be helpful for other users of the -dragonfly design, so move it into a shared helper function. - -Signed-off-by: Jouni Malinen -Signed-off-by: Rameshkumar Sundaram -(cherry picked from commit 8ebd8aacc2343fae0374d07d66aea16c05abc5e2) ---- - src/common/dragonfly.c | 34 ++++++++++++++++++++++++++++++++++ - src/common/dragonfly.h | 2 ++ - src/common/sae.c | 14 ++------------ - 3 files changed, 38 insertions(+), 12 deletions(-) - -diff --git a/src/common/dragonfly.c b/src/common/dragonfly.c -index 547be66..1e84271 100644 ---- a/src/common/dragonfly.c -+++ b/src/common/dragonfly.c -@@ -213,3 +213,37 @@ int dragonfly_generate_scalar(const struct crypto_bignum *order, - "dragonfly: Unable to get randomness for own scalar"); - return -1; - } -+ -+ -+/* res = sqrt(val) */ -+int dragonfly_sqrt(struct crypto_ec *ec, const struct crypto_bignum *val, -+ struct crypto_bignum *res) -+{ -+ const struct crypto_bignum *prime; -+ struct crypto_bignum *tmp, *one; -+ int ret = 0; -+ u8 prime_bin[DRAGONFLY_MAX_ECC_PRIME_LEN]; -+ size_t prime_len; -+ -+ /* For prime p such that p = 3 mod 4, sqrt(w) = w^((p+1)/4) mod p */ -+ -+ prime = crypto_ec_get_prime(ec); -+ prime_len = crypto_ec_prime_len(ec); -+ tmp = crypto_bignum_init(); -+ one = crypto_bignum_init_uint(1); -+ -+ if (crypto_bignum_to_bin(prime, prime_bin, sizeof(prime_bin), -+ prime_len) < 0 || -+ (prime_bin[prime_len - 1] & 0x03) != 3 || -+ !tmp || !one || -+ /* tmp = (p+1)/4 */ -+ crypto_bignum_add(prime, one, tmp) < 0 || -+ crypto_bignum_rshift(tmp, 2, tmp) < 0 || -+ /* res = sqrt(val) */ -+ crypto_bignum_exptmod(val, tmp, prime, res) < 0) -+ ret = -1; -+ -+ crypto_bignum_deinit(tmp, 0); -+ crypto_bignum_deinit(one, 0); -+ return ret; -+} -diff --git a/src/common/dragonfly.h b/src/common/dragonfly.h -index ec3dd59..84d67f5 100644 ---- a/src/common/dragonfly.h -+++ b/src/common/dragonfly.h -@@ -27,5 +27,7 @@ int dragonfly_generate_scalar(const struct crypto_bignum *order, - struct crypto_bignum *_rand, - struct crypto_bignum *_mask, - struct crypto_bignum *scalar); -+int dragonfly_sqrt(struct crypto_ec *ec, const struct crypto_bignum *val, -+ struct crypto_bignum *res); - - #endif /* DRAGONFLY_H */ -diff --git a/src/common/sae.c b/src/common/sae.c -index 372905d..8974668 100644 ---- a/src/common/sae.c -+++ b/src/common/sae.c -@@ -766,19 +766,9 @@ static struct crypto_ec_point * sswu(struct crypto_ec *ec, int group, - const_time_select_bin(is_qr, bin1, bin2, prime_len, x_y); - wpa_hexdump_key(MSG_DEBUG, "SSWU: x = CSEL(l, x1, x2)", x_y, prime_len); - -- /* y = sqrt(v) -- * For prime p such that p = 3 mod 4 --> v^((p+1)/4) */ -- if (crypto_bignum_to_bin(prime, bin1, sizeof(bin1), prime_len) < 0) -- goto fail; -- if ((bin1[prime_len - 1] & 0x03) != 3) { -- wpa_printf(MSG_DEBUG, "SSWU: prime does not have p = 3 mod 4"); -- goto fail; -- } -+ /* y = sqrt(v) */ - y = crypto_bignum_init(); -- if (!y || -- crypto_bignum_add(prime, one, t1) < 0 || -- crypto_bignum_rshift(t1, 2, t1) < 0 || -- crypto_bignum_exptmod(v, t1, prime, y) < 0) -+ if (!y || dragonfly_sqrt(ec, v, y) < 0) - goto fail; - debug_print_bignum("SSWU: y = sqrt(v)", y, prime_len); - --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q00-005-EAP-pwd-Fix-the-prefix-in-a-debug-message.patch b/feeds/ipq95xx/hostapd/patches/q00-005-EAP-pwd-Fix-the-prefix-in-a-debug-message.patch deleted file mode 100644 index 026306d3..00000000 --- a/feeds/ipq95xx/hostapd/patches/q00-005-EAP-pwd-Fix-the-prefix-in-a-debug-message.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 39a124f8145c8751af95d4017b292d6b4ef423a1 Mon Sep 17 00:00:00 2001 -From: Jouni Malinen -Date: Tue, 1 Feb 2022 19:58:40 +0200 -Subject: [PATCH 5/5] EAP-pwd: Fix the prefix in a debug message - -This was copied from sae.c, but the debug message prefix was not changed -to match the use here. - -Signed-off-by: Jouni Malinen -Signed-off-by: Rameshkumar Sundaram -(cherry picked from commit 34575ad72ebbb5411e394af7090f79a27a60a9aa) ---- - src/eap_common/eap_pwd_common.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/eap_common/eap_pwd_common.c b/src/eap_common/eap_pwd_common.c -index ff22b29..0e3a7b2 100644 ---- a/src/eap_common/eap_pwd_common.c -+++ b/src/eap_common/eap_pwd_common.c -@@ -275,7 +275,7 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, - crypto_bignum_sub(prime, y, y) < 0 || - crypto_bignum_to_bin(y, x_y + MAX_ECC_PRIME_LEN, - MAX_ECC_PRIME_LEN, primebytelen) < 0) { -- wpa_printf(MSG_DEBUG, "SAE: Could not solve y"); -+ wpa_printf(MSG_DEBUG, "EAP-pwd: Could not solve y"); - goto fail; - } - --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q003-001-hostapd-Add-config-to-truncate-ext-capabilities.patch b/feeds/ipq95xx/hostapd/patches/q003-001-hostapd-Add-config-to-truncate-ext-capabilities.patch deleted file mode 100644 index 4a51aff5..00000000 --- a/feeds/ipq95xx/hostapd/patches/q003-001-hostapd-Add-config-to-truncate-ext-capabilities.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 234aa775f8046dc823a0ce72267f62045d81ee08 Mon Sep 17 00:00:00 2001 -From: Harshitha Prem -Date: Wed, 6 Jul 2022 17:03:52 +0530 -Subject: [PATCH] hostapd: Add config to truncate ext capabilities - -Certain legacy clients are not able to scan 11ax vaps due to -extended capabilities which are more than 8bytes in length. -Hence added a work around to trucate the ext caps to 8bytes -based on the hostapd config ext_cap_len. -Legacy clients are able to scan and connect if hostapd config -as ext_cap_len=8, ieee80211ac=1, ieee80211ax=0 - -Signed-off-by: Harshitha Prem ---- - hostapd/config_file.c | 2 ++ - src/ap/ap_config.h | 1 + - src/ap/ieee802_11_shared.c | 3 +++ - 3 files changed, 6 insertions(+) - -diff --git a/hostapd/config_file.c b/hostapd/config_file.c -index ede28a7..d91f3fc 100644 ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -2358,6 +2358,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, - conf->country[2] = strtol(pos, NULL, 16); - } else if (os_strcmp(buf, "ieee80211d") == 0) { - conf->ieee80211d = atoi(pos); -+ } else if (os_strcmp(buf, "ext_cap_len") == 0) { -+ conf->ext_cap_len = atoi(pos); - } else if (os_strcmp(buf, "ieee80211h") == 0) { - conf->ieee80211h = atoi(pos); - } else if (os_strcmp(buf, "dfs_test_mode") == 0) { -diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h -index 5d12cf5..5b14a7f 100644 ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -1059,6 +1059,7 @@ struct hostapd_config { - /* Use driver-generated interface addresses when adding multiple BSSs */ - u8 use_driver_iface_addr; - u8 skip_unii1_dfs_switch; -+ u8 ext_cap_len; - - #ifdef CONFIG_FST - struct fst_iface_cfg fst_cfg; -diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c -index 9536747..98be1ec 100644 ---- a/src/ap/ieee802_11_shared.c -+++ b/src/ap/ieee802_11_shared.c -@@ -456,6 +456,9 @@ u8 * hostapd_eid_ext_capab(struct hostapd_data *hapd, u8 *eid) - if (len < hapd->iface->extended_capa_len) - len = hapd->iface->extended_capa_len; - -+ if (hapd->iconf->ext_cap_len > 0 && hapd->iconf->ext_cap_len < len) -+ len = hapd->iconf->ext_cap_len; -+ - *pos++ = WLAN_EID_EXT_CAPAB; - *pos++ = len; - for (i = 0; i < len; i++, pos++) { --- -2.17.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q01-001-mbssid-add-configuration-options.patch b/feeds/ipq95xx/hostapd/patches/q01-001-mbssid-add-configuration-options.patch deleted file mode 100644 index 6421d4d5..00000000 --- a/feeds/ipq95xx/hostapd/patches/q01-001-mbssid-add-configuration-options.patch +++ /dev/null @@ -1,75 +0,0 @@ -From cb6afcaacd3f0de23882fdd5e341a986a860bb3e Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 10 Sep 2021 14:47:55 -0700 -Subject: [PATCH 01/15] mbssid: add configuration options - -Add configuration options to enable multiple BSSID (MBSSID) and -enhanced multiple BSSID advertisements (EMA). -MBSSID enablement is mandatory to enable EMA. - -Signed-off-by: John Crispin -Signed-off-by: Aloka Dixit ---- - hostapd/config_file.c | 4 ++++ - hostapd/hostapd.conf | 10 ++++++++++ - src/ap/ap_config.c | 5 +++++ - src/ap/ap_config.h | 2 ++ - 4 files changed, 21 insertions(+) - ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -4658,6 +4658,10 @@ static int hostapd_config_fill(struct ho - return 1; - } else if (os_strcmp(buf, "rnr") == 0) { - bss->rnr = atoi(pos); -+ } else if (os_strcmp(buf, "mbssid") == 0) { -+ conf->mbssid = atoi(pos); -+ } else if (os_strcmp(buf, "ema") == 0) { -+ conf->ema = atoi(pos); - } else { - wpa_printf(MSG_ERROR, - "Line %d: unknown configuration item '%s'", ---- a/hostapd/hostapd.conf -+++ b/hostapd/hostapd.conf -@@ -986,6 +986,16 @@ wmm_ac_vo_acm=0 - # Valid range: 0..20 TUs; default is 0 (disabled) - #unsol_bcast_probe_resp_interval=0 - -+# Multiple BSSID element support in beacon and probe response frames. -+# 0 = Disabled -+# 1 = Enabled -+#mbssid=0 -+ -+# Enhanced multiple BSSID advertisements support in beacons. -+# 0 = Disabled -+# 1 = Enabled -+#ema=0 -+ - ##### IEEE 802.1X-2004 related configuration ################################## - - # Require IEEE 802.1X authorization ---- a/src/ap/ap_config.c -+++ b/src/ap/ap_config.c -@@ -1503,6 +1503,11 @@ int hostapd_config_check(struct hostapd_ - return -1; - } - -+ if (!conf->mbssid && conf->ema) { -+ wpa_printf(MSG_ERROR, "mbssid must be enabled to enable ema"); -+ return -1; -+ } -+ - for (i = 0; i < conf->num_bss; i++) { - if (hostapd_config_check_bss(conf->bss[i], conf, full_config)) - return -1; ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -1123,6 +1123,8 @@ struct hostapd_config { - unsigned int airtime_update_interval; - #define AIRTIME_MODE_MAX (__AIRTIME_MODE_MAX - 1) - #endif /* CONFIG_AIRTIME_POLICY */ -+ u8 mbssid; -+ u8 ema; - }; - - static inline u8 hostapd_get_he_6ghz_reg_pwr_type(struct hostapd_config *conf) diff --git a/feeds/ipq95xx/hostapd/patches/q01-001-tests-Initial-EHT-testing.patch b/feeds/ipq95xx/hostapd/patches/q01-001-tests-Initial-EHT-testing.patch deleted file mode 100644 index 386bc773..00000000 --- a/feeds/ipq95xx/hostapd/patches/q01-001-tests-Initial-EHT-testing.patch +++ /dev/null @@ -1,786 +0,0 @@ -From 5758cb14681541dfab829d1ae204c861c05072a7 Mon Sep 17 00:00:00 2001 -From: Muna Sinada -Date: Mon, 4 Oct 2021 11:05:51 -0700 -Subject: [PATCH] tests: Initial EHT testing - -Add initial tests for EHT. - -Tests include the following: - - - eht80_to_24g_eht - EHT with 80 MHz channel width reconfigured to - 2.4 GHz EHT - - eht_40 - EHT and 40 MHz channel - - eht_use_sta_nsts - EHT with 80 MHz channel width and use_sta_nsts=1 - - eht_open - EHT AP with open mode configuration - - eht80_invalid2 - EHT with invalid 80 MHz channel configuration (seg0) - - eht80b - EHT with 80 MHz channel width (HT40- channel 40) - - eht80d - EHT with 80 MHz channel width (HT40- channel 48) - - eht_on_24ghz - Subset of EHT features on 2.4 GHz - - eht_params - EHT AP parameters - - eht_wifi_generation_24 - - eht_wifi_generation - - eht80 - EHT with 80 MHz channel width - - eht_20 - EHT and 20 MHz channel - - eht_disabled_on_sta - EHT AP and EHT STA disabled on STA - - eht80c - EHT with 80 MHz channel width (HT40+ channel 44) - - eht80_params - EHT with 80 MHz channel width and number of optional - features enabled - - eht80_csa - EHT with 80 MHz channel width and CSA - - eht160 - EHT with 160 MHz channel width [long] - - eht80_invalid - EHT with invalid 80 MHz channel configuration - (seg1: 80+80 not supported) - -Signed-off-by: Muna Sinada ---- - tests/hwsim/example-hostapd.config | 1 + - tests/hwsim/example-wpa_supplicant.config | 2 + - tests/hwsim/test_eht.py | 691 ++++++++++++++++++++++++++++++ - tests/hwsim/wpasupplicant.py | 2 +- - 4 files changed, 695 insertions(+), 1 deletion(-) - create mode 100644 tests/hwsim/test_eht.py - -diff --git a/tests/hwsim/example-hostapd.config b/tests/hwsim/example-hostapd.config -index d01a1d2edcfe..17cde61069a3 100644 ---- a/tests/hwsim/example-hostapd.config -+++ b/tests/hwsim/example-hostapd.config -@@ -50,6 +50,7 @@ CONFIG_LIBNL3_ROUTE=y - CONFIG_IEEE80211R=y - CONFIG_IEEE80211AC=y - CONFIG_IEEE80211AX=y -+CONFIG_IEEE80211BE=y - - CONFIG_OCV=y - -diff --git a/tests/hwsim/example-wpa_supplicant.config b/tests/hwsim/example-wpa_supplicant.config -index 5e5acd695729..6ed491f7a713 100644 ---- a/tests/hwsim/example-wpa_supplicant.config -+++ b/tests/hwsim/example-wpa_supplicant.config -@@ -60,6 +60,7 @@ CONFIG_CTRL_IFACE_DBUS_INTRO=y - CONFIG_IEEE80211R=y - CONFIG_IEEE80211AC=y - CONFIG_IEEE80211AX=y -+CONFIG_IEEE80211BE=y - - CONFIG_OCV=y - -@@ -103,6 +104,7 @@ CONFIG_TLSV12=y - CONFIG_HT_OVERRIDES=y - CONFIG_VHT_OVERRIDES=y - CONFIG_HE_OVERRIDES=y -+CONFIG_EHT_OVERRIDES=y - - CONFIG_DEBUG_LINUX_TRACING=y - -diff --git a/tests/hwsim/test_eht.py b/tests/hwsim/test_eht.py -new file mode 100644 -index 000000000000..70206bcf375a ---- /dev/null -+++ b/tests/hwsim/test_eht.py -@@ -0,0 +1,691 @@ -+# EHT tests -+# Copyright (c) 2019, The Linux Foundation -+# Copyright (c) 2022, Qualcomm Innovation Center, Inc -+# -+# This software may be distributed under the terms of the BSD license. -+# See README for more details. -+ -+import logging -+logger = logging.getLogger() -+import os -+import subprocess, time -+ -+import hwsim_utils -+import hostapd -+from wpasupplicant import WpaSupplicant -+from utils import * -+from test_dfs import wait_dfs_event -+ -+def test_eht_open(dev, apdev): -+ """EHT AP with open mode configuration""" -+ params = {"ssid": "eht", -+ "ieee80211ax": "1", -+ "ieee80211be": "1"} -+ hapd = hostapd.add_ap(apdev[0], params) -+ if hapd.get_status_field("ieee80211be") != "1": -+ raise Exception("STATUS did not indicate ieee80211be=1") -+ dev[0].connect("eht", key_mgmt="NONE", scan_freq="2412") -+ sta = hapd.get_sta(dev[0].own_addr()) -+ if "[EHT]" not in sta['flags']: -+ raise Exception("Missing STA flag: EHT") -+ -+def test_eht_disabled_on_sta(dev, apdev): -+ """EHT AP and EHT STA disabled on STA""" -+ params = {"ssid": "eht", -+ "ieee80211ax": "1", -+ "ieee80211be": "1"} -+ hapd = hostapd.add_ap(apdev[0], params) -+ dev[0].connect("eht", key_mgmt="NONE", scan_freq="2412", disable_eht="1") -+ sta = hapd.get_sta(dev[0].own_addr()) -+ if "[EHT]" in sta['flags']: -+ raise Exception("Unexpected STA flag: EHT") -+ -+def test_eht_params(dev, apdev): -+ """EHT AP parameters""" -+ params = {"ssid": "eht", -+ "ieee80211ax": "1", -+ "ieee80211be": "1", -+ "eht_su_beamformer": "0", -+ "eht_mu_beamformer": "0", -+ "eht_oper_chwidth": "0", -+ "eht_oper_centr_freq_seg0_idx": "1"} -+ hapd = hostapd.add_ap(apdev[0], params) -+ if hapd.get_status_field("ieee80211be") != "1": -+ raise Exception("STATUS did not indicate ieee80211be=1") -+ dev[0].connect("eht", key_mgmt="NONE", scan_freq="2412") -+ -+def eht_supported(): -+ cmd = subprocess.Popen(["iw", "reg", "get"], stdout=subprocess.PIPE) -+ reg = cmd.stdout.read().decode() -+ if "@ 80)" in reg or "@ 160)" in reg: -+ return True -+ return False -+ -+def test_eht80(dev, apdev): -+ """EHT with 80 MHz channel width""" -+ try: -+ hapd = None -+ params = {"ssid": "eht", -+ "country_code": "FI", -+ "hw_mode": "a", -+ "channel": "36", -+ "ht_capab": "[HT40+]", -+ "ieee80211n": "1", -+ "ieee80211ac": "1", -+ "ieee80211ax": "1", -+ "vht_oper_chwidth": "1", -+ "vht_capab": "[MAX-MPDU-11454]", -+ "vht_oper_centr_freq_seg0_idx": "42", -+ "he_oper_chwidth": "1", -+ "he_oper_centr_freq_seg0_idx": "42", -+ "ieee80211be": "1", -+ "eht_oper_chwidth": "1", -+ "eht_oper_centr_freq_seg0_idx": "42"} -+ hapd = hostapd.add_ap(apdev[0], params) -+ bssid = apdev[0]['bssid'] -+ -+ dev[0].connect("eht", key_mgmt="NONE", scan_freq="5180") -+ hwsim_utils.test_connectivity(dev[0], hapd) -+ sig = dev[0].request("SIGNAL_POLL").splitlines() -+ if "FREQUENCY=5180" not in sig: -+ raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig)) -+ if "WIDTH=80 MHz" not in sig: -+ raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig)) -+ est = dev[0].get_bss(bssid)['est_throughput'] -+ if est != "600502": -+ raise Exception("Unexpected BSS est_throughput: " + est) -+ status = dev[0].get_status() -+ if status["ieee80211ac"] != "1": -+ raise Exception("Unexpected STATUS ieee80211ac value (STA)") -+ status = hapd.get_status() -+ logger.info("hostapd STATUS: " + str(status)) -+ if status["ieee80211n"] != "1": -+ raise Exception("Unexpected STATUS ieee80211n value") -+ if status["ieee80211ac"] != "1": -+ raise Exception("Unexpected STATUS ieee80211ac value") -+ if status["ieee80211ax"] != "1": -+ raise Exception("Unexpected STATUS ieee80211ax value") -+ if status["secondary_channel"] != "1": -+ raise Exception("Unexpected STATUS secondary_channel value") -+ if status["vht_oper_chwidth"] != "1": -+ raise Exception("Unexpected STATUS vht_oper_chwidth value") -+ if status["vht_oper_centr_freq_seg0_idx"] != "42": -+ raise Exception("Unexpected STATUS vht_oper_centr_freq_seg0_idx value") -+ if "vht_caps_info" not in status: -+ raise Exception("Missing vht_caps_info") -+ if status["he_oper_chwidth"] != "1": -+ raise Exception("Unexpected STATUS he_oper_chwidth value") -+ if status["he_oper_centr_freq_seg0_idx"] != "42": -+ raise Exception("Unexpected STATUS he_oper_centr_freq_seg0_idx value") -+ if status["ieee80211be"] != "1": -+ raise Exception("Unexpected STATUS ieee80211be value") -+ if status["eht_oper_chwidth"] != "1": -+ raise Exception("Unexpected STATUS eht_oper_chwidth value") -+ if status["eht_oper_centr_freq_seg0_idx"] != "42": -+ raise Exception("Unexpected STATUS eht_oper_centr_freq_seg0_idx value") -+ -+ sta = hapd.get_sta(dev[0].own_addr()) -+ logger.info("hostapd STA: " + str(sta)) -+ if "[HT]" not in sta['flags']: -+ raise Exception("Missing STA flag: HT") -+ if "[VHT]" not in sta['flags']: -+ raise Exception("Missing STA flag: VHT") -+ if "[HE]" not in sta['flags']: -+ raise Exception("Missing STA flag: HE") -+ if "[EHT]" not in sta['flags']: -+ raise Exception("Missing STA flag: EHT") -+ -+ except Exception as e: -+ if isinstance(e, Exception) and str(e) == "AP startup failed": -+ if not eht_supported(): -+ raise HwsimSkip("80 MHz channel not supported in regulatory information") -+ raise -+ finally: -+ dev[0].request("DISCONNECT") -+ clear_regdom(hapd, dev) -+ -+def _test_eht_wifi_generation(dev, apdev, conf, scan_freq): -+ """EHT and wifi_generation""" -+ try: -+ hapd = None -+ params = {"ssid": "eht", -+ "country_code": "FI", -+ "ieee80211n": "1", -+ "ieee80211ax": "1", -+ "ieee80211be": "1"} -+ params.update(conf) -+ hapd = hostapd.add_ap(apdev[0], params) -+ bssid = apdev[0]['bssid'] -+ -+ dev[0].connect("eht", key_mgmt="NONE", scan_freq=scan_freq) -+ status = dev[0].get_status() -+ if 'wifi_generation' not in status: -+ # For now, assume this is because of missing kernel support -+ raise HwsimSkip("Association Request IE reporting not supported") -+ if status['wifi_generation'] != "7": -+ raise Exception("Unexpected wifi_generation value: " + status['wifi_generation']) -+ -+ wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') -+ wpas.interface_add("wlan5", drv_params="force_connect_cmd=1") -+ wpas.connect("eht", key_mgmt="NONE", scan_freq=scan_freq) -+ status = wpas.get_status() -+ if 'wifi_generation' not in status: -+ # For now, assume this is because of missing kernel support -+ raise HwsimSkip("Association Request IE reporting not supported") -+ if status['wifi_generation'] != "7": -+ raise Exception("Unexpected wifi_generation value (connect): " + status['wifi_generation']) -+ except Exception as e: -+ if isinstance(e, Exception) and str(e) == "AP startup failed": -+ if not eht_supported(): -+ raise HwsimSkip("80 MHz channel not supported in regulatory information") -+ raise -+ finally: -+ dev[0].request("DISCONNECT") -+ clear_regdom(hapd, dev) -+ -+def test_eht_wifi_generation(dev, apdev): -+ conf = {"hw_mode": "a", -+ "channel": "36", -+ "ht_capab": "[HT40+]", -+ "ieee80211ac": "1", -+ "vht_capab": "[MAX-MPDU-11454]", -+ "vht_oper_chwidth": "1", -+ "vht_oper_centr_freq_seg0_idx": "42", -+ "he_oper_chwidth": "1", -+ "he_oper_centr_freq_seg0_idx": "42", -+ "eht_oper_chwidth": "1", -+ "eht_oper_centr_freq_seg0_idx": "42"} -+ -+ _test_eht_wifi_generation(dev, apdev, conf, "5180") -+ -+def test_eht_wifi_generation_24(dev, apdev): -+ conf = {"hw_mode": "g", -+ "channel": "1"} -+ _test_eht_wifi_generation(dev, apdev, conf, "2412") -+ -+def eht80_test(apdev, dev, channel, ht_capab): -+ clear_scan_cache(apdev) -+ try: -+ hapd = None -+ params = {"ssid": "eht", -+ "country_code": "FI", -+ "hw_mode": "a", -+ "channel": str(channel), -+ "ieee80211n": "1", -+ "ht_capab": ht_capab, -+ "ieee80211ac": "1", -+ "vht_capab": "[MAX-MPDU-11454]", -+ "vht_oper_chwidth": "1", -+ "vht_oper_centr_freq_seg0_idx": "42", -+ "ieee80211ax": "1", -+ "he_oper_chwidth": "1", -+ "he_oper_centr_freq_seg0_idx": "42", -+ "ieee80211be": "1", -+ "eht_oper_chwidth": "1", -+ "eht_oper_centr_freq_seg0_idx": "42"} -+ hapd = hostapd.add_ap(apdev, params) -+ bssid = apdev['bssid'] -+ -+ dev[0].connect("eht", key_mgmt="NONE", -+ scan_freq=str(5000 + 5 * channel)) -+ hwsim_utils.test_connectivity(dev[0], hapd) -+ except Exception as e: -+ if isinstance(e, Exception) and str(e) == "AP startup failed": -+ if not eht_supported(): -+ raise HwsimSkip("80 MHz channel not supported in regulatory information") -+ raise -+ finally: -+ clear_regdom(hapd, dev) -+ -+def test_eht80b(dev, apdev): -+ """EHT with 80 MHz channel width (HT40- channel 40)""" -+ eht80_test(apdev[0], dev, 40, "[HT40-]") -+ -+def test_eht80c(dev, apdev): -+ """EHT with 80 MHz channel width (HT40+ channel 44)""" -+ eht80_test(apdev[0], dev, 44, "[HT40+]") -+ -+def test_eht80d(dev, apdev): -+ """EHT with 80 MHz channel width (HT40- channel 48)""" -+ eht80_test(apdev[0], dev, 48, "[HT40-]") -+ -+def test_eht80_params(dev, apdev): -+ """EHT with 80 MHz channel width and number of optional features enabled""" -+ try: -+ hapd = None -+ params = {"ssid": "eht", -+ "country_code": "FI", -+ "hw_mode": "a", -+ "channel": "36", -+ "ieee80211n": "1", -+ "ht_capab": "[HT40+][SHORT-GI-40][DSS_CCK-40]", -+ "ieee80211ac": "1", -+ "vht_capab": "[MAX-MPDU-11454][RXLDPC][SHORT-GI-80][TX-STBC-2BY1][RX-STBC-1][MAX-A-MPDU-LEN-EXP0]", -+ "vht_oper_chwidth": "1", -+ "vht_oper_centr_freq_seg0_idx": "42", -+ "require_vht": "1", -+ "ieee80211ax": "1", -+ "he_oper_chwidth": "1", -+ "he_oper_centr_freq_seg0_idx": "42", -+ "ieee80211be": "1", -+ "eht_oper_chwidth": "1", -+ "eht_oper_centr_freq_seg0_idx": "42", -+ "eht_su_beamformer": "1", -+ "eht_mu_beamformer": "1"} -+ hapd = hostapd.add_ap(apdev[0], params) -+ -+ dev[1].connect("eht", key_mgmt="NONE", scan_freq="5180", -+ disable_vht="1", wait_connect=False) -+ dev[0].connect("eht", key_mgmt="NONE", scan_freq="5180") -+ dev[2].connect("eht", key_mgmt="NONE", scan_freq="5180", -+ disable_sgi="1") -+ ev = dev[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"]) -+ if ev is None: -+ raise Exception("Association rejection timed out") -+ if "status_code=104" not in ev: -+ raise Exception("Unexpected rejection status code") -+ dev[1].request("DISCONNECT") -+ hwsim_utils.test_connectivity(dev[0], hapd) -+ sta0 = hapd.get_sta(dev[0].own_addr()) -+ sta2 = hapd.get_sta(dev[2].own_addr()) -+ capab0 = int(sta0['vht_caps_info'], base=16) -+ capab2 = int(sta2['vht_caps_info'], base=16) -+ if capab0 & 0x60 == 0: -+ raise Exception("dev[0] did not support SGI") -+ if capab2 & 0x60 != 0: -+ raise Exception("dev[2] claimed support for SGI") -+ except Exception as e: -+ if isinstance(e, Exception) and str(e) == "AP startup failed": -+ if not eht_supported(): -+ raise HwsimSkip("80 MHz channel not supported in regulatory information") -+ raise -+ finally: -+ clear_regdom(hapd, dev, count=3) -+ -+def test_eht80_invalid(dev, apdev): -+ """EHT with invalid 80 MHz channel configuration (seg1: 80+80 not supported)""" -+ try: -+ hapd = None -+ params = {"ssid": "eht", -+ "country_code": "US", -+ "hw_mode": "a", -+ "channel": "36", -+ "ieee80211n": "1", -+ "ht_capab": "[HT40+]", -+ "ieee80211ac": "1", -+ "vht_capab": "[MAX-MPDU-11454]", -+ "vht_oper_chwidth": "1", -+ "vht_oper_centr_freq_seg0_idx": "42", -+ "vht_oper_centr_freq_seg1_idx": "159", -+ "ieee80211ax": "1", -+ "he_oper_chwidth": "1", -+ "he_oper_centr_freq_seg0_idx": "42", -+ "he_oper_centr_freq_seg1_idx": "159", -+ "ieee80211be": "1", -+ "eht_oper_chwidth": "1", -+ "eht_oper_centr_freq_seg0_idx": "42", -+ "ieee80211d": "1", -+ "ieee80211h": "1"} -+ hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) -+ # This fails due to unexpected seg1 configuration -+ ev = hapd.wait_event(["AP-DISABLED"], timeout=5) -+ if ev is None: -+ raise Exception("AP-DISABLED not reported") -+ except Exception as e: -+ if isinstance(e, Exception) and str(e) == "AP startup failed": -+ if not eht_supported(): -+ raise HwsimSkip("80/160 MHz channel not supported in regulatory information") -+ raise -+ finally: -+ clear_regdom(hapd, dev) -+ -+def test_eht80_invalid2(dev, apdev): -+ """EHT with invalid 80 MHz channel configuration (seg0)""" -+ try: -+ hapd = None -+ params = {"ssid": "eht", -+ "country_code": "US", -+ "hw_mode": "a", -+ "channel": "36", -+ "ieee80211n": "1", -+ "ht_capab": "[HT40+]", -+ "ieee80211ac": "1", -+ "vht_oper_chwidth": "1", -+ "vht_oper_centr_freq_seg0_idx": "42", -+ "ieee80211ax": "1", -+ "he_oper_chwidth": "1", -+ "he_oper_centr_freq_seg0_idx": "42", -+ "ieee80211be": "1", -+ "eht_oper_chwidth": "1", -+ "eht_oper_centr_freq_seg0_idx": "46", -+ "ieee80211d": "1", -+ "ieee80211h": "1"} -+ hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) -+ # This fails due to invalid seg0 configuration -+ ev = hapd.wait_event(["AP-DISABLED"], timeout=5) -+ if ev is None: -+ raise Exception("AP-DISABLED not reported") -+ except Exception as e: -+ if isinstance(e, Exception) and str(e) == "AP startup failed": -+ if not eht_supported(): -+ raise HwsimSkip("80/160 MHz channel not supported in regulatory information") -+ raise -+ finally: -+ clear_regdom(hapd, dev) -+ -+def test_eht80_to_24g_eht(dev, apdev): -+ """EHT with 80 MHz channel width reconfigured to 2.4 GHz EHT""" -+ try: -+ params = {"ssid": "eht", -+ "country_code": "FI", -+ "hw_mode": "a", -+ "channel": "36", -+ "ieee80211n": "1", -+ "ht_capab": "[HT40+]", -+ "ieee80211ac": "1", -+ "vht_capab": "[MAX-MPDU-11454]", -+ "vht_oper_chwidth": "1", -+ "vht_oper_centr_freq_seg0_idx": "42", -+ "ieee80211ax": "1", -+ "he_oper_chwidth": "1", -+ "he_oper_centr_freq_seg0_idx": "42", -+ "ieee80211be": "1", -+ "eht_oper_chwidth": "1", -+ "eht_oper_centr_freq_seg0_idx": "42"} -+ hapd = hostapd.add_ap(apdev[0], params) -+ bssid = apdev[0]['bssid'] -+ -+ hapd.disable() -+ hapd.set("ieee80211ac", "0") -+ hapd.set("hw_mode", "g") -+ hapd.set("channel", "1") -+ hapd.set("ht_capab", "") -+ hapd.set("vht_capab", "") -+ hapd.set("vht_oper_chwidth", "") -+ hapd.set("vht_oper_centr_freq_seg0_idx", "") -+ hapd.set("he_oper_chwidth", "") -+ hapd.set("he_oper_centr_freq_seg0_idx", "") -+ hapd.set("eht_oper_chwidth", "") -+ hapd.set("eht_oper_centr_freq_seg0_idx", "") -+ hapd.enable() -+ -+ dev[0].connect("eht", key_mgmt="NONE", scan_freq="2412") -+ except Exception as e: -+ if isinstance(e, Exception) and str(e) == "AP startup failed": -+ if not eht_supported(): -+ raise HwsimSkip("80 MHz channel not supported in regulatory information") -+ raise -+ finally: -+ dev[0].request("DISCONNECT") -+ clear_regdom(hapd, dev) -+ -+def test_eht_20(devs, apdevs): -+ """EHT and 20 MHz channel""" -+ dev = devs[0] -+ ap = apdevs[0] -+ try: -+ hapd = None -+ params = {"ssid": "eht", -+ "country_code": "DE", -+ "hw_mode": "a", -+ "channel": "36", -+ "ieee80211n": "1", -+ "ht_capab": "", -+ "ieee80211ac": "1", -+ "vht_capab": "", -+ "vht_oper_chwidth": "0", -+ "vht_oper_centr_freq_seg0_idx": "0", -+ "supported_rates": "60 120 240 360 480 540", -+ "require_vht": "1", -+ "ieee80211ax": "1", -+ "he_oper_chwidth": "0", -+ "he_oper_centr_freq_seg0_idx": "0", -+ "ieee80211be": "1", -+ "eht_oper_chwidth": "0", -+ "eht_oper_centr_freq_seg0_idx": "0"} -+ -+ hapd = hostapd.add_ap(ap, params) -+ dev.connect("eht", scan_freq="5180", key_mgmt="NONE") -+ hwsim_utils.test_connectivity(dev, hapd) -+ finally: -+ dev.request("DISCONNECT") -+ clear_regdom(hapd, devs) -+ -+def test_eht_40(devs, apdevs): -+ """EHT and 40 MHz channel""" -+ dev = devs[0] -+ ap = apdevs[0] -+ try: -+ hapd = None -+ params = {"ssid": "eht", -+ "country_code": "DE", -+ "hw_mode": "a", -+ "channel": "36", -+ "ieee80211n": "1", -+ "ht_capab": "[HT40+]", -+ "ieee80211ac": "1", -+ "vht_capab": "", -+ "vht_oper_chwidth": "0", -+ "vht_oper_centr_freq_seg0_idx": "38", -+ "ieee80211ax": "1", -+ "he_oper_chwidth": "0", -+ "he_oper_centr_freq_seg0_idx": "38", -+ "ieee80211be": "1", -+ "eht_oper_chwidth": "0", -+ "eht_oper_centr_freq_seg0_idx": "38", -+ "eht_su_beamformer": "1", -+ "eht_mu_beamformer": "1"} -+ hapd = hostapd.add_ap(ap, params) -+ dev.connect("eht", scan_freq="5180", key_mgmt="NONE") -+ hwsim_utils.test_connectivity(dev, hapd) -+ finally: -+ dev.request("DISCONNECT") -+ clear_regdom(hapd, devs) -+ -+@long_duration_test -+def test_eht160(dev, apdev): -+ """EHT with 160 MHz channel width""" -+ try: -+ hapd = None -+ params = {"ssid": "eht", -+ "country_code": "FI", -+ "hw_mode": "a", -+ "channel": "36", -+ "ieee80211n": "1", -+ "ht_capab": "[HT40+]", -+ "ieee80211ac": "1", -+ "vht_capab": "[VHT160]", -+ "vht_oper_chwidth": "2", -+ "vht_oper_centr_freq_seg0_idx": "50", -+ "ieee80211ax": "1", -+ "he_oper_chwidth": "2", -+ "he_oper_centr_freq_seg0_idx": "50", -+ "ieee80211be": "1", -+ "eht_oper_chwidth": "2", -+ "eht_oper_centr_freq_seg0_idx": "50", -+ "ieee80211d": "1", -+ "ieee80211h": "1"} -+ -+ hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) -+ bssid = apdev[0]['bssid'] -+ -+ ev = wait_dfs_event(hapd, "DFS-CAC-START", 5) -+ if "DFS-CAC-START" not in ev: -+ raise Exception("Unexpected DFS event") -+ -+ state = hapd.get_status_field("state") -+ if state != "DFS": -+ if state == "DISABLED" and not os.path.exists("dfs"): -+ # Not all systems have recent enough CRDA version and -+ # wireless-regdb changes to support 160 MHz and DFS. For now, -+ # do not report failures for this test case. -+ raise HwsimSkip("CRDA or wireless-regdb did not support 160 MHz") -+ raise Exception("Unexpected interface state: " + state) -+ -+ logger.info("Waiting for CAC to complete") -+ -+ ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70) -+ if "success=1" not in ev: -+ raise Exception("CAC failed") -+ if "freq=5180" not in ev: -+ raise Exception("Unexpected DFS freq result") -+ -+ ev = hapd.wait_event(["AP-ENABLED"], timeout=5) -+ if not ev: -+ raise Exception("AP setup timed out") -+ -+ dev[0].connect("eht", key_mgmt="NONE", scan_freq="5180") -+ dev[0].wait_regdom(country_ie=True) -+ hwsim_utils.test_connectivity(dev[0], hapd) -+ sig = dev[0].request("SIGNAL_POLL").splitlines() -+ if "FREQUENCY=5180" not in sig: -+ raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig)) -+ if "WIDTH=160 MHz" not in sig: -+ raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig)) -+ est = dev[0].get_bss(bssid)['est_throughput'] -+ if est != "1201002": -+ raise Exception("Unexpected BSS est_throughput: " + est) -+ except Exception as e: -+ if isinstance(e, Exception) and str(e) == "AP startup failed": -+ if not eht_supported(): -+ raise HwsimSkip("80/160 MHz channel not supported in regulatory information") -+ raise -+ finally: -+ if hapd: -+ hapd.request("DISABLE") -+ dev[0].disconnect_and_stop_scan() -+ subprocess.call(['iw', 'reg', 'set', '00']) -+ dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5) -+ dev[0].flush_scan_cache() -+ -+def test_eht_on_24ghz(dev, apdev): -+ """Subset of EHT features on 2.4 GHz""" -+ hapd = None -+ params = {"ssid": "eht", -+ "hw_mode": "g", -+ "channel": "1", -+ "ieee80211n": "1", -+ "vht_oper_chwidth": "0", -+ "vht_oper_centr_freq_seg0_idx": "1", -+ "ieee80211ax": "1", -+ "he_oper_chwidth": "0", -+ "he_oper_centr_freq_seg0_idx": "1", -+ "ieee80211be": "1", -+ "eht_oper_chwidth": "0", -+ "eht_oper_centr_freq_seg0_idx": "1"} -+ hapd = hostapd.add_ap(apdev[0], params) -+ try: -+ dev[0].connect("eht", scan_freq="2412", key_mgmt="NONE") -+ hwsim_utils.test_connectivity(dev[0], hapd) -+ sta = hapd.get_sta(dev[0].own_addr()) -+ -+ dev[1].connect("eht", scan_freq="2412", key_mgmt="NONE") -+ sta = hapd.get_sta(dev[1].own_addr()) -+ -+ finally: -+ dev[0].request("DISCONNECT") -+ dev[1].request("DISCONNECT") -+ if hapd: -+ hapd.request("DISABLE") -+ subprocess.call(['iw', 'reg', 'set', '00']) -+ dev[0].flush_scan_cache() -+ dev[1].flush_scan_cache() -+ -+def test_eht80_csa(dev, apdev): -+ """EHT with 80 MHz channel width and CSA""" -+ csa_supported(dev[0]) -+ try: -+ hapd = None -+ params = {"ssid": "eht", -+ "country_code": "US", -+ "hw_mode": "a", -+ "channel": "149", -+ "ieee80211n": "1", -+ "ht_capab": "[HT40+]", -+ "ieee80211ac": "1", -+ "vht_oper_chwidth": "1", -+ "vht_oper_centr_freq_seg0_idx": "155", -+ "ieee80211ax": "1", -+ "he_oper_chwidth": "1", -+ "he_oper_centr_freq_seg0_idx": "155", -+ "ieee80211be": "1", -+ "eht_oper_chwidth": "1", -+ "eht_oper_centr_freq_seg0_idx": "155"} -+ hapd = hostapd.add_ap(apdev[0], params) -+ -+ dev[0].connect("eht", key_mgmt="NONE", scan_freq="5745") -+ hwsim_utils.test_connectivity(dev[0], hapd) -+ -+ hapd.request("CHAN_SWITCH 5 5180 ht vht he eht blocktx center_freq1=5210 sec_channel_offset=1 bandwidth=80") -+ ev = hapd.wait_event(["CTRL-EVENT-STARTED-CHANNEL-SWITCH"], timeout=10) -+ if ev is None: -+ raise Exception("Channel switch start event not seen") -+ if "freq=5180" not in ev: -+ raise Exception("Unexpected channel in CS started") -+ ev = hapd.wait_event(["CTRL-EVENT-CHANNEL-SWITCH"], timeout=10) -+ if ev is None: -+ raise Exception("Channel switch completion event not seen") -+ if "freq=5180" not in ev: -+ raise Exception("Unexpected channel in CS completed") -+ ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10) -+ if ev is None: -+ raise Exception("CSA finished event timed out") -+ if "freq=5180" not in ev: -+ raise Exception("Unexpected channel in CSA finished event") -+ time.sleep(0.5) -+ hwsim_utils.test_connectivity(dev[0], hapd) -+ -+ hapd.request("CHAN_SWITCH 5 5745") -+ ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10) -+ if ev is None: -+ raise Exception("CSA finished event timed out") -+ if "freq=5745" not in ev: -+ raise Exception("Unexpected channel in CSA finished event") -+ time.sleep(0.5) -+ hwsim_utils.test_connectivity(dev[0], hapd) -+ -+ # This CSA to same channel will fail in kernel, so use this only for -+ # extra code coverage. -+ hapd.request("CHAN_SWITCH 5 5745") -+ hapd.wait_event(["AP-CSA-FINISHED"], timeout=1) -+ except Exception as e: -+ if isinstance(e, Exception) and str(e) == "AP startup failed": -+ if not eht_supported(): -+ raise HwsimSkip("80 MHz channel not supported in regulatory information") -+ raise -+ finally: -+ dev[0].request("DISCONNECT") -+ clear_regdom(hapd, dev) -+ -+def test_eht_use_sta_nsts(dev, apdev): -+ """EHT with 80 MHz channel width and use_sta_nsts=1""" -+ try: -+ hapd = None -+ params = {"ssid": "eht", -+ "country_code": "FI", -+ "hw_mode": "a", -+ "channel": "36", -+ "ieee80211n": "1", -+ "ht_capab": "[HT40+]", -+ "ieee80211ac": "1", -+ "vht_oper_chwidth": "1", -+ "vht_oper_centr_freq_seg0_idx": "42", -+ "ieee80211ax": "1", -+ "he_oper_chwidth": "1", -+ "he_oper_centr_freq_seg0_idx": "42", -+ "ieee80211be": "1", -+ "eht_oper_chwidth": "1", -+ "eht_oper_centr_freq_seg0_idx": "42", -+ "use_sta_nsts": "1"} -+ hapd = hostapd.add_ap(apdev[0], params) -+ bssid = apdev[0]['bssid'] -+ -+ dev[0].connect("eht", key_mgmt="NONE", scan_freq="5180") -+ hwsim_utils.test_connectivity(dev[0], hapd) -+ except Exception as e: -+ if isinstance(e, Exception) and str(e) == "AP startup failed": -+ if not eht_supported(): -+ raise HwsimSkip("80/160 MHz channel not supported in regulatory information") -+ raise -+ finally: -+ clear_regdom(hapd, dev) -diff --git a/tests/hwsim/wpasupplicant.py b/tests/hwsim/wpasupplicant.py -index 160aa3e2df88..2aacbe046ecb 100644 ---- a/tests/hwsim/wpasupplicant.py -+++ b/tests/hwsim/wpasupplicant.py -@@ -1092,7 +1092,7 @@ class WpaSupplicant: - "wep_tx_keyidx", "scan_freq", "freq_list", "eap", - "eapol_flags", "fragment_size", "scan_ssid", "auth_alg", - "wpa_ptk_rekey", "disable_ht", "disable_vht", "bssid", -- "disable_he", -+ "disable_he", "disable_eht", - "disable_max_amsdu", "ampdu_factor", "ampdu_density", - "disable_ht40", "disable_sgi", "disable_ldpc", - "ht40_intolerant", "update_identifier", "mac_addr", --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q01-002-mbssid-retrieve-driver-capabilities.patch b/feeds/ipq95xx/hostapd/patches/q01-002-mbssid-retrieve-driver-capabilities.patch deleted file mode 100644 index 799bc83f..00000000 --- a/feeds/ipq95xx/hostapd/patches/q01-002-mbssid-retrieve-driver-capabilities.patch +++ /dev/null @@ -1,56 +0,0 @@ -From c35d82bffc9f5fe96d78b3817f20201c57a2248c Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Wed, 22 Sep 2021 17:00:05 -0700 -Subject: [PATCH 02/15] mbssid: retrieve driver capabilities - -Retrieve driver capabilities for maximum number of interfaces for -MBSSID and maximum allowed profile periodicity for enhanced MBSSID -advertisements. - -Signed-off-by: Aloka Dixit ---- - hostapd/main.c | 3 +++ - src/ap/hostapd.h | 5 +++++ - src/drivers/driver.h | 5 +++++ - 3 files changed, 13 insertions(+) - ---- a/hostapd/main.c -+++ b/hostapd/main.c -@@ -253,6 +253,9 @@ static int hostapd_driver_init(struct ho - wpa_printf(MSG_ERROR, "set_wowlan failed"); - } - os_free(triggs); -+ -+ iface->mbssid_max_interfaces = capa.mbssid_max_interfaces; -+ iface->ema_max_periodicity = capa.ema_max_periodicity; - } - - return 0; ---- a/src/ap/hostapd.h -+++ b/src/ap/hostapd.h -@@ -612,6 +612,11 @@ struct hostapd_iface { - /* Previous WMM element information */ - struct hostapd_wmm_ac_params prev_wmm[WMM_AC_NUM]; - -+ /* Maximum number of interfaces supported for MBSSID advertisements */ -+ u8 mbssid_max_interfaces; -+ /* Maximum profile periodicity for enhanced MBSSID advertisements */ -+ u8 ema_max_periodicity; -+ - int (*enable_iface_cb)(struct hostapd_iface *iface); - int (*disable_iface_cb)(struct hostapd_iface *iface); - }; ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -2185,6 +2185,11 @@ struct wpa_driver_capa { - - /* Maximum number of supported CSA counters */ - u16 max_csa_counters; -+ -+ /* Maximum number of interfaces supported for MBSSID advertisements */ -+ u8 mbssid_max_interfaces; -+ /* Maximum profile periodicity for enhanced MBSSID advertisements */ -+ u8 ema_max_periodicity; - }; - - diff --git a/feeds/ipq95xx/hostapd/patches/q01-003-mbssid-configure-all-BSSes-before-beacon-setup.patch b/feeds/ipq95xx/hostapd/patches/q01-003-mbssid-configure-all-BSSes-before-beacon-setup.patch deleted file mode 100644 index 36becfd6..00000000 --- a/feeds/ipq95xx/hostapd/patches/q01-003-mbssid-configure-all-BSSes-before-beacon-setup.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 278ab7c6660beeb657a088736bc28fbb63ee296d Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Fri, 10 Sep 2021 15:02:05 -0700 -Subject: [PATCH 03/15] mbssid: configure all BSSes before beacon setup - -With existing design, the transmitted beacon is set before RSN -information element is formed for any nontransmitted profile hence the -beacon has these profiles with open encryption. -It also sets wrong DTIM period, profile periodicity values until all -non-transmitting BSSes are up. - -Retrieve configurations for all nontransmitted profiles before setting -the beacon to ensures that beacons reflect correct information. - -Signed-off-by: Aloka Dixit ---- - src/ap/hostapd.c | 93 +++++++++++++++++++++++++++++++++--------------- - 1 file changed, 65 insertions(+), 28 deletions(-) - -Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/hostapd.c -+++ hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.c -@@ -1131,6 +1131,47 @@ static int db_table_create_radius_attrib - - #endif /* CONFIG_NO_RADIUS */ - -+static int hostapd_set_beacon(struct hostapd_data *hapd) -+{ -+ struct hostapd_bss_config *conf = hapd->conf; -+ int flush_old_stations = 1; -+ -+#ifdef CONFIG_MESH -+ if ((hapd->conf->mesh & MESH_ENABLED) && hapd->iface->mconf == NULL) -+ flush_old_stations = 0; -+#endif /* CONFIG_MESH */ -+ -+ if (!conf->start_disabled && ieee802_11_set_beacon(hapd) < 0) -+ return -1; -+ -+ if (flush_old_stations && !conf->start_disabled && -+ conf->broadcast_deauth) { -+ u8 addr[ETH_ALEN]; -+ -+ /* Should any previously associated STA not have noticed that -+ * the AP had stopped and restarted, send one more -+ * deauthentication notification now that the AP is ready to -+ * operate. -+ */ -+ wpa_dbg(hapd->msg_ctx, MSG_DEBUG, -+ "Deauthenticate all stations at BSS start"); -+ os_memset(addr, 0xff, ETH_ALEN); -+ hostapd_drv_sta_deauth(hapd, addr, -+ WLAN_REASON_PREV_AUTH_NOT_VALID); -+ } -+ -+ if (hapd->wpa_auth && wpa_init_keys(hapd->wpa_auth) < 0) -+ return -1; -+ -+ if (hapd->driver && hapd->driver->set_operstate) -+ hapd->driver->set_operstate(hapd->drv_priv, 1); -+ -+ hostapd_ubus_add_bss(hapd); -+ hostapd_ucode_add_bss(hapd); -+ -+ return 0; -+} -+ - - /** - * hostapd_setup_bss - Per-BSS setup (initialization) -@@ -1432,32 +1473,8 @@ int hostapd_setup_bss(struct hostapd_dat - return -1; - } - -- if (!conf->start_disabled && ieee802_11_set_beacon(hapd) < 0) -- return -1; -- -- if (flush_old_stations && !conf->start_disabled && -- conf->broadcast_deauth) { -- u8 addr[ETH_ALEN]; -- -- /* Should any previously associated STA not have noticed that -- * the AP had stopped and restarted, send one more -- * deauthentication notification now that the AP is ready to -- * operate. */ -- wpa_dbg(hapd->msg_ctx, MSG_DEBUG, -- "Deauthenticate all stations at BSS start"); -- os_memset(addr, 0xff, ETH_ALEN); -- hostapd_drv_sta_deauth(hapd, addr, -- WLAN_REASON_PREV_AUTH_NOT_VALID); -- } -- -- if (hapd->wpa_auth && wpa_init_keys(hapd->wpa_auth) < 0) -- return -1; -- -- if (hapd->driver && hapd->driver->set_operstate) -- hapd->driver->set_operstate(hapd->drv_priv, 1); -- -- hostapd_ubus_add_bss(hapd); -- hostapd_ucode_add_bss(hapd); -+ if (set_beacon) -+ return hostapd_set_beacon(hapd); - - return 0; - } -@@ -2169,7 +2186,7 @@ static int hostapd_setup_interface_compl - hapd = iface->bss[j]; - if (j) - os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN); -- if (hostapd_setup_bss(hapd, j == 0, true)) { -+ if (hostapd_setup_bss(hapd, j == 0, (hapd->iconf->mbssid? 0 : 1))) { - for (;;) { - hapd = iface->bss[j]; - hostapd_bss_deinit_no_free(hapd); -@@ -2183,6 +2200,24 @@ static int hostapd_setup_interface_compl - if (is_zero_ether_addr(hapd->conf->bssid)) - prev_addr = hapd->own_addr; - } -+ -+ if (hapd->iconf->mbssid) { -+ for (j = 0; j < iface->num_bss; j++) { -+ hapd = iface->bss[j]; -+ if (hostapd_set_beacon(hapd)) { -+ for (;;) { -+ hapd = iface->bss[j]; -+ hostapd_bss_deinit_no_free(hapd); -+ hostapd_free_hapd_data(hapd); -+ if (j == 0) -+ break; -+ j--; -+ } -+ goto fail; -+ } -+ } -+ } -+ - hapd = iface->bss[0]; - - hostapd_tx_queue_params(iface); diff --git a/feeds/ipq95xx/hostapd/patches/q01-004-mbssid-get-and-set-configuration-parameters.patch b/feeds/ipq95xx/hostapd/patches/q01-004-mbssid-get-and-set-configuration-parameters.patch deleted file mode 100644 index 0bb77db9..00000000 --- a/feeds/ipq95xx/hostapd/patches/q01-004-mbssid-get-and-set-configuration-parameters.patch +++ /dev/null @@ -1,161 +0,0 @@ -From b5ab26896c423a8bf7761552018ce5e399dc6b6b Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 10 Sep 2021 14:48:07 -0700 -Subject: [PATCH 04/15] mbssid: get and set configuration parameters - -Add helper functions to retrieve the context for the transmitting -interfaces of the MBSSID set and the index of a given BSS. - -Set device parameters - BSS index, transmitting BSS and -total number of BSS in the MBSSID set. - -Signed-off-by: John Crispin -Signed-off-by: Aloka Dixit ---- - src/ap/beacon.c | 36 ++++++++++++++++++++++++++++++++++-- - src/ap/hostapd.c | 23 +++++++++++++++++++++++ - src/ap/hostapd.h | 2 ++ - src/drivers/driver.h | 15 +++++++++++++++ - 4 files changed, 74 insertions(+), 2 deletions(-) - ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -459,6 +459,33 @@ static u8 * hostapd_eid_supported_op_cla - } - - -+static int hostapd_set_mbssid_beacon(struct hostapd_data *hapd, -+ struct wpa_driver_ap_params *params) -+{ -+ struct hostapd_iface *iface = hapd->iface; -+ -+ if (!iface->conf->mbssid || iface->num_bss == 1) -+ return 0; -+ -+ if (!iface->mbssid_max_interfaces) { -+ wpa_printf(MSG_ERROR, "MBSSID: Driver doesn't support " -+ "multi-BSSID advertisements"); -+ return -1; -+ } else if (iface->num_bss > iface->mbssid_max_interfaces) { -+ wpa_printf(MSG_ERROR, "MBSSID: Driver supports maximum %u " -+ "interfaces for multi-BSSID advertisements", -+ iface->mbssid_max_interfaces); -+ return -1; -+ } -+ -+ params->mbssid_tx_iface = hostapd_mbssid_get_tx_bss(hapd)->conf->iface; -+ params->mbssid_index = hostapd_mbssid_get_bss_index(hapd); -+ params->mbssid_count = iface->num_bss; -+ -+ return 0; -+} -+ -+ - static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, - const struct ieee80211_mgmt *req, - int is_p2p, size_t *resp_len) -@@ -1203,7 +1230,6 @@ static u8 * hostapd_probe_resp_offloads( - /* Generate a Probe Response template for the non-P2P case */ - return hostapd_gen_probe_resp(hapd, NULL, 0, resp_len); - } -- - #endif /* NEED_AP_MLME */ - - -@@ -1498,7 +1524,11 @@ int ieee802_11_build_ap_params(struct ho - #ifdef NEED_AP_MLME - u16 capab_info; - u8 *pos, *tailpos, *tailend, *csa_pos; -+#endif /* NEED_AP_MLME */ -+ -+ os_memset(params, 0, sizeof(*params)); - -+#ifdef NEED_AP_MLME - #define BEACON_HEAD_BUF_SIZE 256 - #define BEACON_TAIL_BUF_SIZE 512 - head = os_zalloc(BEACON_HEAD_BUF_SIZE); -@@ -1632,6 +1662,9 @@ int ieee802_11_build_ap_params(struct ho - tailpos = hostapd_eid_ht_capabilities(hapd, tailpos); - tailpos = hostapd_eid_ht_operation(hapd, tailpos); - -+ if (hostapd_set_mbssid_beacon(hapd, params)) -+ return -1; -+ - tailpos = hostapd_eid_ext_capab(hapd, tailpos); - - /* -@@ -1743,7 +1776,6 @@ int ieee802_11_build_ap_params(struct ho - resp = hostapd_probe_resp_offloads(hapd, &resp_len); - #endif /* NEED_AP_MLME */ - -- os_memset(params, 0, sizeof(*params)); - params->head = (u8 *) head; - params->head_len = head_len; - params->tail = tail; ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -89,6 +89,29 @@ int hostapd_for_each_interface(struct ha - } - - -+struct hostapd_data * hostapd_mbssid_get_tx_bss(struct hostapd_data *hapd) -+{ -+ if (hapd->iconf->mbssid) -+ return hapd->iface->bss[0]; -+ -+ return hapd; -+} -+ -+ -+int hostapd_mbssid_get_bss_index(struct hostapd_data *hapd) -+{ -+ if (hapd->iconf->mbssid) { -+ size_t i; -+ -+ for (i = 1; i < hapd->iface->num_bss; i++) -+ if (hapd->iface->bss[i] == hapd) -+ return i; -+ } -+ -+ return 0; -+} -+ -+ - void hostapd_reconfig_encryption(struct hostapd_data *hapd) - { - if (hapd->wpa_auth) ---- a/src/ap/hostapd.h -+++ b/src/ap/hostapd.h -@@ -714,6 +714,8 @@ struct hostapd_data * hostapd_get_iface( - void hostapd_event_sta_opmode_changed(struct hostapd_data *hapd, const u8 *addr, - enum smps_mode smps_mode, - enum chan_width chan_width, u8 rx_nss); -+struct hostapd_data * hostapd_mbssid_get_tx_bss(struct hostapd_data *hapd); -+int hostapd_mbssid_get_bss_index(struct hostapd_data *hapd); - - #ifdef CONFIG_FST - void fst_hostapd_fill_iface_obj(struct hostapd_data *hapd, ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -1627,6 +1627,21 @@ struct wpa_driver_ap_params { - * 2 = BURST beacon tx mode - */ - int beacon_tx_mode; -+ -+ /** -+ * mbssid_tx_iface - Transmitting interface of the set -+ */ -+ const char *mbssid_tx_iface; -+ -+ /** -+ * mbssid_index - The index of this BSS in the group -+ */ -+ unsigned int mbssid_index; -+ -+ /** -+ * mbssid_count - Total number of BSSs in the group -+ */ -+ unsigned int mbssid_count; - }; - - struct wpa_driver_mesh_bss_params { diff --git a/feeds/ipq95xx/hostapd/patches/q01-005-mbssid-add-multiple-BSSID-elements.patch b/feeds/ipq95xx/hostapd/patches/q01-005-mbssid-add-multiple-BSSID-elements.patch deleted file mode 100644 index 575f6cb5..00000000 --- a/feeds/ipq95xx/hostapd/patches/q01-005-mbssid-add-multiple-BSSID-elements.patch +++ /dev/null @@ -1,450 +0,0 @@ -From 78dcbdbbf8a5ab304b72b7c967f6618642d4f78e Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 10 Sep 2021 14:56:37 -0700 -Subject: [PATCH 05/15] mbssid: add multiple BSSID elements - -Add data as per IEEE Std 802.11-2020 9.4.2.45 Multiple BSSID element. -Include this element in beacons and probe response frames when mbssid -is enabled. Split the BSSes into multiple elements if the data -does not fit in 255 bytes allowed for a single element. - -Add support for enhanced multiple BSSID advertisements (EMA) by -sending offsets to the start of each MBSSID element to nl80211. -Mac80211 generates different EMA beacons by including only one -multiple BSSID element in each beacon frame. - -Signed-off-by: John Crispin -Signed-off-by: Aloka Dixit ---- - src/ap/beacon.c | 67 ++++++++++- - src/ap/ieee802_11.c | 212 +++++++++++++++++++++++++++++++++++ - src/ap/ieee802_11.h | 5 +- - src/common/ieee802_11_defs.h | 2 + - src/drivers/driver.h | 27 +++++ - 5 files changed, 309 insertions(+), 4 deletions(-) - ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -463,6 +463,9 @@ static int hostapd_set_mbssid_beacon(str - struct wpa_driver_ap_params *params) - { - struct hostapd_iface *iface = hapd->iface; -+ struct hostapd_data *tx_bss; -+ size_t len; -+ u8 num_mbssid = 0, *end; - - if (!iface->conf->mbssid || iface->num_bss == 1) - return 0; -@@ -478,10 +481,55 @@ static int hostapd_set_mbssid_beacon(str - return -1; - } - -- params->mbssid_tx_iface = hostapd_mbssid_get_tx_bss(hapd)->conf->iface; -+ tx_bss = hostapd_mbssid_get_tx_bss(hapd); -+ params->mbssid_tx_iface = tx_bss->conf->iface; - params->mbssid_index = hostapd_mbssid_get_bss_index(hapd); - params->mbssid_count = iface->num_bss; - -+ len = hostapd_eid_mbssid_len(tx_bss, WLAN_FC_STYPE_BEACON, &num_mbssid); -+ if (hapd->iconf->ema) { -+ if (!iface->ema_max_periodicity) { -+ wpa_printf(MSG_WARNING, "MBSSID: Driver doesn't support" -+ " enhanced multiple BSSID advertisements"); -+ return -1; -+ } -+ if (num_mbssid > iface->ema_max_periodicity) { -+ wpa_printf(MSG_WARNING, "MBSSID: Driver supports " -+ "maximum %u EMA profile periodicity", -+ iface->ema_max_periodicity); -+ return -1; -+ } -+ params->ema = 1; -+ } -+ -+ if (hapd != tx_bss || !num_mbssid) -+ return 0; -+ -+ params->mbssid_elem_count = num_mbssid; -+ params->mbssid_elem = os_zalloc(len); -+ if (!params->mbssid_elem) { -+ wpa_printf(MSG_ERROR, "Memory allocation failed for multiple " -+ "BSSID elements"); -+ return -1; -+ } -+ -+ params->mbssid_elem_offset = os_zalloc(params->mbssid_elem_count * -+ sizeof(u8 *)); -+ if (!params->mbssid_elem_offset) { -+ wpa_printf(MSG_ERROR, "MBSSID: Memory allocation failed for " -+ "multiple BSSID element offsets"); -+ os_free(params->mbssid_elem); -+ params->mbssid_elem = NULL; -+ return -1; -+ } -+ -+ end = hostapd_eid_mbssid(tx_bss, params->mbssid_elem, -+ params->mbssid_elem + len, -+ WLAN_FC_STYPE_BEACON, -+ params->mbssid_elem_count, -+ params->mbssid_elem_offset); -+ params->mbssid_elem_len = end - params->mbssid_elem; -+ - return 0; - } - -@@ -494,8 +542,11 @@ static u8 * hostapd_gen_probe_resp(struc - u8 *pos, *epos, *csa_pos; - size_t buflen; - -+ hapd = hostapd_mbssid_get_tx_bss(hapd); -+ - #define MAX_PROBERESP_LEN 768 - buflen = MAX_PROBERESP_LEN; -+ - #ifdef CONFIG_WPS - if (hapd->wps_probe_resp_ie) - buflen += wpabuf_len(hapd->wps_probe_resp_ie); -@@ -532,6 +583,7 @@ static u8 * hostapd_gen_probe_resp(struc - } - #endif /* CONFIG_IEEE80211AX */ - -+ buflen += hostapd_eid_mbssid_len(hapd, WLAN_FC_STYPE_PROBE_RESP, NULL); - buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP); - buflen += hostapd_mbo_ie_len(hapd); - buflen += hostapd_eid_owe_trans_len(hapd); -@@ -600,6 +652,8 @@ static u8 * hostapd_gen_probe_resp(struc - pos = hostapd_eid_supported_op_classes(hapd, pos); - pos = hostapd_eid_ht_capabilities(hapd, pos); - pos = hostapd_eid_ht_operation(hapd, pos); -+ pos = hostapd_eid_mbssid(hapd, pos, epos, WLAN_FC_STYPE_PROBE_RESP, 0, -+ NULL); - - pos = hostapd_eid_ext_capab(hapd, pos); - -@@ -1155,6 +1209,9 @@ void handle_probe_req(struct hostapd_dat - } - #endif /* CONFIG_TESTING_OPTIONS */ - -+ if (hapd != hostapd_mbssid_get_tx_bss(hapd) && res != EXACT_SSID_MATCH) -+ return; -+ - wpa_msg_ctrl(hapd->msg_ctx, MSG_INFO, RX_PROBE_REQUEST "sa=" MACSTR - " signal=%d", MAC2STR(mgmt->sa), ssi_signal); - -@@ -1181,7 +1238,8 @@ void handle_probe_req(struct hostapd_dat - hapd->cs_c_off_ecsa_proberesp; - } - -- ret = hostapd_drv_send_mlme(hapd, resp, resp_len, noack, -+ ret = hostapd_drv_send_mlme(hostapd_mbssid_get_tx_bss(hapd), resp, -+ resp_len, noack, - csa_offs_len ? csa_offs : NULL, - csa_offs_len, 0); - -@@ -1661,7 +1719,6 @@ int ieee802_11_build_ap_params(struct ho - tailpos = hostapd_eid_supported_op_classes(hapd, tailpos); - tailpos = hostapd_eid_ht_capabilities(hapd, tailpos); - tailpos = hostapd_eid_ht_operation(hapd, tailpos); -- - if (hostapd_set_mbssid_beacon(hapd, params)) - return -1; - -@@ -1880,6 +1937,10 @@ void ieee802_11_free_ap_params(struct wp - params->head = NULL; - os_free(params->proberesp); - params->proberesp = NULL; -+ os_free(params->mbssid_elem); -+ params->mbssid_elem = NULL; -+ os_free(params->mbssid_elem_offset); -+ params->mbssid_elem_offset = NULL; - #ifdef CONFIG_FILS - os_free(params->fd_frame_tmpl); - params->fd_frame_tmpl = NULL; ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -3974,6 +3974,23 @@ static void handle_auth(struct hostapd_d - } - - -+u8 hostapd_max_bssid_indicator(struct hostapd_data *hapd) -+{ -+ size_t num_bss_nontx; -+ u8 max_bssid_ind = 0; -+ -+ if (!hapd->iconf->mbssid || hapd->iface->num_bss <= 1) -+ return 0; -+ -+ num_bss_nontx = hapd->iface->num_bss - 1; -+ while (num_bss_nontx > 0) { -+ max_bssid_ind++; -+ num_bss_nontx >>= 1; -+ } -+ return max_bssid_ind; -+} -+ -+ - int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta) - { - int i, j = 32, aid; -@@ -7667,4 +7684,199 @@ u8 * hostapd_eid_rnr(struct hostapd_data - return eid; - } - -+ -+static size_t hostapd_eid_mbssid_elem_len(struct hostapd_data *hapd, -+ u32 frame_type, size_t *bss_index) -+{ -+ size_t len = 3, i; -+ -+ for (i = *bss_index; i < hapd->iface->num_bss; i++) { -+ struct hostapd_data *bss = hapd->iface->bss[i]; -+ const u8 *auth, *rsn, *rsnx; -+ size_t nontx_profile_len, auth_len; -+ -+ if (!bss || !bss->conf || !bss->started) -+ continue; -+ -+ /* -+ * Sublement ID: 1 byte -+ * Length: 1 byte -+ * Nontransmitted capabilities: 4 bytes -+ * SSID element: 2 + variable -+ * Multiple BSSID Index Element: 3 bytes (+2 bytes in beacons) -+ * Fixed length = 1 + 1 + 4 + 2 + 3 = 11 -+ */ -+ nontx_profile_len = 11 + bss->conf->ssid.ssid_len; -+ -+ if (frame_type == WLAN_FC_STYPE_BEACON) -+ nontx_profile_len += 2; -+ -+ auth = wpa_auth_get_wpa_ie(bss->wpa_auth, &auth_len); -+ if (auth) { -+ rsn = get_ie(auth, auth_len, WLAN_EID_RSN); -+ if (rsn) -+ nontx_profile_len += (2 + rsn[1]); -+ -+ rsnx = get_ie(auth, auth_len, WLAN_EID_RSNX); -+ if (rsnx) -+ nontx_profile_len += (2 + rsnx[1]); -+ } -+ -+ if ((len + nontx_profile_len) > 255) -+ goto mbssid_too_big; -+ -+ len += nontx_profile_len; -+ } -+ -+mbssid_too_big: -+ *bss_index = i; -+ return len; -+} -+ -+ -+size_t hostapd_eid_mbssid_len(struct hostapd_data *hapd, u32 frame_type, -+ u8 *elem_count) -+{ -+ size_t len = 0, bss_index = 1; -+ -+ if (!hapd->iconf->mbssid || hapd->iface->num_bss <= 1 || -+ (frame_type != WLAN_FC_STYPE_BEACON && -+ frame_type != WLAN_FC_STYPE_PROBE_RESP)) -+ return 0; -+ -+ if (frame_type == WLAN_FC_STYPE_BEACON) { -+ if (!elem_count) { -+ wpa_printf(MSG_ERROR, "MBSSID: Insufficient data for " -+ "beacons"); -+ return 0; -+ } -+ *elem_count = 0; -+ } -+ -+ while (bss_index < hapd->iface->num_bss) { -+ len += hostapd_eid_mbssid_elem_len(hapd, frame_type, -+ &bss_index); -+ -+ if (frame_type == WLAN_FC_STYPE_BEACON) -+ *elem_count += 1; -+ } -+ return len; -+} -+ -+ -+static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end, -+ u32 frame_type, u8 max_bssid_indicator, -+ size_t *bss_index) -+{ -+ size_t i; -+ u8 *eid_len_offset, *max_bssid_indicator_offset; -+ -+ *eid++ = WLAN_EID_MULTIPLE_BSSID; -+ eid_len_offset = eid++; -+ max_bssid_indicator_offset = eid++; -+ -+ for (i = *bss_index; i < hapd->iface->num_bss; i++) { -+ struct hostapd_data *bss = hapd->iface->bss[i]; -+ struct hostapd_bss_config *conf; -+ u8 *eid_len_pos, *nontx_bss_start = eid; -+ const u8 *auth, *rsn, *rsnx; -+ size_t auth_len = 0; -+ u16 capab_info; -+ -+ if (!bss || !bss->conf || !bss->started) -+ continue; -+ conf = bss->conf; -+ -+ *eid++ = WLAN_EID_SUBELEMENT_NONTRANSMITTED_BSSID_PROFILE; -+ eid_len_pos = eid++; -+ -+ *eid++ = WLAN_EID_NONTRANSMITTED_BSSID_CAPA; -+ *eid++ = sizeof(capab_info); -+ capab_info = host_to_le16(hostapd_own_capab_info(bss)); -+ os_memcpy(eid, (const void *)&capab_info, sizeof(capab_info)); -+ eid += sizeof(capab_info); -+ -+ *eid++ = WLAN_EID_SSID; -+ *eid++ = conf->ssid.ssid_len; -+ os_memcpy(eid, conf->ssid.ssid, conf->ssid.ssid_len); -+ eid += conf->ssid.ssid_len; -+ -+ *eid++ = WLAN_EID_MULTIPLE_BSSID_INDEX; -+ if (frame_type == WLAN_FC_STYPE_BEACON) { -+ *eid++ = 3; -+ *eid++ = i; -+ *eid++ = conf->dtim_period; -+ *eid++ = 0xFF; -+ } else { -+ *eid++ = 1; -+ *eid++ = i; -+ } -+ -+ auth = wpa_auth_get_wpa_ie(bss->wpa_auth, &auth_len); -+ if (auth) { -+ rsn = get_ie(auth, auth_len, WLAN_EID_RSN); -+ if (rsn) { -+ os_memcpy(eid, rsn, 2 + rsn[1]); -+ eid += (2 + rsn[1]); -+ } -+ -+ rsnx = get_ie(auth, auth_len, WLAN_EID_RSNX); -+ if (rsnx) { -+ os_memcpy(eid, rsnx, 2 + rsnx[1]); -+ eid += (2 + rsnx[1]); -+ } -+ } -+ -+ *eid_len_pos = (eid - eid_len_pos) - 1; -+ -+ if (((eid - eid_len_offset) - 1) > 255) { -+ eid = nontx_bss_start; -+ goto mbssid_too_big; -+ } -+ } -+ -+mbssid_too_big: -+ *bss_index = i; -+ *max_bssid_indicator_offset = max_bssid_indicator; -+ if (*max_bssid_indicator_offset < 1) -+ *max_bssid_indicator_offset = 1; -+ *eid_len_offset = (eid - eid_len_offset) - 1; -+ return eid; -+} -+ -+ -+u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end, -+ u32 frame_type, u8 elem_count, u8 **elem_offset) -+{ -+ size_t bss_index = 1; -+ u8 elem_index = 0; -+ -+ if (!hapd->iconf->mbssid || hapd->iface->num_bss <= 1 || -+ (frame_type != WLAN_FC_STYPE_BEACON && -+ frame_type != WLAN_FC_STYPE_PROBE_RESP)) -+ return eid; -+ -+ if (frame_type == WLAN_FC_STYPE_BEACON && !elem_offset) { -+ wpa_printf(MSG_ERROR, "MBSSID: Insufficient data for beacons"); -+ return eid; -+ } -+ -+ while (bss_index < hapd->iface->num_bss) { -+ if (frame_type == WLAN_FC_STYPE_BEACON) { -+ if (elem_index == elem_count) { -+ wpa_printf(MSG_WARNING, "MBSSID: More number of" -+ " elements than provided array"); -+ break; -+ } -+ -+ elem_offset[elem_index] = eid; -+ elem_index = elem_index + 1; -+ } -+ eid = hostapd_eid_mbssid_elem(hapd, eid, end, frame_type, -+ hostapd_max_bssid_indicator(hapd), -+ &bss_index); -+ } -+ return eid; -+} -+ - #endif /* CONFIG_NATIVE_WINDOWS */ ---- a/src/ap/ieee802_11.h -+++ b/src/ap/ieee802_11.h -@@ -129,8 +129,11 @@ u8 * hostapd_eid_time_zone(struct hostap - int hostapd_update_time_adv(struct hostapd_data *hapd); - void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr); - u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid); -- - int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta); -+size_t hostapd_eid_mbssid_len(struct hostapd_data *hapd, u32 frame_type, -+ u8 *elem_count); -+u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end, -+ u32 frame_type, u8 elem_count, u8 **elem_offset); - #ifdef CONFIG_SAE - void sae_clear_retransmit_timer(struct hostapd_data *hapd, - struct sta_info *sta); ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -491,6 +491,8 @@ - #define WLAN_EID_EXT_ANTI_CLOGGING_TOKEN 93 - #define WLAN_EID_EXT_PASN_PARAMS 100 - -+#define WLAN_EID_SUBELEMENT_NONTRANSMITTED_BSSID_PROFILE 0 -+ - /* Operating Triplet can be any integer >= 201 - * From IEEE P802.11-REVmd/D4.0: The first octet in each Subband - * Triplet field or Operating Triplet field contains an unsigned ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -1642,6 +1642,33 @@ struct wpa_driver_ap_params { - * mbssid_count - Total number of BSSs in the group - */ - unsigned int mbssid_count; -+ -+ /** -+ * mbssid_elem - Buffer containing all multiple BSSID elements -+ */ -+ u8 *mbssid_elem; -+ -+ /** -+ * mbssid_elem_len - Total length of all multiple BSSID elements -+ */ -+ size_t mbssid_elem_len; -+ -+ /** -+ * mbssid_elem_count - The number of multiple bssid elements -+ */ -+ u8 mbssid_elem_count; -+ -+ /** -+ * mbssid_elem_offset - Offsets to elements in mbssid_elem. -+ * Kernel will use these offsets to generate multiple BSSID beacons. -+ */ -+ u8 **mbssid_elem_offset; -+ -+ /** -+ * ema - Enhanced multi-bssid advertisements support. -+ */ -+ u8 ema; -+ - }; - - struct wpa_driver_mesh_bss_params { diff --git a/feeds/ipq95xx/hostapd/patches/q01-006-mbssid-add-MBSSID-configuration-element.patch b/feeds/ipq95xx/hostapd/patches/q01-006-mbssid-add-MBSSID-configuration-element.patch deleted file mode 100644 index 8bf85416..00000000 --- a/feeds/ipq95xx/hostapd/patches/q01-006-mbssid-add-MBSSID-configuration-element.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 23a89229c9aa2b833d9aa2db163f0b56d913b9bb Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Fri, 10 Sep 2021 16:31:14 -0700 -Subject: [PATCH 06/15] mbssid: add MBSSID configuration element - -Add data as per IEEE Std 802.11ax-2021 9.4.2.260 Multiple BSSID -Configuration element when enhanced multiple BSSID -advertisements (EMA) are enabled. -This element informs the clients about the EMA profile periodicity of -the multiple BSSID set. - -Co-developed-by: John Crispin -Signed-off-by: John Crispin -Signed-off-by: Aloka Dixit ---- - src/ap/beacon.c | 35 ++++++++++++++++++++++------------- - src/common/ieee802_11_defs.h | 1 + - 2 files changed, 23 insertions(+), 13 deletions(-) - ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -459,8 +459,9 @@ static u8 * hostapd_eid_supported_op_cla - } - - --static int hostapd_set_mbssid_beacon(struct hostapd_data *hapd, -- struct wpa_driver_ap_params *params) -+static u8 * hostapd_set_mbssid_beacon(struct hostapd_data *hapd, -+ struct wpa_driver_ap_params *params, -+ u8 *eid) - { - struct hostapd_iface *iface = hapd->iface; - struct hostapd_data *tx_bss; -@@ -468,17 +469,17 @@ static int hostapd_set_mbssid_beacon(str - u8 num_mbssid = 0, *end; - - if (!iface->conf->mbssid || iface->num_bss == 1) -- return 0; -+ return eid; - - if (!iface->mbssid_max_interfaces) { - wpa_printf(MSG_ERROR, "MBSSID: Driver doesn't support " - "multi-BSSID advertisements"); -- return -1; -+ return eid; - } else if (iface->num_bss > iface->mbssid_max_interfaces) { - wpa_printf(MSG_ERROR, "MBSSID: Driver supports maximum %u " - "interfaces for multi-BSSID advertisements", - iface->mbssid_max_interfaces); -- return -1; -+ return eid; - } - - tx_bss = hostapd_mbssid_get_tx_bss(hapd); -@@ -491,26 +492,26 @@ static int hostapd_set_mbssid_beacon(str - if (!iface->ema_max_periodicity) { - wpa_printf(MSG_WARNING, "MBSSID: Driver doesn't support" - " enhanced multiple BSSID advertisements"); -- return -1; -+ return eid; - } - if (num_mbssid > iface->ema_max_periodicity) { - wpa_printf(MSG_WARNING, "MBSSID: Driver supports " - "maximum %u EMA profile periodicity", - iface->ema_max_periodicity); -- return -1; -+ return eid; - } - params->ema = 1; - } - - if (hapd != tx_bss || !num_mbssid) -- return 0; -+ return eid; - - params->mbssid_elem_count = num_mbssid; - params->mbssid_elem = os_zalloc(len); - if (!params->mbssid_elem) { - wpa_printf(MSG_ERROR, "Memory allocation failed for multiple " - "BSSID elements"); -- return -1; -+ return eid; - } - - params->mbssid_elem_offset = os_zalloc(params->mbssid_elem_count * -@@ -520,7 +521,7 @@ static int hostapd_set_mbssid_beacon(str - "multiple BSSID element offsets"); - os_free(params->mbssid_elem); - params->mbssid_elem = NULL; -- return -1; -+ return eid; - } - - end = hostapd_eid_mbssid(tx_bss, params->mbssid_elem, -@@ -530,7 +531,14 @@ static int hostapd_set_mbssid_beacon(str - params->mbssid_elem_offset); - params->mbssid_elem_len = end - params->mbssid_elem; - -- return 0; -+ if (hapd->iconf->ema) { -+ *eid++ = WLAN_EID_EXTENSION; -+ *eid++ = 3; -+ *eid++ = WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION; -+ *eid++ = iface->num_bss; -+ *eid++ = params->mbssid_elem_count; -+ } -+ return eid; - } - - -@@ -1634,6 +1642,8 @@ int ieee802_11_build_ap_params(struct ho - } - #endif /* CONFIG_IEEE80211AX */ - -+ if (hapd->iconf->ema) -+ tail_len += 5; /* Multiple BSSID Configuration element */ - tail_len += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_BEACON); - tail_len += hostapd_mbo_ie_len(hapd); - tail_len += hostapd_eid_owe_trans_len(hapd); -@@ -1719,8 +1729,7 @@ int ieee802_11_build_ap_params(struct ho - tailpos = hostapd_eid_supported_op_classes(hapd, tailpos); - tailpos = hostapd_eid_ht_capabilities(hapd, tailpos); - tailpos = hostapd_eid_ht_operation(hapd, tailpos); -- if (hostapd_set_mbssid_beacon(hapd, params)) -- return -1; -+ tailpos = hostapd_set_mbssid_beacon(hapd, params, tailpos); - - tailpos = hostapd_eid_ext_capab(hapd, tailpos); - ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -481,6 +481,7 @@ - #define WLAN_EID_EXT_SPATIAL_REUSE 39 - #define WLAN_EID_EXT_COLOR_CHANGE_ANNOUNCEMENT 42 - #define WLAN_EID_EXT_OCV_OCI 54 -+#define WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION 55 - #define WLAN_EID_EXT_SHORT_SSID_LIST 58 - #define WLAN_EID_EXT_HE_6GHZ_BAND_CAP 59 - #define WLAN_EID_EXT_EDMG_CAPABILITIES 61 diff --git a/feeds/ipq95xx/hostapd/patches/q01-007-mbssid-add-non-inheritance-element.patch b/feeds/ipq95xx/hostapd/patches/q01-007-mbssid-add-non-inheritance-element.patch deleted file mode 100644 index 7a129487..00000000 --- a/feeds/ipq95xx/hostapd/patches/q01-007-mbssid-add-non-inheritance-element.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 20bb093c1a0555c365afabb1809c8edb7bde4178 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 10 Sep 2021 14:58:04 -0700 -Subject: [PATCH 07/15] mbssid: add non-inheritance element - -Add data as per IEEE Std 802.11-2020 9.4.2.240 Non-Inheritance element -if the transmitted profile is secured but non-transmitted profiles -use open security. - -Signed-off-by: John Crispin -Signed-off-by: Sowmiya Sree Elavalagan -Signed-off-by: Aloka Dixit ---- - src/ap/ieee802_11.c | 30 ++++++++++++++++++++++++++++-- - src/common/ieee802_11_defs.h | 1 + - 2 files changed, 29 insertions(+), 2 deletions(-) - ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -7688,12 +7688,14 @@ u8 * hostapd_eid_rnr(struct hostapd_data - static size_t hostapd_eid_mbssid_elem_len(struct hostapd_data *hapd, - u32 frame_type, size_t *bss_index) - { -+ struct hostapd_data *tx_bss = hostapd_mbssid_get_tx_bss(hapd); - size_t len = 3, i; - - for (i = *bss_index; i < hapd->iface->num_bss; i++) { - struct hostapd_data *bss = hapd->iface->bss[i]; -- const u8 *auth, *rsn, *rsnx; -+ const u8 *auth, *rsn = NULL, *rsnx = NULL; - size_t nontx_profile_len, auth_len; -+ u8 ie_count = 0; - - if (!bss || !bss->conf || !bss->started) - continue; -@@ -7721,6 +7723,12 @@ static size_t hostapd_eid_mbssid_elem_le - if (rsnx) - nontx_profile_len += (2 + rsnx[1]); - } -+ if (!rsn && hostapd_wpa_ie(tx_bss, WLAN_EID_RSN)) -+ ie_count++; -+ if (!rsnx && hostapd_wpa_ie(tx_bss, WLAN_EID_RSNX)) -+ ie_count++; -+ if (ie_count) -+ nontx_profile_len += (4 + ie_count); - - if ((len + nontx_profile_len) > 255) - goto mbssid_too_big; -@@ -7768,6 +7776,7 @@ static u8 * hostapd_eid_mbssid_elem(stru - u32 frame_type, u8 max_bssid_indicator, - size_t *bss_index) - { -+ struct hostapd_data *tx_bss = hostapd_mbssid_get_tx_bss(hapd); - size_t i; - u8 *eid_len_offset, *max_bssid_indicator_offset; - -@@ -7779,7 +7788,8 @@ static u8 * hostapd_eid_mbssid_elem(stru - struct hostapd_data *bss = hapd->iface->bss[i]; - struct hostapd_bss_config *conf; - u8 *eid_len_pos, *nontx_bss_start = eid; -- const u8 *auth, *rsn, *rsnx; -+ const u8 *auth, *rsn = NULL, *rsnx = NULL; -+ u8 ie_count = 0, non_inherit_ie[2]; - size_t auth_len = 0; - u16 capab_info; - -@@ -7826,6 +7836,22 @@ static u8 * hostapd_eid_mbssid_elem(stru - eid += (2 + rsnx[1]); - } - } -+ if (!rsn && hostapd_wpa_ie(tx_bss, WLAN_EID_RSN)) { -+ non_inherit_ie[ie_count] = WLAN_EID_RSN; -+ ie_count++; -+ } -+ if (!rsnx && hostapd_wpa_ie(tx_bss, WLAN_EID_RSNX)) { -+ non_inherit_ie[ie_count] = WLAN_EID_RSNX; -+ ie_count++; -+ } -+ if (ie_count) { -+ *eid++ = WLAN_EID_EXTENSION; -+ *eid++ = 2 + ie_count; -+ *eid++ = WLAN_EID_EXT_NON_INHERITANCE; -+ *eid++ = ie_count; -+ os_memcpy(eid, non_inherit_ie, ie_count); -+ eid += ie_count; -+ } - - *eid_len_pos = (eid - eid_len_pos) - 1; - ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -482,6 +482,7 @@ - #define WLAN_EID_EXT_COLOR_CHANGE_ANNOUNCEMENT 42 - #define WLAN_EID_EXT_OCV_OCI 54 - #define WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION 55 -+#define WLAN_EID_EXT_NON_INHERITANCE 56 - #define WLAN_EID_EXT_SHORT_SSID_LIST 58 - #define WLAN_EID_EXT_HE_6GHZ_BAND_CAP 59 - #define WLAN_EID_EXT_EDMG_CAPABILITIES 61 diff --git a/feeds/ipq95xx/hostapd/patches/q01-008-mbssid-make-the-AID-space-shared.patch b/feeds/ipq95xx/hostapd/patches/q01-008-mbssid-make-the-AID-space-shared.patch deleted file mode 100644 index 761efcb0..00000000 --- a/feeds/ipq95xx/hostapd/patches/q01-008-mbssid-make-the-AID-space-shared.patch +++ /dev/null @@ -1,29 +0,0 @@ -From efb94ba16134dd58b51a920c9a8a145459ee38ef Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 10 Sep 2021 14:58:14 -0700 -Subject: [PATCH 08/15] mbssid: make the AID space shared - -As described in IEEE Std 802.11-2020 11.1.3.8 Multiple BSSID procedure, -set the lowest AID value assigned to any client equal to 2^n, -where n is the maximum BSSID indicator of the MBSSID set. - -Signed-off-by: John Crispin -Signed-off-by: Aloka Dixit ---- - src/ap/ieee802_11.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -4016,7 +4016,10 @@ int hostapd_get_aid(struct hostapd_data - } - if (j == 32) - return -1; -- aid = i * 32 + j + 1; -+ aid = i * 32 + j; -+ -+ aid += (1 << hostapd_max_bssid_indicator(hapd)); -+ - if (aid > 2007) - return -1; - diff --git a/feeds/ipq95xx/hostapd/patches/q01-009-mbssid-set-extended-capabilities.patch b/feeds/ipq95xx/hostapd/patches/q01-009-mbssid-set-extended-capabilities.patch deleted file mode 100644 index ee4b58f2..00000000 --- a/feeds/ipq95xx/hostapd/patches/q01-009-mbssid-set-extended-capabilities.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 6167dad7647fca057215110b0f371a949f952fd0 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Fri, 10 Sep 2021 15:12:06 -0700 -Subject: [PATCH 09/15] mbssid: set extended capabilities - -Set extended capabilities as described in IEEE Std 802.11-2020 -section 9.4.2.26 Extended Capabilities element. - -Co-developed-by: John Crispin -Signed-off-by: John Crispin -Signed-off-by: Aloka Dixit ---- - src/ap/beacon.c | 38 ++++++++++++++++++++++++++++++++++++-- - 1 file changed, 36 insertions(+), 2 deletions(-) - -Index: b/src/ap/beacon.c -=================================================================== ---- a/src/ap/beacon.c 2022-10-17 02:00:55.052754218 +0530 -+++ b/src/ap/beacon.c 2022-10-17 02:02:21.956146621 +0530 -@@ -542,12 +542,41 @@ static u8 * hostapd_set_mbssid_beacon(st - } - - -+static u8 * hostapd_ext_capab_mbssid(struct hostapd_data *hapd, u8 *eid, -+ u8 *eid_ext_cap, u8 ema_periodicity) -+{ -+ size_t len; -+ -+ if (eid == eid_ext_cap) -+ return eid; -+ -+ len = eid_ext_cap[1]; -+ eid_ext_cap += 2; -+ -+ if (!hapd->iconf->mbssid && len >= 3) -+ eid_ext_cap[2] &= ~0x40; -+ -+ if (!hapd->iconf->ema && len >= 11) -+ eid_ext_cap[10] &= ~0x08; -+ -+ if (hapd->iconf->mbssid && ema_periodicity <= 1) { -+ while (len < 11) { -+ *eid++ = 0x00; -+ len++; -+ } -+ eid_ext_cap[10] |= 0x01; -+ } -+ -+ return eid; -+} -+ -+ - static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, - const struct ieee80211_mgmt *req, - int is_p2p, size_t *resp_len) - { - struct ieee80211_mgmt *resp; -- u8 *pos, *epos, *csa_pos; -+ u8 *pos, *epos, *csa_pos, *ext_cap_pos; - size_t buflen; - - hapd = hostapd_mbssid_get_tx_bss(hapd); -@@ -663,7 +692,10 @@ static u8 * hostapd_gen_probe_resp(struc - pos = hostapd_eid_mbssid(hapd, pos, epos, WLAN_FC_STYPE_PROBE_RESP, 0, - NULL); - -+ ext_cap_pos = pos; - pos = hostapd_eid_ext_capab(hapd, pos); -+ if (!is_6ghz_op_class(hapd->iconf->op_class)) -+ pos = hostapd_ext_capab_mbssid(hapd, pos, ext_cap_pos, 1); - - pos = hostapd_eid_time_adv(hapd, pos); - pos = hostapd_eid_time_zone(hapd, pos); -@@ -1589,7 +1621,7 @@ int ieee802_11_build_ap_params(struct ho - size_t resp_len = 0; - #ifdef NEED_AP_MLME - u16 capab_info; -- u8 *pos, *tailpos, *tailend, *csa_pos; -+ u8 *pos, *tailpos, *tailend, *csa_pos, *ext_cap_pos; - #endif /* NEED_AP_MLME */ - - os_memset(params, 0, sizeof(*params)); -@@ -1731,7 +1763,11 @@ int ieee802_11_build_ap_params(struct ho - tailpos = hostapd_eid_ht_operation(hapd, tailpos); - tailpos = hostapd_set_mbssid_beacon(hapd, params, tailpos); - -+ ext_cap_pos = tailpos; - tailpos = hostapd_eid_ext_capab(hapd, tailpos); -+ if (!is_6ghz_op_class(hapd->iconf->op_class)) -+ tailpos = hostapd_ext_capab_mbssid(hapd, tailpos, ext_cap_pos, -+ params->mbssid_elem_count); - - /* - * TODO: Time Advertisement element should only be included in some diff --git a/feeds/ipq95xx/hostapd/patches/q01-010-mbssid-DTIM-period-configuration-for-EMA-AP.patch b/feeds/ipq95xx/hostapd/patches/q01-010-mbssid-DTIM-period-configuration-for-EMA-AP.patch deleted file mode 100644 index dc360af3..00000000 --- a/feeds/ipq95xx/hostapd/patches/q01-010-mbssid-DTIM-period-configuration-for-EMA-AP.patch +++ /dev/null @@ -1,45 +0,0 @@ -From d8d604c6e7dcfae8aa51d16d1d0033b2d9e132e9 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Fri, 10 Sep 2021 14:59:32 -0700 -Subject: [PATCH 10/15] mbssid: DTIM period configuration for EMA AP - -Set the DTIM periods of non-transmitted profiles equal to the EMA -profile periodicity if those are not a multiple of the latter -already as recommended in IEEE P802.11ax/D8.0, October 2020, -Multiple BSSID configuration examples, AA.1 Introduction. - -Signed-off-by: Aloka Dixit ---- - src/ap/ieee802_11.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -7777,7 +7777,7 @@ size_t hostapd_eid_mbssid_len(struct hos - - static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end, - u32 frame_type, u8 max_bssid_indicator, -- size_t *bss_index) -+ size_t *bss_index, u8 elem_count) - { - struct hostapd_data *tx_bss = hostapd_mbssid_get_tx_bss(hapd); - size_t i; -@@ -7818,6 +7818,9 @@ static u8 * hostapd_eid_mbssid_elem(stru - if (frame_type == WLAN_FC_STYPE_BEACON) { - *eid++ = 3; - *eid++ = i; -+ if (hapd->iconf->ema && -+ (conf->dtim_period % elem_count)) -+ conf->dtim_period = elem_count; - *eid++ = conf->dtim_period; - *eid++ = 0xFF; - } else { -@@ -7903,7 +7906,7 @@ u8 * hostapd_eid_mbssid(struct hostapd_d - } - eid = hostapd_eid_mbssid_elem(hapd, eid, end, frame_type, - hostapd_max_bssid_indicator(hapd), -- &bss_index); -+ &bss_index, elem_count); - } - return eid; - } diff --git a/feeds/ipq95xx/hostapd/patches/q01-011-mbssid-hidden-SSID-support.patch b/feeds/ipq95xx/hostapd/patches/q01-011-mbssid-hidden-SSID-support.patch deleted file mode 100644 index 11d5a3fd..00000000 --- a/feeds/ipq95xx/hostapd/patches/q01-011-mbssid-hidden-SSID-support.patch +++ /dev/null @@ -1,118 +0,0 @@ -From e6ae627eb7370cbdbdf31a7d9a1b30d5586292c9 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Fri, 10 Sep 2021 15:04:43 -0700 -Subject: [PATCH 11/15] mbssid: hidden SSID support - -Hidden nontransmitted BSSID profiles will be included in the beacons -and probe responses but SSID value will be removed or set to all -zeros depending on the configured value of 'ignore_broadcast_ssid'. -If complete profiles are omitted, clients cannot stay connected to -the AP. -For unicast probe requests with SSID set to a hidden nontransmitted -BSS, complete SSID should be included in the response. - -Signed-off-by: Aloka Dixit -Signed-off-by: Sowmiya Sree Elavalagan ---- - src/ap/beacon.c | 25 +++++++++++++++++++------ - src/ap/ieee802_11.c | 24 +++++++++++++++++++----- - 2 files changed, 38 insertions(+), 11 deletions(-) - ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -578,6 +578,7 @@ static u8 * hostapd_gen_probe_resp(struc - struct ieee80211_mgmt *resp; - u8 *pos, *epos, *csa_pos, *ext_cap_pos; - size_t buflen; -+ struct hostapd_data *hapd_probed = hapd; - - hapd = hostapd_mbssid_get_tx_bss(hapd); - -@@ -620,7 +621,8 @@ static u8 * hostapd_gen_probe_resp(struc - } - #endif /* CONFIG_IEEE80211AX */ - -- buflen += hostapd_eid_mbssid_len(hapd, WLAN_FC_STYPE_PROBE_RESP, NULL); -+ buflen += hostapd_eid_mbssid_len(hapd_probed, WLAN_FC_STYPE_PROBE_RESP, -+ NULL); - buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP); - buflen += hostapd_mbo_ie_len(hapd); - buflen += hostapd_eid_owe_trans_len(hapd); -@@ -648,9 +650,20 @@ static u8 * hostapd_gen_probe_resp(struc - - pos = resp->u.probe_resp.variable; - *pos++ = WLAN_EID_SSID; -- *pos++ = hapd->conf->ssid.ssid_len; -- os_memcpy(pos, hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len); -- pos += hapd->conf->ssid.ssid_len; -+ if (hapd->conf->ignore_broadcast_ssid && hapd != hapd_probed) { -+ if (hapd->conf->ignore_broadcast_ssid == 2) { -+ *pos++ = hapd->conf->ssid.ssid_len; -+ os_memset(pos, 0, hapd->conf->ssid.ssid_len); -+ pos += hapd->conf->ssid.ssid_len; -+ } else { -+ *pos++ = 0; /* empty SSID */ -+ } -+ } else { -+ *pos++ = hapd->conf->ssid.ssid_len; -+ os_memcpy(pos, hapd->conf->ssid.ssid, -+ hapd->conf->ssid.ssid_len); -+ pos += hapd->conf->ssid.ssid_len; -+ } - - /* Supported rates */ - pos = hostapd_eid_supp_rates(hapd, pos); -@@ -689,8 +702,8 @@ static u8 * hostapd_gen_probe_resp(struc - pos = hostapd_eid_supported_op_classes(hapd, pos); - pos = hostapd_eid_ht_capabilities(hapd, pos); - pos = hostapd_eid_ht_operation(hapd, pos); -- pos = hostapd_eid_mbssid(hapd, pos, epos, WLAN_FC_STYPE_PROBE_RESP, 0, -- NULL); -+ pos = hostapd_eid_mbssid(hapd_probed, pos, epos, -+ WLAN_FC_STYPE_PROBE_RESP, 0, NULL); - - ext_cap_pos = pos; - pos = hostapd_eid_ext_capab(hapd, pos); ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -7707,11 +7707,16 @@ static size_t hostapd_eid_mbssid_elem_le - * Sublement ID: 1 byte - * Length: 1 byte - * Nontransmitted capabilities: 4 bytes -- * SSID element: 2 + variable -+ * SSID element: 2 + variable (except for hidden BSS) - * Multiple BSSID Index Element: 3 bytes (+2 bytes in beacons) - * Fixed length = 1 + 1 + 4 + 2 + 3 = 11 - */ -- nontx_profile_len = 11 + bss->conf->ssid.ssid_len; -+ nontx_profile_len = 11; -+ -+ if (!bss->conf->ignore_broadcast_ssid || -+ bss->conf->ignore_broadcast_ssid == 2 || -+ (frame_type == WLAN_FC_STYPE_PROBE_RESP && bss == hapd)) -+ nontx_profile_len += bss->conf->ssid.ssid_len; - - if (frame_type == WLAN_FC_STYPE_BEACON) - nontx_profile_len += 2; -@@ -7810,9 +7815,18 @@ static u8 * hostapd_eid_mbssid_elem(stru - eid += sizeof(capab_info); - - *eid++ = WLAN_EID_SSID; -- *eid++ = conf->ssid.ssid_len; -- os_memcpy(eid, conf->ssid.ssid, conf->ssid.ssid_len); -- eid += conf->ssid.ssid_len; -+ if (!conf->ignore_broadcast_ssid || -+ (frame_type == WLAN_FC_STYPE_PROBE_RESP && bss == hapd)) { -+ *eid++ = conf->ssid.ssid_len; -+ os_memcpy(eid, conf->ssid.ssid, conf->ssid.ssid_len); -+ eid += conf->ssid.ssid_len; -+ } else if (conf->ignore_broadcast_ssid == 2) { -+ *eid++ = conf->ssid.ssid_len; -+ os_memset(eid, 0, conf->ssid.ssid_len); -+ eid += conf->ssid.ssid_len; -+ } else { -+ *eid++ = 0; -+ } - - *eid++ = WLAN_EID_MULTIPLE_BSSID_INDEX; - if (frame_type == WLAN_FC_STYPE_BEACON) { diff --git a/feeds/ipq95xx/hostapd/patches/q01-012-mbssid-process-known-BSSID-element.patch b/feeds/ipq95xx/hostapd/patches/q01-012-mbssid-process-known-BSSID-element.patch deleted file mode 100644 index d2d44253..00000000 --- a/feeds/ipq95xx/hostapd/patches/q01-012-mbssid-process-known-BSSID-element.patch +++ /dev/null @@ -1,253 +0,0 @@ -From 7f24d44812413a9f05c1ed0fd4059f7461789d4a Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Fri, 10 Sep 2021 15:24:49 -0700 -Subject: [PATCH 12/15] mbssid: process known BSSID element - -Process the known BSSID elements if included by non-AP stations. -The format is described in IEEE Std 802.11ax-2021 9.4.2.261. - -Non-AP stations may include this element in directed probe requests -to indicate which of the multiple BSSIDs they have already discovered. -AP should exclude these profiles from the probe response. - -Signed-off-by: Aloka Dixit ---- - src/ap/beacon.c | 21 ++++++++++------- - src/ap/ieee802_11.c | 42 ++++++++++++++++++++++++++++------ - src/ap/ieee802_11.h | 6 +++-- - src/common/ieee802_11_common.c | 4 ++++ - src/common/ieee802_11_common.h | 2 ++ - src/common/ieee802_11_defs.h | 1 + - 6 files changed, 59 insertions(+), 17 deletions(-) - ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -487,7 +487,8 @@ static u8 * hostapd_set_mbssid_beacon(st - params->mbssid_index = hostapd_mbssid_get_bss_index(hapd); - params->mbssid_count = iface->num_bss; - -- len = hostapd_eid_mbssid_len(tx_bss, WLAN_FC_STYPE_BEACON, &num_mbssid); -+ len = hostapd_eid_mbssid_len(tx_bss, WLAN_FC_STYPE_BEACON, &num_mbssid, -+ NULL, 0); - if (hapd->iconf->ema) { - if (!iface->ema_max_periodicity) { - wpa_printf(MSG_WARNING, "MBSSID: Driver doesn't support" -@@ -528,7 +529,7 @@ static u8 * hostapd_set_mbssid_beacon(st - params->mbssid_elem + len, - WLAN_FC_STYPE_BEACON, - params->mbssid_elem_count, -- params->mbssid_elem_offset); -+ params->mbssid_elem_offset, NULL, 0); - params->mbssid_elem_len = end - params->mbssid_elem; - - if (hapd->iconf->ema) { -@@ -573,7 +574,8 @@ static u8 * hostapd_ext_capab_mbssid(str - - static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, - const struct ieee80211_mgmt *req, -- int is_p2p, size_t *resp_len) -+ int is_p2p, size_t *resp_len, -+ const u8 *known_bss, u8 known_bss_len) - { - struct ieee80211_mgmt *resp; - u8 *pos, *epos, *csa_pos, *ext_cap_pos; -@@ -622,7 +624,7 @@ static u8 * hostapd_gen_probe_resp(struc - #endif /* CONFIG_IEEE80211AX */ - - buflen += hostapd_eid_mbssid_len(hapd_probed, WLAN_FC_STYPE_PROBE_RESP, -- NULL); -+ NULL, known_bss, known_bss_len); - buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP); - buflen += hostapd_mbo_ie_len(hapd); - buflen += hostapd_eid_owe_trans_len(hapd); -@@ -703,7 +705,8 @@ static u8 * hostapd_gen_probe_resp(struc - pos = hostapd_eid_ht_capabilities(hapd, pos); - pos = hostapd_eid_ht_operation(hapd, pos); - pos = hostapd_eid_mbssid(hapd_probed, pos, epos, -- WLAN_FC_STYPE_PROBE_RESP, 0, NULL); -+ WLAN_FC_STYPE_PROBE_RESP, 0, NULL, -+ known_bss, known_bss_len); - - ext_cap_pos = pos; - pos = hostapd_eid_ext_capab(hapd, pos); -@@ -1268,7 +1271,8 @@ void handle_probe_req(struct hostapd_dat - " signal=%d", MAC2STR(mgmt->sa), ssi_signal); - - resp = hostapd_gen_probe_resp(hapd, mgmt, elems.p2p != NULL, -- &resp_len); -+ &resp_len, elems.mbssid_known_bss, -+ elems.mbssid_known_bss_len); - if (resp == NULL) - return; - -@@ -1338,7 +1342,7 @@ static u8 * hostapd_probe_resp_offloads( - "this"); - - /* Generate a Probe Response template for the non-P2P case */ -- return hostapd_gen_probe_resp(hapd, NULL, 0, resp_len); -+ return hostapd_gen_probe_resp(hapd, NULL, 0, resp_len, NULL, 0); - } - #endif /* NEED_AP_MLME */ - -@@ -1355,7 +1359,8 @@ static u8 * hostapd_unsol_bcast_probe_re - hapd->conf->unsol_bcast_probe_resp_interval; - - return hostapd_gen_probe_resp(hapd, NULL, 0, -- ¶ms->unsol_bcast_probe_resp_tmpl_len); -+ ¶ms->unsol_bcast_probe_resp_tmpl_len, -+ NULL, 0); - } - #endif /* CONFIG_IEEE80211AX */ - ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -7689,7 +7689,9 @@ u8 * hostapd_eid_rnr(struct hostapd_data - - - static size_t hostapd_eid_mbssid_elem_len(struct hostapd_data *hapd, -- u32 frame_type, size_t *bss_index) -+ u32 frame_type, size_t *bss_index, -+ const u8 *known_bss, -+ size_t known_bss_len) - { - struct hostapd_data *tx_bss = hostapd_mbssid_get_tx_bss(hapd); - size_t len = 3, i; -@@ -7700,6 +7702,12 @@ static size_t hostapd_eid_mbssid_elem_le - size_t nontx_profile_len, auth_len; - u8 ie_count = 0; - -+ if (known_bss && (known_bss_len > (i / 8))) { -+ known_bss = &known_bss[i / 8]; -+ if (*known_bss & (u8)(BIT(i % 8))) -+ continue; -+ } -+ - if (!bss || !bss->conf || !bss->started) - continue; - -@@ -7751,7 +7759,8 @@ mbssid_too_big: - - - size_t hostapd_eid_mbssid_len(struct hostapd_data *hapd, u32 frame_type, -- u8 *elem_count) -+ u8 *elem_count, const u8 *known_bss, -+ size_t known_bss_len) - { - size_t len = 0, bss_index = 1; - -@@ -7771,7 +7780,8 @@ size_t hostapd_eid_mbssid_len(struct hos - - while (bss_index < hapd->iface->num_bss) { - len += hostapd_eid_mbssid_elem_len(hapd, frame_type, -- &bss_index); -+ &bss_index, known_bss, -+ known_bss_len); - - if (frame_type == WLAN_FC_STYPE_BEACON) - *elem_count += 1; -@@ -7782,7 +7792,8 @@ size_t hostapd_eid_mbssid_len(struct hos - - static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end, - u32 frame_type, u8 max_bssid_indicator, -- size_t *bss_index, u8 elem_count) -+ size_t *bss_index, u8 elem_count, -+ const u8 *known_bss, size_t known_bss_len) - { - struct hostapd_data *tx_bss = hostapd_mbssid_get_tx_bss(hapd); - size_t i; -@@ -7801,6 +7812,12 @@ static u8 * hostapd_eid_mbssid_elem(stru - size_t auth_len = 0; - u16 capab_info; - -+ if (known_bss && (known_bss_len > (i / 8))) { -+ known_bss = &known_bss[i / 8]; -+ if (*known_bss & (u8)(BIT(i % 8))) -+ continue; -+ } -+ - if (!bss || !bss->conf || !bss->started) - continue; - conf = bss->conf; -@@ -7892,10 +7909,12 @@ mbssid_too_big: - - - u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end, -- u32 frame_type, u8 elem_count, u8 **elem_offset) -+ u32 frame_type, u8 elem_count, u8 **elem_offset, -+ const u8 *known_bss, size_t known_bss_len) - { - size_t bss_index = 1; - u8 elem_index = 0; -+ u8 max_bssid_indicator = hostapd_max_bssid_indicator(hapd); - - if (!hapd->iconf->mbssid || hapd->iface->num_bss <= 1 || - (frame_type != WLAN_FC_STYPE_BEACON && -@@ -7919,8 +7938,9 @@ u8 * hostapd_eid_mbssid(struct hostapd_d - elem_index = elem_index + 1; - } - eid = hostapd_eid_mbssid_elem(hapd, eid, end, frame_type, -- hostapd_max_bssid_indicator(hapd), -- &bss_index, elem_count); -+ max_bssid_indicator, &bss_index, -+ elem_count, known_bss, -+ known_bss_len); - } - return eid; - } ---- a/src/ap/ieee802_11.h -+++ b/src/ap/ieee802_11.h -@@ -131,9 +131,11 @@ void hostapd_client_poll_ok(struct hosta - u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid); - int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta); - size_t hostapd_eid_mbssid_len(struct hostapd_data *hapd, u32 frame_type, -- u8 *elem_count); -+ u8 *elem_count, const u8 *known_bss, -+ size_t known_bss_len); - u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end, -- u32 frame_type, u8 elem_count, u8 **elem_offset); -+ u32 frame_type, u8 elem_count, u8 **elem_offset, -+ const u8 *known_bss, size_t known_bss_len); - #ifdef CONFIG_SAE - void sae_clear_retransmit_timer(struct hostapd_data *hapd, - struct sta_info *sta); ---- a/src/common/ieee802_11_common.c -+++ b/src/common/ieee802_11_common.c -@@ -307,6 +307,10 @@ static int ieee802_11_parse_extension(co - elems->pasn_params = pos; - elems->pasn_params_len = elen; - break; -+ case WLAN_EID_EXT_KNOWN_BSSID: -+ elems->mbssid_known_bss = pos; -+ elems->mbssid_known_bss_len = elen; -+ break; - default: - if (show_errors) { - wpa_printf(MSG_MSGDUMP, ---- a/src/common/ieee802_11_common.h -+++ b/src/common/ieee802_11_common.h -@@ -118,6 +118,7 @@ struct ieee802_11_elems { - const u8 *sae_pk; - const u8 *s1g_capab; - const u8 *pasn_params; -+ const u8 *mbssid_known_bss; - - u8 ssid_len; - u8 supp_rates_len; -@@ -172,6 +173,7 @@ struct ieee802_11_elems { - u8 short_ssid_list_len; - u8 sae_pk_len; - u8 pasn_params_len; -+ u8 mbssid_known_bss_len; - - struct mb_ies_info mb_ies; - struct frag_ies_info frag_ies; ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -483,6 +483,7 @@ - #define WLAN_EID_EXT_OCV_OCI 54 - #define WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION 55 - #define WLAN_EID_EXT_NON_INHERITANCE 56 -+#define WLAN_EID_EXT_KNOWN_BSSID 57 - #define WLAN_EID_EXT_SHORT_SSID_LIST 58 - #define WLAN_EID_EXT_HE_6GHZ_BAND_CAP 59 - #define WLAN_EID_EXT_EDMG_CAPABILITIES 61 diff --git a/feeds/ipq95xx/hostapd/patches/q01-013-mbssid-add-nl80211-support.patch b/feeds/ipq95xx/hostapd/patches/q01-013-mbssid-add-nl80211-support.patch deleted file mode 100644 index 9927ac50..00000000 --- a/feeds/ipq95xx/hostapd/patches/q01-013-mbssid-add-nl80211-support.patch +++ /dev/null @@ -1,195 +0,0 @@ -From eb4acfa2e5c146f7637f6abc78b672e885f8780d Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 10 Sep 2021 15:24:54 -0700 -Subject: [PATCH 13/15] mbssid: add nl80211 support - -Send MBSSID and EMA configuration parameters to kernel. - -Signed-off-by: John Crispin -Signed-off-by: Aloka Dixit ---- - src/drivers/driver_nl80211.c | 51 +++++++++++++++++++++++++++- - src/drivers/driver_nl80211_capa.c | 26 +++++++++++++++ - src/drivers/nl80211_copy.h | 55 +++++++++++++++++++++++++++++++ - 3 files changed, 131 insertions(+), 1 deletion(-) - ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -4537,6 +4537,53 @@ static int nl80211_unsol_bcast_probe_res - #endif /* CONFIG_IEEE80211AX */ - - -+static int nl80211_mbssid(struct nl_msg *msg, -+ struct wpa_driver_ap_params *params) -+{ -+ struct nlattr *config, *elems; -+ int ifidx; -+ -+ config = nla_nest_start(msg, NL80211_ATTR_MBSSID_CONFIG); -+ if (!config) -+ goto fail; -+ -+ nla_put_u8(msg, NL80211_MBSSID_CONFIG_ATTR_INDEX, params->mbssid_index); -+ if (params->mbssid_tx_iface) { -+ ifidx = if_nametoindex(params->mbssid_tx_iface); -+ if (ifidx <= 0) -+ goto fail; -+ nla_put_u32(msg, -+ NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX, -+ ifidx); -+ } -+ -+ if (params->ema) -+ nla_put_flag(msg, NL80211_MBSSID_CONFIG_ATTR_EMA); -+ -+ nla_nest_end(msg, config); -+ -+ if (params->mbssid_elem_count && params->mbssid_elem_len && -+ params->mbssid_elem_offset && *params->mbssid_elem_offset) { -+ u8 i, **offs = params->mbssid_elem_offset; -+ -+ elems = nla_nest_start(msg, NL80211_ATTR_MBSSID_ELEMS); -+ if (!elems) -+ goto fail; -+ -+ for (i = 0; i < params->mbssid_elem_count - 1; i++) -+ nla_put(msg, i + 1, offs[i + 1] - offs[i], offs[i]); -+ nla_put(msg, i + 1, -+ *offs + params->mbssid_elem_len- offs[i], -+ offs[i]); -+ nla_nest_end(msg, elems); -+ } -+ return 0; -+ -+fail: -+ return -1; -+} -+ -+ - static int wpa_driver_nl80211_set_ap(void *priv, - struct wpa_driver_ap_params *params) - { -@@ -4834,6 +4881,9 @@ static int wpa_driver_nl80211_set_ap(voi - goto fail; - #endif /* CONFIG_FILS */ - -+ if (params->mbssid_count && nl80211_mbssid(msg, params) < 0) -+ goto fail; -+ - ret = send_and_recv_msgs_connect_handle(drv, msg, bss, 1); - if (ret) { - wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)", -@@ -5445,7 +5495,6 @@ const char * nl80211_iftype_str(enum nl8 - } - } - -- - static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv, - const char *ifname, - enum nl80211_iftype iftype, ---- a/src/drivers/driver_nl80211_capa.c -+++ b/src/drivers/driver_nl80211_capa.c -@@ -846,6 +846,29 @@ err: - } - - -+static void wiphy_info_mbssid(struct wpa_driver_capa *cap, struct nlattr *attr) -+{ -+ struct nlattr *config[NL80211_MBSSID_CONFIG_ATTR_MAX + 1]; -+ -+ if (nla_parse_nested(config, NL80211_MBSSID_CONFIG_ATTR_MAX, attr, -+ NULL)) -+ return; -+ -+ if (!config[NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES]) -+ return; -+ -+ cap->mbssid_max_interfaces = -+ nla_get_u8(config[NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES]); -+ -+ if (config[NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY]) -+ cap->ema_max_periodicity = -+ nla_get_u8(config[NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY]); -+ -+ wpa_printf(MSG_DEBUG, -+ "multiple_bssid: max interfaces %u, max profile periodicity %u\n", -+ cap->mbssid_max_interfaces, cap->ema_max_periodicity); -+} -+ - static int wiphy_info_handler(struct nl_msg *msg, void *arg) - { - struct nlattr *tb[NL80211_ATTR_MAX + 1]; -@@ -1070,6 +1093,9 @@ static int wiphy_info_handler(struct nl_ - if (tb[NL80211_ATTR_WIPHY_SELF_MANAGED_REG]) - capa->flags |= WPA_DRIVER_FLAGS_SELF_MANAGED_REGULATORY; - -+ if (tb[NL80211_ATTR_MBSSID_CONFIG]) -+ wiphy_info_mbssid(capa, tb[NL80211_ATTR_MBSSID_CONFIG]); -+ - return NL_SKIP; - } - ---- a/src/drivers/nl80211_copy.h -+++ b/src/drivers/nl80211_copy.h -@@ -7376,6 +7376,61 @@ enum nl80211_sar_specs_attrs { - NL80211_SAR_ATTR_SPECS_MAX = __NL80211_SAR_ATTR_SPECS_LAST - 1, - }; - -+/** -+ * enum nl80211_mbssid_config_attributes - multiple BSSID (MBSSID) and enhanced -+ * multi-BSSID advertisements (EMA) in AP mode. -+ * Kernel uses some of these attributes to advertise driver's support for -+ * MBSSID and EMA. -+ * Remaining attributes should be used by the userspace to configure the -+ * features. -+ * -+ * @__NL80211_MBSSID_CONFIG_ATTR_INVALID: Invalid -+ * -+ * @NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES: Used by the kernel to advertise -+ * the maximum number of MBSSID interfaces supported by the driver. -+ * Driver should indicate MBSSID support by setting -+ * wiphy->mbssid_max_interfaces to a value more than or equal to 2. -+ * -+ * @NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY: Used by the kernel -+ * to advertise the maximum profile periodicity supported by the driver -+ * if EMA is enabled. Driver should indicate EMA support to the userspace -+ * by setting wiphy->ema_max_profile_periodicity to -+ * a non-zero value. -+ * -+ * @NL80211_MBSSID_CONFIG_ATTR_INDEX: Mandatory parameter to pass the index of -+ * this BSS (u8) in the multiple BSSID set. -+ * Value must be set to 0 for the transmitting interface and non-zero for -+ * all non-transmitting interfaces. The userspace will be responsible -+ * for using unique indices for the interfaces. -+ * Range: 0 to wiphy->mbssid_max_interfaces-1. -+ * -+ * @NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX: Mandatory parameter for -+ * a non-transmitted profile which provides the interface index (u32) of -+ * the transmitted profile. The value must match one of the interface -+ * indices advertised by the kernel. Optional if the interface being set up -+ * is the transmitting one, however, if provided then the value must match -+ * the interface index of the same. -+ * -+ * @NL80211_MBSSID_CONFIG_ATTR_EMA: Flag used to enable EMA AP feature. -+ * Setting this flag is permitted only if the driver advertises EMA support -+ * by setting wiphy->ema_max_profile_periodicity to non-zero. -+ * -+ * @__NL80211_MBSSID_CONFIG_ATTR_LAST: Internal -+ * @NL80211_MBSSID_CONFIG_ATTR_MAX: highest attribute -+ */ -+enum nl80211_mbssid_config_attributes { -+ __NL80211_MBSSID_CONFIG_ATTR_INVALID, -+ -+ NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES, -+ NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY, -+ NL80211_MBSSID_CONFIG_ATTR_INDEX, -+ NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX, -+ NL80211_MBSSID_CONFIG_ATTR_EMA, -+ -+ /* keep last */ -+ __NL80211_MBSSID_CONFIG_ATTR_LAST, -+ NL80211_MBSSID_CONFIG_ATTR_MAX = __NL80211_MBSSID_CONFIG_ATTR_LAST - 1, -+}; - - /** - * enum nl80211_beacon_tx_mode - Beacon Tx Mode enum. diff --git a/feeds/ipq95xx/hostapd/patches/q01-014-mbssid-RNR-for-EMA-AP.patch b/feeds/ipq95xx/hostapd/patches/q01-014-mbssid-RNR-for-EMA-AP.patch deleted file mode 100644 index eb7aad3c..00000000 --- a/feeds/ipq95xx/hostapd/patches/q01-014-mbssid-RNR-for-EMA-AP.patch +++ /dev/null @@ -1,412 +0,0 @@ -From 4a58da0a8bcb37f5ceac80fabb64c38ec2eedd94 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Thu, 10 Dec 2020 15:13:11 -0800 -Subject: [PATCH 14/15] hostad: RNR for EMA AP - -(1) Enable RNR by default for EMA AP. -(2) Only for EMA AP, split reduced neighbor report in as many groups as - number of multiple BSSID offset groups. - Each RNR group skips the profiles already include in the corresponding - MBSSID groups. - The last additional group will have data common for all EMA beacons. -(3) Enable reduced neighbor report by default in 5GHz/2.4GHz beacons - and probe responses if one or more 6GHz APs are co-located. - -Signed-off-by: Aloka Dixit ---- - src/ap/beacon.c | 52 ++++++++++++++------- - src/ap/ieee802_11.c | 106 +++++++++++++++++++++++++++++++++++++------ - src/ap/ieee802_11.h | 5 +- - src/drivers/driver.h | 22 +++++++++ - 4 files changed, 152 insertions(+), 33 deletions(-) - ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -488,7 +488,7 @@ static u8 * hostapd_set_mbssid_beacon(st - params->mbssid_count = iface->num_bss; - - len = hostapd_eid_mbssid_len(tx_bss, WLAN_FC_STYPE_BEACON, &num_mbssid, -- NULL, 0); -+ NULL, 0, ¶ms->rnr_elem_len); - if (hapd->iconf->ema) { - if (!iface->ema_max_periodicity) { - wpa_printf(MSG_WARNING, "MBSSID: Driver doesn't support" -@@ -509,27 +509,30 @@ static u8 * hostapd_set_mbssid_beacon(st - - params->mbssid_elem_count = num_mbssid; - params->mbssid_elem = os_zalloc(len); -- if (!params->mbssid_elem) { -- wpa_printf(MSG_ERROR, "Memory allocation failed for multiple " -- "BSSID elements"); -- return eid; -- } -+ if (!params->mbssid_elem) -+ goto error; - - params->mbssid_elem_offset = os_zalloc(params->mbssid_elem_count * - sizeof(u8 *)); -- if (!params->mbssid_elem_offset) { -- wpa_printf(MSG_ERROR, "MBSSID: Memory allocation failed for " -- "multiple BSSID element offsets"); -- os_free(params->mbssid_elem); -- params->mbssid_elem = NULL; -- return eid; -- } -+ if (!params->mbssid_elem_offset) -+ goto error; -+ -+ params->rnr_elem = os_zalloc(params->rnr_elem_len); -+ if (!params->rnr_elem) -+ goto error; -+ -+ params->rnr_elem_offset = os_zalloc((params->mbssid_elem_count + 1) * -+ sizeof(u8 *)); -+ if (!params->rnr_elem_offset) -+ goto error; - - end = hostapd_eid_mbssid(tx_bss, params->mbssid_elem, - params->mbssid_elem + len, - WLAN_FC_STYPE_BEACON, - params->mbssid_elem_count, -- params->mbssid_elem_offset, NULL, 0); -+ params->mbssid_elem_offset, NULL, 0, -+ params->rnr_elem, params->rnr_elem_offset, -+ ¶ms->rnr_elem_count, params->rnr_elem_len); - params->mbssid_elem_len = end - params->mbssid_elem; - - if (hapd->iconf->ema) { -@@ -540,6 +543,19 @@ static u8 * hostapd_set_mbssid_beacon(st - *eid++ = params->mbssid_elem_count; - } - return eid; -+ -+error: -+ os_free(params->mbssid_elem); -+ params->mbssid_elem = NULL; -+ os_free(params->mbssid_elem_offset); -+ params->mbssid_elem_offset = NULL; -+ os_free(params->rnr_elem); -+ params->rnr_elem = NULL; -+ os_free(params->rnr_elem_offset); -+ params->rnr_elem_offset = NULL; -+ wpa_printf(MSG_ERROR, -+ "Memory allocation failed for multiple BSSID elements"); -+ return eid; - } - - -@@ -624,7 +640,7 @@ static u8 * hostapd_gen_probe_resp(struc - #endif /* CONFIG_IEEE80211AX */ - - buflen += hostapd_eid_mbssid_len(hapd_probed, WLAN_FC_STYPE_PROBE_RESP, -- NULL, known_bss, known_bss_len); -+ NULL, known_bss, known_bss_len, NULL); - buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP); - buflen += hostapd_mbo_ie_len(hapd); - buflen += hostapd_eid_owe_trans_len(hapd); -@@ -706,7 +722,7 @@ static u8 * hostapd_gen_probe_resp(struc - pos = hostapd_eid_ht_operation(hapd, pos); - pos = hostapd_eid_mbssid(hapd_probed, pos, epos, - WLAN_FC_STYPE_PROBE_RESP, 0, NULL, -- known_bss, known_bss_len); -+ known_bss, known_bss_len, NULL, NULL, NULL, 0); - - ext_cap_pos = pos; - pos = hostapd_eid_ext_capab(hapd, pos); -@@ -2002,6 +2018,10 @@ void ieee802_11_free_ap_params(struct wp - params->mbssid_elem = NULL; - os_free(params->mbssid_elem_offset); - params->mbssid_elem_offset = NULL; -+ os_free(params->rnr_elem); -+ params->rnr_elem = NULL; -+ os_free(params->rnr_elem_offset); -+ params->rnr_elem_offset = NULL; - #ifdef CONFIG_FILS - os_free(params->fd_frame_tmpl); - params->fd_frame_tmpl = NULL; ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -7336,9 +7336,12 @@ static size_t hostapd_eid_nr_db_len(stru - } - - -+const int ema_not_applicable = -1; - static size_t hostapd_eid_rnr_iface_len(struct hostapd_data *hapd, - struct hostapd_data *reporting_hapd, -- size_t *current_len) -+ size_t *current_len, -+ int ema_bss_index_1, -+ int ema_bss_index_2) - { - size_t total_len = 0, len = *current_len; - int tbtt_count = 0; -@@ -7364,6 +7367,10 @@ static size_t hostapd_eid_rnr_iface_len( - bss->conf->ignore_broadcast_ssid) - continue; - -+ if ((ema_bss_index_1 != -1) && (ema_bss_index_2 != -1) && -+ (i >= ema_bss_index_1) && (i < ema_bss_index_2)) -+ continue; -+ - if (len + RNR_TBTT_INFO_LEN > 255 || - tbtt_count >= RNR_TBTT_INFO_COUNT_MAX) - break; -@@ -7442,7 +7449,9 @@ static size_t hostapd_eid_rnr_colocation - continue; - - len += hostapd_eid_rnr_iface_len(iface->bss[0], hapd, -- current_len); -+ current_len, -+ ema_not_applicable, -+ ema_not_applicable); - } - - return len; -@@ -7465,15 +7474,20 @@ size_t hostapd_eid_rnr_len(struct hostap - total_len += hostapd_eid_rnr_colocation_len( - hapd, ¤t_len); - -- if (hapd->conf->rnr && hapd->iface->num_bss > 1) -+ if (hapd->conf->rnr && hapd->iface->num_bss > 1 && -+ !hapd->iconf->mbssid) - total_len += hostapd_eid_rnr_iface_len(hapd, hapd, -- ¤t_len); -+ ¤t_len, -+ ema_not_applicable, -+ ema_not_applicable); - break; - - case WLAN_FC_STYPE_ACTION: - if (hapd->iface->num_bss > 1 && mode == STANDALONE_6GHZ) - total_len += hostapd_eid_rnr_iface_len(hapd, hapd, -- ¤t_len); -+ ¤t_len, -+ ema_not_applicable, -+ ema_not_applicable); - break; - - default: -@@ -7541,7 +7555,8 @@ static u8 * hostapd_eid_nr_db(struct hos - - static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd, - struct hostapd_data *reporting_hapd, -- u8 *eid, size_t *current_len) -+ u8 *eid, size_t *current_len, -+ int ema_bss_index_1, int ema_bss_index_2) - { - struct hostapd_data *bss; - struct hostapd_iface *iface = hapd->iface; -@@ -7586,6 +7601,10 @@ static u8 * hostapd_eid_rnr_iface(struct - bss->conf->ignore_broadcast_ssid) - continue; - -+ if ((ema_bss_index_1 != -1) && (ema_bss_index_2 != -1) && -+ (i >= ema_bss_index_1) && (i < ema_bss_index_2)) -+ continue; -+ - if (len + RNR_TBTT_INFO_LEN > 255 || - tbtt_count >= RNR_TBTT_INFO_COUNT_MAX) - break; -@@ -7599,6 +7618,12 @@ static u8 * hostapd_eid_rnr_iface(struct - reporting_hapd->conf->ssid.short_ssid) - bss_param |= RNR_BSS_PARAM_SAME_SSID; - -+ if (hapd->iconf->mbssid) { -+ bss_param |= RNR_BSS_PARAM_MULTIPLE_BSSID; -+ if (bss == hostapd_mbssid_get_tx_bss(hapd)) -+ bss_param |= RNR_BSS_PARAM_TRANSMITTED_BSSID; -+ } -+ - if (is_6ghz_op_class(hapd->iconf->op_class) && - bss->conf->unsol_bcast_probe_resp_interval) - bss_param |= -@@ -7642,7 +7667,8 @@ static u8 * hostapd_eid_rnr_colocation(s - continue; - - eid = hostapd_eid_rnr_iface(iface->bss[0], hapd, eid, -- current_len); -+ current_len, ema_not_applicable, -+ ema_not_applicable); - } - - return eid; -@@ -7666,15 +7692,20 @@ u8 * hostapd_eid_rnr(struct hostapd_data - eid = hostapd_eid_rnr_colocation(hapd, eid, - ¤t_len); - -- if (hapd->conf->rnr && hapd->iface->num_bss > 1) -+ if (hapd->conf->rnr && hapd->iface->num_bss > 1 && -+ !hapd->iconf->mbssid) - eid = hostapd_eid_rnr_iface(hapd, hapd, eid, -- ¤t_len); -+ ¤t_len, -+ ema_not_applicable, -+ ema_not_applicable); - break; - - case WLAN_FC_STYPE_ACTION: - if (hapd->iface->num_bss > 1 && mode == STANDALONE_6GHZ) - eid = hostapd_eid_rnr_iface(hapd, hapd, eid, -- ¤t_len); -+ ¤t_len, -+ ema_not_applicable, -+ ema_not_applicable); - break; - - default: -@@ -7760,9 +7791,9 @@ mbssid_too_big: - - size_t hostapd_eid_mbssid_len(struct hostapd_data *hapd, u32 frame_type, - u8 *elem_count, const u8 *known_bss, -- size_t known_bss_len) -+ size_t known_bss_len, size_t *rnr_len) - { -- size_t len = 0, bss_index = 1; -+ size_t len = 0, bss_index = 1, rnr_cur_len = 0, rnr_count; - - if (!hapd->iconf->mbssid || hapd->iface->num_bss <= 1 || - (frame_type != WLAN_FC_STYPE_BEACON && -@@ -7779,13 +7810,26 @@ size_t hostapd_eid_mbssid_len(struct hos - } - - while (bss_index < hapd->iface->num_bss) { -+ rnr_count = bss_index; - len += hostapd_eid_mbssid_elem_len(hapd, frame_type, - &bss_index, known_bss, - known_bss_len); - - if (frame_type == WLAN_FC_STYPE_BEACON) - *elem_count += 1; -+ if (hapd->iconf->ema && rnr_len) { -+ rnr_cur_len = 0; -+ (*rnr_len) += hostapd_eid_rnr_iface_len(hapd, -+ hostapd_mbssid_get_tx_bss(hapd), -+ &rnr_cur_len, -+ rnr_count, -+ bss_index); -+ } - } -+ -+ if (hapd->iconf->ema && rnr_len) -+ (*rnr_len) += hostapd_eid_rnr_len(hapd, frame_type); -+ - return len; - } - -@@ -7910,11 +7954,13 @@ mbssid_too_big: - - u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end, - u32 frame_type, u8 elem_count, u8 **elem_offset, -- const u8 *known_bss, size_t known_bss_len) -+ const u8 *known_bss, size_t known_bss_len, u8 *rnr_eid, -+ u8 **rnr_offsets, int *rnr_count, int rnr_len) - { -- size_t bss_index = 1; -- u8 elem_index = 0; -+ size_t bss_index = 1, cur_len = 0; -+ u8 elem_index = 0, *rnr_start_eid = rnr_eid; - u8 max_bssid_indicator = hostapd_max_bssid_indicator(hapd); -+ bool add_rnr = false; - - if (!hapd->iconf->mbssid || hapd->iface->num_bss <= 1 || - (frame_type != WLAN_FC_STYPE_BEACON && -@@ -7926,7 +7972,12 @@ u8 * hostapd_eid_mbssid(struct hostapd_d - return eid; - } - -+ if (hapd->iconf->ema && frame_type == WLAN_FC_STYPE_BEACON && rnr_len) -+ add_rnr = true; -+ - while (bss_index < hapd->iface->num_bss) { -+ int rnr_start_count = bss_index; -+ - if (frame_type == WLAN_FC_STYPE_BEACON) { - if (elem_index == elem_count) { - wpa_printf(MSG_WARNING, "MBSSID: More number of" -@@ -7941,7 +7992,32 @@ u8 * hostapd_eid_mbssid(struct hostapd_d - max_bssid_indicator, &bss_index, - elem_count, known_bss, - known_bss_len); -+ -+ if (add_rnr == true) { -+ rnr_offsets[*rnr_count] = rnr_eid; -+ *rnr_count = *rnr_count + 1; -+ cur_len = 0; -+ -+ rnr_eid = hostapd_eid_rnr_iface(hapd, -+ hostapd_mbssid_get_tx_bss(hapd), -+ rnr_eid, &cur_len, -+ rnr_start_count, -+ bss_index); -+ } - } -+ -+ if ((add_rnr == true) && ((rnr_eid - rnr_start_eid) < rnr_len)) { -+ rnr_offsets[*rnr_count] = rnr_eid; -+ *rnr_count = *rnr_count + 1; -+ cur_len = 0; -+ -+ if (hapd->conf->rnr) -+ rnr_eid = hostapd_eid_nr_db(hapd, rnr_eid, &cur_len); -+ if (get_colocation_mode(hapd) == COLOCATED_LOWER_BAND) -+ rnr_eid = hostapd_eid_rnr_colocation(hapd, rnr_eid, -+ &cur_len); -+ } -+ - return eid; - } - ---- a/src/ap/ieee802_11.h -+++ b/src/ap/ieee802_11.h -@@ -132,10 +132,11 @@ u8 * hostapd_eid_bss_max_idle_period(str - int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta); - size_t hostapd_eid_mbssid_len(struct hostapd_data *hapd, u32 frame_type, - u8 *elem_count, const u8 *known_bss, -- size_t known_bss_len); -+ size_t known_bss_len, size_t *rnr_len); - u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end, - u32 frame_type, u8 elem_count, u8 **elem_offset, -- const u8 *known_bss, size_t known_bss_len); -+ const u8 *known_bss, size_t known_bss_len, u8 *rnr_eid, -+ u8 **rnr_offsets, int *rnr_count, int rnr_len); - #ifdef CONFIG_SAE - void sae_clear_retransmit_timer(struct hostapd_data *hapd, - struct sta_info *sta); ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -1669,6 +1669,27 @@ struct wpa_driver_ap_params { - */ - u8 ema; - -+ /** -+ * rnr_elem - This buffer contains all of reduced neighbor report (RNR) -+ * elements -+ */ -+ u8 *rnr_elem; -+ -+ /** -+ * rnr_elem_len - Length of rnr_elem buffer -+ */ -+ size_t rnr_elem_len; -+ -+ /** -+ * rnr_elem_count - Number of RNR elements -+ */ -+ int rnr_elem_count; -+ -+ /** -+ * rnr_elem_offset - The offsets to the elements in rnr_elem. -+ * Kernel will use these to include RNR elements in EMA beacons. -+ */ -+ u8 **rnr_elem_offset; - }; - - struct wpa_driver_mesh_bss_params { -@@ -2340,6 +2361,7 @@ struct wpa_bss_params { - int wpa_key_mgmt; - int rsn_preauth; - enum mfp_options ieee80211w; -+ - }; - - #define WPA_STA_AUTHORIZED BIT(0) diff --git a/feeds/ipq95xx/hostapd/patches/q01-015-mbssid-Netlink-changes-for-RNR-offsets.patch b/feeds/ipq95xx/hostapd/patches/q01-015-mbssid-Netlink-changes-for-RNR-offsets.patch deleted file mode 100644 index 3debe29f..00000000 --- a/feeds/ipq95xx/hostapd/patches/q01-015-mbssid-Netlink-changes-for-RNR-offsets.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 842ecae7678e62d97e7a9ca6efbe821444720e41 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Mon, 14 Dec 2020 11:41:59 -0800 -Subject: [PATCH 15/15] hostapd: Netlink changes for RNR offsets - -This patch adds new nested netlink attribute NL80211_ATTR_EMA_RNR_ELEMS -used to send reduced neighbor report (RNR) elements to kernel when EMA -is enabled. -This attribute includes the count of RNR elements and data at each index. -While generating EMA beacons, kernel will include RNR group at a given -index along with MBSSID group. -Last element, if present, has RNR data common for all EMA beacons. - -Signed-off-by: Aloka Dixit ---- - src/drivers/driver_nl80211.c | 19 +++++++++++++++++++ - src/drivers/nl80211_copy.h | 2 ++ - 2 files changed, 21 insertions(+) - ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -4577,6 +4577,25 @@ static int nl80211_mbssid(struct nl_msg - offs[i]); - nla_nest_end(msg, elems); - } -+ -+ if (!params->ema) -+ return 0; -+ -+ if (params->rnr_elem_count && params->rnr_elem_len && -+ params->rnr_elem_offset && *params->rnr_elem_offset) { -+ u8 i, **offs = params->rnr_elem_offset; -+ -+ elems = nla_nest_start(msg, NL80211_ATTR_EMA_RNR_ELEMS); -+ if (!elems) -+ goto fail; -+ -+ for (i = 0; i < params->rnr_elem_count - 1; i++) -+ nla_put(msg, i + 1, offs[i + 1] - offs[i], offs[i]); -+ nla_put(msg, i + 1, -+ *offs + params->rnr_elem_len- offs[i], -+ offs[i]); -+ nla_nest_end(msg, elems); -+ } - return 0; - - fail: ---- a/src/drivers/nl80211_copy.h -+++ b/src/drivers/nl80211_copy.h -@@ -3109,6 +3109,8 @@ enum nl80211_attrs { - - NL80211_ATTR_6G_REG_POWER_MODE, - -+ NL80211_ATTR_EMA_RNR_ELEMS, -+ - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, diff --git a/feeds/ipq95xx/hostapd/patches/q01-016-mbssid-support-extended-rates-in-non-tx-profiles.patch b/feeds/ipq95xx/hostapd/patches/q01-016-mbssid-support-extended-rates-in-non-tx-profiles.patch deleted file mode 100644 index dfdbc1f2..00000000 --- a/feeds/ipq95xx/hostapd/patches/q01-016-mbssid-support-extended-rates-in-non-tx-profiles.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 96b57fdd283c3856f390e971d3acbe3f88107c0d Mon Sep 17 00:00:00 2001 -From: Sowmiya Sree Elavalagan -Date: Tue, 15 Mar 2022 13:49:02 -0700 -Subject: [PATCH] mbssid: support extended rates in non-tx profiles - -Add extended supported rates for non-transmitting interface if -applicable. If the transmitting interface supports it and -the non-transmitting interface does not then add it in the -non-inheritance element. - -Signed-off-by: Sowmiya Sree Elavalagan ---- - src/ap/ap_config.h | 1 + - src/ap/ieee802_11.c | 11 +++++++++++ - 2 files changed, 12 insertions(+) - ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -911,6 +911,7 @@ struct hostapd_bss_config { - - u8 rnr; - int beacon_tx_mode; -+ bool xrates_supported; - }; - - /** ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -166,6 +166,7 @@ u8 * hostapd_eid_ext_supp_rates(struct h - int i, num, count; - int h2e_required; - -+ hapd->conf->xrates_supported = 0; - if (hapd->iface->current_rates == NULL) - return eid; - -@@ -215,6 +216,7 @@ u8 * hostapd_eid_ext_supp_rates(struct h - *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY; - } - -+ hapd->conf->xrates_supported = 1; - return pos; - } - -@@ -7774,6 +7776,10 @@ static size_t hostapd_eid_mbssid_elem_le - ie_count++; - if (!rsnx && hostapd_wpa_ie(tx_bss, WLAN_EID_RSNX)) - ie_count++; -+ if (bss->conf->xrates_supported) -+ nontx_profile_len += 8; -+ else if (hapd->conf->xrates_supported) -+ ie_count++; - if (ie_count) - nontx_profile_len += (4 + ie_count); - -@@ -7852,7 +7858,7 @@ static u8 * hostapd_eid_mbssid_elem(stru - struct hostapd_bss_config *conf; - u8 *eid_len_pos, *nontx_bss_start = eid; - const u8 *auth, *rsn = NULL, *rsnx = NULL; -- u8 ie_count = 0, non_inherit_ie[2]; -+ u8 ie_count = 0, non_inherit_ie[3]; - size_t auth_len = 0; - u16 capab_info; - -@@ -7917,6 +7923,7 @@ static u8 * hostapd_eid_mbssid_elem(stru - eid += (2 + rsnx[1]); - } - } -+ eid = hostapd_eid_ext_supp_rates(bss, eid); - if (!rsn && hostapd_wpa_ie(tx_bss, WLAN_EID_RSN)) { - non_inherit_ie[ie_count] = WLAN_EID_RSN; - ie_count++; -@@ -7925,6 +7932,11 @@ static u8 * hostapd_eid_mbssid_elem(stru - non_inherit_ie[ie_count] = WLAN_EID_RSNX; - ie_count++; - } -+ if (hapd->conf->xrates_supported && -+ !bss->conf->xrates_supported) { -+ non_inherit_ie[ie_count] = WLAN_EID_EXT_SUPP_RATES; -+ ie_count++; -+ } - if (ie_count) { - *eid++ = WLAN_EID_EXTENSION; - *eid++ = 2 + ie_count; diff --git a/feeds/ipq95xx/hostapd/patches/q02-001-hostapd-fix-unsol-config.patch b/feeds/ipq95xx/hostapd/patches/q02-001-hostapd-fix-unsol-config.patch deleted file mode 100644 index a6486f49..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-001-hostapd-fix-unsol-config.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 2adeba3ef1f8cf283b0d3c3b9c4a0e009fc85f65 Mon Sep 17 00:00:00 2001 -From: Karthikeyan Kathirvel -Date: Fri, 25 Mar 2022 14:36:33 +0530 -Subject: [PATCH] hostapd: unable to config unsolicited broadcast Probe - Response - -Unsolicited broadcast Probe Response config is not working in hostapd, -this is because fils_discovery_min_int was used by mistake where -fils_discovery_max_int should have been used, latter is the one used to -decide whether FILS discovery is enabled or not. - -Signed-off-by: Karthikeyan Kathirvel ---- - src/ap/ap_config.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c -index e91c042..4ceb480 100644 ---- a/src/ap/ap_config.c -+++ b/src/ap/ap_config.c -@@ -1427,7 +1427,7 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss, - #endif /* CONFIG_SAE_PK */ - - #ifdef CONFIG_FILS -- if (full_config && bss->fils_discovery_min_int && -+ if (full_config && bss->fils_discovery_max_int && - bss->unsol_bcast_probe_resp_interval) { - wpa_printf(MSG_ERROR, - "Cannot enable both FILS discovery and unsolicited broadcast Probe Response at the same time"); --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-001-nl80211-sync-kernel-definitions.patch b/feeds/ipq95xx/hostapd/patches/q02-001-nl80211-sync-kernel-definitions.patch deleted file mode 100644 index fd264294..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-001-nl80211-sync-kernel-definitions.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 3c5da4abf9298e72e89b012ef9a1cc9a4b53975e Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Tue, 20 Jul 2021 13:47:09 -0700 -Subject: [PATCH 01/23] nl80211: sync kernel definitions - -Signed-off-by: Aloka Dixit ---- - src/drivers/nl80211_copy.h | 39 +++++++++++++++++++++++++++++++++++++- - 1 file changed, 38 insertions(+), 1 deletion(-) - ---- a/src/drivers/nl80211_copy.h -+++ b/src/drivers/nl80211_copy.h -@@ -1784,7 +1784,8 @@ enum nl80211_commands { - * features NL80211_EXT_FEATURE_BEACON_RATE_LEGACY, - * NL80211_EXT_FEATURE_BEACON_RATE_HT, - * NL80211_EXT_FEATURE_BEACON_RATE_VHT and -- * NL80211_EXT_FEATURE_BEACON_RATE_HE. -+ * NL80211_EXT_FEATURE_BEACON_RATE_HE and -+ * NL80211_EXT_FEATURE_BEACON_RATE_EHT. - * - * @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain - * at least one byte, currently used with @NL80211_CMD_REGISTER_FRAME. -@@ -2592,6 +2593,10 @@ enum nl80211_commands { - * @NL80211_ATTR_AWGN_INTERFERENCE_BITMAP: u32 attribute specifying the - * interference bitmap of operating bandwidth for %NL80211_CMD_AWGN_DETECT - * -+ * @NL80211_ATTR_EHT_CAPABILITY: EHT Capability information element (from -+ * association request when used with NL80211_CMD_NEW_STATION). Can be set -+ * only if %NL80211_STA_FLAG_WME is set. -+ * - * @NUM_NL80211_ATTR: total number of nl80211_attrs available - * @NL80211_ATTR_MAX: highest attribute number currently defined - * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -3099,6 +3104,10 @@ enum nl80211_attrs { - NL80211_ATTR_MBSSID_CONFIG, - NL80211_ATTR_MBSSID_ELEMS, - -+ NL80211_ATTR_RADAR_BACKGROUND, -+ -+ NL80211_ATTR_AP_SETTINGS_FLAGS, -+ - NL80211_ATTR_BEACON_TX_MODE, - - NL80211_ATTR_WIPHY_ANTENNA_GAIN, -@@ -3111,6 +3120,10 @@ enum nl80211_attrs { - - NL80211_ATTR_EMA_RNR_ELEMS, - -+ NL80211_ATTR_EHT_CAPABILITY = NL80211_ATTR_MBSSID_ELEMS + 15, -+ -+ NL80211_ATTR_DISABLE_EHT, -+ - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, -@@ -3690,6 +3703,8 @@ enum nl80211_mpath_info { - NL80211_MPATH_INFO_MAX = __NL80211_MPATH_INFO_AFTER_LAST - 1 - }; - -+#define NL80211_EHT_NSS_MAX 16 -+ - /** - * enum nl80211_band_iftype_attr - Interface type data attributes - * -@@ -3708,6 +3723,16 @@ enum nl80211_mpath_info { - * defined - * @NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA: HE 6GHz band capabilities (__le16), - * given for all 6 GHz band channels -+ * @NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS: vendor element capabilities that are -+ * advertised on this band/for this iftype (binary) -+ * @NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC: EHT MAC capabilities as in EHT -+ * capabilities element -+ * @NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY: EHT PHY capabilities as in EHT -+ * capabilities element -+ * @NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET: EHT supported NSS/MCS as in EHT -+ * capabilities element -+ * @NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE: EHT PPE thresholds information as -+ * defined in EHT capabilities element - * @__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST: internal use - */ - enum nl80211_band_iftype_attr { -@@ -3719,6 +3744,11 @@ enum nl80211_band_iftype_attr { - NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET, - NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE, - NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA, -+ NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS, -+ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC, -+ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY, -+ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET, -+ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE, - - /* keep last */ - __NL80211_BAND_IFTYPE_ATTR_AFTER_LAST, -@@ -4915,6 +4945,9 @@ enum nl80211_key_attributes { - * see &struct nl80211_txrate_he - * @NL80211_TXRATE_HE_GI: configure HE GI, 0.8us, 1.6us and 3.2us. - * @NL80211_TXRATE_HE_LTF: configure HE LTF, 1XLTF, 2XLTF and 4XLTF. -+ * @NL80211_TXRATE_EHT: EHT rates allowed for TX rate selection, -+ * see &struct nl80211_txrate_eht -+ * - * @__NL80211_TXRATE_AFTER_LAST: internal - * @NL80211_TXRATE_MAX: highest TX rate attribute - */ -@@ -4927,6 +4960,7 @@ enum nl80211_tx_rate_attributes { - NL80211_TXRATE_HE, - NL80211_TXRATE_HE_GI, - NL80211_TXRATE_HE_LTF, -+ NL80211_TXRATE_EHT, - - /* keep last */ - __NL80211_TXRATE_AFTER_LAST, -@@ -4960,6 +4994,14 @@ enum nl80211_txrate_gi { - }; - - /** -+ * struct nl80211_txrate_eht - EHT MCS/NSS txrate bitmap -+ * @mcs: MCS bitmap table for each NSS (array index 0 for 1 stream, etc.) -+ */ -+struct nl80211_txrate_eht { -+ __u16 mcs[NL80211_EHT_NSS_MAX]; -+}; -+ -+/** - * enum nl80211_band - Frequency band - * @NL80211_BAND_2GHZ: 2.4 GHz ISM band - * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) -@@ -6029,6 +6071,9 @@ enum nl80211_feature_flags { - * frame protection for all management frames exchanged during the - * negotiation and range measurement procedure. - * -+ * @NL80211_EXT_FEATURE_BEACON_RATE_EHT: Driver supports beacon rate -+ * configuration (AP/mesh) with EHT rates. -+ * - * @NUM_NL80211_EXT_FEATURES: number of extended features. - * @MAX_NL80211_EXT_FEATURES: highest extended feature index. - */ -@@ -6093,6 +6138,10 @@ enum nl80211_ext_feature_index { - NL80211_EXT_FEATURE_SECURE_LTF, - NL80211_EXT_FEATURE_SECURE_RTT, - NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE, -+ NL80211_EXT_FEATURE_BSS_COLOR, -+ NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD, -+ NL80211_EXT_FEATURE_RADAR_BACKGROUND, -+ NL80211_EXT_FEATURE_BEACON_RATE_EHT, - - /* add new features before the definition below */ - NUM_NL80211_EXT_FEATURES, diff --git a/feeds/ipq95xx/hostapd/patches/q02-002-eht-define-EHT-elements.patch b/feeds/ipq95xx/hostapd/patches/q02-002-eht-define-EHT-elements.patch deleted file mode 100644 index 98e432b6..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-002-eht-define-EHT-elements.patch +++ /dev/null @@ -1,107 +0,0 @@ -From a39239c62e4d86cbd0afacbcf2f286341cb4695f Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Mon, 28 Jun 2021 13:27:48 -0700 -Subject: [PATCH 02/23] eht: define EHT elements - -Define following fields described in IEEE P802.11be/D1.4, January 2022, -- 9.4.2.313 EHT Capabilities element -- 9.4.2.311 EHT Operation element - -Signed-off-by: Aloka Dixit ---- - src/common/ieee802_11_defs.h | 77 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 77 insertions(+) - ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -493,6 +493,9 @@ - #define WLAN_EID_EXT_REJECTED_GROUPS 92 - #define WLAN_EID_EXT_ANTI_CLOGGING_TOKEN 93 - #define WLAN_EID_EXT_PASN_PARAMS 100 -+#define WLAN_EID_EXT_EHT_OPERATION 106 -+#define WLAN_EID_EXT_EHT_MULTI_LINK 107 -+#define WLAN_EID_EXT_EHT_CAPABILITY 108 - - /* Operating Triplet can be any integer >= 201 - * From IEEE P802.11-REVmd/D4.0: The first octet in each Subband -@@ -2404,6 +2407,80 @@ struct ieee80211_he_mu_edca_parameter_se - /* B7: Reserved if sent by an AP; More Data Ack if sent by a non-AP STA */ - #define HE_QOS_INFO_MORE_DATA_ACK ((u8) (BIT(7))) - -+#define EHT_MAC_CAPAB_MAX_LEN 2 -+#define EHT_PHY_CAPAB_MAX_LEN 9 -+#define EHT_MCS_NSS_CAPAB_MAX_LEN 9 -+/* -+ * Maximum PPE threshold length: 62 bytes -+ * NSS: 4 bits (maximum NSS: 16), RU index: 5 bits, each pair: 6 bits -+ * 9 + (5 * 16 * 6) = 489 bits, Padding: 7 bits -+ */ -+#define EHT_PPE_THRESH_CAPAB_MAX_LEN 62 -+ -+/* IEEE P802.11be/D1.4, January 2022, section 9.4.2.313 */ -+struct ieee80211_eht_capabilities { -+ u8 mac_cap[EHT_MAC_CAPAB_MAX_LEN]; -+ u8 phy_cap[EHT_PHY_CAPAB_MAX_LEN]; -+ u8 optional[71]; -+} STRUCT_PACKED; -+ -+/* -+ * struct ieee80211_eht_operation - eht operation element -+ * -+ * This structure is the "EHT Operation Element" fields as -+ * described in P802.11be_D1.4 section 9.4.2.311 -+ * -+ * FIXME: The spec is unclear how big the fields are, and doesn't -+ * indicate the "Disabled Subchannel Bitmap Present" in the -+ * structure (Figure 9-1002a) at all ... -+ */ -+struct ieee80211_eht_operation { -+ u8 chan_width; -+ u8 ccfs; -+ u8 present_bm; -+ /* contains disabled subchannel bitmap */ -+ u8 optional[]; -+} STRUCT_PACKED; -+ -+/* IEEE P802.11be/D1.4, January 2022, section 9.4.2.313.3 */ -+#define EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_IDX 0 -+#define EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK ((u8) BIT(1)) -+ -+#define EHT_PHYCAP_SU_BEAMFORMER_IDX 0 -+#define EHT_PHYCAP_SU_BEAMFORMER ((u8) BIT(5)) -+#define EHT_PHYCAP_SU_BEAMFORMEE_IDX 0 -+#define EHT_PHYCAP_SU_BEAMFORMEE ((u8) BIT(6)) -+ -+#define EHT_PHYCAP_PPE_THRESHOLD_PRESENT_IDX 5 -+#define EHT_PHYCAP_PPE_THRESHOLD_PRESENT ((u8) BIT(3)) -+ -+#define EHT_PHYCAP_PPE_THRESHOLD_PRESENT_IDX 5 -+ -+#define EHT_PHYCAP_MU_BEAMFORMER_IDX 7 -+#define EHT_PHYCAP_MU_BEAMFORMER_80MHZ ((u8) BIT(4)) -+#define EHT_PHYCAP_MU_BEAMFORMER_160MHZ ((u8) BIT(5)) -+#define EHT_PHYCAP_MU_BEAMFORMER_320MHZ ((u8) BIT(6)) -+#define EHT_PHYCAP_MU_BEAMFORMER_MASK (EHT_PHYCAP_MU_BEAMFORMER_80MHZ | \ -+ EHT_PHYCAP_MU_BEAMFORMER_160MHZ | \ -+ EHT_PHYCAP_MU_BEAMFORMER_320MHZ) -+ -+/* -+ * IEEE P802.11be/D1.0, May 2021, -+ * section 9.4.2.295c.4 Supported EHT-MCS And NSS Set field -+ */ -+#define EHT_NSS_MAX_STREAMS 8 -+#define EHT_PHYCAP_MCS_NSS_LEN_20MHZ_ONLY 4 -+#define EHT_PHYCAP_MCS_NSS_LEN_20MHZ_PLUS 3 -+ -+/* IEEE P802.11be/D1.0, May 2021, 9.4.2.295c.5 EHT PPE Thresholds field */ -+#define EHT_PPE_THRES_NSS_SHIFT 0 -+#define EHT_PPE_THRES_NSS_MASK ((u8) (BIT(0) | BIT(1) | \ -+ BIT(2) | BIT(3))) -+#define EHT_PPE_THRES_RU_INDEX_SHIFT 4 -+#define EHT_PPE_THRES_RU_INDEX_MASK ((u8) (BIT(0) | BIT(1) | \ -+ BIT(2) | BIT(3) | \ -+ BIT(4))) -+ - /* IEEE P802.11ay/D4.0, 9.4.2.251 - EDMG Operation element */ - #define EDMG_BSS_OPERATING_CHANNELS_OFFSET 6 - #define EDMG_OPERATING_CHANNEL_WIDTH_OFFSET 7 diff --git a/feeds/ipq95xx/hostapd/patches/q02-003-eht-configuration-options-to-enable-disable-the-supp.patch b/feeds/ipq95xx/hostapd/patches/q02-003-eht-configuration-options-to-enable-disable-the-supp.patch deleted file mode 100644 index 785f0cc0..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-003-eht-configuration-options-to-enable-disable-the-supp.patch +++ /dev/null @@ -1,580 +0,0 @@ -From 1194cfc2d5835f2cb64b94eaae4431f3995fdc60 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Mon, 28 Jun 2021 13:30:29 -0700 -Subject: [PATCH] eht: configuration options to enable/disable the support - -Add compilation for flag 802.11be along with options to enable -EHT support per radio and disable_per interface. - -Enabling HE is mandatory to enable EHT mode. - -Tested-by: Pradeep Kumar Chitrapu -Signed-off-by: Aloka Dixit ---- - hostapd/Makefile | 4 ++++ - hostapd/config_file.c | 6 ++++++ - hostapd/hostapd.conf | 10 ++++++++++ - src/ap/ap_config.c | 17 +++++++++++++++++ - src/ap/ap_config.h | 2 ++ - src/ap/ctrl_iface_ap.c | 5 ++++- - src/ap/sta_info.c | 7 ++++--- - src/ap/sta_info.h | 2 +- - src/common/hw_features_common.c | 2 ++ - src/drivers/driver.h | 7 +++++++ - src/drivers/driver_nl80211.c | 14 ++++++++++++-- - wpa_supplicant/Makefile | 11 +++++++++++ - wpa_supplicant/ap.c | 5 +++++ - wpa_supplicant/config.c | 4 ++++ - wpa_supplicant/config_file.c | 3 +++ - wpa_supplicant/config_ssid.h | 12 ++++++++++++ - wpa_supplicant/ctrl_iface.c | 7 ++++--- - wpa_supplicant/events.c | 2 ++ - wpa_supplicant/sme.c | 3 +++ - wpa_supplicant/wpa_cli.c | 3 +++ - wpa_supplicant/wpa_supplicant.c | 39 +++++++++++++++++++++++++++++++++++++-- - wpa_supplicant/wpa_supplicant_i.h | 4 ++++ - 22 files changed, 157 insertions(+), 12 deletions(-) - -diff --git a/hostapd/Makefile b/hostapd/Makefile -index 002d68833c46..bf7d250fe6c6 100644 ---- a/hostapd/Makefile -+++ b/hostapd/Makefile -@@ -349,6 +349,10 @@ CFLAGS += -DCONFIG_IEEE80211AX - OBJS += ../src/ap/ieee802_11_he.o - endif - -+ifdef CONFIG_IEEE80211BE -+CFLAGS += -DCONFIG_IEEE80211BE -+endif -+ - ifdef CONFIG_MBO - CFLAGS += -DCONFIG_MBO - OBJS += ../src/ap/mbo_ap.o -diff --git a/hostapd/config_file.c b/hostapd/config_file.c -index 340eb4874f70..a928beb6dfe8 100644 ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -4622,6 +4622,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, - bss->disable_11ac = !!atoi(pos); - } else if (os_strcmp(buf, "disable_11ax") == 0) { - bss->disable_11ax = !!atoi(pos); -+ } else if (os_strcmp(buf, "disable_11be") == 0) { -+ bss->disable_11be = !!atoi(pos); - } else if (os_strcmp(buf, "beacon_tx_mode") == 0) { - int val = atoi(pos); - -@@ -4662,6 +4664,10 @@ static int hostapd_config_fill(struct hostapd_config *conf, - conf->mbssid = atoi(pos); - } else if (os_strcmp(buf, "ema") == 0) { - conf->ema = atoi(pos); -+#ifdef CONFIG_IEEE80211BE -+ } else if (os_strcmp(buf, "ieee80211be") == 0) { -+ conf->ieee80211be = atoi(pos); -+#endif /* CONFIG_IEEE80211BE */ - } else { - wpa_printf(MSG_ERROR, - "Line %d: unknown configuration item '%s'", -diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf -index 3303679211f5..9d35e0bcd49f 100644 ---- a/hostapd/hostapd.conf -+++ b/hostapd/hostapd.conf -@@ -996,6 +996,16 @@ wmm_ac_vo_acm=0 - # 1 = Enabled - #ema=0 - -+##### IEEE 802.11be related configuration ##################################### -+ -+#ieee80211be: Whether IEEE 802.11be (EHT) is enabled -+# 0 = disabled (default) -+# 1 = enabled -+#ieee80211be=1 -+ -+#disable_11be: Boolean (0/1) to disable EHT for a specific BSS -+#disable_11be=0 -+ - ##### IEEE 802.1X-2004 related configuration ################################## - - # Require IEEE 802.1X authorization -diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c -index 4ceb4803af5e..f036eb663c99 100644 ---- a/src/ap/ap_config.c -+++ b/src/ap/ap_config.c -@@ -1435,6 +1435,15 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss, - } - #endif /* CONFIG_FILS */ - -+#ifdef CONFIG_IEEE80211BE -+ if (full_config && bss->disable_11be == false && -+ bss->disable_11ax == true) { -+ bss->disable_11be = true; -+ wpa_printf(MSG_ERROR, -+ "Disabling IEEE 802.11be as IEEE 802.11ax is disabled for this BSS"); -+ } -+#endif /* CONFIG_IEEE80211BE */ -+ - return 0; - } - -@@ -1508,6 +1517,14 @@ int hostapd_config_check(struct hostapd_config *conf, int full_config) - return -1; - } - -+#ifdef CONFIG_IEEE80211BE -+ if (full_config && conf->ieee80211be && !conf->ieee80211ax) { -+ wpa_printf(MSG_ERROR, -+ "Cannot set ieee80211be without ieee80211ax"); -+ return -1; -+ } -+#endif /* CONFIG_IEEE80211BE */ -+ - for (i = 0; i < conf->num_bss; i++) { - if (hostapd_config_check_bss(conf->bss[i], conf, full_config)) - return -1; -diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h -index ebcca548d8cd..0bf8ca345172 100644 ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -537,6 +537,7 @@ struct hostapd_bss_config { - bool disable_11n; - bool disable_11ac; - bool disable_11ax; -+ bool disable_11be; - - /* IEEE 802.11v */ - int time_advertisement; -@@ -1127,6 +1128,7 @@ struct hostapd_config { - #endif /* CONFIG_AIRTIME_POLICY */ - u8 mbssid; - u8 ema; -+ int ieee80211be; - }; - - static inline u8 hostapd_get_he_6ghz_reg_pwr_type(struct hostapd_config *conf) -diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c -index e63cbf72dc54..c58715e8b765 100644 ---- a/src/ap/ctrl_iface_ap.c -+++ b/src/ap/ctrl_iface_ap.c -@@ -331,7 +331,7 @@ static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd, - return len; - len += ret; - -- ret = ap_sta_flags_txt(sta->flags, buf + len, buflen - len); -+ ret = ap_sta_flags_txt(sta->flags, sta->flags_ext, buf + len, buflen - len); - if (ret < 0) - return len; - len += ret; -@@ -1040,6 +1040,7 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf, - "ieee80211n=%d\n" - "ieee80211ac=%d\n" - "ieee80211ax=%d\n" -+ "ieee80211be=%d\n" - "beacon_int=%u\n" - "dtim_period=%d\n", - iface->conf->channel, -@@ -1052,6 +1053,8 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf, - !hapd->conf->disable_11ac, - iface->conf->ieee80211ax && - !hapd->conf->disable_11ax, -+ iface->conf->ieee80211be && -+ !hapd->conf->disable_11be, - iface->conf->beacon_int, - hapd->conf->dtim_period); - if (os_snprintf_error(buflen - len, ret)) -diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c -index 33ba7b8c5e66..0d446a7498e0 100644 ---- a/src/ap/sta_info.c -+++ b/src/ap/sta_info.c -@@ -1454,13 +1454,13 @@ void ap_sta_clear_disconnect_timeouts(struct hostapd_data *hapd, - } - - --int ap_sta_flags_txt(u32 flags, char *buf, size_t buflen) -+int ap_sta_flags_txt(u32 flags, u32 flags_ext, char *buf, size_t buflen) - { - int res; - - buf[0] = '\0'; - res = os_snprintf(buf, buflen, -- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", -+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", - (flags & WLAN_STA_AUTH ? "[AUTH]" : ""), - (flags & WLAN_STA_ASSOC ? "[ASSOC]" : ""), - (flags & WLAN_STA_AUTHORIZED ? "[AUTHORIZED]" : ""), -@@ -1483,7 +1483,8 @@ int ap_sta_flags_txt(u32 flags, char *buf, size_t buflen) - (flags & WLAN_STA_6GHZ ? "[6GHZ]" : ""), - (flags & WLAN_STA_VENDOR_VHT ? "[VENDOR_VHT]" : ""), - (flags & WLAN_STA_WNM_SLEEP_MODE ? -- "[WNM_SLEEP_MODE]" : "")); -+ "[WNM_SLEEP_MODE]" : ""), -+ (flags_ext & WLAN_STA_EXT_EHT ? "[EHT]" : "")); - if (os_snprintf_error(buflen, res)) - res = -1; - -diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h -index cac4318acafe..ec898bd15e1b 100644 ---- a/src/ap/sta_info.h -+++ b/src/ap/sta_info.h -@@ -401,7 +401,7 @@ void ap_sta_disassoc_cb(struct hostapd_data *hapd, struct sta_info *sta); - void ap_sta_clear_disconnect_timeouts(struct hostapd_data *hapd, - struct sta_info *sta); - --int ap_sta_flags_txt(u32 flags, char *buf, size_t buflen); -+int ap_sta_flags_txt(u32 flags, u32 flags_ext, char *buf, size_t buflen); - void ap_sta_delayed_1x_auth_fail_disconnect(struct hostapd_data *hapd, - struct sta_info *sta); - int ap_sta_pending_delayed_1x_auth_fail_disconnect(struct hostapd_data *hapd, -diff --git a/src/common/hw_features_common.c b/src/common/hw_features_common.c -index 539b40555ca9..d99cf606911c 100644 ---- a/src/common/hw_features_common.c -+++ b/src/common/hw_features_common.c -@@ -390,6 +390,8 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data, - { - if (!he_cap || !he_cap->he_supported) - he_enabled = 0; -+ if (!eht_cap || !eht_cap->eht_supported) -+ eht_enabled = 0; - os_memset(data, 0, sizeof(*data)); - data->mode = mode; - data->freq = freq; -diff --git a/src/drivers/driver.h b/src/drivers/driver.h -index ef86419fa5c9..01dab4dfdb78 100644 ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -1133,6 +1133,13 @@ struct wpa_driver_associate_params { - int disable_he; - #endif /* CONFIG_HE_OVERRIDES */ - -+#ifdef CONFIG_EHT_OVERRIDES -+ /** -+ * disable_eht - Disable EHT for this connection -+ */ -+ int disable_eht; -+#endif /* CONFIG_EHT_OVERRIDES */ -+ - /** - * req_key_mgmt_offload - Request key management offload for connection - * -diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c -index a8faf5193287..c79594399ce6 100644 ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -4969,6 +4969,7 @@ static int nl80211_put_freq_params(struct nl_msg *msg, - if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq->freq)) - return -ENOBUFS; - -+ wpa_printf(MSG_DEBUG, " * eht_enabled=%d", freq->eht_enabled); - wpa_printf(MSG_DEBUG, " * he_enabled=%d", freq->he_enabled); - wpa_printf(MSG_DEBUG, " * vht_enabled=%d", freq->vht_enabled); - wpa_printf(MSG_DEBUG, " * ht_enabled=%d", freq->ht_enabled); -@@ -5061,9 +5062,10 @@ static int nl80211_set_channel(struct i802_bss *bss, - int ret; - - wpa_printf(MSG_DEBUG, -- "nl80211: Set freq %d (ht_enabled=%d, vht_enabled=%d, he_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz)", -+ "nl80211: Set freq %d (ht_enabled=%d, vht_enabled=%d, he_enabled=%d, eht_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz)", - freq->freq, freq->ht_enabled, freq->vht_enabled, freq->he_enabled, -- freq->bandwidth, freq->center_freq1, freq->center_freq2); -+ freq->eht_enabled, freq->bandwidth, freq->center_freq1, -+ freq->center_freq2); - - msg = nl80211_bss_msg(bss, 0, set_chan ? NL80211_CMD_SET_CHANNEL : - NL80211_CMD_SET_WIPHY); -@@ -6042,6 +6044,14 @@ static int nl80211_ht_vht_overrides(struct nl_msg *msg, - } - #endif /* CONFIG_HE_OVERRIDES */ - -+#ifdef CONFIG_EHT_OVERRIDES -+ if (params->disable_eht) { -+ wpa_printf(MSG_DEBUG, " * EHT disabled"); -+ if (nla_put_flag(msg, NL80211_ATTR_DISABLE_EHT)) -+ return -1; -+ } -+#endif /* CONFIG_EHT_OVERRIDES */ -+ - return 0; - } - -diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile -index 4c6592b62f5b..b5015c3f4019 100644 ---- a/wpa_supplicant/Makefile -+++ b/wpa_supplicant/Makefile -@@ -193,6 +193,10 @@ ifdef CONFIG_HE_OVERRIDES - CFLAGS += -DCONFIG_HE_OVERRIDES - endif - -+ifdef CONFIG_EHT_OVERRIDES -+CFLAGS += -DCONFIG_EHT_OVERRIDES -+endif -+ - ifndef CONFIG_BACKEND - CONFIG_BACKEND=file - endif -@@ -942,6 +946,9 @@ endif - ifdef CONFIG_IEEE80211AX - OBJS += ../src/ap/ieee802_11_he.o - endif -+ifdef CONFIG_IEEE80211BE -+OBJS += ../src/ap/ieee802_11_eht.o -+endif - ifdef CONFIG_WNM_AP - CFLAGS += -DCONFIG_WNM_AP - OBJS += ../src/ap/wnm_ap.o -@@ -971,6 +978,10 @@ ifdef CONFIG_IEEE80211AX - CFLAGS += -DCONFIG_IEEE80211AX - endif - -+ifdef CONFIG_IEEE80211BE -+CFLAGS += -DCONFIG_IEEE80211BE -+endif -+ - ifdef NEED_AP_MLME - OBJS += ../src/ap/wmm.o - OBJS += ../src/ap/ap_list.o -diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c -index 5c65d2dd68cc..a9d995af7719 100644 ---- a/wpa_supplicant/ap.c -+++ b/wpa_supplicant/ap.c -@@ -395,6 +395,11 @@ int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s, - HT_CAP_INFO_TX_STBC | - HT_CAP_INFO_MAX_AMSDU_SIZE); - -+ if (mode->eht_capab[wpas_mode_to_ieee80211_mode( -+ ssid->mode)].eht_supported && -+ ssid->eht) -+ conf->ieee80211be = 1; -+ - /* check this before VHT, because setting oper chan - * width and friends is the same call for HE and VHT - * and checks if conf->ieee8021ax == 1 */ -diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c -index 8274ec9e53d4..c2e24125ae5a 100644 ---- a/wpa_supplicant/config.c -+++ b/wpa_supplicant/config.c -@@ -2764,6 +2764,9 @@ static const struct parse_data ssid_fields[] = { - #ifdef CONFIG_HE_OVERRIDES - { INT_RANGE(disable_he, 0, 1)}, - #endif /* CONFIG_HE_OVERRIDES */ -+#ifdef CONFIG_EHT_OVERRIDES -+ { INT_RANGE(disable_eht, 0, 1)}, -+#endif /* CONFIG_EHT_OVERRIDES */ - { INT(ap_max_inactivity) }, - { INT(dtim_period) }, - { INT(beacon_int) }, -@@ -3273,6 +3276,7 @@ void wpa_config_set_network_defaults(struct wpa_ssid *ssid) - ssid->ht = 1; - ssid->vht = 1; - ssid->he = 1; -+ ssid->eht = 1; - #ifdef IEEE8021X_EAPOL - ssid->eapol_flags = DEFAULT_EAPOL_FLAGS; - ssid->eap_workaround = DEFAULT_EAP_WORKAROUND; -diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c -index d5187c95aabb..58346e02ffc3 100644 ---- a/wpa_supplicant/config_file.c -+++ b/wpa_supplicant/config_file.c -@@ -887,6 +887,9 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) - #ifdef CONFIG_HE_OVERRIDES - INT(disable_he); - #endif /* CONFIG_HE_OVERRIDES */ -+#ifdef CONFIG_EHT_OVERRIDES -+ INT(disable_eht); -+#endif /* CONFIG_EHT_OVERRIDES */ - INT(disable_40mhz_scan); - INT(beacon_tx_mode); - INT(enable_160mhz_bw); -diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h -index 395b7e517fd0..4ac5324aea8e 100644 ---- a/wpa_supplicant/config_ssid.h -+++ b/wpa_supplicant/config_ssid.h -@@ -567,6 +567,8 @@ struct wpa_ssid { - - int he; - -+ int eht; -+ - int max_oper_chwidth; - - unsigned int vht_center_freq1; -@@ -814,6 +816,16 @@ struct wpa_ssid { - int disable_he; - #endif /* CONFIG_HE_OVERRIDES */ - -+#ifdef CONFIG_EHT_OVERRIDES -+ /** -+ * disable_eht - Disable EHT (IEEE 802.11be) for this network -+ * -+ * By default, use it if it is available, but this can be configured -+ * to 1 to have it disabled. -+ */ -+ int disable_eht; -+#endif /* CONFIG_EHT_OVERRIDES */ -+ - /** - * ap_max_inactivity - Timeout in seconds to detect STA's inactivity - * -diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c -index b53a538bec54..45befc9f1dc0 100644 ---- a/wpa_supplicant/ctrl_iface.c -+++ b/wpa_supplicant/ctrl_iface.c -@@ -2306,11 +2306,12 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s, - - if (wpa_s->connection_set && - (wpa_s->connection_ht || wpa_s->connection_vht || -- wpa_s->connection_he)) { -+ wpa_s->connection_he || wpa_s->connection_eht)) { - ret = os_snprintf(pos, end - pos, - "wifi_generation=%u\n", -- wpa_s->connection_he ? 6 : -- (wpa_s->connection_vht ? 5 : 4)); -+ wpa_s->connection_eht ? 7 : -+ (wpa_s->connection_he ? 6 : -+ (wpa_s->connection_vht ? 5 : 4))); - if (os_snprintf_error(end - pos, ret)) - return pos - buf; - pos += ret; -diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c -index 13929de49c97..d53e54e65408 100644 ---- a/wpa_supplicant/events.c -+++ b/wpa_supplicant/events.c -@@ -2952,6 +2952,8 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s, - BAND_2_4_GHZ); - wpa_s->connection_he = req_elems.he_capabilities && - resp_elems.he_capabilities; -+ wpa_s->connection_eht = req_elems.eht_capabilities && -+ resp_elems.eht_capabilities; - } - } - -diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c -index 1dc7001a7305..9f37e64fe85c 100644 ---- a/wpa_supplicant/sme.c -+++ b/wpa_supplicant/sme.c -@@ -1980,6 +1980,9 @@ mscs_fail: - #ifdef CONFIG_HE_OVERRIDES - wpa_supplicant_apply_he_overrides(wpa_s, ssid, ¶ms); - #endif /* CONFIG_HE_OVERRIDES */ -+#ifdef CONFIG_EHT_OVERRIDES -+ wpa_supplicant_apply_eht_overrides(wpa_s, ssid, ¶ms); -+#endif /* CONFIG_EHT_OVERRIDES */ - #ifdef CONFIG_IEEE80211R - if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies && - get_ie(wpa_s->sme.ft_ies, wpa_s->sme.ft_ies_len, -diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c -index 23e09a66e259..8e5a8ff2d1e5 100644 ---- a/wpa_supplicant/wpa_cli.c -+++ b/wpa_supplicant/wpa_cli.c -@@ -1471,6 +1471,9 @@ static const char *network_fields[] = { - #ifdef CONFIG_HE_OVERRIDES - "disable_he", - #endif /* CONFIG_HE_OVERRIDES */ -+#ifdef CONFIG_EHT_OVERRIDES -+ "disable_eht", -+#endif /* CONFIG_EHT_OVERRIDES */ - "ap_max_inactivity", "dtim_period", "beacon_int", - #ifdef CONFIG_MACSEC - "macsec_policy", -diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c -index 07cd01c65776..593e5b851616 100644 ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -2584,10 +2584,18 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, - - /* Allow HE on 2.4 GHz without VHT: see nl80211_put_freq_params() */ - if (is_24ghz) { -+#ifdef CONFIG_EHT_OVERRIDES -+ if (is_24ghz && ssid->disable_eht) -+ freq->eht_enabled = 0; -+ else -+#endif /* CONFIG_EHT_OVERRIDES */ -+ freq->eht_enabled = mode->eht_capab[ieee80211_mode].eht_supported; -+ - #ifdef CONFIG_HE_OVERRIDES -- if (ssid->disable_he) -+ if (ssid->disable_he) { - freq->he_enabled = 0; -- else -+ freq->eht_enabled = 0; -+ } else - #endif /* CONFIG_HE_OVERRIDES */ - freq->he_enabled = mode->he_capab[ieee80211_mode].he_supported; - -@@ -2691,6 +2699,13 @@ skip_vht80: - vht_freq.he_enabled = 0; - #endif /* CONFIG_HE_OVERRIDES */ - -+#ifdef CONFIG_EHT_OVERRIDES -+skip_vht80: -+ if (ssid->disable_eht) -+ vht_freq.eht_enabled = 0; -+#endif /* CONFIG_EHT_OVERRIDES */ -+ -+ - #ifdef CONFIG_HT_OVERRIDES - skip_ht40: - #endif /* CONFIG_HT_OVERRIDES */ -@@ -2845,6 +2860,12 @@ skip_to_6ghz: - freq->he_enabled = 0; - } - #endif /* CONFIG_HE_OVERRIDES */ -+#ifdef CONFIG_EHT_OVERRIDES -+ if (ssid->disable_eht) { -+ vht_freq.eht_enabled = 0; -+ freq->eht_enabled = 0; -+ } -+#endif /* CONFIG_EHT_OVERRIDES */ - if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq, - freq->channel, ssid->enable_edmg, - ssid->edmg_channel, freq->ht_enabled, -@@ -4061,6 +4082,9 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) - #ifdef CONFIG_HE_OVERRIDES - wpa_supplicant_apply_he_overrides(wpa_s, ssid, ¶ms); - #endif /* CONFIG_HE_OVERRIDES */ -+#ifdef CONFIG_EHT_OVERRIDES -+ wpa_supplicant_apply_eht_overrides(wpa_s, ssid, ¶ms); -+#endif /* CONFIG_EHT_OVERRIDES */ - - #ifdef CONFIG_P2P - /* -@@ -5857,6 +5881,17 @@ void wpa_supplicant_apply_he_overrides( - } - #endif /* CONFIG_HE_OVERRIDES */ - -+#ifdef CONFIG_EHT_OVERRIDES -+void wpa_supplicant_apply_eht_overrides( -+ struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, -+ struct wpa_driver_associate_params *params) -+{ -+ if (!ssid) -+ return; -+ -+ params->disable_eht = ssid->disable_eht; -+} -+#endif /* CONFIG_EHT_OVERRIDES */ - - static int pcsc_reader_init(struct wpa_supplicant *wpa_s) - { -diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h -index 5fa765fda25c..fd75d1bfe813 100644 ---- a/wpa_supplicant/wpa_supplicant_i.h -+++ b/wpa_supplicant/wpa_supplicant_i.h -@@ -958,6 +958,7 @@ struct wpa_supplicant { - unsigned int connection_ht:1; - unsigned int connection_vht:1; - unsigned int connection_he:1; -+ unsigned int connection_eht:1; - unsigned int disable_mbo_oce:1; - - struct os_reltime last_mac_addr_change; -@@ -1532,6 +1533,9 @@ void wpa_supplicant_apply_vht_overrides( - void wpa_supplicant_apply_he_overrides( - struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, - struct wpa_driver_associate_params *params); -+void wpa_supplicant_apply_eht_overrides( -+ struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, -+ struct wpa_driver_associate_params *params); - - int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); - int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s, --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-004-eht-operating-channel-width-configuration.patch b/feeds/ipq95xx/hostapd/patches/q02-004-eht-operating-channel-width-configuration.patch deleted file mode 100644 index be9802bc..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-004-eht-operating-channel-width-configuration.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 69e25643c80531592bd048ba08ff66d14aee4ca5 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Mon, 20 Sep 2021 13:53:40 -0700 -Subject: [PATCH 04/23] eht: operating channel width configuration - -Add new configuration options to configure EHT operating channel width -and center frequency. - -Signed-off-by: Aloka Dixit ---- - hostapd/config_file.c | 4 ++++ - hostapd/hostapd.conf | 9 +++++++++ - src/ap/ap_config.h | 20 ++++++++++++++++++++ - src/ap/ctrl_iface_ap.c | 13 +++++++++++++ - 4 files changed, 46 insertions(+) - ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -4626,6 +4626,10 @@ static int hostapd_config_fill(struct ho - #ifdef CONFIG_IEEE80211BE - } else if (os_strcmp(buf, "ieee80211be") == 0) { - conf->ieee80211be = atoi(pos); -+ } else if (os_strcmp(buf, "eht_oper_chwidth") == 0) { -+ conf->eht_oper_chwidth = atoi(pos); -+ } else if (os_strcmp(buf, "eht_oper_centr_freq_seg0_idx") == 0) { -+ conf->eht_oper_centr_freq_seg0_idx = atoi(pos); - #endif /* CONFIG_IEEE80211BE */ - } else { - wpa_printf(MSG_ERROR, ---- a/hostapd/hostapd.conf -+++ b/hostapd/hostapd.conf -@@ -973,6 +973,15 @@ wmm_ac_vo_acm=0 - #disable_11be: Boolean (0/1) to disable EHT for a specific BSS - #disable_11be=0 - -+# EHT operating channel information; see matching he_* parameters for details. -+# The field eht_oper_centr_freq_seg0_idx field is used to indicate center -+# frequency of 40, 80 and 160 MHz bandwidth operation. -+# In 6 GHz band, eht_oper_chwidth is ignored and the channel width is -+# derived from the configured operating class (IEEE P802.11be/D1.1, July 2021, -+# Annex E, E.1 Country information and operating classes). -+#eht_oper_chwidth -+#eht_oper_centr_freq_seg0_idx -+ - ##### IEEE 802.1X-2004 related configuration ################################## - - # Require IEEE 802.1X authorization ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -1113,6 +1113,10 @@ struct hostapd_config { - #endif /* CONFIG_AIRTIME_POLICY */ - - int ieee80211be; -+#ifdef CONFIG_IEEE80211BE -+ u8 eht_oper_chwidth; -+ u8 eht_oper_centr_freq_seg0_idx; -+#endif /* CONFIG_IEEE80211BE */ - }; - - static inline u8 hostapd_get_he_6ghz_reg_pwr_type(struct hostapd_config *conf) -@@ -1127,6 +1131,10 @@ static inline u8 hostapd_get_he_6ghz_reg - - static inline u8 hostapd_get_oper_chwidth(struct hostapd_config *conf) - { -+#ifdef CONFIG_IEEE80211BE -+ if (conf->ieee80211be) -+ return conf->eht_oper_chwidth; -+#endif /* CONFIG_IEEE80211BE */ - #ifdef CONFIG_IEEE80211AX - if (conf->ieee80211ax) - return conf->he_oper_chwidth; -@@ -1137,6 +1145,10 @@ static inline u8 hostapd_get_oper_chwidt - static inline void - hostapd_set_oper_chwidth(struct hostapd_config *conf, u8 oper_chwidth) - { -+#ifdef CONFIG_IEEE80211BE -+ if (conf->ieee80211be) -+ conf->eht_oper_chwidth = oper_chwidth; -+#endif /* CONFIG_IEEE80211BE */ - #ifdef CONFIG_IEEE80211AX - if (conf->ieee80211ax) - conf->he_oper_chwidth = oper_chwidth; -@@ -1147,6 +1159,10 @@ hostapd_set_oper_chwidth(struct hostapd_ - static inline u8 - hostapd_get_oper_centr_freq_seg0_idx(struct hostapd_config *conf) - { -+#ifdef CONFIG_IEEE80211BE -+ if (conf->ieee80211be) -+ return conf->eht_oper_centr_freq_seg0_idx; -+#endif /* CONFIG_IEEE80211BE */ - #ifdef CONFIG_IEEE80211AX - if (conf->ieee80211ax) - return conf->he_oper_centr_freq_seg0_idx; -@@ -1158,6 +1174,10 @@ static inline void - hostapd_set_oper_centr_freq_seg0_idx(struct hostapd_config *conf, - u8 oper_centr_freq_seg0_idx) - { -+#ifdef CONFIG_IEEE80211BE -+ if (conf->ieee80211be) -+ conf->eht_oper_centr_freq_seg0_idx = oper_centr_freq_seg0_idx; -+#endif /* CONFIG_IEEE80211BE */ - #ifdef CONFIG_IEEE80211AX - if (conf->ieee80211ax) - conf->he_oper_centr_freq_seg0_idx = oper_centr_freq_seg0_idx; ---- a/src/ap/ctrl_iface_ap.c -+++ b/src/ap/ctrl_iface_ap.c -@@ -1050,6 +1050,19 @@ int hostapd_ctrl_iface_status(struct hos - return len; - len += ret; - -+#ifdef CONFIG_IEEE80211BE -+ if (iface->conf->ieee80211be && !hapd->conf->disable_11be) { -+ ret = os_snprintf(buf + len, buflen - len, -+ "eht_oper_chwidth=%d\n" -+ "eht_oper_centr_freq_seg0_idx=%d\n", -+ iface->conf->eht_oper_chwidth, -+ iface->conf->eht_oper_centr_freq_seg0_idx); -+ if (os_snprintf_error(buflen - len, ret)) -+ return len; -+ len += ret; -+ } -+#endif /* CONFIG_IEEE80211BE */ -+ - #ifdef CONFIG_IEEE80211AX - if (iface->conf->ieee80211ax && !hapd->conf->disable_11ax) { - ret = os_snprintf(buf + len, buflen - len, diff --git a/feeds/ipq95xx/hostapd/patches/q02-005-eht-beamforming-capabilities-configuration.patch b/feeds/ipq95xx/hostapd/patches/q02-005-eht-beamforming-capabilities-configuration.patch deleted file mode 100644 index 716e741b..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-005-eht-beamforming-capabilities-configuration.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 23a71230cec01409bc535e110a52e70ba2511319 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Tue, 29 Jun 2021 17:20:42 -0700 -Subject: [PATCH 05/23] eht: beamforming capabilities configuration - -Add configuration options to set SU/MU beamforming capabilities. - -Signed-off-by: Aloka Dixit ---- - hostapd/config_file.c | 6 ++++++ - src/ap/ap_config.h | 10 ++++++++++ - 2 files changed, 16 insertions(+) - -diff --git a/hostapd/config_file.c b/hostapd/config_file.c -index b15f94889f16..dada06c365b2 100644 ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -4733,6 +4733,12 @@ static int hostapd_config_fill(struct hostapd_config *conf, - conf->eht_oper_chwidth = atoi(pos); - } else if (os_strcmp(buf, "eht_oper_centr_freq_seg0_idx") == 0) { - conf->eht_oper_centr_freq_seg0_idx = atoi(pos); -+ } else if (os_strcmp(buf, "eht_su_beamformer") == 0) { -+ conf->eht_phy_capab.su_beamformer = atoi(pos); -+ } else if (os_strcmp(buf, "eht_su_beamformee") == 0) { -+ conf->eht_phy_capab.su_beamformee = atoi(pos); -+ } else if (os_strcmp(buf, "eht_mu_beamformer") == 0) { -+ conf->eht_phy_capab.mu_beamformer = atoi(pos); - #endif /* CONFIG_IEEE80211BE */ - } else { - wpa_printf(MSG_ERROR, -diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h -index 0670a7c3380c..69f8ddac0396 100644 ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -937,6 +937,15 @@ struct spatial_reuse { - u8 srg_partial_bssid_bitmap[8]; - }; - -+/** -+ * struct eht_phy_capabilities_info - EHT PHY capabilities -+ */ -+struct eht_phy_capabilities_info { -+ bool su_beamformer; -+ bool su_beamformee; -+ bool mu_beamformer; -+}; -+ - /** - * struct hostapd_config - Per-radio interface configuration - */ -@@ -1106,6 +1115,7 @@ struct hostapd_config { - #ifdef CONFIG_IEEE80211BE - u8 eht_oper_chwidth; - u8 eht_oper_centr_freq_seg0_idx; -+ struct eht_phy_capabilities_info eht_phy_capab; - #endif /* CONFIG_IEEE80211BE */ - }; - --- -2.31.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-006-eht-macro-for-320-MHZ-channel-width.patch b/feeds/ipq95xx/hostapd/patches/q02-006-eht-macro-for-320-MHZ-channel-width.patch deleted file mode 100644 index 2395ecfe..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-006-eht-macro-for-320-MHZ-channel-width.patch +++ /dev/null @@ -1,33 +0,0 @@ -From d8b4c1a635e5aecf9afed3861cfad92bf75c823c Mon Sep 17 00:00:00 2001 -From: Muna Sinada -Date: Thu, 15 Jul 2021 10:26:21 -0700 -Subject: [PATCH 06/23] eht: macro for 320 MHZ channel width - -Add CHANWIDTH_320MHZ macro for 320 MHz bandwidth. - -Signed-off-by: Muna Sinada -Signed-off-by: Aloka Dixit ---- - src/common/ieee802_11_defs.h | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -1348,7 +1348,7 @@ struct ieee80211_ampe_ie { - - #define VHT_RX_NSS_MAX_STREAMS 8 - --/* VHT/EDMG channel widths */ -+/* EHT/HE/VHT/EDMG channel widths */ - #define CHANWIDTH_USE_HT 0 - #define CHANWIDTH_80MHZ 1 - #define CHANWIDTH_160MHZ 2 -@@ -1358,7 +1358,7 @@ struct ieee80211_ampe_ie { - #define CHANWIDTH_6480MHZ 6 - #define CHANWIDTH_8640MHZ 7 - #define CHANWIDTH_40MHZ_6GHZ 8 -- -+#define CHANWIDTH_320MHZ 9 - #define HE_NSS_MAX_STREAMS 8 - - #define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs) diff --git a/feeds/ipq95xx/hostapd/patches/q02-007-eht-support-for-operating-class-137.patch b/feeds/ipq95xx/hostapd/patches/q02-007-eht-support-for-operating-class-137.patch deleted file mode 100644 index 6c2ed175..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-007-eht-support-for-operating-class-137.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 0e520bc273ba6cb91137a19bb86c4b1ef8be43fe Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Mon, 20 Sep 2021 13:57:58 -0700 -Subject: [PATCH 07/23] eht: support for operating class 137 - -IEEE P802.11be/D1.4, January 2022, Annex E, section E.1 adds a new -value 137 to be used for 320 Mhz bandwidth in 6GHz band. -Modify existing functions related to operating class to include this -value. - -Signed-off-by: Aloka Dixit ---- - src/common/ieee802_11_common.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c -index 5b74ddcdf62b..d7f8914e35bf 100644 ---- a/src/common/ieee802_11_common.c -+++ b/src/common/ieee802_11_common.c -@@ -1052,6 +1052,9 @@ enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq, - case CHANWIDTH_80P80MHZ: - *op_class = 135; - break; -+ case CHANWIDTH_320MHZ: -+ *op_class = 137; -+ break; - default: - if (sec_channel) - *op_class = 132; -@@ -1444,6 +1447,7 @@ static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan) - case 133: /* UHB channels, 80 MHz: 7, 23, 39.. */ - case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */ - case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */ -+ case 137: /* UHB channels, 320 MHz: 31, 63, 95, 127, 159, 191 */ - if (chan < 1 || chan > 233) - return -1; - return 5950 + chan * 5; -@@ -2279,7 +2283,11 @@ bool is_6ghz_freq(int freq) - - bool is_6ghz_op_class(u8 op_class) - { -+#ifdef CONFIG_IEEE80211BE -+ return op_class >= 131 && op_class <= 137; -+#else - return op_class >= 131 && op_class <= 136; -+#endif /* CONFIG_IEEE80211BE */ - } - - -@@ -2585,6 +2593,8 @@ int op_class_to_bandwidth(u8 op_class) - return 160; - case 136: /* UHB channels, 20 MHz: 2 */ - return 20; -+ case 137: /* UHB channels, 320 MHz: 31 63 95 127 159 191 */ -+ return 320; - case 180: /* 60 GHz band, channels 1..8 */ - return 2160; - case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */ -@@ -2647,6 +2657,8 @@ int op_class_to_ch_width(u8 op_class) - return CHANWIDTH_80P80MHZ; - case 136: /* UHB channels, 20 MHz: 2 */ - return CHANWIDTH_USE_HT; -+ case 137: /* 320 MHz: 31 63 95 127 159 191 */ -+ return CHANWIDTH_320MHZ; - case 180: /* 60 GHz band, channels 1..8 */ - return CHANWIDTH_2160MHZ; - case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */ --- -2.31.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-008-eht-add-capabilities-element-in-management-frames.patch b/feeds/ipq95xx/hostapd/patches/q02-008-eht-add-capabilities-element-in-management-frames.patch deleted file mode 100644 index 435d601e..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-008-eht-add-capabilities-element-in-management-frames.patch +++ /dev/null @@ -1,316 +0,0 @@ -From add539d6f28cce4519abad790fd4e423078b4ab7 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Tue, 29 Jun 2021 16:46:36 -0700 -Subject: [PATCH 08/23] eht: add capabilities element in management frames. - -Add EHT capabilities IE in beacons, probe responses and association -response frames. - -Signed-off-by: Aloka Dixit -Signed-off-by: Pradeep Kumar Chitrapu ---- - hostapd/Makefile | 1 + - src/ap/beacon.c | 22 ++++++ - src/ap/ieee802_11.c | 10 +++ - src/ap/ieee802_11.h | 4 ++ - src/ap/ieee802_11_eht.c | 154 ++++++++++++++++++++++++++++++++++++++++ - src/drivers/driver.h | 14 ++++ - 6 files changed, 205 insertions(+) - create mode 100644 src/ap/ieee802_11_eht.c - ---- a/hostapd/Makefile -+++ b/hostapd/Makefile -@@ -351,6 +351,7 @@ endif - - ifdef CONFIG_IEEE80211BE - CFLAGS += -DCONFIG_IEEE80211BE -+OBJS += ../src/ap/ieee802_11_eht.o - endif - - ifdef CONFIG_MBO ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -639,6 +639,11 @@ static u8 * hostapd_gen_probe_resp(struc - } - #endif /* CONFIG_IEEE80211AX */ - -+#ifdef CONFIG_IEEE80211BE -+ if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) -+ buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP); -+#endif /* CONFIG_IEEE80211BE */ -+ - buflen += hostapd_eid_mbssid_len(hapd_probed, WLAN_FC_STYPE_PROBE_RESP, - NULL, known_bss, known_bss_len, NULL); - buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP); -@@ -780,6 +785,11 @@ static u8 * hostapd_gen_probe_resp(struc - } - #endif /* CONFIG_IEEE80211AX */ - -+#ifdef CONFIG_IEEE80211BE -+ if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) -+ pos = hostapd_eid_eht_capab(hapd, pos, IEEE80211_MODE_AP); -+#endif /* CONFIG_IEEE80211BE */ -+ - #ifdef CONFIG_IEEE80211AC - if (hapd->conf->vendor_vht) - pos = hostapd_eid_vendor_vht(hapd, pos); -@@ -1707,6 +1717,11 @@ int ieee802_11_build_ap_params(struct ho - } - #endif /* CONFIG_IEEE80211AX */ - -+#ifdef CONFIG_IEEE80211BE -+ if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) -+ tail_len += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP); -+#endif /* CONFIG_IEEE80211BE */ -+ - if (hapd->iconf->ema) - tail_len += 5; /* Multiple BSSID Configuration element */ - tail_len += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_BEACON); -@@ -1857,6 +1872,12 @@ int ieee802_11_build_ap_params(struct ho - } - #endif /* CONFIG_IEEE80211AX */ - -+#ifdef CONFIG_IEEE80211BE -+ if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) -+ tailpos = hostapd_eid_eht_capab(hapd, tailpos, -+ IEEE80211_MODE_AP); -+#endif /* CONFIG_IEEE80211BE */ -+ - #ifdef CONFIG_IEEE80211AC - if (hapd->conf->vendor_vht) - tailpos = hostapd_eid_vendor_vht(hapd, tailpos); ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -5083,6 +5083,11 @@ static u16 send_assoc_resp(struct hostap - if (sta && sta->dpp_pfs) - buflen += 5 + sta->dpp_pfs->curve->prime_len; - #endif /* CONFIG_DPP2 */ -+#ifdef CONFIG_IEEE80211BE -+ if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) -+ buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP); -+#endif /* CONFIG_IEEE80211BE */ -+ - buf = os_zalloc(buflen); - if (!buf) { - res = WLAN_STATUS_UNSPECIFIED_FAILURE; -@@ -5197,6 +5202,11 @@ static u16 send_assoc_resp(struct hostap - } - #endif /* CONFIG_IEEE80211AX */ - -+#ifdef CONFIG_IEEE80211BE -+ if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) -+ p = hostapd_eid_eht_capab(hapd, p, IEEE80211_MODE_AP); -+#endif /* CONFIG_IEEE80211BE */ -+ - p = hostapd_eid_ext_capab(hapd, p); - p = hostapd_eid_bss_max_idle_period(hapd, p); - if (sta && sta->qos_map_enabled) ---- a/src/ap/ieee802_11.h -+++ b/src/ap/ieee802_11.h -@@ -215,5 +215,8 @@ void auth_sae_process_commit(void *eloop - u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len); - size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type); - u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type); -- -+size_t hostapd_eid_eht_capab_len(struct hostapd_data *hapd, -+ enum ieee80211_op_mode opmode); -+u8 * hostapd_eid_eht_capab(struct hostapd_data *hapd, u8 *eid, -+ enum ieee80211_op_mode opmode); - #endif /* IEEE802_11_H */ ---- /dev/null -+++ b/src/ap/ieee802_11_eht.c -@@ -0,0 +1,164 @@ -+/* -+ * hostapd / IEEE 802.11be EHT -+ * -+ * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include "utils/includes.h" -+#include "utils/common.h" -+#include "hostapd.h" -+#include "ieee802_11.h" -+ -+static u8 ieee80211_eht_ppet_size(const u8 *ppe_thres, const u8 *phy_cap_info) -+{ -+ u8 sz = 0, ru; -+ -+ if ((phy_cap_info[EHT_PHYCAP_PPE_THRESHOLD_PRESENT_IDX] & -+ EHT_PHYCAP_PPE_THRESHOLD_PRESENT) == 0) -+ return 0; -+ -+ ru = (ppe_thres[0] & -+ (EHT_PPE_THRES_RU_INDEX_MASK << EHT_PPE_THRES_RU_INDEX_SHIFT)); -+ while (ru) { -+ if (ru & 0x1) -+ sz++; -+ ru >>= 1; -+ } -+ -+ ru = (ppe_thres[1] & (EHT_PPE_THRES_RU_INDEX_MASK >> -+ (8 - EHT_PPE_THRES_RU_INDEX_SHIFT))); -+ while (ru) { -+ if (ru & 0x1) -+ sz++; -+ ru >>= 1; -+ } -+ -+ sz *= (1 + (ppe_thres[0] & EHT_PPE_THRES_NSS_MASK)); -+ sz = (sz * 6) + 9; -+ if (sz % 8) -+ sz += 8; -+ sz /= 8; -+ -+ return sz; -+} -+ -+ -+static u8 ieee80211_eht_mcs_set_size(const u8 *he_phy_cap, -+ const u8 *eht_phy_cap) -+{ -+ u8 sz = EHT_PHYCAP_MCS_NSS_LEN_20MHZ_PLUS; -+ -+ if ((he_phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] & -+ (HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G | -+ HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G | -+ HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G | -+ HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G)) == 0) -+ return EHT_PHYCAP_MCS_NSS_LEN_20MHZ_ONLY; -+ -+ if (he_phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] & -+ (HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G | -+ HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G)) -+ sz += EHT_PHYCAP_MCS_NSS_LEN_20MHZ_PLUS; -+ -+ if (eht_phy_cap[EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_IDX] & -+ EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK) -+ sz += EHT_PHYCAP_MCS_NSS_LEN_20MHZ_PLUS; -+ -+ return sz; -+} -+ -+ -+size_t hostapd_eid_eht_capab_len(struct hostapd_data *hapd, -+ enum ieee80211_op_mode opmode) -+{ -+ struct hostapd_hw_modes *mode; -+ struct eht_capabilities *eht_cap; -+ size_t len = 3 + EHT_MAC_CAPAB_MAX_LEN + EHT_PHY_CAPAB_MAX_LEN; -+ -+ mode = hapd->iface->current_mode; -+ if (!mode) -+ return 0; -+ -+ eht_cap = &mode->eht_capab[opmode]; -+ if (!eht_cap->eht_supported) -+ return 0; -+ -+ len += ieee80211_eht_mcs_set_size(mode->he_capab[opmode].phy_cap, -+ eht_cap->phy_cap); -+ len += ieee80211_eht_ppet_size(eht_cap->ppet, eht_cap->phy_cap); -+ -+ return len; -+} -+ -+u8 * hostapd_eid_eht_capab(struct hostapd_data *hapd, u8 *eid, -+ enum ieee80211_op_mode opmode) -+{ -+ struct hostapd_hw_modes *mode; -+ struct eht_capabilities *eht_cap; -+ struct ieee80211_eht_capabilities *cap; -+ size_t mcs_nss_len, ppe_thresh_len; -+ u8 *pos = eid, *length_pos; -+ -+ mode = hapd->iface->current_mode; -+ if (!mode) -+ return eid; -+ -+ eht_cap = &mode->eht_capab[opmode]; -+ if (!eht_cap->eht_supported) -+ return eid; -+ -+ *pos++ = WLAN_EID_EXTENSION; -+ length_pos = pos++; -+ *pos++ = WLAN_EID_EXT_EHT_CAPABILITY; -+ -+ cap = (struct ieee80211_eht_capabilities *) pos; -+ os_memset(cap, 0, sizeof(*cap)); -+ os_memcpy(cap->mac_cap, eht_cap->mac_cap, EHT_MAC_CAPAB_MAX_LEN); -+ os_memcpy(cap->phy_cap, eht_cap->phy_cap, EHT_PHY_CAPAB_MAX_LEN); -+ -+ if (!is_6ghz_op_class(hapd->iconf->op_class)) -+ cap->phy_cap[EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_IDX] &= -+ ~EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK; -+ if (!hapd->iface->conf->eht_phy_capab.su_beamformer) -+ cap->phy_cap[EHT_PHYCAP_SU_BEAMFORMER_IDX] &= -+ ~EHT_PHYCAP_SU_BEAMFORMER; -+ -+ if (!hapd->iface->conf->eht_phy_capab.su_beamformee) -+ cap->phy_cap[EHT_PHYCAP_SU_BEAMFORMEE_IDX] &= -+ ~EHT_PHYCAP_SU_BEAMFORMEE; -+ -+ if (!hapd->iface->conf->eht_phy_capab.mu_beamformer) -+ cap->phy_cap[EHT_PHYCAP_MU_BEAMFORMER_IDX] &= -+ ~EHT_PHYCAP_MU_BEAMFORMER_MASK; -+ -+ pos = cap->optional; -+ -+ mcs_nss_len = ieee80211_eht_mcs_set_size(mode->he_capab[opmode].phy_cap, -+ eht_cap->phy_cap); -+ if (mcs_nss_len) { -+ os_memcpy(pos, eht_cap->mcs, mcs_nss_len); -+ pos += mcs_nss_len; -+ } -+ -+ ppe_thresh_len = ieee80211_eht_ppet_size(eht_cap->ppet, -+ eht_cap->phy_cap); -+ if (ppe_thresh_len) { -+ os_memcpy(pos, eht_cap->ppet, ppe_thresh_len); -+ pos += ppe_thresh_len; -+ } -+ -+ *length_pos = pos - (eid + 2); -+ return pos; -+} ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -201,6 +201,15 @@ struct he_capabilities { - u16 he_6ghz_capa; - }; - -+/* struct eht_capabilities - IEEE 802.11be EHT capabilities */ -+struct eht_capabilities { -+ u8 eht_supported; -+ u8 mac_cap[EHT_MAC_CAPAB_MAX_LEN]; -+ u8 phy_cap[EHT_PHY_CAPAB_MAX_LEN]; -+ u8 mcs[EHT_MCS_NSS_CAPAB_MAX_LEN]; -+ u8 ppet[EHT_PPE_THRESH_CAPAB_MAX_LEN]; -+}; -+ - #define HOSTAPD_MODE_FLAG_HT_INFO_KNOWN BIT(0) - #define HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN BIT(1) - -@@ -305,6 +314,11 @@ struct hostapd_hw_modes { - * supported in 6G band. - */ - s8 psd_values[NL80211_REG_NUM_POWER_MODES]; -+ -+ /** -+ * eht_capab - EHT (IEEE 802.11be) capabilities -+ */ -+ struct eht_capabilities eht_capab[IEEE80211_MODE_NUM]; - }; - - diff --git a/feeds/ipq95xx/hostapd/patches/q02-009-eht-add-operation-element-in-management-frames.patch b/feeds/ipq95xx/hostapd/patches/q02-009-eht-add-operation-element-in-management-frames.patch deleted file mode 100644 index 112591f9..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-009-eht-add-operation-element-in-management-frames.patch +++ /dev/null @@ -1,198 +0,0 @@ -From d0022739c2d8ae04151a1537d960daef280ca732 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Tue, 15 Feb 2022 00:51:19 -0800 -Subject: [PATCH 09/23] eht: add operation element in management frames - -Add EHT operation element in beacon, probe response and association -response frames using the format described in IEEE P802.11be/D1.4, -January 2022, section 9.4.2.311. - -Length of this field is not yet provided in this version of the -specification, assume 1 byte for each field. - -Signed-off-by: Aloka Dixit -Signed-off-by: Muna Sinada ---- - src/ap/beacon.c | 16 ++++++++--- - src/ap/ieee802_11.c | 5 +++- - src/ap/ieee802_11.h | 1 + - src/ap/ieee802_11_eht.c | 51 ++++++++++++++++++++++++++++++++++++ - src/common/ieee802_11_defs.h | 10 +++++++ - 5 files changed, 78 insertions(+), 5 deletions(-) - ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -640,8 +640,10 @@ static u8 * hostapd_gen_probe_resp(struc - #endif /* CONFIG_IEEE80211AX */ - - #ifdef CONFIG_IEEE80211BE -- if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) -+ if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { - buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP); -+ buflen += (3 + sizeof(struct ieee80211_eht_operation)); -+ } - #endif /* CONFIG_IEEE80211BE */ - - buflen += hostapd_eid_mbssid_len(hapd_probed, WLAN_FC_STYPE_PROBE_RESP, -@@ -786,8 +788,10 @@ static u8 * hostapd_gen_probe_resp(struc - #endif /* CONFIG_IEEE80211AX */ - - #ifdef CONFIG_IEEE80211BE -- if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) -+ if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { - pos = hostapd_eid_eht_capab(hapd, pos, IEEE80211_MODE_AP); -+ pos = hostapd_eid_eht_operation(hapd, pos, IEEE80211_MODE_AP); -+ } - #endif /* CONFIG_IEEE80211BE */ - - #ifdef CONFIG_IEEE80211AC -@@ -1718,8 +1722,10 @@ int ieee802_11_build_ap_params(struct ho - #endif /* CONFIG_IEEE80211AX */ - - #ifdef CONFIG_IEEE80211BE -- if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) -+ if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { - tail_len += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP); -+ tail_len += (3 + sizeof(struct ieee80211_eht_operation)); -+ } - #endif /* CONFIG_IEEE80211BE */ - - if (hapd->iconf->ema) -@@ -1873,9 +1879,12 @@ int ieee802_11_build_ap_params(struct ho - #endif /* CONFIG_IEEE80211AX */ - - #ifdef CONFIG_IEEE80211BE -- if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) -+ if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { - tailpos = hostapd_eid_eht_capab(hapd, tailpos, - IEEE80211_MODE_AP); -+ tailpos = hostapd_eid_eht_operation(hapd, tailpos, -+ IEEE80211_MODE_AP); -+ } - #endif /* CONFIG_IEEE80211BE */ - - #ifdef CONFIG_IEEE80211AC ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -5084,8 +5084,10 @@ static u16 send_assoc_resp(struct hostap - buflen += 5 + sta->dpp_pfs->curve->prime_len; - #endif /* CONFIG_DPP2 */ - #ifdef CONFIG_IEEE80211BE -- if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) -+ if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { - buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP); -+ buflen += (3 + sizeof(struct ieee80211_eht_operation)); -+ } - #endif /* CONFIG_IEEE80211BE */ - - buf = os_zalloc(buflen); -@@ -5203,8 +5205,10 @@ static u16 send_assoc_resp(struct hostap - #endif /* CONFIG_IEEE80211AX */ - - #ifdef CONFIG_IEEE80211BE -- if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) -+ if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { - p = hostapd_eid_eht_capab(hapd, p, IEEE80211_MODE_AP); -+ p = hostapd_eid_eht_operation(hapd, p, IEEE80211_MODE_AP); -+ } - #endif /* CONFIG_IEEE80211BE */ - - p = hostapd_eid_ext_capab(hapd, p); ---- a/src/ap/ieee802_11.h -+++ b/src/ap/ieee802_11.h -@@ -219,4 +219,6 @@ size_t hostapd_eid_eht_capab_len(struct - enum ieee80211_op_mode opmode); - u8 * hostapd_eid_eht_capab(struct hostapd_data *hapd, u8 *eid, - enum ieee80211_op_mode opmode); -+u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid, -+ enum ieee80211_op_mode opmode); - #endif /* IEEE802_11_H */ ---- a/src/ap/ieee802_11_eht.c -+++ b/src/ap/ieee802_11_eht.c -@@ -162,3 +162,60 @@ u8 * hostapd_eid_eht_capab(struct hostap - *length_pos = pos - (eid + 2); - return pos; - } -+ -+ -+u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid, -+ enum ieee80211_op_mode opmode) -+{ -+ struct hostapd_hw_modes *mode; -+ struct ieee80211_eht_operation *oper; -+ u8 *pos = eid, *length_pos, chwidth, seg0 = 0; -+ -+ mode = hapd->iface->current_mode; -+ if (!mode) -+ return eid; -+ -+ if (!mode->eht_capab[opmode].eht_supported) -+ return eid; -+ -+ *pos++ = WLAN_EID_EXTENSION; -+ length_pos = pos++; -+ *pos++ = WLAN_EID_EXT_EHT_OPERATION; -+ -+ oper = (struct ieee80211_eht_operation *) pos; -+ os_memset(oper, 0, sizeof(*oper)); -+ -+ if (is_6ghz_op_class(hapd->iconf->op_class)) -+ chwidth = op_class_to_ch_width(hapd->iconf->op_class); -+ else -+ chwidth = hapd->iconf->eht_oper_chwidth; -+ -+ seg0 = hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf); -+ -+ switch (chwidth) { -+ case CHANWIDTH_320MHZ: -+ *pos++ = EHT_OPERATION_CHANNEL_WIDTH_320MHZ; -+ break; -+ case CHANWIDTH_160MHZ: -+ *pos++ = EHT_OPERATION_CHANNEL_WIDTH_160MHZ; -+ break; -+ case CHANWIDTH_80MHZ: -+ *pos++ = EHT_OPERATION_CHANNEL_WIDTH_80MHZ; -+ break; -+ case CHANWIDTH_USE_HT: -+ if (seg0) -+ *pos++ = EHT_OPERATION_CHANNEL_WIDTH_40MHZ; -+ else -+ pos++; -+ break; -+ default: -+ return eid; -+ } -+ -+ if (!seg0) -+ seg0 = hapd->iconf->channel; -+ *pos++ = seg0; -+ -+ *length_pos = pos - (eid + 2); -+ return pos; -+} ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -2476,6 +2476,11 @@ struct ieee80211_eht_operation { - u8 optional[]; - } STRUCT_PACKED; - -+#define EHT_OPERATION_CHANNEL_WIDTH_40MHZ 1 -+#define EHT_OPERATION_CHANNEL_WIDTH_80MHZ 2 -+#define EHT_OPERATION_CHANNEL_WIDTH_160MHZ 3 -+#define EHT_OPERATION_CHANNEL_WIDTH_320MHZ 4 -+ - /* IEEE P802.11be/D1.4, January 2022, section 9.4.2.313.3 */ - #define EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_IDX 0 - #define EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK ((u8) BIT(1)) -@@ -2515,6 +2520,11 @@ struct ieee80211_eht_operation { - BIT(2) | BIT(3) | \ - BIT(4))) - -+#define EHT_OPERATION_CHANNEL_WIDTH_40MHZ 1 -+#define EHT_OPERATION_CHANNEL_WIDTH_80MHZ 2 -+#define EHT_OPERATION_CHANNEL_WIDTH_160MHZ 3 -+#define EHT_OPERATION_CHANNEL_WIDTH_320MHZ 4 -+ - /* IEEE P802.11ay/D4.0, 9.4.2.251 - EDMG Operation element */ - #define EDMG_BSS_OPERATING_CHANNELS_OFFSET 6 - #define EDMG_OPERATING_CHANNEL_WIDTH_OFFSET 7 diff --git a/feeds/ipq95xx/hostapd/patches/q02-010-nl80211-parse-EHT-capabilities-passed-by-kernel.patch b/feeds/ipq95xx/hostapd/patches/q02-010-nl80211-parse-EHT-capabilities-passed-by-kernel.patch deleted file mode 100644 index 9553c53a..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-010-nl80211-parse-EHT-capabilities-passed-by-kernel.patch +++ /dev/null @@ -1,94 +0,0 @@ -From fe0a0d3556de5caa1498b8a406cd1c6496c5ad1e Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Tue, 29 Jun 2021 17:03:50 -0700 -Subject: [PATCH 10/23] nl80211: parse EHT capabilities passed by kernel - -Add nl80211 support to parse the EHT capabilities passed by the -kernel using new attributes added in NL80211_BAND_ATTR_IFTYPE_DATA. - -Signed-off-by: Aloka Dixit ---- - src/drivers/driver_nl80211_capa.c | 48 +++++++++++++++++++++++++++++-- - 1 file changed, 46 insertions(+), 2 deletions(-) - -diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c -index 200c545c2b70..b37167cc2075 100644 ---- a/src/drivers/driver_nl80211_capa.c -+++ b/src/drivers/driver_nl80211_capa.c -@@ -1774,12 +1774,14 @@ static int phy_info_rates(struct hostapd_hw_modes *mode, struct nlattr *tb) - } - - --static void phy_info_iftype_copy(struct he_capabilities *he_capab, -+static void phy_info_iftype_copy(struct hostapd_hw_modes *mode, - enum ieee80211_op_mode opmode, - struct nlattr **tb, struct nlattr **tb_flags) - { - enum nl80211_iftype iftype; - size_t len; -+ struct he_capabilities *he_capab = &mode->he_capab[opmode]; -+ struct eht_capabilities *eht_capab = &mode->eht_capab[opmode]; - - switch (opmode) { - case IEEE80211_MODE_INFRA: -@@ -1849,6 +1851,48 @@ static void phy_info_iftype_copy(struct he_capabilities *he_capab, - capa = nla_get_u16(tb[NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA]); - he_capab->he_6ghz_capa = le_to_host16(capa); - } -+ -+ if (!tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC] || -+ !tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]) -+ return; -+ -+ eht_capab->eht_supported = 1; -+ -+ if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC]) { -+ len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC]); -+ if (len > sizeof(eht_capab->mac_cap)) -+ len = sizeof(eht_capab->mac_cap); -+ os_memcpy(eht_capab->mac_cap, -+ nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC]), -+ len); -+ } -+ -+ if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]) { -+ len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]); -+ if (len > sizeof(eht_capab->phy_cap)) -+ len = sizeof(eht_capab->phy_cap); -+ os_memcpy(eht_capab->phy_cap, -+ nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]), -+ len); -+ } -+ -+ if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET]) { -+ len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET]); -+ if (len > sizeof(eht_capab->mcs)) -+ len = sizeof(eht_capab->mcs); -+ os_memcpy(eht_capab->mcs, -+ nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET]), -+ len); -+ } -+ -+ if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]) { -+ len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]); -+ if (len > sizeof(eht_capab->ppet)) -+ len = sizeof(eht_capab->ppet); -+ os_memcpy(&eht_capab->ppet, -+ nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]), -+ len); -+ } - } - - -@@ -1870,7 +1914,7 @@ static int phy_info_iftype(struct hostapd_hw_modes *mode, - return NL_STOP; - - for (i = 0; i < IEEE80211_MODE_NUM; i++) -- phy_info_iftype_copy(&mode->he_capab[i], i, tb, tb_flags); -+ phy_info_iftype_copy(mode, i, tb, tb_flags); - - return NL_OK; - } --- -2.31.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-011-eht-parse-elements-received-in-management-frames.patch b/feeds/ipq95xx/hostapd/patches/q02-011-eht-parse-elements-received-in-management-frames.patch deleted file mode 100644 index 44829cf8..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-011-eht-parse-elements-received-in-management-frames.patch +++ /dev/null @@ -1,51 +0,0 @@ -From a6480aca3e0e8c0509c852dae89d2016b616c486 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Fri, 2 Jul 2021 12:21:11 -0700 -Subject: [PATCH 11/23] eht: parse elements received in management frames - -Parse and store pointers to EHT capabilities and operation elements -received in management frames. - -Signed-off-by: Aloka Dixit ---- - src/common/ieee802_11_common.c | 8 ++++++++ - src/common/ieee802_11_common.h | 4 ++++ - 2 files changed, 12 insertions(+) - ---- a/src/common/ieee802_11_common.c -+++ b/src/common/ieee802_11_common.c -@@ -311,6 +311,14 @@ static int ieee802_11_parse_extension(co - elems->mbssid_known_bss = pos; - elems->mbssid_known_bss_len = elen; - break; -+ case WLAN_EID_EXT_EHT_CAPABILITY: -+ elems->eht_capabilities = pos; -+ elems->eht_capabilities_len = elen; -+ break; -+ case WLAN_EID_EXT_EHT_OPERATION: -+ elems->eht_operation = pos; -+ elems->eht_operation_len = elen; -+ break; - default: - if (show_errors) { - wpa_printf(MSG_MSGDUMP, ---- a/src/common/ieee802_11_common.h -+++ b/src/common/ieee802_11_common.h -@@ -119,6 +119,8 @@ struct ieee802_11_elems { - const u8 *s1g_capab; - const u8 *pasn_params; - const u8 *mbssid_known_bss; -+ const u8 *eht_capabilities; -+ const u8 *eht_operation; - - u8 ssid_len; - u8 supp_rates_len; -@@ -174,6 +176,8 @@ struct ieee802_11_elems { - u8 sae_pk_len; - u8 pasn_params_len; - u8 mbssid_known_bss_len; -+ u8 eht_capabilities_len; -+ u8 eht_operation_len; - - struct mb_ies_info mb_ies; - struct frag_ies_info frag_ies; diff --git a/feeds/ipq95xx/hostapd/patches/q02-012-eht-process-association-request.patch b/feeds/ipq95xx/hostapd/patches/q02-012-eht-process-association-request.patch deleted file mode 100644 index 06e3c7c9..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-012-eht-process-association-request.patch +++ /dev/null @@ -1,216 +0,0 @@ -From a181193ed7b1d7ec37d6fe58d1e7c0f8c1ad15d7 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Fri, 2 Jul 2021 12:22:20 -0700 -Subject: [PATCH 12/23] eht: process association request - -Parse EHT capabilities sent by a non-AP STA in association requests. -Validate the IE length, matching MCS rates between AP tx and STA rx. -Store the capabilities in the station info structure. - -Signed-off-by: Aloka Dixit ---- - src/ap/ieee802_11.c | 10 ++++ - src/ap/ieee802_11.h | 3 ++ - src/ap/ieee802_11_eht.c | 117 ++++++++++++++++++++++++++++++++++++++++ - src/ap/sta_info.c | 1 + - src/ap/sta_info.h | 6 +++ - 5 files changed, 137 insertions(+) - ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -4593,6 +4593,16 @@ static int check_assoc_ies(struct hostap - } - } - #endif /* CONFIG_IEEE80211AX */ -+#ifdef CONFIG_IEEE80211BE -+ if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { -+ resp = copy_sta_eht_capab(hapd, sta, IEEE80211_MODE_AP, -+ elems.he_capabilities, -+ elems.eht_capabilities, -+ elems.eht_capabilities_len); -+ if (resp != WLAN_STATUS_SUCCESS) -+ return resp; -+ } -+#endif /* CONFIG_IEEE80211BE */ - - #ifdef CONFIG_P2P - if (elems.p2p) { ---- a/src/ap/ieee802_11.h -+++ b/src/ap/ieee802_11.h -@@ -221,4 +221,7 @@ u8 * hostapd_eid_eht_capab(struct hostap - enum ieee80211_op_mode opmode); - u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid, - enum ieee80211_op_mode opmode); -+u16 copy_sta_eht_capab(struct hostapd_data *hapd, struct sta_info *sta, -+ enum ieee80211_op_mode opmode, const u8 *he_capab, -+ const u8 *eht_capab, size_t eht_capab_len); - #endif /* IEEE802_11_H */ ---- a/src/ap/ieee802_11_eht.c -+++ b/src/ap/ieee802_11_eht.c -@@ -20,6 +20,7 @@ - #include "utils/common.h" - #include "hostapd.h" - #include "ieee802_11.h" -+#include "sta_info.h" - - static u8 ieee80211_eht_ppet_size(const u8 *ppe_thres, const u8 *phy_cap_info) - { -@@ -219,3 +220,119 @@ u8 * hostapd_eid_eht_operation(struct ho - *length_pos = pos - (eid + 2); - return pos; - } -+ -+ -+static int check_valid_eht_mcs_nss(struct hostapd_data *hapd, const u8 *ap_mcs, -+ const u8 *sta_mcs, u8 mcs_count, u8 map_len) -+{ -+ u8 i, j; -+ -+ for (i = 0; i < mcs_count; i++) { -+ ap_mcs += (i * 3); -+ sta_mcs += (i * 3); -+ -+ for (j = 0; j < map_len; j++) { -+ if (((ap_mcs[j] >> 4) & 0xFF) == 0) -+ continue; -+ -+ if ((sta_mcs[j] & 0xFF) == 0) -+ continue; -+ -+ return 1; -+ } -+ } -+ -+ wpa_printf(MSG_DEBUG, -+ "No matching EHT MCS found between AP TX and STA RX"); -+ return 0; -+} -+ -+static int check_valid_eht_mcs(struct hostapd_data *hapd, const u8 *sta_eht_capab, -+ enum ieee80211_op_mode opmode) -+{ -+ struct hostapd_hw_modes *mode; -+ const u8 *ap_mcs, *sta_mcs; -+ -+ mode = hapd->iface->current_mode; -+ if (!mode) -+ return 1; -+ -+ ap_mcs = mode->eht_capab[opmode].mcs; -+ sta_mcs = ((const struct ieee80211_eht_capabilities *) sta_eht_capab)->optional; -+ -+ if (ieee80211_eht_mcs_set_size(mode->he_capab[opmode].phy_cap, -+ mode->eht_capab[opmode].phy_cap) == -+ EHT_PHYCAP_MCS_NSS_LEN_20MHZ_ONLY) { -+ return check_valid_eht_mcs_nss(hapd, ap_mcs, sta_mcs, 1, -+ EHT_PHYCAP_MCS_NSS_LEN_20MHZ_ONLY); -+ -+ } else { -+ u8 mcs_count = 1; -+ -+ switch (hapd->iface->conf->eht_oper_chwidth) { -+ /* TODO CHANWIDTH_320MHZ */ -+ case CHANWIDTH_80P80MHZ: -+ case CHANWIDTH_160MHZ: -+ mcs_count = 2; -+ break; -+ default: -+ break; -+ } -+ -+ return check_valid_eht_mcs_nss(hapd, ap_mcs, sta_mcs, mcs_count, -+ EHT_PHYCAP_MCS_NSS_LEN_20MHZ_PLUS); -+ } -+ -+ return 0; -+} -+ -+ -+static int ieee80211_invalid_eht_cap_size(const u8 *he_cap, const u8 *eht_cap, -+ size_t len) -+{ -+ struct ieee80211_eht_capabilities *cap; -+ const u8 *he_phy_cap; -+ size_t cap_len; -+ -+ he_phy_cap = ((struct ieee80211_he_capabilities *)he_cap)->he_phy_capab_info; -+ cap = (struct ieee80211_eht_capabilities *) eht_cap; -+ cap_len = sizeof(*cap); -+ if (len < cap_len) -+ return 1; -+ -+ cap_len += ieee80211_eht_mcs_set_size(he_phy_cap, cap->phy_cap); -+ if (len < cap_len) -+ return 1; -+ -+ cap_len += ieee80211_eht_ppet_size(&eht_cap[cap_len], cap->phy_cap); -+ -+ return (len != cap_len); -+} -+ -+ -+u16 copy_sta_eht_capab(struct hostapd_data *hapd, struct sta_info *sta, -+ enum ieee80211_op_mode opmode, const u8 *he_capab, -+ const u8 *eht_capab, size_t eht_capab_len) -+{ -+ if (!eht_capab || !hapd->iconf->ieee80211be || -+ hapd->conf->disable_11be || -+ ieee80211_invalid_eht_cap_size(he_capab, eht_capab, eht_capab_len) || -+ !check_valid_eht_mcs(hapd, eht_capab, opmode)) { -+ sta->flags_ext &= ~WLAN_STA_EXT_EHT; -+ os_free(sta->eht_capab); -+ sta->eht_capab = NULL; -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ if (!sta->eht_capab) { -+ sta->eht_capab = os_zalloc(eht_capab_len); -+ if (!sta->eht_capab) -+ return WLAN_STATUS_UNSPECIFIED_FAILURE; -+ } -+ -+ sta->flags_ext |= WLAN_STA_EXT_EHT; -+ os_memcpy(sta->eht_capab, eht_capab, eht_capab_len); -+ sta->eht_capab_len = eht_capab_len; -+ -+ return WLAN_STATUS_SUCCESS; -+} ---- a/src/ap/sta_info.c -+++ b/src/ap/sta_info.c -@@ -358,6 +358,7 @@ void ap_free_sta(struct hostapd_data *ha - os_free(sta->vht_operation); - os_free(sta->he_capab); - os_free(sta->he_6ghz_capab); -+ os_free(sta->eht_capab); - hostapd_free_psk_list(sta->psk); - os_free(sta->identity); - os_free(sta->radius_cui); ---- a/src/ap/sta_info.h -+++ b/src/ap/sta_info.h -@@ -46,6 +46,9 @@ - #define WLAN_STA_PENDING_DEAUTH_CB BIT(30) - #define WLAN_STA_NONERP BIT(31) - -+/* STA flags_ext */ -+#define WLAN_STA_EXT_EHT BIT(0) -+ - /* Maximum number of supported rates (from both Supported Rates and Extended - * Supported Rates IEs). */ - #define WLAN_SUPP_RATES_MAX 32 -@@ -113,6 +116,7 @@ struct sta_info { - u16 aid; /* STA's unique AID (1 .. 2007) or 0 if not yet assigned */ - u16 disconnect_reason_code; /* RADIUS server override */ - u32 flags; /* Bitfield of WLAN_STA_* */ -+ u32 flags_ext; /* Bitfield of WLAN_STA_EXT_* */ - u16 capability; - u16 listen_interval; /* or beacon_int for APs */ - u8 supported_rates[WLAN_SUPP_RATES_MAX]; -@@ -214,6 +218,8 @@ struct sta_info { - struct ieee80211_he_capabilities *he_capab; - size_t he_capab_len; - struct ieee80211_he_6ghz_band_cap *he_6ghz_capab; -+ struct ieee80211_eht_capabilities *eht_capab; -+ size_t eht_capab_len; - - int sa_query_count; /* number of pending SA Query requests; - * 0 = no SA Query in progress */ diff --git a/feeds/ipq95xx/hostapd/patches/q02-013-eht-changes-in-STA-addition-path.patch b/feeds/ipq95xx/hostapd/patches/q02-013-eht-changes-in-STA-addition-path.patch deleted file mode 100644 index 7790939c..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-013-eht-changes-in-STA-addition-path.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 4278083ffec33d4f5c74530326eeab62255b140e Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Tue, 6 Jul 2021 11:18:27 -0700 -Subject: [PATCH 13/23] eht: changes in STA addition path - -Add support for EHT capabilities in the during the addition of -a new station. - -Signed-off-by: Aloka Dixit ---- - src/ap/ap_drv_ops.c | 5 ++++- - src/ap/ap_drv_ops.h | 3 ++- - src/ap/ieee802_11.c | 9 +++++++++ - src/ap/ieee802_11.h | 4 ++++ - src/ap/ieee802_11_eht.c | 16 ++++++++++++++++ - src/ap/sta_info.c | 2 +- - src/drivers/driver.h | 2 ++ - 7 files changed, 38 insertions(+), 3 deletions(-) - -diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c -index e917736664bd..09378eac72d2 100644 ---- a/src/ap/ap_drv_ops.c -+++ b/src/ap/ap_drv_ops.c -@@ -417,7 +417,8 @@ int hostapd_sta_add(struct hostapd_data *hapd, - const struct ieee80211_ht_capabilities *ht_capab, - const struct ieee80211_vht_capabilities *vht_capab, - const struct ieee80211_he_capabilities *he_capab, -- size_t he_capab_len, -+ const struct ieee80211_eht_capabilities *eht_capab, -+ size_t he_capab_len, size_t eht_capab_len, - const struct ieee80211_he_6ghz_band_cap *he_6ghz_capab, - u32 flags, u8 qosinfo, u8 vht_opmode, int supp_p2p_ps, - int set) -@@ -440,6 +441,8 @@ int hostapd_sta_add(struct hostapd_data *hapd, - params.vht_capabilities = vht_capab; - params.he_capab = he_capab; - params.he_capab_len = he_capab_len; -+ params.eht_capab = eht_capab; -+ params.eht_capab_len = eht_capab_len; - params.he_6ghz_capab = he_6ghz_capab; - params.vht_opmode_enabled = !!(flags & WLAN_STA_VHT_OPMODE_ENABLED); - params.vht_opmode = vht_opmode; -diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h -index 61c8f64eb471..08f52dfa7390 100644 ---- a/src/ap/ap_drv_ops.h -+++ b/src/ap/ap_drv_ops.h -@@ -42,7 +42,8 @@ int hostapd_sta_add(struct hostapd_data *hapd, - const struct ieee80211_ht_capabilities *ht_capab, - const struct ieee80211_vht_capabilities *vht_capab, - const struct ieee80211_he_capabilities *he_capab, -- size_t he_capab_len, -+ const struct ieee80211_eht_capabilities *eht_capab, -+ size_t he_capab_len, size_t eht_capab_len, - const struct ieee80211_he_6ghz_band_cap *he_6ghz_capab, - u32 flags, u8 qosinfo, u8 vht_opmode, int supp_p2p_ps, - int set); -diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c -index 18eca78f3c84..c8f308b80f67 100644 ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -4934,6 +4934,7 @@ static int add_associated_sta(struct hostapd_data *hapd, - struct ieee80211_ht_capabilities ht_cap; - struct ieee80211_vht_capabilities vht_cap; - struct ieee80211_he_capabilities he_cap; -+ struct ieee80211_eht_capabilities eht_cap; - int set = 1; - - /* -@@ -4990,6 +4991,12 @@ static int add_associated_sta(struct hostapd_data *hapd, - sta->he_capab_len); - } - #endif /* CONFIG_IEEE80211AX */ -+#ifdef CONFIG_IEEE80211BE -+ if (sta->flags & WLAN_STA_EXT_EHT) { -+ hostapd_get_eht_capab(hapd, sta->eht_capab, &eht_cap, -+ sta->eht_capab_len); -+ } -+#endif /* CONFIG_IEEE80211BE */ - - /* - * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags -@@ -5002,7 +5009,9 @@ static int add_associated_sta(struct hostapd_data *hapd, - sta->flags & WLAN_STA_HT ? &ht_cap : NULL, - sta->flags & WLAN_STA_VHT ? &vht_cap : NULL, - sta->flags & WLAN_STA_HE ? &he_cap : NULL, -+ sta->flags_ext & WLAN_STA_EXT_EHT ? &eht_cap : NULL, - sta->flags & WLAN_STA_HE ? sta->he_capab_len : 0, -+ sta->flags_ext & WLAN_STA_EXT_EHT ? sta->eht_capab_len : 0, - sta->he_6ghz_capab, - sta->flags | WLAN_STA_ASSOC, sta->qosinfo, - sta->vht_opmode, sta->p2p_ie ? 1 : 0, -diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h -index a9be10238afa..338599f7c71c 100644 ---- a/src/ap/ieee802_11.h -+++ b/src/ap/ieee802_11.h -@@ -78,6 +78,10 @@ void hostapd_get_he_capab(struct hostapd_data *hapd, - const struct ieee80211_he_capabilities *he_cap, - struct ieee80211_he_capabilities *neg_he_cap, - size_t he_capab_len); -+void hostapd_get_eht_capab(struct hostapd_data *hapd, -+ const struct ieee80211_eht_capabilities *src, -+ struct ieee80211_eht_capabilities *dest, -+ size_t len); - int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta); - u16 copy_sta_ht_capab(struct hostapd_data *hapd, struct sta_info *sta, - const u8 *ht_capab); -diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c -index dc3dedeffac6..f19af1114005 100644 ---- a/src/ap/ieee802_11_eht.c -+++ b/src/ap/ieee802_11_eht.c -@@ -320,3 +320,19 @@ u16 copy_sta_eht_capab(struct hostapd_data *hapd, struct sta_info *sta, - - return WLAN_STATUS_SUCCESS; - } -+ -+ -+void hostapd_get_eht_capab(struct hostapd_data *hapd, -+ const struct ieee80211_eht_capabilities *src, -+ struct ieee80211_eht_capabilities *dest, -+ size_t len) -+{ -+ if (!src || !dest) -+ return; -+ -+ if (len > sizeof(*dest)) -+ len = sizeof(*dest); -+ /* TODO: mask out unsupported features */ -+ -+ os_memcpy(dest, src, len); -+} -diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c -index 8d880403f347..711680bb8950 100644 ---- a/src/ap/sta_info.c -+++ b/src/ap/sta_info.c -@@ -1554,7 +1554,7 @@ int ap_sta_re_add(struct hostapd_data *hapd, struct sta_info *sta) - if (hostapd_sta_add(hapd, sta->addr, 0, 0, - sta->supported_rates, - sta->supported_rates_len, -- 0, NULL, NULL, NULL, 0, NULL, -+ 0, NULL, NULL, NULL, NULL, 0, 0, NULL, - sta->flags, 0, 0, 0, 0)) { - hostapd_logger(hapd, sta->addr, - HOSTAPD_MODULE_IEEE80211, -diff --git a/src/drivers/driver.h b/src/drivers/driver.h -index 7dcdd2140f18..34e73b739d25 100644 ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -2210,6 +2210,8 @@ struct hostapd_sta_add_params { - const struct ieee80211_he_capabilities *he_capab; - size_t he_capab_len; - const struct ieee80211_he_6ghz_band_cap *he_6ghz_capab; -+ const struct ieee80211_eht_capabilities *eht_capab; -+ size_t eht_capab_len; - u32 flags; /* bitmask of WPA_STA_* flags */ - u32 flags_mask; /* unset bits in flags */ - #ifdef CONFIG_MESH --- -2.31.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-014-nl80211-pass-station-s-EHT-capabilities-to-kernel.patch b/feeds/ipq95xx/hostapd/patches/q02-014-nl80211-pass-station-s-EHT-capabilities-to-kernel.patch deleted file mode 100644 index 8e518f8b..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-014-nl80211-pass-station-s-EHT-capabilities-to-kernel.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 650c1ad30199e90a02a70da54e37c6ef4c780c4b Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Tue, 6 Jul 2021 11:19:43 -0700 -Subject: [PATCH 14/23] nl80211: pass station's EHT capabilities to kernel - -Pass non-AP station's EHT capabilities to the kernel using new -attribute NL80211_ATTR_EHT_CAPABILITY. - -Signed-off-by: Aloka Dixit ---- - src/drivers/driver_nl80211.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c -index 40b3e1b5c5ed..a7807d6a9a08 100644 ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -5150,6 +5150,14 @@ static int wpa_driver_nl80211_sta_add(void *priv, - goto fail; - } - -+ if (params->eht_capab) { -+ wpa_hexdump(MSG_DEBUG, " * eht_capab", -+ (u8 *) params->eht_capab, params->eht_capab_len); -+ if (nla_put(msg, NL80211_ATTR_EHT_CAPABILITY, -+ params->eht_capab_len, params->eht_capab)) -+ goto fail; -+ } -+ - if (params->ext_capab) { - wpa_hexdump(MSG_DEBUG, " * ext_capab", - params->ext_capab, params->ext_capab_len); --- -2.31.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-015-eht-changes-to-the-neighbor-report-element.patch b/feeds/ipq95xx/hostapd/patches/q02-015-eht-changes-to-the-neighbor-report-element.patch deleted file mode 100644 index eae128c1..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-015-eht-changes-to-the-neighbor-report-element.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 740d243df39b5df9c59cc6131d9b4da2b213a8d9 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Tue, 17 Aug 2021 16:11:22 -0700 -Subject: [PATCH 15/23] eht: changes to the neighbor report element - -Set bit 21 in the neighbor report for an EHT AP as described in -IEEE P802.11be/D1.4, January 2022, section 9.4.2.36. -Also move the check for 'he' outside the check for 'ht' as ht and vht -are not enabled for 6GHz band. - -Signed-off-by: Aloka Dixit ---- - src/ap/neighbor_db.c | 8 ++++++-- - src/common/ieee802_11_defs.h | 1 + - 2 files changed, 7 insertions(+), 2 deletions(-) - ---- a/src/ap/neighbor_db.c -+++ b/src/ap/neighbor_db.c -@@ -243,6 +243,7 @@ void hostapd_neighbor_set_own_report(str - int ht = hapd->iconf->ieee80211n && !hapd->conf->disable_11n; - int vht = hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac; - int he = hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax; -+ int eht = he && hapd->iconf->ieee80211be && !hapd->conf->disable_11be; - struct wpa_ssid_value ssid; - u8 channel, op_class; - u8 center_freq1_idx = 0, center_freq2_idx = 0; -@@ -278,8 +279,12 @@ void hostapd_neighbor_set_own_report(str - /* VHT bit added in IEEE P802.11-REVmc/D4.3 */ - if (vht) - bssid_info |= NEI_REP_BSSID_INFO_VHT; -- if (he) -- bssid_info |= NEI_REP_BSSID_INFO_HE; -+ } -+ -+ if (he) { -+ bssid_info |= NEI_REP_BSSID_INFO_HE; -+ if (eht) -+ bssid_info |= NEI_REP_BSSID_INFO_EHT; - } - - /* TODO: Set NEI_REP_BSSID_INFO_MOBILITY_DOMAIN if MDE is set */ ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -2237,7 +2237,7 @@ enum phy_type { - #define NEI_REP_BSSID_INFO_VHT BIT(12) - #define NEI_REP_BSSID_INFO_FTM BIT(13) - #define NEI_REP_BSSID_INFO_HE BIT(14) -- -+#define NEI_REP_BSSID_INFO_EHT BIT(21) - /* - * IEEE P802.11-REVmc/D5.0 Table 9-152 - HT/VHT Operation Information - * subfields. diff --git a/feeds/ipq95xx/hostapd/patches/q02-016-eht-additions-in-FILS-discovery-frames.patch b/feeds/ipq95xx/hostapd/patches/q02-016-eht-additions-in-FILS-discovery-frames.patch deleted file mode 100644 index 799777e5..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-016-eht-additions-in-FILS-discovery-frames.patch +++ /dev/null @@ -1,160 +0,0 @@ -From 1405e5078b42f9af4e7caed2803a7ffeecc81f29 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Mon, 19 Jul 2021 11:21:46 -0700 -Subject: [PATCH 16/23] eht: additions in FILS discovery frames - -Add support for following as per IEEE P802.11be/D1.4, January 2022, -section 9.6.7.36, -- new EHT phy index -- EHT MCS rates -- support for 320 MHZ - -Signed-off-by: Aloka Dixit ---- - src/ap/beacon.c | 85 ++++++++++++++++++++++++------------ - src/common/ieee802_11_defs.h | 2 + - 2 files changed, 60 insertions(+), 27 deletions(-) - -diff --git a/src/ap/beacon.c b/src/ap/beacon.c -index 72b80f768d93..0a62ef7a1687 100644 ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -1196,6 +1196,45 @@ void sta_track_del(struct hostapd_sta_info *info) - - #ifdef CONFIG_FILS - -+static u16 hostapd_fils_discovery_cap_nss(struct hostapd_hw_modes *mode, -+ u16 phy_index, u8 len) -+{ -+ u16 nss = 0; -+ -+ if (phy_index == FD_CAP_PHY_INDEX_EHT) { -+ u8 rx_nss = 0, tx_nss = 0; -+ u8 *mcs = mode->eht_capab[IEEE80211_MODE_AP].mcs; -+ -+ rx_nss = mcs[0] & 0x0F; -+ tx_nss = (mcs[0] & 0xF0) >> 4; -+ nss = (tx_nss < rx_nss ? tx_nss : rx_nss); -+ } else if (phy_index == FD_CAP_PHY_INDEX_HE) { -+ u8 i; -+ u16 *mcs = (u16 *) mode->he_capab[IEEE80211_MODE_AP].mcs; -+ -+ for (i = 0; i < HE_NSS_MAX_STREAMS; i++) { -+ u16 mask = 0x3 << (i * 2); -+ -+ if (len == 4 && (((mcs[0] & mask) == mask) || -+ ((mcs[1] & mask) == mask))) -+ continue; -+ -+ if (len == 8 && (((mcs[2] & mask) == mask) || -+ ((mcs[3] & mask) == mask))) -+ continue; -+ -+ if (len == 12 && (((mcs[4] & mask) == mask) || -+ ((mcs[5] & mask) == mask))) -+ continue; -+ -+ nss++; -+ } -+ } -+ -+ return nss; -+} -+ -+ - static u16 hostapd_fils_discovery_cap(struct hostapd_data *hapd) - { - u16 cap_info, phy_index = 0; -@@ -1207,9 +1246,19 @@ static u16 hostapd_fils_discovery_cap(struct hostapd_data *hapd) - cap_info |= FD_CAP_PRIVACY; - - if (is_6ghz_op_class(hapd->iconf->op_class)) { -- phy_index = FD_CAP_PHY_INDEX_HE; -+#ifdef CONFIG_IEEE80211BE -+ if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) -+ phy_index = FD_CAP_PHY_INDEX_EHT; -+#endif /* CONFIG_IEEE80211BE */ -+#ifdef CONFIG_IEEE80211AX -+ if (!phy_index && -+ hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) -+ phy_index = FD_CAP_PHY_INDEX_HE; -+#endif /* CONFIG_IEEE80211AX */ - - switch (hapd->iconf->op_class) { -+ case 137: -+ chwidth = FD_CAP_BSS_CHWIDTH_320; - case 135: - mcs_nss_size += 4; - /* fallthrough */ -@@ -1244,8 +1293,13 @@ static u16 hostapd_fils_discovery_cap(struct hostapd_data *hapd) - break; - } - -+#ifdef CONFIG_IEEE80211BE -+ if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) -+ phy_index = FD_CAP_PHY_INDEX_EHT; -+#endif /* CONFIG_IEEE80211BE */ - #ifdef CONFIG_IEEE80211AX -- if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) -+ if (!phy_index && -+ hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) - phy_index = FD_CAP_PHY_INDEX_HE; - #endif /* CONFIG_IEEE80211AX */ - #ifdef CONFIG_IEEE80211AC -@@ -1262,31 +1316,8 @@ static u16 hostapd_fils_discovery_cap(struct hostapd_data *hapd) - cap_info |= chwidth << FD_CAP_BSS_CHWIDTH_SHIFT; - - if (mode) { -- u16 *mcs = (u16 *) mode->he_capab[IEEE80211_MODE_AP].mcs; -- int i; -- u16 nss = 0; -- -- for (i = 0; i < HE_NSS_MAX_STREAMS; i++) { -- u16 nss_mask = 0x3 << (i * 2); -- -- if (mcs_nss_size == 4 && -- (((mcs[0] & nss_mask) == nss_mask) || -- ((mcs[1] & nss_mask) == nss_mask))) -- continue; -- -- if (mcs_nss_size == 8 && -- (((mcs[2] & nss_mask) == nss_mask) || -- ((mcs[3] & nss_mask) == nss_mask))) -- continue; -- -- if (mcs_nss_size == 12 && -- (((mcs[4] & nss_mask) == nss_mask) || -- ((mcs[5] & nss_mask) == nss_mask))) -- continue; -- -- nss++; -- } -- -+ u16 nss = hostapd_fils_discovery_cap_nss(mode, phy_index, -+ mcs_nss_size); - if (nss > 4) - cap_info |= FD_CAP_NSS_5_8 << FD_CAP_NSS_SHIFT; - else if (nss) -diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h -index 79e14cc90403..b5cb680737d6 100644 ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -2538,6 +2538,7 @@ enum mscs_description_subelem { - #define FD_CAP_BSS_CHWIDTH_40 1 - #define FD_CAP_BSS_CHWIDTH_80 2 - #define FD_CAP_BSS_CHWIDTH_160_80_80 3 -+#define FD_CAP_BSS_CHWIDTH_320 4 - #define FD_CAP_BSS_CHWIDTH_SHIFT 2 - - #define FD_CAP_NSS_1 0 -@@ -2552,6 +2553,7 @@ enum mscs_description_subelem { - #define FD_CAP_PHY_INDEX_HT 2 - #define FD_CAP_PHY_INDEX_VHT 3 - #define FD_CAP_PHY_INDEX_HE 4 /* P802.11ax */ -+#define FD_CAP_PHY_INDEX_EHT 5 /* P802.11be */ - #define FD_CAP_PHY_INDEX_SHIFT 10 - - /* --- -2.31.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-017-eht-additions-to-hostapd_set_freq_params.patch b/feeds/ipq95xx/hostapd/patches/q02-017-eht-additions-to-hostapd_set_freq_params.patch deleted file mode 100644 index bf8bedf3..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-017-eht-additions-to-hostapd_set_freq_params.patch +++ /dev/null @@ -1,308 +0,0 @@ -From bcbde623ce398a9f3503db3756c2c5acaafcad91 Mon Sep 17 00:00:00 2001 -From: Muna Sinada -Date: Thu, 15 Jul 2021 09:35:12 -0700 -Subject: [PATCH 17/23] eht: additions to hostapd_set_freq_params() - -Modify hostapd_set_freq_params to include EHT parameters and the calling -functions. - -Signed-off-by: Muna Sinada -Signed-off-by: Aloka Dixit ---- - src/ap/ap_drv_ops.c | 14 +++++++++----- - src/ap/ap_drv_ops.h | 6 +++--- - src/ap/beacon.c | 2 ++ - src/ap/dfs.c | 6 +++++- - src/ap/hostapd.c | 5 ++++- - src/common/hw_features_common.c | 24 ++++++++++++++++++------ - src/common/hw_features_common.h | 6 ++++-- - src/drivers/driver.h | 5 +++++ - wpa_supplicant/mesh.c | 8 ++++++-- - wpa_supplicant/wpa_supplicant.c | 6 ++++-- - 10 files changed, 60 insertions(+), 22 deletions(-) - ---- a/src/ap/ap_drv_ops.c -+++ b/src/ap/ap_drv_ops.c -@@ -550,7 +550,7 @@ int hostapd_flush(struct hostapd_data *h - int hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode, - int freq, int channel, int edmg, u8 edmg_channel, - int ht_enabled, int vht_enabled, -- int he_enabled, -+ int he_enabled, int eht_enabled, - int sec_channel_offset, int oper_chwidth, - int center_segment0, int center_segment1) - { -@@ -559,12 +559,14 @@ int hostapd_set_freq(struct hostapd_data - - if (hostapd_set_freq_params(&data, mode, freq, channel, edmg, - edmg_channel, ht_enabled, -- vht_enabled, he_enabled, sec_channel_offset, -- oper_chwidth, -+ vht_enabled, he_enabled, eht_enabled, -+ sec_channel_offset, oper_chwidth, - center_segment0, center_segment1, - cmode ? cmode->vht_capab : 0, - cmode ? - &cmode->he_capab[IEEE80211_MODE_AP] : NULL, -+ cmode ? -+ &cmode->eht_capab[IEEE80211_MODE_AP] : NULL, - hapd->iconf->he_6ghz_reg_pwr_type)) - return -1; - -@@ -815,7 +817,7 @@ int hostapd_drv_send_action_addr3_ap(str - int hostapd_start_dfs_cac(struct hostapd_iface *iface, - enum hostapd_hw_mode mode, int freq, - int channel, int ht_enabled, int vht_enabled, -- int he_enabled, -+ int he_enabled, int eht_enabled, - int sec_channel_offset, int oper_chwidth, - int center_segment0, int center_segment1) - { -@@ -835,11 +837,13 @@ int hostapd_start_dfs_cac(struct hostapd - - if (hostapd_set_freq_params(&data, mode, freq, channel, 0, 0, - ht_enabled, -- vht_enabled, he_enabled, sec_channel_offset, -+ vht_enabled, he_enabled, eht_enabled, -+ sec_channel_offset, - oper_chwidth, center_segment0, - center_segment1, - cmode->vht_capab, - &cmode->he_capab[IEEE80211_MODE_AP], -+ &cmode->eht_capab[IEEE80211_MODE_AP], - hapd->iconf->he_6ghz_reg_pwr_type)) { - wpa_printf(MSG_ERROR, "Can't set freq params"); - return -1; ---- a/src/ap/ap_drv_ops.h -+++ b/src/ap/ap_drv_ops.h -@@ -65,8 +65,8 @@ int hostapd_get_seqnum(const char *ifnam - int hostapd_flush(struct hostapd_data *hapd); - int hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode, - int freq, int channel, int edmg, u8 edmg_channel, -- int ht_enabled, int vht_enabled, -- int he_enabled, int sec_channel_offset, int oper_chwidth, -+ int ht_enabled, int vht_enabled, int he_enabled, -+ int eht_enabled, int sec_channel_offset, int oper_chwidth, - int center_segment0, int center_segment1); - int hostapd_set_rts(struct hostapd_data *hapd, int rts); - int hostapd_set_frag(struct hostapd_data *hapd, int frag); -@@ -129,7 +129,7 @@ int hostapd_add_tspec(struct hostapd_dat - int hostapd_start_dfs_cac(struct hostapd_iface *iface, - enum hostapd_hw_mode mode, int freq, - int channel, int ht_enabled, int vht_enabled, -- int he_enabled, -+ int he_enabled, int eht_enabled, - int sec_channel_offset, int oper_chwidth, - int center_segment0, int center_segment1); - int hostapd_drv_do_acs(struct hostapd_data *hapd); ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -2162,12 +2162,14 @@ static int __ieee802_11_set_beacon(struc - iconf->channel, iconf->enable_edmg, - iconf->edmg_channel, iconf->ieee80211n, - iconf->ieee80211ac, iconf->ieee80211ax, -+ iconf->ieee80211be, - iconf->secondary_channel, - hostapd_get_oper_chwidth(iconf), - hostapd_get_oper_centr_freq_seg0_idx(iconf), - hostapd_get_oper_centr_freq_seg1_idx(iconf), - cmode->vht_capab, - &cmode->he_capab[IEEE80211_MODE_AP], -+ &cmode->eht_capab[IEEE80211_MODE_AP], - iconf->he_6ghz_reg_pwr_type) == 0) - params.freq = &freq; - ---- a/src/ap/dfs.c -+++ b/src/ap/dfs.c -@@ -871,7 +871,7 @@ int hostapd_handle_dfs(struct hostapd_if - res = hostapd_start_dfs_cac( - iface, iface->conf->hw_mode, iface->freq, iface->conf->channel, - iface->conf->ieee80211n, iface->conf->ieee80211ac, -- iface->conf->ieee80211ax, -+ iface->conf->ieee80211ax, iface->conf->ieee80211be, - iface->conf->secondary_channel, - hostapd_get_oper_chwidth(iface->conf), - hostapd_get_oper_centr_freq_seg0_idx(iface->conf), -@@ -1084,12 +1084,14 @@ static int hostapd_dfs_testmode_set_beac - iface->conf->ieee80211n, - iface->conf->ieee80211ac, - iface->conf->ieee80211ax, -+ iface->conf->ieee80211be, - secondary_channel, - hostapd_get_oper_chwidth(iface->conf), - vht_oper_centr_freq_seg0_idx, - vht_oper_centr_freq_seg1_idx, - iface->current_mode->vht_capab, - &iface->current_mode->he_capab[IEEE80211_MODE_AP], -+ &iface->current_mode->eht_capab[IEEE80211_MODE_AP], - hapd->iconf->he_6ghz_reg_pwr_type); - - if (err) { -@@ -1226,12 +1228,14 @@ static int hostapd_dfs_start_channel_swi - iface->conf->ieee80211n, - iface->conf->ieee80211ac, - iface->conf->ieee80211ax, -+ iface->conf->ieee80211be, - secondary_channel, - new_vht_oper_chwidth, - oper_centr_freq_seg0_idx, - oper_centr_freq_seg1_idx, - cmode->vht_capab, - &cmode->he_capab[ieee80211_mode], -+ &cmode->eht_capab[ieee80211_mode], - iface->conf->he_6ghz_reg_pwr_type); - - if (err) { ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -2117,6 +2117,7 @@ static int hostapd_setup_interface_compl - hapd->iconf->ieee80211n, - hapd->iconf->ieee80211ac, - hapd->iconf->ieee80211ax, -+ hapd->iconf->ieee80211be, - hapd->iconf->secondary_channel, - hostapd_get_oper_chwidth(hapd->iconf), - hostapd_get_oper_centr_freq_seg0_idx( -@@ -3524,12 +3525,14 @@ static int hostapd_change_config_freq(st - conf->channel, conf->enable_edmg, - conf->edmg_channel, conf->ieee80211n, - conf->ieee80211ac, conf->ieee80211ax, -- conf->secondary_channel, -+ conf->ieee80211be, conf->secondary_channel, - hostapd_get_oper_chwidth(conf), - hostapd_get_oper_centr_freq_seg0_idx(conf), - hostapd_get_oper_centr_freq_seg1_idx(conf), - conf->vht_capab, - mode ? &mode->he_capab[IEEE80211_MODE_AP] : -+ NULL, -+ mode ? &mode->eht_capab[IEEE80211_MODE_AP] : - NULL, hapd->iconf->he_6ghz_reg_pwr_type)) - return -1; - ---- a/src/common/hw_features_common.c -+++ b/src/common/hw_features_common.c -@@ -383,10 +383,12 @@ int hostapd_set_freq_params(struct hosta - int freq, int channel, int enable_edmg, - u8 edmg_channel, int ht_enabled, - int vht_enabled, int he_enabled, -- int sec_channel_offset, -+ int eht_enabled, int sec_channel_offset, - int oper_chwidth, int center_segment0, - int center_segment1, u32 vht_caps, -- struct he_capabilities *he_cap, u8 reg_6g_pwr_mode) -+ struct he_capabilities *he_cap, -+ struct eht_capabilities *eht_cap, -+ u8 reg_6g_pwr_mode) - { - if (!he_cap || !he_cap->he_supported) - he_enabled = 0; -@@ -397,6 +399,7 @@ int hostapd_set_freq_params(struct hosta - data->ht_enabled = ht_enabled; - data->vht_enabled = vht_enabled; - data->he_enabled = he_enabled; -+ data->eht_enabled = eht_enabled; - data->sec_channel_offset = sec_channel_offset; - data->center_freq1 = freq + sec_channel_offset * 10; - data->center_freq2 = 0; -@@ -415,9 +418,9 @@ int hostapd_set_freq_params(struct hosta - &data->edmg); - - if (is_6ghz_freq(freq)) { -- if (!data->he_enabled) { -+ if (!data->he_enabled && !data->eht_enabled) { - wpa_printf(MSG_ERROR, -- "Can't set 6 GHz mode - HE isn't enabled"); -+ "Can't set 6 GHz mode - HE and EHT aren't enabled"); - return -1; - } - -@@ -482,7 +485,16 @@ int hostapd_set_freq_params(struct hosta - return 0; - } - -- if (data->he_enabled) switch (oper_chwidth) { -+ if (data->eht_enabled) switch (oper_chwidth) { -+ case CHANWIDTH_320MHZ: -+ if (!(eht_cap->phy_cap[EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_IDX] & -+ EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK)) { -+ wpa_printf(MSG_ERROR, -+ "320 MHz channel width is not supported in 5 / 6GHz"); -+ return -1; -+ } -+ break; -+ } else if (data->he_enabled) switch (oper_chwidth) { - case CHANWIDTH_USE_HT: - if (sec_channel_offset == 0) - break; -@@ -545,7 +557,7 @@ int hostapd_set_freq_params(struct hosta - break; - } - -- if (data->he_enabled || data->vht_enabled) switch (oper_chwidth) { -+ if (data->eht_enabled || data->he_enabled || data->vht_enabled) switch (oper_chwidth) { - case CHANWIDTH_USE_HT: - if (center_segment1 || - (center_segment0 != 0 && ---- a/src/common/hw_features_common.h -+++ b/src/common/hw_features_common.h -@@ -40,10 +40,12 @@ int hostapd_set_freq_params(struct hosta - int freq, int channel, int edmg, u8 edmg_channel, - int ht_enabled, - int vht_enabled, int he_enabled, -- int sec_channel_offset, -+ int eht_enabled, int sec_channel_offset, - int oper_chwidth, int center_segment0, - int center_segment1, u32 vht_caps, -- struct he_capabilities *he_caps, u8 reg_6g_pwr_mode); -+ struct he_capabilities *he_caps, -+ struct eht_capabilities *eht_cap, -+ u8 reg_6g_pwr_mode); - void set_disable_ht40(struct ieee80211_ht_capabilities *htcaps, - int disabled); - int ieee80211ac_cap_check(u32 hw, u32 conf); ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -814,6 +814,11 @@ struct hostapd_freq_params { - * 2 - VLP_AP - */ - u8 he_6ghz_reg_pwr_type; -+ -+ /** -+ * eht_enabled - Whether EHT is enabled -+ */ -+ int eht_enabled; - }; - - /** ---- a/wpa_supplicant/mesh.c -+++ b/wpa_supplicant/mesh.c -@@ -227,12 +227,13 @@ static int wpas_mesh_update_freq_params( - ifmsh->conf->ieee80211n, - ifmsh->conf->ieee80211ac, - ifmsh->conf->ieee80211ax, -+ 0, - ifmsh->conf->secondary_channel, - hostapd_get_oper_chwidth(ifmsh->conf), - hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf), - hostapd_get_oper_centr_freq_seg1_idx(ifmsh->conf), - ifmsh->conf->vht_capab, -- he_capab, ifmsh->conf->he_6ghz_reg_pwr_type)) { -+ he_capab, NULL, ifmsh->conf->he_6ghz_reg_pwr_type)) { - wpa_printf(MSG_ERROR, "Error updating mesh frequency params"); - wpa_supplicant_mesh_deinit(wpa_s, true); - return -1; ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -2849,9 +2849,10 @@ skip_to_6ghz: - freq->channel, ssid->enable_edmg, - ssid->edmg_channel, freq->ht_enabled, - vht_freq.vht_enabled, vht_freq.he_enabled, -- freq->sec_channel_offset, -+ 0, freq->sec_channel_offset, - chwidth, seg0, seg1, vht_caps, -- &mode->he_capab[ieee80211_mode], 0) != 0) -+ &mode->he_capab[ieee80211_mode], NULL, -+ 0) != 0) - return; - - *freq = vht_freq; diff --git a/feeds/ipq95xx/hostapd/patches/q02-018-eht-support-for-channel-switch-command.patch b/feeds/ipq95xx/hostapd/patches/q02-018-eht-support-for-channel-switch-command.patch deleted file mode 100644 index 930ef44a..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-018-eht-support-for-channel-switch-command.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 15f8ed3e8f3226654aecf17800854486ab1356bf Mon Sep 17 00:00:00 2001 -From: Muna Sinada -Date: Wed, 21 Jul 2021 10:12:52 -0700 -Subject: [PATCH 18/23] eht: support for channel switch command - -Add option to hostapd client command to allow switch in EHT mode. - -Signed-off-by: Muna Sinada -Signed-off-by: Aloka Dixit ---- - hostapd/ctrl_iface.c | 2 +- - hostapd/hostapd_cli.c | 2 +- - src/ap/ap_config.h | 5 +++++ - src/ap/ctrl_iface_ap.c | 1 + - src/ap/hostapd.c | 14 +++++++++++--- - 5 files changed, 19 insertions(+), 5 deletions(-) - ---- a/hostapd/ctrl_iface.c -+++ b/hostapd/ctrl_iface.c -@@ -2771,7 +2771,7 @@ static int hostapd_ctrl_iface_chan_switc - - for (i = 0; i < iface->num_bss; i++) { - -- /* Save CHAN_SWITCH VHT and HE config */ -+ /* Save CHAN_SWITCH VHT, HE and EHT config */ - hostapd_chan_switch_config(iface->bss[i], - &settings.freq_params); - ---- a/hostapd/hostapd_cli.c -+++ b/hostapd/hostapd_cli.c -@@ -1188,7 +1188,7 @@ static int hostapd_cli_cmd_chan_switch(s - "arguments (count and freq)\n" - "usage: [sec_channel_offset=] " - "[center_freq1=] [center_freq2=] [bandwidth=] " -- "[blocktx] [ht|vht]\n"); -+ "[blocktx] [ht|vht|he|eht]\n"); - return -1; - } - ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -1127,6 +1127,11 @@ struct hostapd_config { - u8 eht_oper_centr_freq_seg0_idx; - struct eht_phy_capabilities_info eht_phy_capab; - #endif /* CONFIG_IEEE80211BE */ -+ -+ /* EHT enable/disable config from CHAN_SWITCH */ -+#define CH_SWITCH_EHT_ENABLED BIT(0) -+#define CH_SWITCH_EHT_DISABLED BIT(1) -+ unsigned int ch_switch_eht_config; - }; - - static inline u8 hostapd_get_he_6ghz_reg_pwr_type(struct hostapd_config *conf) ---- a/src/ap/ctrl_iface_ap.c -+++ b/src/ap/ctrl_iface_ap.c -@@ -1258,6 +1258,7 @@ int hostapd_parse_csa_settings(const cha - settings->freq_params.ht_enabled = !!os_strstr(pos, " ht"); - settings->freq_params.vht_enabled = !!os_strstr(pos, " vht"); - settings->freq_params.he_enabled = !!os_strstr(pos, " he"); -+ settings->freq_params.eht_enabled = !!os_strstr(pos, " eht"); - settings->block_tx = !!os_strstr(pos, " blocktx"); - #undef SET_CSA_SETTING - ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -3581,11 +3581,12 @@ static int hostapd_fill_csa_settings(str - &hapd->iface->cs_oper_class, - &chan) == NUM_HOSTAPD_MODES) { - wpa_printf(MSG_DEBUG, -- "invalid frequency for channel switch (freq=%d, sec_channel_offset=%d, vht_enabled=%d, he_enabled=%d)", -+ "invalid frequency for channel switch (freq=%d, sec_channel_offset=%d, vht_enabled=%d, he_enabled=%d, eht_enabled=%d)", - settings->freq_params.freq, - settings->freq_params.sec_channel_offset, - settings->freq_params.vht_enabled, -- settings->freq_params.he_enabled); -+ settings->freq_params.he_enabled, -+ settings->freq_params.eht_enabled); - return -1; - } - -@@ -3646,6 +3647,11 @@ void hostapd_cleanup_cs_params(struct ho - void hostapd_chan_switch_config(struct hostapd_data *hapd, - struct hostapd_freq_params *freq_params) - { -+ if (freq_params->eht_enabled) -+ hapd->iconf->ch_switch_eht_config |= CH_SWITCH_EHT_ENABLED; -+ else -+ hapd->iconf->ch_switch_eht_config |= CH_SWITCH_EHT_DISABLED; -+ - if (freq_params->he_enabled) - hapd->iconf->ch_switch_he_config |= CH_SWITCH_HE_ENABLED; - else -@@ -3658,7 +3664,8 @@ void hostapd_chan_switch_config(struct h - - hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, - HOSTAPD_LEVEL_INFO, -- "CHAN_SWITCH HE config 0x%x VHT config 0x%x", -+ "CHAN_SWITCH EHT config 0x%x HE config 0x%x VHT config 0x%x", -+ hapd->iconf->ch_switch_eht_config, - hapd->iconf->ch_switch_he_config, - hapd->iconf->ch_switch_vht_config); - } -@@ -3733,6 +3740,7 @@ hostapd_switch_channel_fallback(struct h - iface->conf->ieee80211n = freq_params->ht_enabled; - iface->conf->ieee80211ac = freq_params->vht_enabled; - iface->conf->ieee80211ax = freq_params->he_enabled; -+ iface->conf->ieee80211be = freq_params->eht_enabled; - hostapd_set_oper_centr_freq_seg0_idx(iface->conf, seg0_idx); - hostapd_set_oper_centr_freq_seg1_idx(iface->conf, seg1_idx); - hostapd_set_oper_chwidth(iface->conf, bw); diff --git a/feeds/ipq95xx/hostapd/patches/q02-019-eht-add-checks-for-channel-switch-announcement.patch b/feeds/ipq95xx/hostapd/patches/q02-019-eht-add-checks-for-channel-switch-announcement.patch deleted file mode 100644 index 4a376857..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-019-eht-add-checks-for-channel-switch-announcement.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 6ea74653334ab1ab9d347e40bc0ef64960526c05 Mon Sep 17 00:00:00 2001 -From: Muna Sinada -Date: Wed, 21 Jul 2021 10:17:40 -0700 -Subject: [PATCH 19/23] eht: add checks for channel switch announcement - -Add checks to confirm that respective modes VHT/HE/EHT are not disabled -for the interface before adding the CSA related fields in the management -frames. - -Signed-off-by: Muna Sinada -Signed-off-by: Aloka Dixit ---- - src/ap/beacon.c | 10 ++++++++-- - src/ap/ieee802_11.c | 3 ++- - 2 files changed, 10 insertions(+), 3 deletions(-) - ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -643,7 +643,10 @@ static u8 * hostapd_gen_probe_resp(struc - pos = hostapd_eid_txpower_envelope(hapd, pos); - #endif /* CONFIG_IEEE80211AX */ - -- pos = hostapd_eid_wb_chsw_wrapper(hapd, pos); -+ if ((hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) || -+ (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) || -+ (hapd->iconf->ieee80211be && !hapd->conf->disable_11be)) -+ pos = hostapd_eid_wb_chsw_wrapper(hapd, pos); - - pos = hostapd_eid_rnr(hapd, pos, WLAN_FC_STYPE_PROBE_RESP); - pos = hostapd_eid_fils_indic(hapd, pos, 0); -@@ -1757,7 +1760,10 @@ int ieee802_11_build_ap_params(struct ho - tailpos = hostapd_eid_txpower_envelope(hapd, tailpos); - #endif /* CONFIG_IEEE80211AX */ - -- tailpos = hostapd_eid_wb_chsw_wrapper(hapd, tailpos); -+ if ((hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) || -+ (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) || -+ (hapd->iconf->ieee80211be && !hapd->conf->disable_11be)) -+ tailpos = hostapd_eid_wb_chsw_wrapper(hapd, tailpos); - - tailpos = hostapd_eid_rnr(hapd, tailpos, WLAN_FC_STYPE_BEACON); - tailpos = hostapd_eid_fils_indic(hapd, tailpos, 0); ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -7198,7 +7198,8 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct - - if (!hapd->cs_freq_params.channel || - (!hapd->cs_freq_params.vht_enabled && -- !hapd->cs_freq_params.he_enabled)) -+ !hapd->cs_freq_params.he_enabled && -+ !hapd->cs_freq_params.eht_enabled)) - return eid; - - /* bandwidth: 0: 40, 1: 80, 2: 160, 3: 80+80 */ diff --git a/feeds/ipq95xx/hostapd/patches/q02-020-eht-changes-to-channel-switch-exchange-with-driver.patch b/feeds/ipq95xx/hostapd/patches/q02-020-eht-changes-to-channel-switch-exchange-with-driver.patch deleted file mode 100644 index 780ec2a1..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-020-eht-changes-to-channel-switch-exchange-with-driver.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 34237060f4970c887152e705ea15353996309e21 Mon Sep 17 00:00:00 2001 -From: Muna Sinada -Date: Wed, 21 Jul 2021 10:29:16 -0700 -Subject: [PATCH 20/23] eht: changes to channel switch exchange with driver - -Add EHT mode to channel switch related settings exchanged between -the userspace and the driver. - -Signed-off-by: Muna Sinada -Signed-off-by: Aloka Dixit ---- - src/ap/drv_callbacks.c | 40 +++++++++++++++++++++++++++--------- - src/drivers/driver_nl80211.c | 5 +++-- - 2 files changed, 33 insertions(+), 12 deletions(-) - ---- a/src/ap/drv_callbacks.c -+++ b/src/ap/drv_callbacks.c -@@ -881,10 +881,11 @@ void hostapd_event_ch_switch(struct host - - hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, - HOSTAPD_LEVEL_INFO, -- "driver %s channel switch: freq=%d, ht=%d, vht_ch=0x%x, he_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d", -+ "driver %s channel switch: freq=%d, ht=%d, vht_ch=0x%x, he_ch=0x%x, eht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d", - finished ? "had" : "starting", - freq, ht, hapd->iconf->ch_switch_vht_config, -- hapd->iconf->ch_switch_he_config, offset, -+ hapd->iconf->ch_switch_he_config, -+ hapd->iconf->ch_switch_eht_config, offset, - width, channel_width_to_string(width), cf1, cf2); - - if (!hapd->iface->current_mode) { -@@ -929,22 +930,24 @@ void hostapd_event_ch_switch(struct host - hapd->iconf->ieee80211n = ht; - if (!ht) { - hapd->iconf->ieee80211ac = 0; -- if (!is_6ghz_freq(hapd->iface->freq)) -+ if (!is_6ghz_freq(hapd->iface->freq)) { - hapd->iconf->ieee80211ax = 0; -+ hapd->iconf->ieee80211be = 0; -+ } - } else { - if (hapd->iconf->ch_switch_vht_config) { - /* CHAN_SWITCH VHT config */ - if (hapd->iconf->ch_switch_vht_config & -- CH_SWITCH_VHT_ENABLED) -+ CH_SWITCH_VHT_ENABLED) - hapd->iconf->ieee80211ac = 1; - else if (hapd->iconf->ch_switch_vht_config & -- CH_SWITCH_VHT_DISABLED) -+ CH_SWITCH_VHT_DISABLED) - hapd->iconf->ieee80211ac = 0; - } - if (hapd->iconf->ch_switch_he_config) { - /* CHAN_SWITCH HE config */ - if (hapd->iconf->ch_switch_he_config & -- CH_SWITCH_HE_ENABLED) { -+ CH_SWITCH_HE_ENABLED) { - hapd->iconf->ieee80211ax = 1; - if (!is_6ghz_freq(hapd->iface->freq)) - hapd->iconf->ieee80211ac = 1; -@@ -953,9 +956,23 @@ void hostapd_event_ch_switch(struct host - CH_SWITCH_HE_DISABLED) - hapd->iconf->ieee80211ax = 0; - } -+ if (hapd->iconf->ch_switch_eht_config) { -+ /* CHAN_SWITCH EHT config */ -+ if (hapd->iconf->ch_switch_eht_config & -+ CH_SWITCH_EHT_ENABLED) { -+ hapd->iconf->ieee80211be = 1; -+ hapd->iconf->ieee80211ax = 1; -+ if (!is_6ghz_freq(hapd->iface->freq)) -+ hapd->iconf->ieee80211ac = 1; -+ } else if (hapd->iconf->ch_switch_eht_config & -+ CH_SWITCH_EHT_DISABLED) -+ hapd->iconf->ieee80211be = 0; -+ } - } -+ - hapd->iconf->ch_switch_vht_config = 0; - hapd->iconf->ch_switch_he_config = 0; -+ hapd->iconf->ch_switch_eht_config = 0; - - hapd->iconf->secondary_channel = offset; - hostapd_set_oper_chwidth(hapd->iconf, chwidth); diff --git a/feeds/ipq95xx/hostapd/patches/q02-021-nl80211-check-driver-capabilities-for-beacon-rates.patch b/feeds/ipq95xx/hostapd/patches/q02-021-nl80211-check-driver-capabilities-for-beacon-rates.patch deleted file mode 100644 index 16f703c6..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-021-nl80211-check-driver-capabilities-for-beacon-rates.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 6a26c187beb14ccdee95d95ab0194410ba9e0ded Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Tue, 20 Jul 2021 13:50:06 -0700 -Subject: [PATCH 21/23] nl80211: check driver capabilities for beacon rates - -Set flag WPA_DRIVER_FLAGS2_BEACON_RATE_EHT if the driver advertises -support for EHT rates for beacon transmission. - -Signed-off-by: Aloka Dixit ---- - src/drivers/driver.h | 2 ++ - src/drivers/driver_nl80211_capa.c | 4 ++++ - 2 files changed, 6 insertions(+) - ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -2149,6 +2149,8 @@ struct wpa_driver_capa { - #define WPA_DRIVER_FLAGS2_OCV 0x0000000000000080ULL - /** Driver expects user space implementation of SME in AP mode */ - #define WPA_DRIVER_FLAGS2_AP_SME 0x0000000000000100ULL -+/** Driver supports Beacon frame TX rate configuration (EHT rates) */ -+#define WPA_DRIVER_FLAGS2_BEACON_RATE_EHT 0x0000000000000400ULL - u64 flags2; - - #define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \ ---- a/src/drivers/driver_nl80211_capa.c -+++ b/src/drivers/driver_nl80211_capa.c -@@ -563,6 +563,10 @@ static void wiphy_info_ext_feature_flags - capa->flags2 |= WPA_DRIVER_FLAGS2_BEACON_RATE_HE; - - if (ext_feature_isset(ext_features, len, -+ NL80211_EXT_FEATURE_BEACON_RATE_EHT)) -+ capa->flags2 |= WPA_DRIVER_FLAGS2_BEACON_RATE_EHT; -+ -+ if (ext_feature_isset(ext_features, len, - NL80211_EXT_FEATURE_SET_SCAN_DWELL)) - capa->rrm_flags |= WPA_DRIVER_FLAGS_SUPPORT_SET_SCAN_DWELL; - diff --git a/feeds/ipq95xx/hostapd/patches/q02-022-eht-configuration-option-for-beacon-rates.patch b/feeds/ipq95xx/hostapd/patches/q02-022-eht-configuration-option-for-beacon-rates.patch deleted file mode 100644 index ef2590dc..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-022-eht-configuration-option-for-beacon-rates.patch +++ /dev/null @@ -1,83 +0,0 @@ -From ed2488e7b721ca430ddbe1245f7b40396b4685c9 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Thu, 22 Jul 2021 13:07:26 -0700 -Subject: [PATCH 22/23] eht: configuration option for beacon rates - -Add a new option 'eht' under 'beacon_rate' to configure EHT MCS rates. -Valid values for this option will be 0-15. - -Signed-off-by: Aloka Dixit ---- - hostapd/config_file.c | 10 ++++++++++ - hostapd/hostapd.conf | 2 ++ - src/common/defs.h | 3 ++- - src/drivers/driver.h | 5 +++-- - 4 files changed, 17 insertions(+), 3 deletions(-) - -diff --git a/hostapd/config_file.c b/hostapd/config_file.c -index dada06c365b2..a5c1efb20b2d 100644 ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -3334,6 +3334,16 @@ static int hostapd_config_fill(struct hostapd_config *conf, - } - conf->rate_type = BEACON_RATE_HE; - conf->beacon_rate = val; -+ } else if (os_strncmp(pos, "eht:", 3) == 0) { -+ val = atoi(pos + 3); -+ if (val < 0 || val > 15) { -+ wpa_printf(MSG_ERROR, -+ "Line %d: invalid beacon_rate EHT-MCS %d", -+ line, val); -+ return 1; -+ } -+ conf->rate_type = BEACON_RATE_EHT; -+ conf->beacon_rate = val; - } else { - val = atoi(pos); - if (val < 10 || val > 10000) { -diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf -index b84d3d9fa677..e03bea2b3541 100644 ---- a/hostapd/hostapd.conf -+++ b/hostapd/hostapd.conf -@@ -285,6 +285,8 @@ fragm_threshold=-1 - # beacon_rate=vht: - # HE: - # beacon_rate=he: -+# EHT: -+# beacon_rate=eht: - # - # For example, beacon_rate=10 for 1 Mbps or beacon_rate=60 for 6 Mbps (OFDM). - #beacon_rate=10 -diff --git a/src/common/defs.h b/src/common/defs.h -index f43bdb5d1b15..ad66eb244715 100644 ---- a/src/common/defs.h -+++ b/src/common/defs.h -@@ -406,7 +406,8 @@ enum beacon_rate_type { - BEACON_RATE_LEGACY, - BEACON_RATE_HT, - BEACON_RATE_VHT, -- BEACON_RATE_HE -+ BEACON_RATE_HE, -+ BEACON_RATE_EHT, - }; - - enum eap_proxy_sim_state { -diff --git a/src/drivers/driver.h b/src/drivers/driver.h -index cc09eddfd168..076f290b28a4 100644 ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -1290,8 +1290,9 @@ struct wpa_driver_ap_params { - * This parameter can be used to set a specific Beacon frame data rate - * for the BSS. The interpretation of this value depends on the - * rate_type (legacy: in 100 kbps units, HT: HT-MCS, VHT: VHT-MCS, -- * HE: HE-MCS). If beacon_rate == 0 and rate_type == 0 -- * (BEACON_RATE_LEGACY), the default Beacon frame data rate is used. -+ * HE: HE-MCS, EHT: EHT-MCS). -+ * If beacon_rate == 0 and rate_type == 0 (BEACON_RATE_LEGACY), -+ * the default Beacon frame data rate is used. - */ - unsigned int beacon_rate; - --- -2.31.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-023-nl80211-pass-EHT-beacon-rate-configuration-to-kernel.patch b/feeds/ipq95xx/hostapd/patches/q02-023-nl80211-pass-EHT-beacon-rate-configuration-to-kernel.patch deleted file mode 100644 index d1bea9ae..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-023-nl80211-pass-EHT-beacon-rate-configuration-to-kernel.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 49de97b9da238db0af0fbbd89408c87cf9c7e139 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Thu, 22 Jul 2021 13:13:08 -0700 -Subject: [PATCH 23/23] nl80211: pass EHT beacon rate configuration to kernel - -Propagate EHT beacon rate to kernel if the driver has advertised -support for this configuration. Legacy, HT, VHT and HE rates will be -set to NULL. - -Signed-off-by: Aloka Dixit ---- - src/drivers/driver_nl80211.c | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - -diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c -index b5e336be826b..088e58edf2a7 100644 ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -4290,6 +4290,7 @@ static int nl80211_put_beacon_rate(struct nl_msg *msg, u64 flags, u64 flags2, - struct nlattr *bands, *band; - struct nl80211_txrate_vht vht_rate; - struct nl80211_txrate_he he_rate; -+ struct nl80211_txrate_eht eht_rate; - - if (!params->freq || - (params->beacon_rate == 0 && -@@ -4323,6 +4324,7 @@ static int nl80211_put_beacon_rate(struct nl_msg *msg, u64 flags, u64 flags2, - - os_memset(&vht_rate, 0, sizeof(vht_rate)); - os_memset(&he_rate, 0, sizeof(he_rate)); -+ os_memset(&eht_rate, 0, sizeof(eht_rate)); - - switch (params->rate_type) { - case BEACON_RATE_LEGACY: -@@ -4391,6 +4393,26 @@ static int nl80211_put_beacon_rate(struct nl_msg *msg, u64 flags, u64 flags2, - wpa_printf(MSG_DEBUG, " * beacon_rate = HE-MCS %u", - params->beacon_rate); - break; -+ -+ case BEACON_RATE_EHT: -+ if (!(flags2 & WPA_DRIVER_FLAGS2_BEACON_RATE_EHT)) { -+ wpa_printf(MSG_INFO, -+ "nl80211: Driver does not support setting Beacon frame rate (EHT)"); -+ return -1; -+ } -+ eht_rate.mcs[0] = BIT(params->beacon_rate); -+ if (nla_put(msg, NL80211_TXRATE_LEGACY, 0, NULL) || -+ nla_put(msg, NL80211_TXRATE_HT, 0, NULL) || -+ nla_put(msg, NL80211_TXRATE_VHT, sizeof(vht_rate), -+ &vht_rate) || -+ nla_put(msg, NL80211_TXRATE_HE, sizeof(he_rate), -+ &he_rate) || -+ nla_put(msg, NL80211_TXRATE_EHT, sizeof(eht_rate), -+ &eht_rate)) -+ return -1; -+ wpa_printf(MSG_DEBUG, " * beacon_rate = EHT-MCS %u", -+ params->beacon_rate); -+ break; - } - - nla_nest_end(msg, band); --- -2.31.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-024-hostapd-11BE-bringup-Fixes.patch b/feeds/ipq95xx/hostapd/patches/q02-024-hostapd-11BE-bringup-Fixes.patch deleted file mode 100644 index 4fdc025d..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-024-hostapd-11BE-bringup-Fixes.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 4009d6184a38cbc6a7c5bd842913c169b139da7c Mon Sep 17 00:00:00 2001 -From: Pradeep Kumar Chitrapu -Date: Wed, 23 Feb 2022 11:58:52 -0800 -Subject: [PATCH] hostapd: 11BE bringup Fixes - - - Fix EHT MCS rates length calculation. - - Process PPE Thresholds only if there are additional bytes - available in EHT Caps after MAC CAPS. PHY CAPS and - MCS rates. This is temporary workaround to ignore - other driversnot adding PPE thresholds in EHT CAP - inspite of setting eht_ppe_threshlds_present bit in - EHT PHY CAPS. - - Fix ppe threshold size computation - -Signed-off-by: Pradeep Kumar Chitrapu ---- - src/ap/ieee802_11_eht.c | 33 ++++++++++++++++++--------------- - src/common/ieee802_11_defs.h | 13 +++++++------ - 2 files changed, 25 insertions(+), 21 deletions(-) - ---- a/src/ap/ieee802_11_eht.c -+++ b/src/ap/ieee802_11_eht.c -@@ -24,29 +24,29 @@ - - static u8 ieee80211_eht_ppet_size(const u8 *ppe_thres, const u8 *phy_cap_info) - { -- u8 sz = 0, ru; -+ u8 sz = 0, nss, num_nss = 0; -+ u32 ru; - - if ((phy_cap_info[EHT_PHYCAP_PPE_THRESHOLD_PRESENT_IDX] & - EHT_PHYCAP_PPE_THRESHOLD_PRESENT) == 0) - return 0; - -- ru = (ppe_thres[0] & -- (EHT_PPE_THRES_RU_INDEX_MASK << EHT_PPE_THRES_RU_INDEX_SHIFT)); -+ ru = (u32) ppe_thres[0]; -+ ru = (ru & EHT_PPE_THRES_RU_INDEX_MASK) >> EHT_PPE_THRES_RU_INDEX_SHIFT; - while (ru) { - if (ru & 0x1) - sz++; - ru >>= 1; - } - -- ru = (ppe_thres[1] & (EHT_PPE_THRES_RU_INDEX_MASK >> -- (8 - EHT_PPE_THRES_RU_INDEX_SHIFT))); -- while (ru) { -- if (ru & 0x1) -- sz++; -- ru >>= 1; -+ nss = (ppe_thres[0] & EHT_PPE_THRES_NSS_MASK) >> EHT_PPE_THRES_NSS_SHIFT; -+ while (nss) { -+ if (nss & 0x1) -+ num_nss++; -+ nss >>= 1; - } - -- sz *= (1 + (ppe_thres[0] & EHT_PPE_THRES_NSS_MASK)); -+ sz = sz * (1 + num_nss); - sz = (sz * 6) + 9; - if (sz % 8) - sz += 8; -@@ -246,6 +246,7 @@ static int check_valid_eht_mcs(struct ho - { - struct hostapd_hw_modes *mode; - const u8 *ap_mcs, *sta_mcs; -+ u8 len; - - mode = hapd->iface->current_mode; - if (!mode) -@@ -254,9 +255,9 @@ static int check_valid_eht_mcs(struct ho - ap_mcs = mode->eht_capab[opmode].mcs; - sta_mcs = ((const struct ieee80211_eht_capabilities *) sta_eht_capab)->optional; - -- if (ieee80211_eht_mcs_set_size(mode->he_capab[opmode].phy_cap, -- mode->eht_capab[opmode].phy_cap) == -- EHT_PHYCAP_MCS_NSS_LEN_20MHZ_ONLY) { -+ len = ieee80211_eht_mcs_set_size(mode->he_capab[opmode].phy_cap, -+ mode->eht_capab[opmode].phy_cap); -+ if (len == EHT_PHYCAP_MCS_NSS_LEN_20MHZ_ONLY) { - return check_valid_eht_mcs_nss(hapd, ap_mcs, sta_mcs, 1, - EHT_PHYCAP_MCS_NSS_LEN_20MHZ_ONLY); - -@@ -274,7 +275,7 @@ static int check_valid_eht_mcs(struct ho - } - - return check_valid_eht_mcs_nss(hapd, ap_mcs, sta_mcs, mcs_count, -- EHT_PHYCAP_MCS_NSS_LEN_20MHZ_PLUS); -+ len); - } - - return 0; -@@ -298,7 +299,9 @@ static int ieee80211_invalid_eht_cap_siz - if (len < cap_len) - return 1; - -- cap_len += ieee80211_eht_ppet_size(&eht_cap[cap_len], cap->phy_cap); -+ if ((cap->phy_cap[EHT_PHYCAP_PPE_THRESHOLD_PRESENT_IDX] & -+ EHT_PHYCAP_PPE_THRESHOLD_PRESENT) == 0 && len > cap_len) -+ cap_len += ieee80211_eht_ppet_size(&eht_cap[cap_len], cap->phy_cap); - - return (len != cap_len); - } ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -2511,14 +2511,14 @@ struct ieee80211_eht_operation { - #define EHT_PHYCAP_MCS_NSS_LEN_20MHZ_ONLY 4 - #define EHT_PHYCAP_MCS_NSS_LEN_20MHZ_PLUS 3 - --/* IEEE P802.11be/D1.0, May 2021, 9.4.2.295c.5 EHT PPE Thresholds field */ -+/* IEEE P802.11be/D1.4, May 2021, 9.4.2.295c.5 EHT PPE Thresholds field */ - #define EHT_PPE_THRES_NSS_SHIFT 0 - #define EHT_PPE_THRES_NSS_MASK ((u8) (BIT(0) | BIT(1) | \ -- BIT(2) | BIT(3))) -+ BIT(2) | BIT(3))) - #define EHT_PPE_THRES_RU_INDEX_SHIFT 4 --#define EHT_PPE_THRES_RU_INDEX_MASK ((u8) (BIT(0) | BIT(1) | \ -- BIT(2) | BIT(3) | \ -- BIT(4))) -+#define EHT_PPE_THRES_RU_INDEX_MASK ((u8) (BIT(4) | BIT(5) | \ -+ BIT(6) | BIT(7) | \ -+ BIT(8))) - - #define EHT_OPERATION_CHANNEL_WIDTH_40MHZ 1 - #define EHT_OPERATION_CHANNEL_WIDTH_80MHZ 2 diff --git a/feeds/ipq95xx/hostapd/patches/q02-025-hostapd-WAR-patch-for-prop-issue.patch b/feeds/ipq95xx/hostapd/patches/q02-025-hostapd-WAR-patch-for-prop-issue.patch deleted file mode 100644 index e710bc7b..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-025-hostapd-WAR-patch-for-prop-issue.patch +++ /dev/null @@ -1,131 +0,0 @@ -From c47c9c66e37ecff2519ce17f22db1b542ec4436c Mon Sep 17 00:00:00 2001 -From: Pradeep Kumar Chitrapu -Date: Wed, 9 Mar 2022 09:47:40 -0800 -Subject: [PATCH] hostapd: workaround to match EHT client - -Current AP code is using IEEE P802.11be/D1.4 whereas client devices -are designed as per IEEE P802.11be/D1.3. -Roll-back the AP code to match client temporarily. - -Signed-off-by: Pradeep Kumar Chitrapu -Signed-off-by: Aloka Dixit ---- - src/ap/ieee802_11_eht.c | 33 +++++++++++++++++---------------- - src/common/ieee802_11_defs.h | 17 ++++++++++++----- - 2 files changed, 29 insertions(+), 21 deletions(-) - ---- a/src/ap/ieee802_11_eht.c -+++ b/src/ap/ieee802_11_eht.c -@@ -170,7 +170,7 @@ u8 * hostapd_eid_eht_operation(struct ho - { - struct hostapd_hw_modes *mode; - struct ieee80211_eht_operation *oper; -- u8 *pos = eid, *length_pos, chwidth, seg0 = 0; -+ u8 *pos = eid, oper_size = 0, chwidth; - - mode = hapd->iface->current_mode; - if (!mode) -@@ -179,45 +179,49 @@ u8 * hostapd_eid_eht_operation(struct ho - if (!mode->eht_capab[opmode].eht_supported) - return eid; - -+ oper_size = sizeof(struct ieee80211_eht_operation); - *pos++ = WLAN_EID_EXTENSION; -- length_pos = pos++; -+ *pos++ = 1 + oper_size; - *pos++ = WLAN_EID_EXT_EHT_OPERATION; - - oper = (struct ieee80211_eht_operation *) pos; - os_memset(oper, 0, sizeof(*oper)); - -+ oper->ccfs = hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf); -+ if (!oper->ccfs) -+ oper->ccfs = hapd->iconf->channel; -+ - if (is_6ghz_op_class(hapd->iconf->op_class)) - chwidth = op_class_to_ch_width(hapd->iconf->op_class); - else - chwidth = hapd->iconf->eht_oper_chwidth; - -- seg0 = hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf); -- - switch (chwidth) { - case CHANWIDTH_320MHZ: -- *pos++ = EHT_OPERATION_CHANNEL_WIDTH_320MHZ; -+ oper->width = EHT_OPERATION_CHANNEL_WIDTH_320MHZ; - break; - case CHANWIDTH_160MHZ: -- *pos++ = EHT_OPERATION_CHANNEL_WIDTH_160MHZ; -+ oper->width = EHT_OPERATION_CHANNEL_WIDTH_160MHZ; - break; - case CHANWIDTH_80MHZ: -- *pos++ = EHT_OPERATION_CHANNEL_WIDTH_80MHZ; -+ oper->width = EHT_OPERATION_CHANNEL_WIDTH_80MHZ; - break; - case CHANWIDTH_USE_HT: -- if (seg0) -- *pos++ = EHT_OPERATION_CHANNEL_WIDTH_40MHZ; -+ if ((is_6ghz_op_class(hapd->iconf->op_class) && -+ op_class_to_bandwidth(hapd->iconf->op_class) == 40) || -+ hapd->iconf->secondary_channel) -+ oper->width = EHT_OPERATION_CHANNEL_WIDTH_40MHZ; - else -- pos++; -+ oper->width = EHT_OPERATION_CHANNEL_WIDTH_20MHZ; -+ - break; - default: -- return eid; -+ oper->width = EHT_OPERATION_CHANNEL_WIDTH_20MHZ; -+ break; - } - -- if (!seg0) -- seg0 = hapd->iconf->channel; -- *pos++ = seg0; -+ pos += oper_size; - -- *length_pos = pos - (eid + 2); - return pos; - } - -@@ -295,6 +299,7 @@ static int ieee80211_invalid_eht_cap_siz - const u8 *he_phy_cap; - size_t cap_len; - -+ return 0; - he_phy_cap = ((struct ieee80211_he_capabilities *)he_cap)->he_phy_capab_info; - cap = (struct ieee80211_eht_capabilities *) eht_cap; - cap_len = sizeof(*cap); ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -2458,6 +2458,7 @@ struct ieee80211_eht_capabilities { - u8 optional[71]; - } STRUCT_PACKED; - -+#define EHT_OPERATION_CCFS_SHIFT 4 - /* - * struct ieee80211_eht_operation - eht operation element - * -@@ -2469,13 +2470,17 @@ struct ieee80211_eht_capabilities { - * structure (Figure 9-1002a) at all ... - */ - struct ieee80211_eht_operation { -- u8 chan_width; -+ u8 width:3, -+ reserved:5; - u8 ccfs; -- u8 present_bm; -- /* contains disabled subchannel bitmap */ -- u8 optional[]; -+ u8 disable_sub_chan_bitmap_present:1, -+ reserved2:7; -+ le16 disabled_subchannel_bitmap; -+ -+ /* Add puncture pattern here when supported */ - } STRUCT_PACKED; - -+#define EHT_OPERATION_CHANNEL_WIDTH_20MHZ 0 - #define EHT_OPERATION_CHANNEL_WIDTH_40MHZ 1 - #define EHT_OPERATION_CHANNEL_WIDTH_80MHZ 2 - #define EHT_OPERATION_CHANNEL_WIDTH_160MHZ 3 diff --git a/feeds/ipq95xx/hostapd/patches/q02-031-ru_puncturing-retrieve-driver-support.patch b/feeds/ipq95xx/hostapd/patches/q02-031-ru_puncturing-retrieve-driver-support.patch deleted file mode 100644 index 41e98512..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-031-ru_puncturing-retrieve-driver-support.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 74cd6b31e4300bd70dd67ecfeab07231fb3436d2 Mon Sep 17 00:00:00 2001 -From: Muna Sinada -Date: Wed, 8 Dec 2021 23:11:27 -0800 -Subject: [PATCH 1/6] ru_puncturing: retrieve driver support - -Retrieve the driver support for RU puncturing which is advertised -using the attribute NL80211_ATTR_RU_PUNCT_SUPP_BW. -Value indicates the bandwidths in which puncturing is supported - -80 MHz, 160 MHz or 320 MHz. - -Absence of the attribute or the value 0 means the driver does not -support this feature. - -Signed-off-by: Muna Sinada -Signed-off-by: Aloka Dixit ---- - hostapd/main.c | 1 + - src/ap/hostapd.h | 3 +++ - src/drivers/driver.h | 3 +++ - src/drivers/driver_nl80211_capa.c | 18 ++++++++++++++++++ - src/drivers/nl80211_copy.h | 12 ++++++++++++ - 5 files changed, 37 insertions(+) - -diff --git a/hostapd/main.c b/hostapd/main.c -index 6e54e9d66fd6..aeef81146306 100644 ---- a/hostapd/main.c -+++ b/hostapd/main.c -@@ -240,6 +240,7 @@ static int hostapd_driver_init(struct hostapd_iface *iface) - iface->extended_capa_mask = capa.extended_capa_mask; - iface->extended_capa_len = capa.extended_capa_len; - iface->drv_max_acl_mac_addrs = capa.max_acl_mac_addrs; -+ iface->ru_punct_supp_bw = capa.ru_punct_supp_bw; - - /* - * Override extended capa with per-interface type (AP), if -diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h -index ccc1c8514878..6cdd2c4e77d5 100644 ---- a/src/ap/hostapd.h -+++ b/src/ap/hostapd.h -@@ -617,6 +617,9 @@ struct hostapd_iface { - /* Maximum profile periodicity for enhanced MBSSID advertisements */ - u8 ema_max_periodicity; - -+ /* Minimum bandwidth the driver supports RU puncturing */ -+ u8 ru_punct_supp_bw; -+ - int (*enable_iface_cb)(struct hostapd_iface *iface); - int (*disable_iface_cb)(struct hostapd_iface *iface); - }; -diff --git a/src/drivers/driver.h b/src/drivers/driver.h -index 4a60239be32f..2252a651c6ab 100644 ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -2275,6 +2275,9 @@ struct wpa_driver_capa { - u8 mbssid_max_interfaces; - /* Maximum profile periodicity for enhanced MBSSID advertisements */ - u8 ema_max_periodicity; -+ -+ /* Minimum bandwidth the driver supports RU Puncturing */ -+ u8 ru_punct_supp_bw; - }; - - -diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c -index dc85e21290ae..593fa47fe854 100644 ---- a/src/drivers/driver_nl80211_capa.c -+++ b/src/drivers/driver_nl80211_capa.c -@@ -1100,6 +1100,24 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg) - if (tb[NL80211_ATTR_MBSSID_CONFIG]) - wiphy_info_mbssid(capa, tb[NL80211_ATTR_MBSSID_CONFIG]); - -+ if (tb[NL80211_ATTR_RU_PUNCT_SUPP_BW]) { -+ u8 supp_bw = nla_get_u8(tb[NL80211_ATTR_RU_PUNCT_SUPP_BW]); -+ -+ switch (supp_bw) { -+ case NL80211_RU_PUNCT_SUPP_BW_80: -+ capa->ru_punct_supp_bw = CHANWIDTH_80MHZ; -+ break; -+ case NL80211_RU_PUNCT_SUPP_BW_160: -+ capa->ru_punct_supp_bw = CHANWIDTH_160MHZ; -+ break; -+ case NL80211_RU_PUNCT_SUPP_BW_320: -+ capa->ru_punct_supp_bw = CHANWIDTH_320MHZ; -+ break; -+ default: -+ break; -+ } -+ } -+ - return NL_SKIP; - } - -diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h -index 7666f18f3e95..77c7a8445e97 100644 ---- a/src/drivers/nl80211_copy.h -+++ b/src/drivers/nl80211_copy.h -@@ -3120,6 +3120,10 @@ enum nl80211_attrs { - - NL80211_ATTR_DISABLE_EHT, - -+ NL80211_ATTR_RU_PUNCT_SUPP_BW, -+ NL80211_ATTR_RU_PUNCT_SUPP_HE, -+ NL80211_ATTR_RU_PUNCT_BITMAP, -+ - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, -@@ -7487,4 +7491,12 @@ enum nl80211_beacon_tx_mode { - NL80211_BEACON_STAGGERED_MODE = 1, - NL80211_BEACON_BURST_MODE = 2, - }; -+ -+enum nl80211_ru_punct_supp_bw { -+ NL80211_RU_PUNCT_NOT_SUPP, -+ NL80211_RU_PUNCT_SUPP_BW_80, -+ NL80211_RU_PUNCT_SUPP_BW_160, -+ NL80211_RU_PUNCT_SUPP_BW_320, -+}; -+ - #endif /* __LINUX_NL80211_H */ --- -2.31.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-032-ru_puncturing-add-configuration-option.patch b/feeds/ipq95xx/hostapd/patches/q02-032-ru_puncturing-add-configuration-option.patch deleted file mode 100644 index d32fccb0..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-032-ru_puncturing-add-configuration-option.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 6a39866dcfc65fb44cfea13f9455b71a516b0f4f Mon Sep 17 00:00:00 2001 -From: Muna Sinada -Date: Wed, 2 Mar 2022 15:29:58 -0800 -Subject: [PATCH 2/6] ru_puncturing: add configuration option - -- New option 'ru_punct_bitmap' to configure RU puncturing bitmap. -- New option 'ru_punct_ofdma' which indicates if kernel should - consider OFDMA pattern. - -Signed-off-by: Muna Sinada -Signed-off-by: Aloka Dixit ---- - hostapd/config_file.c | 4 ++++ - hostapd/hostapd.conf | 11 +++++++++++ - src/ap/ap_config.h | 2 ++ - 3 files changed, 17 insertions(+) - -diff --git a/hostapd/config_file.c b/hostapd/config_file.c -index 72e00c337e07..80f3fc020f2a 100644 ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -4687,6 +4687,10 @@ static int hostapd_config_fill(struct hostapd_config *conf, - conf->eht_phy_capab.su_beamformee = atoi(pos); - } else if (os_strcmp(buf, "eht_mu_beamformer") == 0) { - conf->eht_phy_capab.mu_beamformer = atoi(pos); -+ } else if (os_strcmp(buf, "ru_punct_bitmap") == 0) { -+ conf->ru_punct_bitmap = atoi(pos); -+ } else if (os_strcmp(buf, "ru_punct_ofdma") == 0) { -+ conf->ru_punct_ofdma = atoi(pos); - #endif /* CONFIG_IEEE80211BE */ - } else { - wpa_printf(MSG_ERROR, -diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf -index 481911784f46..5fda6c614c80 100644 ---- a/hostapd/hostapd.conf -+++ b/hostapd/hostapd.conf -@@ -1017,6 +1017,17 @@ wmm_ac_vo_acm=0 - #eht_oper_chwidth - #eht_oper_centr_freq_seg0_idx - -+# RU puncturing bitmap (16 bits) where each bit corresponds to -+# a 20 MHz channel in the given bandwidth, bit 0 corresponding to the channel -+# with lowest frequency. -+# Bit set to 1 indicates that the channel is punctured, otherwise active. -+# Default value is 0 indicating that no channel is punctured. -+#ru_punct_bitmap=4 -+ -+# If the kernel should consider OFDMA patterns while validating the provided -+# RU puncturing bitmap. Default value is 0. -+#ru_punct_ofdma=1 -+ - ##### IEEE 802.1X-2004 related configuration ################################## - - # Require IEEE 802.1X authorization -diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h -index 884809388d18..19955beaefba 100644 ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -1148,6 +1148,8 @@ struct hostapd_config { - #define CH_SWITCH_EHT_ENABLED BIT(0) - #define CH_SWITCH_EHT_DISABLED BIT(1) - unsigned int ch_switch_eht_config; -+ u16 ru_punct_bitmap; -+ u8 ru_punct_ofdma; - }; - - static inline u8 hostapd_get_he_6ghz_reg_pwr_type(struct hostapd_config *conf) --- -2.31.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-033-ru_puncturing-add-bitmap-to-frequency-parameters.patch b/feeds/ipq95xx/hostapd/patches/q02-033-ru_puncturing-add-bitmap-to-frequency-parameters.patch deleted file mode 100644 index c8eb166b..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-033-ru_puncturing-add-bitmap-to-frequency-parameters.patch +++ /dev/null @@ -1,263 +0,0 @@ -From c68ba759850c7e1e35c017884b417b670998b820 Mon Sep 17 00:00:00 2001 -From: Muna Sinada -Date: Wed, 1 Dec 2021 15:53:47 -0800 -Subject: [PATCH 3/6] ru_puncturing: add bitmap to frequency parameters - -Add ru_punct_bitmap and ru_punct_ofdma in frequency settings so -that all commands using this code path will be able to configure -the bitmap as well. - -Signed-off-by: Muna Sinada -Signed-off-by: Aloka Dixit ---- - src/ap/ap_drv_ops.c | 12 ++++++++---- - src/ap/ap_drv_ops.h | 6 ++++-- - src/ap/beacon.c | 4 +++- - src/ap/dfs.c | 11 ++++++++--- - src/ap/hostapd.c | 8 ++++++-- - src/common/hw_features_common.c | 5 ++++- - src/common/hw_features_common.h | 3 ++- - src/drivers/driver.h | 14 ++++++++++++++ - wpa_supplicant/mesh.c | 4 +++- - wpa_supplicant/wpa_supplicant.c | 3 ++- - 10 files changed, 54 insertions(+), 16 deletions(-) - -diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c -index cc2ee5e2edcc..2ba885898cd6 100644 ---- a/src/ap/ap_drv_ops.c -+++ b/src/ap/ap_drv_ops.c -@@ -552,7 +552,8 @@ int hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode, - int ht_enabled, int vht_enabled, - int he_enabled, int eht_enabled, - int sec_channel_offset, int oper_chwidth, -- int center_segment0, int center_segment1) -+ int center_segment0, int center_segment1, -+ u16 ru_punct_bitmap, u8 ru_punct_ofdma) - { - struct hostapd_freq_params data; - struct hostapd_hw_modes *cmode = hapd->iface->current_mode; -@@ -567,7 +568,8 @@ int hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode, - &cmode->he_capab[IEEE80211_MODE_AP] : NULL, - cmode ? - &cmode->eht_capab[IEEE80211_MODE_AP] : NULL, -- hapd->iconf->he_6ghz_reg_pwr_type)) -+ hapd->iconf->he_6ghz_reg_pwr_type, -+ ru_punct_bitmap, ru_punct_ofdma)) - return -1; - - if (hapd->driver == NULL) -@@ -819,7 +821,8 @@ int hostapd_start_dfs_cac(struct hostapd_iface *iface, - int channel, int ht_enabled, int vht_enabled, - int he_enabled, int eht_enabled, - int sec_channel_offset, int oper_chwidth, -- int center_segment0, int center_segment1) -+ int center_segment0, int center_segment1, -+ u16 ru_punct_bitmap, u8 ru_punct_ofdma) - { - struct hostapd_data *hapd = iface->bss[0]; - struct hostapd_freq_params data; -@@ -844,7 +847,8 @@ int hostapd_start_dfs_cac(struct hostapd_iface *iface, - cmode->vht_capab, - &cmode->he_capab[IEEE80211_MODE_AP], - &cmode->eht_capab[IEEE80211_MODE_AP], -- hapd->iconf->he_6ghz_reg_pwr_type)) { -+ hapd->iconf->he_6ghz_reg_pwr_type, -+ ru_punct_bitmap, ru_punct_ofdma)) { - wpa_printf(MSG_ERROR, "Can't set freq params"); - return -1; - } -diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h -index fcac1eeee6dc..9155f1abca9e 100644 ---- a/src/ap/ap_drv_ops.h -+++ b/src/ap/ap_drv_ops.h -@@ -67,7 +67,8 @@ int hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode, - int freq, int channel, int edmg, u8 edmg_channel, - int ht_enabled, int vht_enabled, int he_enabled, - int eht_enabled, int sec_channel_offset, int oper_chwidth, -- int center_segment0, int center_segment1); -+ int center_segment0, int center_segment1, -+ u16 ru_punct_bitmap, u8 ru_punct_ofdma); - int hostapd_set_rts(struct hostapd_data *hapd, int rts); - int hostapd_set_frag(struct hostapd_data *hapd, int frag); - int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr, -@@ -131,7 +132,8 @@ int hostapd_start_dfs_cac(struct hostapd_iface *iface, - int channel, int ht_enabled, int vht_enabled, - int he_enabled, int eht_enabled, - int sec_channel_offset, int oper_chwidth, -- int center_segment0, int center_segment1); -+ int center_segment0, int center_segment1, -+ u16 ru_punct_bitmap, u8 ru_punct_ofdma); - int hostapd_drv_do_acs(struct hostapd_data *hapd); - int hostapd_drv_update_dh_ie(struct hostapd_data *hapd, const u8 *peer, - u16 reason_code, const u8 *ie, size_t ielen); -diff --git a/src/ap/beacon.c b/src/ap/beacon.c -index 9db8cf12e943..e331f9c95b12 100644 ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -2176,7 +2176,9 @@ static int __ieee802_11_set_beacon(struct hostapd_data *hapd) - cmode->vht_capab, - &cmode->he_capab[IEEE80211_MODE_AP], - &cmode->eht_capab[IEEE80211_MODE_AP], -- iconf->he_6ghz_reg_pwr_type) == 0) -+ iconf->he_6ghz_reg_pwr_type, -+ iconf->ru_punct_bitmap, -+ iconf->ru_punct_ofdma) == 0) - params.freq = &freq; - - res = hostapd_drv_set_ap(hapd, ¶ms); -diff --git a/src/ap/dfs.c b/src/ap/dfs.c -index 29d2a8991256..c206eb713629 100644 ---- a/src/ap/dfs.c -+++ b/src/ap/dfs.c -@@ -875,7 +875,8 @@ int hostapd_handle_dfs(struct hostapd_iface *iface) - iface->conf->secondary_channel, - hostapd_get_oper_chwidth(iface->conf), - hostapd_get_oper_centr_freq_seg0_idx(iface->conf), -- hostapd_get_oper_centr_freq_seg1_idx(iface->conf)); -+ hostapd_get_oper_centr_freq_seg1_idx(iface->conf), -+ iface->conf->ru_punct_bitmap, iface->conf->ru_punct_ofdma); - - if (res) { - wpa_printf(MSG_ERROR, "DFS start_dfs_cac() failed, %d", res); -@@ -1092,7 +1093,9 @@ static int hostapd_dfs_testmode_set_beacon_csa(struct hostapd_iface *iface) - iface->current_mode->vht_capab, - &iface->current_mode->he_capab[IEEE80211_MODE_AP], - &iface->current_mode->eht_capab[IEEE80211_MODE_AP], -- hapd->iconf->he_6ghz_reg_pwr_type); -+ hapd->iconf->he_6ghz_reg_pwr_type, -+ iface->conf->ru_punct_bitmap, -+ iface->conf->ru_punct_ofdma); - - if (err) { - wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params"); -@@ -1236,7 +1239,9 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface) - cmode->vht_capab, - &cmode->he_capab[ieee80211_mode], - &cmode->eht_capab[ieee80211_mode], -- iface->conf->he_6ghz_reg_pwr_type); -+ iface->conf->he_6ghz_reg_pwr_type, -+ iface->conf->ru_punct_bitmap, -+ iface->conf->ru_punct_ofdma); - - if (err) { - wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params"); -diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c -index 0b623a2fcdf1..becb726c760b 100644 ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -2123,7 +2123,9 @@ static int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface, - hostapd_get_oper_centr_freq_seg0_idx( - hapd->iconf), - hostapd_get_oper_centr_freq_seg1_idx( -- hapd->iconf))) { -+ hapd->iconf), -+ hapd->iconf->ru_punct_bitmap, -+ hapd->iconf->ru_punct_ofdma)) { - wpa_printf(MSG_ERROR, "Could not set channel for " - "kernel driver"); - goto fail; -@@ -3533,7 +3535,9 @@ static int hostapd_change_config_freq(struct hostapd_data *hapd, - mode ? &mode->he_capab[IEEE80211_MODE_AP] : - NULL, - mode ? &mode->eht_capab[IEEE80211_MODE_AP] : -- NULL, hapd->iconf->he_6ghz_reg_pwr_type)) -+ NULL, hapd->iconf->he_6ghz_reg_pwr_type, -+ conf->ru_punct_bitmap, -+ conf->ru_punct_ofdma)) - return -1; - - switch (params->bandwidth) { -diff --git a/src/common/hw_features_common.c b/src/common/hw_features_common.c -index 2e03265a2e72..786568b7d970 100644 ---- a/src/common/hw_features_common.c -+++ b/src/common/hw_features_common.c -@@ -388,7 +388,8 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data, - int center_segment1, u32 vht_caps, - struct he_capabilities *he_cap, - struct eht_capabilities *eht_cap, -- u8 reg_6g_pwr_mode) -+ u8 reg_6g_pwr_mode, u16 ru_punct_bitmap, -+ u8 ru_punct_ofdma) - { - if (!he_cap || !he_cap->he_supported) - he_enabled = 0; -@@ -403,6 +404,8 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data, - data->sec_channel_offset = sec_channel_offset; - data->center_freq1 = freq + sec_channel_offset * 10; - data->center_freq2 = 0; -+ data->ru_punct_bitmap = ru_punct_bitmap; -+ data->ru_punct_ofdma = ru_punct_ofdma; - if (oper_chwidth == CHANWIDTH_80MHZ) - data->bandwidth = 80; - else if (oper_chwidth == CHANWIDTH_160MHZ || -diff --git a/src/common/hw_features_common.h b/src/common/hw_features_common.h -index 2971b719aaae..1efe293c9939 100644 ---- a/src/common/hw_features_common.h -+++ b/src/common/hw_features_common.h -@@ -45,7 +45,8 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data, - int center_segment1, u32 vht_caps, - struct he_capabilities *he_caps, - struct eht_capabilities *eht_cap, -- u8 reg_6g_pwr_mode); -+ u8 reg_6g_pwr_mode, u16 ru_punct_bitmap, -+ u8 ru_punct_ofdma); - void set_disable_ht40(struct ieee80211_ht_capabilities *htcaps, - int disabled); - int ieee80211ac_cap_check(u32 hw, u32 conf); -diff --git a/src/drivers/driver.h b/src/drivers/driver.h -index 2252a651c6ab..baf05489be8e 100644 ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -819,6 +819,20 @@ struct hostapd_freq_params { - * eht_enabled - Whether EHT is enabled - */ - int eht_enabled; -+ -+ /** -+ * ru_punct_bitmap - RU puncturing bitmap -+ * Each bit corresponds to a 20 MHz subchannel, lowest bit for the -+ * channel with the lowest frequency. Bit set to 1 indicates that the -+ * subchannel is punctured, otherwise active. -+ */ -+ u16 ru_punct_bitmap; -+ -+ /** -+ * ru_punct_ofdma - If ru_punct_bitmap could be one of -+ * the OFDMA patterns -+ */ -+ u8 ru_punct_ofdma; - }; - - /** -diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c -index 15fe87b7e507..97116e049797 100644 ---- a/wpa_supplicant/mesh.c -+++ b/wpa_supplicant/mesh.c -@@ -233,7 +233,9 @@ static int wpas_mesh_update_freq_params(struct wpa_supplicant *wpa_s) - hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf), - hostapd_get_oper_centr_freq_seg1_idx(ifmsh->conf), - ifmsh->conf->vht_capab, -- he_capab, NULL, ifmsh->conf->he_6ghz_reg_pwr_type)) { -+ he_capab, NULL, ifmsh->conf->he_6ghz_reg_pwr_type, -+ ifmsh->conf->ru_punct_bitmap, -+ ifmsh->conf->ru_punct_ofdma)) { - wpa_printf(MSG_ERROR, "Error updating mesh frequency params"); - wpa_supplicant_mesh_deinit(wpa_s, true); - return -1; -diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c -index 07fc3d7ed8ec..cdaf23cf06fe 100644 ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -2852,7 +2852,8 @@ skip_to_6ghz: - 0, freq->sec_channel_offset, - chwidth, seg0, seg1, vht_caps, - &mode->he_capab[ieee80211_mode], NULL, -- 0) != 0) -+ 0, freq->ru_punct_bitmap, -+ freq->ru_punct_ofdma) != 0) - return; - - *freq = vht_freq; --- -2.31.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-034-ru_puncturing-add-bitmap-to-EHT-operation-element.patch b/feeds/ipq95xx/hostapd/patches/q02-034-ru_puncturing-add-bitmap-to-EHT-operation-element.patch deleted file mode 100644 index 9a8034f7..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-034-ru_puncturing-add-bitmap-to-EHT-operation-element.patch +++ /dev/null @@ -1,394 +0,0 @@ -From 765ef9735ee87ccb8e58df2d7e3cba53851ac8ef Mon Sep 17 00:00:00 2001 -From: Muna Sinada -Date: Wed, 2 Mar 2022 15:32:49 -0800 -Subject: [PATCH] ru_puncturing: add bitmap to EHT operation element - -Add RU puncturing bitmap to the EHT operation element. -Bits set to 1 indicate that the subchannel is punctured, otherwise -active. - -Signed-off-by: Muna Sinada -Signed-off-by: Aloka Dixit ---- - hostapd/ctrl_iface.c | 36 +++++++++++++ - src/ap/hw_features.c | 64 +++++++++++++++++++++++ - src/ap/ieee802_11.c | 73 ++++++++++++++++++++++++++ - src/ap/ieee802_11.h | 1 + - src/ap/ieee802_11_eht.c | 27 +++++++++- - src/ap/ieee802_11_he.c | 16 ++++++ - src/ap/ieee802_11_vht.c | 7 +++ - src/common/hw_features_common.c | 92 +++++++++++++++++++++++++++++++++ - src/common/hw_features_common.h | 2 + - src/common/ieee802_11_defs.h | 1 + - 10 files changed, 318 insertions(+), 1 deletion(-) - ---- a/src/ap/hw_features.c -+++ b/src/ap/hw_features.c -@@ -898,6 +898,63 @@ static int hostapd_is_usable_edmg(struct - } - - -+static int hostapd_is_usable_ru_punct_bitmap(struct hostapd_iface *iface) -+{ -+ struct hostapd_config *conf = iface->conf; -+ u8 bw, start_chan; -+ -+ if (!conf->ru_punct_bitmap) { -+ conf->ru_punct_ofdma = 0; -+ return 1; -+ } -+ -+#ifdef CONFIG_IEEE80211BE -+ if (!conf->ieee80211be) { -+ wpa_printf(MSG_ERROR, -+ "Currently RU puncturing is supported only if ieee80211be is enabled"); -+ return 0; -+ } -+ -+ if (iface->freq >= 2412 && iface->freq <= 2484) { -+ wpa_printf(MSG_ERROR, -+ "RU puncturing not supported in 2.4 GHz"); -+ return 0; -+ } -+ -+ switch (conf->eht_oper_chwidth) { -+ case 0: -+ wpa_printf(MSG_ERROR, -+ "RU puncturing is supported only in 80 MHz and 160 MHz"); -+ return 0; -+ case 1: -+ bw = 80; -+ start_chan = conf->eht_oper_centr_freq_seg0_idx - 6; -+ break; -+ case 2: -+ bw = 160; -+ start_chan = conf->eht_oper_centr_freq_seg0_idx - 14; -+ break; -+ default: -+ return 0; -+ } -+ -+ if (is_ru_punct_bitmap_valid(bw, -+ (conf->channel - start_chan) / 4, -+ conf->ru_punct_bitmap, -+ conf->ru_punct_ofdma) == false) { -+ wpa_printf(MSG_ERROR, "Invalid RU puncturing bitmap"); -+ return 0; -+ } -+ -+ return 1; -+#else -+ wpa_printf(MSG_ERROR, -+ "Currently RU puncturing is supported only if ieee80211be is enabled"); -+ return 0; -+#endif /* CONFIG_IEEE80211BE */ -+} -+ -+ - static int hostapd_is_usable_chans(struct hostapd_iface *iface) - { - int secondary_freq; -@@ -920,6 +977,9 @@ static int hostapd_is_usable_chans(struc - if (!hostapd_is_usable_edmg(iface)) - return 0; - -+ if (!hostapd_is_usable_ru_punct_bitmap(iface)) -+ return 0; -+ - if (!iface->conf->secondary_channel) - return 1; - ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -8066,4 +8066,77 @@ u8 * hostapd_eid_mbssid(struct hostapd_d - return eid; - } - -+ -+static void ru_punct_update_bw_80(u8 bitmap, u8 pri_chan, u8 *seg0) -+{ -+ u8 first_chan = *seg0 - 6, sec_chan; -+ -+ switch (bitmap) { -+ case 0x6: -+ *seg0 = 0; -+ return; -+ case 0x8: -+ case 0x4: -+ case 0x2: -+ case 0x1: -+ case 0xC: -+ case 0x3: -+ if (pri_chan < *seg0) -+ *seg0 -= 4; -+ else -+ *seg0 += 4; -+ break; -+ } -+ -+ if (pri_chan < *seg0) -+ sec_chan = pri_chan + 4; -+ else -+ sec_chan = pri_chan - 4; -+ -+ if (bitmap & BIT((sec_chan - first_chan) / 4)) -+ *seg0 = 0; -+} -+ -+ -+static void ru_punct_update_bw_160(u8 bitmap, u8 pri_chan, u8 *width, u8 *seg0) -+{ -+ if (pri_chan < *seg0) { -+ *seg0 -= 8; -+ if (bitmap & 0x0F) { -+ *width = 0; -+ ru_punct_update_bw_80(bitmap & 0xF, -+ pri_chan, -+ seg0); -+ } -+ } else { -+ *seg0 += 8; -+ if (bitmap & 0xF0) { -+ *width = 0; -+ ru_punct_update_bw_80((bitmap & 0xF0) >> 4, -+ pri_chan, -+ seg0); -+ } -+ } -+} -+ -+ -+void ru_punct_update_bw(u16 bitmap, u8 pri_chan, u8 *width, u8 *seg0, u8 *seg1) -+{ -+ if (!bitmap || !(*width) || ((*width) == 3)) -+ return; -+ -+ if (((*width) == 1) && (bitmap & 0xF)) { -+ *width = 0; -+ ru_punct_update_bw_80(bitmap & 0xF, pri_chan, seg0); -+ } -+ -+ if ((*width) == 2 && (bitmap & 0xFF)) { -+ *width = 1; -+ *seg1 = 0; -+ ru_punct_update_bw_160(bitmap & 0xFF, pri_chan, width, seg0); -+ } -+ -+ /* Add for 320 MHz */ -+} -+ - #endif /* CONFIG_NATIVE_WINDOWS */ ---- a/src/ap/ieee802_11.h -+++ b/src/ap/ieee802_11.h -@@ -228,4 +228,5 @@ u8 * hostapd_eid_eht_operation(struct ho - u16 copy_sta_eht_capab(struct hostapd_data *hapd, struct sta_info *sta, - enum ieee80211_op_mode opmode, const u8 *he_capab, - const u8 *eht_capab, size_t eht_capab_len); -+void ru_punct_update_bw(u16 bitmap, u8 pri_chan, u8 *width, u8 *seg0, u8 *seg1); - #endif /* IEEE802_11_H */ ---- a/src/ap/ieee802_11_eht.c -+++ b/src/ap/ieee802_11_eht.c -@@ -196,17 +196,37 @@ u8 * hostapd_eid_eht_operation(struct ho - else - chwidth = hapd->iconf->eht_oper_chwidth; - -+ if (hapd->iconf->ru_punct_bitmap && !hapd->iface->ru_punct_supp_bw) { -+ hapd->iconf->ru_punct_bitmap = 0; -+ wpa_printf(MSG_ERROR, -+ "Driver does not support RU puncturing. Setting bitmap to 0"); -+ } -+ - switch (chwidth) { - case CHANWIDTH_320MHZ: - oper->width = EHT_OPERATION_CHANNEL_WIDTH_320MHZ; - break; - case CHANWIDTH_160MHZ: - oper->width = EHT_OPERATION_CHANNEL_WIDTH_160MHZ; -+ if (hapd->iconf->ru_punct_bitmap && -+ hapd->iface->ru_punct_supp_bw == CHANWIDTH_320MHZ) { -+ hapd->iconf->ru_punct_bitmap = 0; -+ wpa_printf(MSG_ERROR, -+ "Driver does not support RU puncturing for bandwidths less than 320 MHz. Setting bitmap to 0"); -+ } - break; - case CHANWIDTH_80MHZ: - oper->width = EHT_OPERATION_CHANNEL_WIDTH_80MHZ; -+ if (hapd->iconf->ru_punct_bitmap && -+ ((hapd->iface->ru_punct_supp_bw == CHANWIDTH_160MHZ) || -+ (hapd->iface->ru_punct_supp_bw == CHANWIDTH_320MHZ))) { -+ hapd->iconf->ru_punct_bitmap = 0; -+ wpa_printf(MSG_ERROR, -+ "Driver does not support RU puncturing for bandwidths less than 160 MHz. Setting bitmap to 0"); -+ } - break; - case CHANWIDTH_USE_HT: -+ hapd->iconf->ru_punct_bitmap = 0; - if ((is_6ghz_op_class(hapd->iconf->op_class) && - op_class_to_bandwidth(hapd->iconf->op_class) == 40) || - hapd->iconf->secondary_channel) -@@ -216,10 +236,16 @@ u8 * hostapd_eid_eht_operation(struct ho - - break; - default: -+ hapd->iconf->ru_punct_bitmap = 0; - oper->width = EHT_OPERATION_CHANNEL_WIDTH_20MHZ; - break; - } - -+ if (hapd->iconf->ru_punct_bitmap) { -+ oper->disable_sub_chan_bitmap_present = 1; -+ oper->disabled_subchannel_bitmap = host_to_le16(hapd->iconf->ru_punct_bitmap); -+ } -+ - pos += oper_size; - - return pos; ---- a/src/ap/ieee802_11_he.c -+++ b/src/ap/ieee802_11_he.c -@@ -215,6 +215,22 @@ u8 * hostapd_eid_he_operation(struct hos - u8 seg0 = hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf); - u8 seg1 = hostapd_get_oper_centr_freq_seg1_idx(hapd->iconf); - -+ if (hapd->iconf->ru_punct_bitmap) { -+ hapd->iconf->he_oper_chwidth = -+ hostapd_get_oper_chwidth(hapd->iconf); -+ hapd->iconf->he_oper_centr_freq_seg0_idx = seg0; -+ hapd->iconf->he_oper_centr_freq_seg1_idx = seg1; -+ -+ ru_punct_update_bw(hapd->iconf->ru_punct_bitmap, -+ hapd->iconf->channel, -+ &hapd->iconf->he_oper_chwidth, -+ &hapd->iconf->he_oper_centr_freq_seg0_idx, -+ &hapd->iconf->he_oper_centr_freq_seg1_idx); -+ -+ seg0 = hapd->iconf->he_oper_centr_freq_seg0_idx; -+ seg1 = hapd->iconf->he_oper_centr_freq_seg1_idx; -+ } -+ - if (!seg0) - seg0 = hapd->iconf->channel; - ---- a/src/ap/ieee802_11_vht.c -+++ b/src/ap/ieee802_11_vht.c -@@ -98,6 +98,13 @@ u8 * hostapd_eid_vht_operation(struct ho - oper = (struct ieee80211_vht_operation *) pos; - os_memset(oper, 0, sizeof(*oper)); - -+ if (hapd->iconf->ru_punct_bitmap) -+ ru_punct_update_bw(hapd->iconf->ru_punct_bitmap, -+ hapd->iconf->channel, -+ &hapd->iconf->vht_oper_chwidth, -+ &hapd->iconf->vht_oper_centr_freq_seg0_idx, -+ &hapd->iconf->vht_oper_centr_freq_seg1_idx); -+ - /* - * center freq = 5 GHz + (5 * index) - * So index 42 gives center freq 5.210 GHz ---- a/src/common/hw_features_common.c -+++ b/src/common/hw_features_common.c -@@ -824,3 +824,95 @@ int chan_pri_allowed(const struct hostap - return !(chan->flag & HOSTAPD_CHAN_DISABLED) && - (chan->allowed_bw & HOSTAPD_CHAN_WIDTH_20); - } -+ -+ -+/* IEEE P802.11be/D1.31, December 2021, Table 36-30 5-bit punctured channel -+ * indication for the non-OFDMA case in an EHT MU PPDU -+ */ -+static const u16 ru_punct_bitmap_80[] = {0xF, 0xE, 0xD, 0xB, 0x7}; -+static const u16 ru_punct_bitmap_160[] = {0xFF, 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, -+ 0xDF, 0xBF, 0x7F, 0xFC, 0xF3, 0xCF, -+ 0x3F}; -+static const u16 ru_punct_bitmap_320[] = {0xFFFF, 0xFFFC, 0xFFF3, 0xFFCF, -+ 0xFF3F, 0xFCFF, 0xF3FF, 0xCFFF, -+ 0x3FFF, 0xFFF0, 0xFF0F, 0xF0FF, -+ 0x0FFF, 0xFFC0, 0xFF30, 0xFCF0, -+ 0xF3F0, 0xCFF0, 0x3FF0, 0x0FFC, -+ 0x0FF3, 0x0FCF, 0x0F3F, 0x0CFF, -+ 0x03FF}; -+ -+ -+bool is_ru_punct_bitmap_valid(u16 bw, u16 pri_ch_bit_pos, u16 ru_punct_bitmap, -+ u8 ru_punct_ofdma) -+{ -+ u8 i, non_ofdma_bitmap_count, ofdma_block_count = 1; -+ u16 bitmap; -+ const u16 *non_ofdma_bitmap; -+ -+ if (!ru_punct_bitmap) /* All channels active */ -+ return true; -+ -+ bitmap = ~ru_punct_bitmap; -+ -+ switch (bw) { -+ case 80: -+ bitmap &= 0xF; -+ non_ofdma_bitmap = &ru_punct_bitmap_80[0]; -+ non_ofdma_bitmap_count = ARRAY_SIZE(ru_punct_bitmap_80); -+ break; -+ -+ case 160: -+ bitmap &= 0xFF; -+ non_ofdma_bitmap = &ru_punct_bitmap_160[0]; -+ non_ofdma_bitmap_count = ARRAY_SIZE(ru_punct_bitmap_160); -+ break; -+ -+ case 320: -+ bitmap &= 0xFFFF; -+ non_ofdma_bitmap = &ru_punct_bitmap_320[0]; -+ non_ofdma_bitmap_count = ARRAY_SIZE(ru_punct_bitmap_320); -+ break; -+ -+ default: -+ return false; -+ } -+ -+ if (!bitmap) /* No channel active */ -+ return false; -+ -+ if (!(bitmap & BIT(pri_ch_bit_pos))) { -+ wpa_printf(MSG_DEBUG, "Primary channel cannot be punctured"); -+ return false; -+ } -+ -+ /* Check for non-OFDMA puncturing patterns */ -+ for (i = 0; i < non_ofdma_bitmap_count; i++) -+ if (non_ofdma_bitmap[i] == bitmap) -+ return true; -+ -+ if (!ru_punct_ofdma) -+ return false; -+ -+ /* Check for OFDMA puncturing patterns */ -+ for (i = 0; i < ofdma_block_count; i++) { -+ switch ((bitmap >> (i * 4)) & 0xF) { -+ /* IEEE P802.11be/D1.31, December 2021, 36.3.12.11.2 Preamble -+ * puncturing for PPDUs in an OFDMA transmission -+ */ -+ case 0xF: -+ case 0x7: -+ case 0xB: -+ case 0xD: -+ case 0xE: -+ case 0x3: -+ case 0xC: -+ case 0x9: -+ case 0x0: -+ break; -+ default: -+ return false; -+ } -+ } -+ -+ return true; -+} ---- a/src/common/hw_features_common.h -+++ b/src/common/hw_features_common.h -@@ -55,5 +55,7 @@ u32 num_chan_to_bw(int num_chans); - int chan_bw_allowed(const struct hostapd_channel_data *chan, u32 bw, - int ht40_plus, int pri); - int chan_pri_allowed(const struct hostapd_channel_data *chan); -+bool is_ru_punct_bitmap_valid(u16 bw, u16 pri_ch_bit_pos, u16 ru_punct_bitmap, -+ u8 ru_punct_ofdma); - - #endif /* HW_FEATURES_COMMON_H */ diff --git a/feeds/ipq95xx/hostapd/patches/q02-035-ru_puncturing-additions-to-channel-switch-command.patch b/feeds/ipq95xx/hostapd/patches/q02-035-ru_puncturing-additions-to-channel-switch-command.patch deleted file mode 100644 index 95941862..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-035-ru_puncturing-additions-to-channel-switch-command.patch +++ /dev/null @@ -1,307 +0,0 @@ -From 710e19ab3a32cb29f833de594b07c7a2639b88b9 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Wed, 22 Dec 2021 14:16:01 -0800 -Subject: [PATCH] ru_puncturing: additions to channel switch command - -Parse the command to retrive the RU puncturing bitmap and if OFDMA -patterns shouldbe considered. - -Signed-off-by: Aloka Dixit ---- - hostapd/ctrl_iface.c | 37 ++++++++++++++++++++++++++++++ - src/ap/ctrl_iface_ap.c | 3 +++ - src/ap/drv_callbacks.c | 14 +++++++---- - src/ap/hostapd.c | 4 ++++ - src/ap/hostapd.h | 1 + - src/drivers/driver.h | 2 ++ - src/drivers/driver_nl80211.c | 6 +++-- - src/drivers/driver_nl80211_event.c | 11 +++++++++ - wpa_supplicant/ap.c | 2 +- - 9 files changed, 73 insertions(+), 7 deletions(-) - -Index: hostapd-2021-12-13-b26f5c0f/hostapd/ctrl_iface.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/hostapd/ctrl_iface.c -+++ hostapd-2021-12-13-b26f5c0f/hostapd/ctrl_iface.c -@@ -33,6 +33,7 @@ - #include "common/version.h" - #include "common/ieee802_11_defs.h" - #include "common/ctrl_iface_common.h" -+#include "common/hw_features_common.h" - #ifdef CONFIG_DPP - #include "common/dpp.h" - #endif /* CONFIG_DPP */ -@@ -2637,6 +2638,7 @@ static int hostapd_ctrl_register_frame(s - static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params) - { - int idx, bw, bw_idx[] = { 20, 40, 80, 160 }; -+ u32 start_freq; - - if (is_6ghz_freq(params->freq)) { - /* Verify if HE was enabled by user or not. 6 GHz does not -@@ -2669,11 +2671,17 @@ static int hostapd_ctrl_check_freq_param - - if (params->center_freq2 || params->sec_channel_offset) - return -1; -+ -+ if (params->ru_punct_bitmap) -+ return -1; - break; - case 40: - if (params->center_freq2 || !params->sec_channel_offset) - return -1; - -+ if (params->ru_punct_bitmap) -+ return -1; -+ - if (!params->center_freq1) - break; - switch (params->sec_channel_offset) { -@@ -2708,6 +2716,9 @@ static int hostapd_ctrl_check_freq_param - return -1; - } - -+ if (params->center_freq2 && params->ru_punct_bitmap) -+ return -1; -+ - /* Adjacent and overlapped are not allowed for 80+80 */ - if (params->center_freq2 && - params->center_freq1 - params->center_freq2 <= 80 && -@@ -2742,6 +2753,32 @@ static int hostapd_ctrl_check_freq_param - return -1; - } - -+ if (!params->ru_punct_bitmap) { -+ params->ru_punct_ofdma = 0; -+ return 0; -+ } -+ -+ if (!params->eht_enabled) { -+ wpa_printf(MSG_ERROR, -+ "Currently RU puncturing is supported only if EHT is enabled"); -+ return -1; -+ } -+ -+ if (params->freq >= 2412 && params->freq <= 2484) { -+ wpa_printf(MSG_ERROR, -+ "RU puncturing not supported in 2.4 GHz"); -+ return -1; -+ } -+ -+ start_freq = params->center_freq1 - (params->bandwidth / 2); -+ if (is_ru_punct_bitmap_valid(params->bandwidth, -+ (params->freq - start_freq) / 20, -+ params->ru_punct_bitmap, -+ params->ru_punct_ofdma) == false) { -+ wpa_printf(MSG_ERROR, "Invalid RU puncturing bitmap"); -+ return -1; -+ } -+ - return 0; - } - #endif /* NEED_AP_MLME */ -Index: hostapd-2021-12-13-b26f5c0f/src/ap/ctrl_iface_ap.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/ctrl_iface_ap.c -+++ hostapd-2021-12-13-b26f5c0f/src/ap/ctrl_iface_ap.c -@@ -1266,10 +1266,13 @@ int hostapd_parse_csa_settings(const cha - SET_CSA_SETTING(center_freq2); - SET_CSA_SETTING(bandwidth); - SET_CSA_SETTING(sec_channel_offset); -+ SET_CSA_SETTING(ru_punct_bitmap); - settings->freq_params.ht_enabled = !!os_strstr(pos, " ht"); - settings->freq_params.vht_enabled = !!os_strstr(pos, " vht"); - settings->freq_params.he_enabled = !!os_strstr(pos, " he"); - settings->freq_params.eht_enabled = !!os_strstr(pos, " eht"); -+ settings->freq_params.ru_punct_ofdma = !!os_strstr(pos, -+ " ru_punct_ofdma"); - settings->block_tx = !!os_strstr(pos, " blocktx"); - #undef SET_CSA_SETTING - -Index: hostapd-2021-12-13-b26f5c0f/src/ap/drv_callbacks.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/drv_callbacks.c -+++ hostapd-2021-12-13-b26f5c0f/src/ap/drv_callbacks.c -@@ -872,6 +872,7 @@ void hostapd_event_sta_opmode_changed(st - - void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, - int offset, int width, int cf1, int cf2, -+ u16 ru_punct_bitmap, u8 ru_punct_ofdma, - int finished) - { - #ifdef NEED_AP_MLME -@@ -881,12 +882,13 @@ void hostapd_event_ch_switch(struct host - - hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, - HOSTAPD_LEVEL_INFO, -- "driver %s channel switch: freq=%d, ht=%d, vht_ch=0x%x, he_ch=0x%x, eht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d", -+ "driver %s channel switch: freq=%d, ht=%d, vht_ch=0x%x, he_ch=0x%x, eht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d, ru_punct_bitmap=0x%x, ru_punct_ofdma=%u", - finished ? "had" : "starting", - freq, ht, hapd->iconf->ch_switch_vht_config, - hapd->iconf->ch_switch_he_config, - hapd->iconf->ch_switch_eht_config, offset, -- width, channel_width_to_string(width), cf1, cf2); -+ width, channel_width_to_string(width), cf1, cf2, -+ ru_punct_bitmap, ru_punct_ofdma); - - if (!hapd->iface->current_mode) { - hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, -@@ -985,6 +987,8 @@ void hostapd_event_ch_switch(struct host - hostapd_set_oper_centr_freq_seg0_idx(hapd->iconf, seg0_idx); - hostapd_set_oper_centr_freq_seg1_idx(hapd->iconf, seg1_idx); - hapd->iconf->op_class = op_class; -+ hapd->iconf->ru_punct_bitmap = ru_punct_bitmap; -+ hapd->iconf->ru_punct_ofdma = ru_punct_ofdma; - if (hapd->iconf->ieee80211ac) { - hapd->iconf->vht_capab &= ~VHT_CAP_SUPP_CHAN_WIDTH_MASK; - if (chwidth == CHANWIDTH_160MHZ) -@@ -999,11 +1003,11 @@ void hostapd_event_ch_switch(struct host - hapd->iface->num_hw_features); - - wpa_msg(hapd->msg_ctx, MSG_INFO, -- "%sfreq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d dfs=%d", -+ "%sfreq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d dfs=%d ru_punct_bitmap=0x%x ru_punct_ofdma=%u", - finished ? WPA_EVENT_CHANNEL_SWITCH : - WPA_EVENT_CHANNEL_SWITCH_STARTED, - freq, ht, offset, channel_width_to_string(width), -- cf1, cf2, is_dfs); -+ cf1, cf2, is_dfs, ru_punct_bitmap, ru_punct_ofdma); - if (!finished) - return; - -@@ -2090,6 +2094,8 @@ void hostapd_wpa_event(void *ctx, enum w - data->ch_switch.ch_width, - data->ch_switch.cf1, - data->ch_switch.cf2, -+ data->ch_switch.ru_punct_bitmap, -+ data->ch_switch.ru_punct_ofdma, - event == EVENT_CH_SWITCH); - break; - case EVENT_CONNECT_FAILED_REASON: -Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/hostapd.c -+++ hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.c -@@ -3624,6 +3624,8 @@ static int hostapd_change_config_freq(st - conf->ieee80211n = params->ht_enabled; - conf->ieee80211ac = params->vht_enabled; - conf->secondary_channel = params->sec_channel_offset; -+ conf->ru_punct_bitmap = params->ru_punct_bitmap; -+ conf->ru_punct_ofdma= params->ru_punct_ofdma; - ieee80211_freq_to_chan(params->center_freq1, - &seg0); - ieee80211_freq_to_chan(params->center_freq2, -@@ -3837,6 +3839,8 @@ hostapd_switch_channel_fallback(struct h - hostapd_set_oper_centr_freq_seg0_idx(iface->conf, seg0_idx); - hostapd_set_oper_centr_freq_seg1_idx(iface->conf, seg1_idx); - hostapd_set_oper_chwidth(iface->conf, bw); -+ iface->conf->ru_punct_bitmap = freq_params->ru_punct_bitmap; -+ iface->conf->ru_punct_ofdma = freq_params->ru_punct_ofdma; - - /* - * Resetting operating class to avoid referring previous values -Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/hostapd.h -+++ hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.h -@@ -730,6 +730,7 @@ int hostapd_probe_req_rx(struct hostapd_ - int ssi_signal); - void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, - int offset, int width, int cf1, int cf2, -+ u16 ru_punct_bitmap, u8 ru_punct_ofdma, - int finished); - struct survey_results; - void hostapd_event_get_survey(struct hostapd_iface *iface, -Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/drivers/driver.h -+++ hostapd-2021-12-13-b26f5c0f/src/drivers/driver.h -@@ -6111,6 +6111,8 @@ union wpa_event_data { - enum chan_width ch_width; - int cf1; - int cf2; -+ u16 ru_punct_bitmap; -+ u8 ru_punct_ofdma; - } ch_switch; - - /** -Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/drivers/driver_nl80211.c -+++ hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211.c -@@ -10064,7 +10064,7 @@ static int nl80211_switch_channel(void * - int i; - - wpa_printf(MSG_DEBUG, -- "nl80211: Channel switch request (cs_count=%u block_tx=%u freq=%d channel=%d sec_channel_offset=%d width=%d cf1=%d cf2=%d%s%s%s)", -+ "nl80211: Channel switch request (cs_count=%u block_tx=%u freq=%d channel=%d sec_channel_offset=%d width=%d cf1=%d cf2=%d%s%s%s puncturing bitmap=0x%04x, ru_punct_ofdma=%u)", - settings->cs_count, settings->block_tx, - settings->freq_params.freq, - settings->freq_params.channel, -@@ -10074,7 +10074,9 @@ static int nl80211_switch_channel(void * - settings->freq_params.center_freq2, - settings->freq_params.ht_enabled ? " ht" : "", - settings->freq_params.vht_enabled ? " vht" : "", -- settings->freq_params.he_enabled ? " he" : ""); -+ settings->freq_params.he_enabled ? " he" : "", -+ settings->freq_params.ru_punct_bitmap, -+ settings->freq_params.ru_punct_ofdma); - - if (!(drv->capa.flags & WPA_DRIVER_FLAGS_AP_CSA)) { - wpa_printf(MSG_DEBUG, "nl80211: Driver does not support channel switch command"); -Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211_event.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/drivers/driver_nl80211_event.c -+++ hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211_event.c -@@ -692,6 +692,8 @@ static void mlme_event_ch_switch(struct - struct nlattr *ifindex, struct nlattr *freq, - struct nlattr *type, struct nlattr *bw, - struct nlattr *cf1, struct nlattr *cf2, -+ struct nlattr *ru_punct_bitmap, -+ struct nlattr *ru_punct_ofdma, - struct nlattr *count, - int finished) - { -@@ -754,6 +756,11 @@ static void mlme_event_ch_switch(struct - data.ch_switch.cf1 = nla_get_u32(cf1); - if (cf2) - data.ch_switch.cf2 = nla_get_u32(cf2); -+ if (ru_punct_bitmap) { -+ data.ch_switch.ru_punct_bitmap = nla_get_u16(ru_punct_bitmap); -+ if (ru_punct_ofdma) -+ data.ch_switch.ru_punct_ofdma = nla_get_flag(ru_punct_ofdma); -+ } - if (count) - data.ch_switch.count = nla_get_u32(count); - -@@ -3113,6 +3120,8 @@ static void do_process_drv_event(struct - tb[NL80211_ATTR_CHANNEL_WIDTH], - tb[NL80211_ATTR_CENTER_FREQ1], - tb[NL80211_ATTR_CENTER_FREQ2], -+ tb[NL80211_ATTR_RU_PUNCT_BITMAP], -+ tb[NL80211_ATTR_RU_PUNCT_SUPP_HE], - tb[NL80211_ATTR_CH_SWITCH_COUNT], - 0); - break; -@@ -3124,6 +3133,8 @@ static void do_process_drv_event(struct - tb[NL80211_ATTR_CHANNEL_WIDTH], - tb[NL80211_ATTR_CENTER_FREQ1], - tb[NL80211_ATTR_CENTER_FREQ2], -+ tb[NL80211_ATTR_RU_PUNCT_BITMAP], -+ tb[NL80211_ATTR_RU_PUNCT_SUPP_HE], - NULL, - 1); - break; -Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/ap.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/ap.c -+++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/ap.c -@@ -1663,7 +1663,7 @@ void wpas_ap_ch_switch(struct wpa_suppli - if (wpa_s->current_ssid) - wpa_s->current_ssid->frequency = freq; - hostapd_event_ch_switch(iface->bss[0], freq, ht, -- offset, width, cf1, cf2, finished); -+ offset, width, cf1, cf2, 0, 0, finished); - } - - diff --git a/feeds/ipq95xx/hostapd/patches/q02-036-ru_puncturing-send-bitmap-to-kernel.patch b/feeds/ipq95xx/hostapd/patches/q02-036-ru_puncturing-send-bitmap-to-kernel.patch deleted file mode 100644 index 1ac6b1c4..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-036-ru_puncturing-send-bitmap-to-kernel.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0abd3e6f6353d6cc2fec8a3d6bab6c895db5c678 Mon Sep 17 00:00:00 2001 -From: Muna Sinada -Date: Wed, 2 Mar 2022 15:47:45 -0800 -Subject: [PATCH 6/6] ru_puncturing: send bitmap to kernel - -Send the user configured bitmap to the kernel. - -Signed-off-by: Muna Sinada -Signed-off-by: Aloka Dixit ---- - src/drivers/driver_nl80211.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -5036,6 +5036,14 @@ static int nl80211_put_freq_params(struc - nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, - freq->center_freq2))) - return -ENOBUFS; -+ if (freq->ru_punct_bitmap) { -+ if (freq->ru_punct_ofdma && -+ nla_put_flag(msg, NL80211_ATTR_RU_PUNCT_SUPP_HE)) -+ return -ENOBUFS; -+ if (nla_put_u16(msg, NL80211_ATTR_RU_PUNCT_BITMAP, -+ freq->ru_punct_bitmap)) -+ return -ENOBUFS; -+ } - } else if (freq->ht_enabled || (freq->he_enabled && is_24ghz)) { - enum nl80211_channel_type ct; - -@@ -5084,10 +5092,10 @@ static int nl80211_set_channel(struct i8 - int ret; - - wpa_printf(MSG_DEBUG, -- "nl80211: Set freq %d (ht_enabled=%d, vht_enabled=%d, he_enabled=%d, eht_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz)", -+ "nl80211: Set freq %d (ht_enabled=%d, vht_enabled=%d, he_enabled=%d, eht_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz, puncturing bitmap=0x%04x)", - freq->freq, freq->ht_enabled, freq->vht_enabled, freq->he_enabled, - freq->eht_enabled, freq->bandwidth, freq->center_freq1, -- freq->center_freq2); -+ freq->center_freq2, freq->ru_punct_bitmap); - - msg = nl80211_bss_msg(bss, 0, set_chan ? NL80211_CMD_SET_CHANNEL : - NL80211_CMD_SET_WIPHY); diff --git a/feeds/ipq95xx/hostapd/patches/q02-037-ulmumimo-parameter-support.patch b/feeds/ipq95xx/hostapd/patches/q02-037-ulmumimo-parameter-support.patch deleted file mode 100644 index 38700c76..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-037-ulmumimo-parameter-support.patch +++ /dev/null @@ -1,221 +0,0 @@ -From 02645e533ed703233f8084232ee333d7148cb8e8 Mon Sep 17 00:00:00 2001 -From: Nagarajan Maran -Date: Thu, 21 Apr 2022 15:00:52 +0530 -Subject: [PATCH] hostapd: UL-MUMIMO param support - -Adding new params for he and eht to enable/disable ul mumimo. -Set 0 to disable or 1 to enable. If param isn't specified, -the driver/underlying hardware decides its default behaviour. -Following param fields are supported in hostapd conf file, -HE: "he_ul_mumimo" -EHT: "eht_ulmumimo_80mhz", "eht_ulmumimo_160mhz", "eht_ulmumimo_320mhz" - -Signed-off-by: Pradeep Kumar Chitrapu -Signed-off-by: Nagarajan Maran -Signed-off-by: Sidhanta Sahu ---- - hostapd/config_file.c | 10 ++++++++++ - hostapd/hostapd.conf | 5 +++++ - src/ap/ap_config.c | 2 ++ - src/ap/ap_config.h | 5 +++++ - src/ap/hw_features.c | 28 ++++++++++++++++++++++++++++ - src/ap/ieee802_11_eht.c | 14 +++++++++++++- - src/ap/ieee802_11_he.c | 7 +++++++ - src/common/ieee802_11_defs.h | 8 +++++++- - 8 files changed, 77 insertions(+), 2 deletions(-) - -diff --git a/hostapd/config_file.c b/hostapd/config_file.c -index 9ac681d..4f2e01c 100644 ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -3422,6 +3422,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, - conf->he_phy_capab.he_su_beamformee = atoi(pos); - } else if (os_strcmp(buf, "he_mu_beamformer") == 0) { - conf->he_phy_capab.he_mu_beamformer = atoi(pos); -+ } else if (os_strcmp(buf, "he_ul_mumimo") == 0) { -+ conf->he_phy_capab.he_ul_mumimo = atoi(pos); - } else if (os_strcmp(buf, "he_bss_color") == 0) { - conf->he_op.he_bss_color = atoi(pos); - if (conf->he_op.he_bss_color > 63) -@@ -4689,6 +4691,14 @@ static int hostapd_config_fill(struct hostapd_config *conf, - conf->eht_phy_capab.su_beamformee = atoi(pos); - } else if (os_strcmp(buf, "eht_mu_beamformer") == 0) { - conf->eht_phy_capab.mu_beamformer = atoi(pos); -+ } else if (os_strcmp(buf, "eht_part_dl_mu_mimo") == 0) { -+ conf->eht_phy_capab.partial_bw_dl_mu_mimo = atoi(pos); -+ } else if (os_strcmp(buf, "eht_ulmumimo_80mhz") == 0) { -+ conf->eht_phy_capab.non_ofdma_ulmumimo_80mhz = atoi(pos); -+ } else if (os_strcmp(buf, "eht_ulmumimo_160mhz") == 0) { -+ conf->eht_phy_capab.non_ofdma_ulmumimo_160mhz = atoi(pos); -+ } else if (os_strcmp(buf, "eht_ulmumimo_320mhz") == 0) { -+ conf->eht_phy_capab.non_ofdma_ulmumimo_320mhz = atoi(pos); - } else if (os_strcmp(buf, "ru_punct_bitmap") == 0) { - conf->ru_punct_bitmap = atoi(pos); - } else if (os_strcmp(buf, "ru_punct_ofdma") == 0) { -diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf -index 5fda6c6..2502767 100644 ---- a/hostapd/hostapd.conf -+++ b/hostapd/hostapd.conf -@@ -832,6 +832,11 @@ wmm_ac_vo_acm=0 - # 1 = supported - #he_mu_beamformer=1 - -+#he_ul_mumimo: HE Uplink multiple user MIMO support -+# -1 or unspecified = Decided by firmware or underlying hardware(Default) -+# 0 = not supported -+# 1 = supported -+ - # he_bss_color: - # 0 = disable - # 1-63 = pre-defined color -diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c -index f036eb6..a237e72 100644 ---- a/src/ap/ap_config.c -+++ b/src/ap/ap_config.c -@@ -273,6 +273,8 @@ struct hostapd_config * hostapd_config_defaults(void) - HE_OPERATION_RTS_THRESHOLD_OFFSET; - /* Set default basic MCS/NSS set to single stream MCS 0-7 */ - conf->he_op.he_basic_mcs_nss_set = 0xfffc; -+ /* Set default to be decided by Driver/underlying HW */ -+ conf->he_phy_capab.he_ul_mumimo = -1; - conf->he_op.he_bss_color_disabled = 1; - conf->he_op.he_bss_color_partial = 0; - conf->he_op.he_bss_color = os_random() % 63 + 1; -diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h -index f082f14..04cd6fb 100644 ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -922,6 +922,7 @@ struct he_phy_capabilities_info { - bool he_su_beamformer; - bool he_su_beamformee; - bool he_mu_beamformer; -+ int he_ul_mumimo; - }; - - /** -@@ -958,6 +959,10 @@ struct eht_phy_capabilities_info { - bool su_beamformer; - bool su_beamformee; - bool mu_beamformer; -+ bool partial_bw_dl_mu_mimo; -+ bool non_ofdma_ulmumimo_80mhz; -+ bool non_ofdma_ulmumimo_160mhz; -+ bool non_ofdma_ulmumimo_320mhz; - }; - - /** -diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c -index d24672c..1dcd0d0 100644 ---- a/src/ap/hw_features.c -+++ b/src/ap/hw_features.c -@@ -677,8 +677,36 @@ static int ieee80211ac_supported_vht_capab(struct hostapd_iface *iface) - - - #ifdef CONFIG_IEEE80211AX -+ -+static int _ieee80211he_cap_check(u8 *hw, u32 offset, u8 bits) -+{ -+ if (bits & hw[offset]) -+ return 1; -+ -+ return 0; -+} -+ - static int ieee80211ax_supported_he_capab(struct hostapd_iface *iface) - { -+ -+ struct hostapd_hw_modes *mode = iface->current_mode; -+ struct he_capabilities *hw = &mode->he_capab[IEEE80211_MODE_AP]; -+ struct hostapd_config *conf = iface->conf; -+ -+#define HE_CAP_CHECK(hw_cap, cap, bytes, conf) \ -+ do { \ -+ if (conf && !_ieee80211he_cap_check(hw_cap, bytes, cap)) { \ -+ wpa_printf(MSG_ERROR, "Driver does not support configured" \ -+ " HE capability [%s]", #cap); \ -+ return 0; \ -+ } \ -+ } while (0) -+ -+ if (conf->he_phy_capab.he_ul_mumimo != -1) -+ HE_CAP_CHECK(hw->phy_cap, HE_PHYCAP_UL_MUMIMO_CAPB, -+ HE_PHYCAP_UL_MUMIMO_CAPB_IDX, -+ conf->he_phy_capab.he_ul_mumimo); -+ - return 1; - } - #endif /* CONFIG_IEEE80211AX */ -diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c -index 1fcd5de..8973cfd 100644 ---- a/src/ap/ieee802_11_eht.c -+++ b/src/ap/ieee802_11_eht.c -@@ -141,9 +141,21 @@ u8 * hostapd_eid_eht_capab(struct hostapd_data *hapd, u8 *eid, - ~EHT_PHYCAP_SU_BEAMFORMEE; - - if (!hapd->iface->conf->eht_phy_capab.mu_beamformer) -- cap->phy_cap[EHT_PHYCAP_MU_BEAMFORMER_IDX] &= -+ cap->phy_cap[EHT_PHYCAP_MU_CAPABILITY_IDX] &= - ~EHT_PHYCAP_MU_BEAMFORMER_MASK; - -+ if (!hapd->iface->conf->eht_phy_capab.non_ofdma_ulmumimo_80mhz) -+ cap->phy_cap[EHT_PHYCAP_MU_CAPABILITY_IDX] &= -+ ~EHT_PHYCAP_NON_OFDMA_UL_MU_MIMO_80MHZ; -+ -+ if (!hapd->iface->conf->eht_phy_capab.non_ofdma_ulmumimo_160mhz) -+ cap->phy_cap[EHT_PHYCAP_MU_CAPABILITY_IDX] &= -+ ~EHT_PHYCAP_NON_OFDMA_UL_MU_MIMO_160MHZ; -+ -+ if (!hapd->iface->conf->eht_phy_capab.non_ofdma_ulmumimo_320mhz) -+ cap->phy_cap[EHT_PHYCAP_MU_CAPABILITY_IDX] &= -+ ~EHT_PHYCAP_NON_OFDMA_UL_MU_MIMO_320MHZ; -+ - pos = cap->optional; - - mcs_nss_len = ieee80211_eht_mcs_set_size(mode->he_capab[opmode].phy_cap, -diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c -index 03b8711..6751526 100644 ---- a/src/ap/ieee802_11_he.c -+++ b/src/ap/ieee802_11_he.c -@@ -153,6 +153,13 @@ u8 * hostapd_eid_he_capab(struct hostapd_data *hapd, u8 *eid, - cap->he_phy_capab_info[HE_PHYCAP_MU_BEAMFORMER_CAPAB_IDX] &= - ~HE_PHYCAP_MU_BEAMFORMER_CAPAB; - -+ if (hapd->iface->conf->he_phy_capab.he_ul_mumimo == 1) -+ cap->he_phy_capab_info[HE_PHYCAP_UL_MUMIMO_CAPB_IDX] |= -+ HE_PHYCAP_UL_MUMIMO_CAPB; -+ else if (hapd->iface->conf->he_phy_capab.he_ul_mumimo == 0) -+ cap->he_phy_capab_info[HE_PHYCAP_UL_MUMIMO_CAPB_IDX] &= -+ ~HE_PHYCAP_UL_MUMIMO_CAPB; -+ - cap->he_phy_capab_info[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &= - he_oper_chwidth; - -diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h -index cfe25c8..e4b891c 100644 ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -2346,6 +2346,9 @@ struct ieee80211_spatial_reuse { - #define HE_PHYCAP_MU_BEAMFORMER_CAPAB_IDX 4 - #define HE_PHYCAP_MU_BEAMFORMER_CAPAB ((u8) BIT(1)) - -+#define HE_PHYCAP_UL_MUMIMO_CAPB_IDX 2 -+#define HE_PHYCAP_UL_MUMIMO_CAPB ((u8) BIT(6)) -+ - #define HE_PHYCAP_PPE_THRESHOLD_PRESENT_IDX 6 - #define HE_PHYCAP_PPE_THRESHOLD_PRESENT ((u8) BIT(7)) - -@@ -2500,7 +2503,10 @@ struct ieee80211_eht_operation { - - #define EHT_PHYCAP_PPE_THRESHOLD_PRESENT_IDX 5 - --#define EHT_PHYCAP_MU_BEAMFORMER_IDX 7 -+#define EHT_PHYCAP_MU_CAPABILITY_IDX 7 -+#define EHT_PHYCAP_NON_OFDMA_UL_MU_MIMO_80MHZ ((u8) BIT(1)) -+#define EHT_PHYCAP_NON_OFDMA_UL_MU_MIMO_160MHZ ((u8) BIT(2)) -+#define EHT_PHYCAP_NON_OFDMA_UL_MU_MIMO_320MHZ ((u8) BIT(3)) - #define EHT_PHYCAP_MU_BEAMFORMER_80MHZ ((u8) BIT(4)) - #define EHT_PHYCAP_MU_BEAMFORMER_160MHZ ((u8) BIT(5)) - #define EHT_PHYCAP_MU_BEAMFORMER_320MHZ ((u8) BIT(6)) --- -2.17.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-041-acs-configuration-option-for-RU-puncturing-threshold.patch b/feeds/ipq95xx/hostapd/patches/q02-041-acs-configuration-option-for-RU-puncturing-threshold.patch deleted file mode 100644 index fc0d2c64..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-041-acs-configuration-option-for-RU-puncturing-threshold.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 08ea6492e671b121c5aabc272bde9b56db81a09d Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Thu, 31 Mar 2022 17:37:51 -0700 -Subject: [PATCH 1/3] acs: configuration option for RU puncturing threshold - -Add new option 'ru_punct_acs_threshold' where the value indicates -the percentage of ideal channel average interference factor above -which a channel should be punctured. Default is set to 75. - -Signed-off-by: Aloka Dixit ---- - hostapd/config_file.c | 2 ++ - hostapd/hostapd.conf | 5 +++++ - src/ap/ap_config.c | 1 + - src/ap/ap_config.h | 1 + - 4 files changed, 9 insertions(+) - ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -4691,6 +4691,14 @@ static int hostapd_config_fill(struct ho - conf->ru_punct_bitmap = atoi(pos); - } else if (os_strcmp(buf, "ru_punct_ofdma") == 0) { - conf->ru_punct_ofdma = atoi(pos); -+ } else if (os_strcmp(buf, "ru_punct_acs_threshold") == 0) { -+ conf->ru_punct_acs_threshold = atoi(pos); -+ if (conf->ru_punct_acs_threshold > 100) { -+ wpa_printf(MSG_ERROR, -+ "Line %d: ru_punct_acs_threshold must be between 0 and 100", -+ line); -+ return 1; -+ } - #endif /* CONFIG_IEEE80211BE */ - } else { - wpa_printf(MSG_ERROR, ---- a/hostapd/hostapd.conf -+++ b/hostapd/hostapd.conf -@@ -1028,6 +1028,12 @@ wmm_ac_vo_acm=0 - # RU puncturing bitmap. Default value is 0. - #ru_punct_ofdma=1 - -+# RU puncturing threshold in automatic channel selection (ACS), where the -+# value indicates the percentage of ideal channel average interference factor -+# above which a channel should be punctured. -+# Default is 0, indicates that ACS algorithm should not puncture any channel. -+#ru_punct_acs_threshold=75 -+ - ##### IEEE 802.1X-2004 related configuration ################################## - - # Require IEEE 802.1X authorization ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -1150,6 +1150,7 @@ struct hostapd_config { - unsigned int ch_switch_eht_config; - u16 ru_punct_bitmap; - u8 ru_punct_ofdma; -+ u8 ru_punct_acs_threshold; - }; - - static inline u8 hostapd_get_he_6ghz_reg_pwr_type(struct hostapd_config *conf) diff --git a/feeds/ipq95xx/hostapd/patches/q02-042-acs-generate-puncturing-bitmap.patch b/feeds/ipq95xx/hostapd/patches/q02-042-acs-generate-puncturing-bitmap.patch deleted file mode 100644 index 22fc42db..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-042-acs-generate-puncturing-bitmap.patch +++ /dev/null @@ -1,165 +0,0 @@ -From 3975ed290f4d1dd7340595296fc8d39be6a41486 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Thu, 31 Mar 2022 15:17:47 -0700 -Subject: [PATCH 2/3] acs: generate puncturing bitmap - -Generate puncturing bitmap after the ideal channel selection using -the threshold. - -Signed-off-by: Aloka Dixit ---- - src/ap/acs.c | 72 +++++++++++++++++++++++++++++++++++++++++--- - src/drivers/driver.h | 5 +++ - 2 files changed, 73 insertions(+), 4 deletions(-) - ---- a/src/ap/acs.c -+++ b/src/ap/acs.c -@@ -275,6 +275,7 @@ static void acs_cleanup_mode(struct host - dl_list_init(&chan->survey_list); - chan->flag |= HOSTAPD_CHAN_SURVEY_LIST_INITIALIZED; - chan->min_nf = 0; -+ chan->ru_punct_bitmap = 0; - } - } - -@@ -644,6 +645,49 @@ static int is_common_24ghz_chan(int chan - #define ACS_24GHZ_PREFER_1_6_11 0.8 - #endif /* ACS_24GHZ_PREFER_1_6_11 */ - -+static void acs_update_puncturing_bitmap(struct hostapd_iface *iface, -+ struct hostapd_hw_modes *mode, u32 bw, -+ int n_chans, -+ struct hostapd_channel_data *chan, -+ long double factor, -+ int index_primary) -+{ -+ struct hostapd_channel_data *adj_chan = NULL; -+ int i; -+ struct hostapd_config *conf = iface->conf; -+ long double threshold = factor * conf->ru_punct_acs_threshold / 100; -+ -+ /* -+ * If threshold is 0 or user configured puncturing pattern is -+ * available then don't add additional puncturing. -+ */ -+ if (!conf->ru_punct_acs_threshold || conf->ru_punct_bitmap) -+ return; -+ -+ if (is_24ghz_mode(mode->mode) || (bw < 80)) -+ return; -+ -+ for (i = 0; i < n_chans; i++) { -+ if (i == index_primary) -+ continue; /* cannot puncture primary channel */ -+ -+ if (i > index_primary) -+ adj_chan = acs_find_chan(iface, -+ chan->freq + -+ ((i - index_primary) * 20)); -+ else -+ adj_chan = acs_find_chan(iface, -+ chan->freq - -+ ((index_primary - i) * 20)); -+ -+ if (!adj_chan) -+ break; -+ -+ if (adj_chan->interference_factor > threshold) -+ chan->ru_punct_bitmap |= BIT(i); -+ } -+} -+ - static void - acs_find_6g_psc_chan_mode(struct hostapd_iface *iface, - struct hostapd_hw_modes *mode, -@@ -740,8 +784,17 @@ acs_find_6g_psc_chan_mode(struct hostapd - - if (acs_usable_chan(chan) && - (!*ideal_chan || factor < *ideal_factor)) { -- *ideal_factor = factor; -+ /* reset puncturing bitmap for the previous ideal channel */ -+ if (*ideal_chan) -+ (*ideal_chan)->ru_punct_bitmap = 0; -+ -+ *ideal_factor = factor; - *ideal_chan = chan; -+ -+ if (iface->conf->ieee80211ax) -+ acs_update_puncturing_bitmap(iface, mode, bw, -+ n_chans, chan, -+ factor, 0); - } - - /* This channel would at least be usable */ -@@ -772,7 +825,11 @@ acs_find_ideal_chan_mode(struct hostapd_ - /* Since in the current ACS implementation the first channel is - * always a primary channel, skip channels not available as - * primary until more sophisticated channel selection is -- * implemented. */ -+ * implemented. -+ * If this implementation is changed to allow any channel in -+ * the bandwidth to be the primary one, the last parameter to -+ * acs_update_puncturing_bitmap() should be changed to the index -+ * of the primary channel */ - if (!chan_pri_allowed(chan)) - continue; - -@@ -923,8 +980,17 @@ acs_find_ideal_chan_mode(struct hostapd_ - - if (acs_usable_chan(chan) && - (!*ideal_chan || factor < *ideal_factor)) { -+ /* reset puncturing bitmap for the previous ideal channel */ -+ if (*ideal_chan) -+ (*ideal_chan)->ru_punct_bitmap = 0; -+ - *ideal_factor = factor; - *ideal_chan = chan; -+ -+ if (iface->conf->ieee80211ax) -+ acs_update_puncturing_bitmap(iface, mode, bw, -+ n_chans, chan, -+ factor, 0); - } - - /* This channel would at least be usable */ -@@ -1006,9 +1072,18 @@ bw_selected: - if (ideal_chan) { - wpa_printf(MSG_DEBUG, "ACS: Ideal channel is %d (%d MHz) with total interference factor of %Lg", - ideal_chan->chan, ideal_chan->freq, ideal_factor); -+ -+ if (iface->conf->ru_punct_acs_threshold) -+ wpa_printf(MSG_DEBUG, "ACS: RU puncturing bitmap 0x%x", -+ ideal_chan->ru_punct_bitmap); -+ - return ideal_chan; - } - -+ if (iface->conf->ru_punct_acs_threshold) -+ wpa_printf(MSG_DEBUG, "ACS: RU puncturing bitmap 0x%x", -+ ideal_chan->ru_punct_bitmap); -+ - return rand_chan; - } - -@@ -1116,6 +1191,7 @@ static void acs_study(struct hostapd_ifa - - iface->conf->channel = ideal_chan->chan; - iface->freq = ideal_chan->freq; -+ iface->conf->ru_punct_bitmap = ideal_chan->ru_punct_bitmap; - - if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) - acs_adjust_center_freq(iface); ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -181,6 +181,11 @@ struct hostapd_channel_data { - * wmm_rules - WMM regulatory rules - */ - struct hostapd_wmm_rule wmm_rules[WMM_AC_NUM]; -+ -+ /** -+ * ru_punct_bitmap - RU puncturing bitmap -+ */ -+ u16 ru_punct_bitmap; - }; - - #define HE_MAC_CAPAB_0 0 diff --git a/feeds/ipq95xx/hostapd/patches/q02-043-acs-validate-the-RU-puncturing-bitmap.patch b/feeds/ipq95xx/hostapd/patches/q02-043-acs-validate-the-RU-puncturing-bitmap.patch deleted file mode 100644 index 6cf8f973..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-043-acs-validate-the-RU-puncturing-bitmap.patch +++ /dev/null @@ -1,45 +0,0 @@ -From f99354a45a72e124252e96b1f746fa8c83a8f597 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit -Date: Thu, 31 Mar 2022 17:19:22 -0700 -Subject: [PATCH 3/3] acs: validate the RU puncturing bitmap - -Validate generated RU puncturing bitmap against non-OFDMA patterns. -Also consider OFDMA patterns if ru_punct_ofdma option is set. - -Signed-off-by: Aloka Dixit ---- - src/ap/acs.c | 22 ++++++++-- - src/common/hw_features_common.c | 75 +++++++++++++++++++++++++++++++++ - src/common/hw_features_common.h | 2 +- - 3 files changed, 94 insertions(+), 5 deletions(-) - ---- a/src/ap/acs.c -+++ b/src/ap/acs.c -@@ -652,7 +652,7 @@ static void acs_update_puncturing_bitmap - long double factor, - int index_primary) - { -- struct hostapd_channel_data *adj_chan = NULL; -+ struct hostapd_channel_data *adj_chan = NULL, *first_chan = chan; - int i; - struct hostapd_config *conf = iface->conf; - long double threshold = factor * conf->ru_punct_acs_threshold / 100; -@@ -682,10 +682,18 @@ static void acs_update_puncturing_bitmap - - if (!adj_chan) - break; -+ else if (i == 0) -+ first_chan = adj_chan; - - if (adj_chan->interference_factor > threshold) - chan->ru_punct_bitmap |= BIT(i); - } -+ -+ if (!is_ru_punct_bitmap_valid(bw, -+ (chan->freq - first_chan->freq) / 20, -+ chan->ru_punct_bitmap, -+ conf->ru_punct_ofdma)) -+ chan->ru_punct_bitmap = 0; - } - - static void diff --git a/feeds/ipq95xx/hostapd/patches/q02-044-01-hostapd-Add-320-MHz-support.patch b/feeds/ipq95xx/hostapd/patches/q02-044-01-hostapd-Add-320-MHz-support.patch deleted file mode 100644 index 014d088b..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-044-01-hostapd-Add-320-MHz-support.patch +++ /dev/null @@ -1,412 +0,0 @@ -From 387b308a6af81ada3643cc1c1658a7756f359b5a Mon Sep 17 00:00:00 2001 -From: Karthikeyan Periyasamy -Date: Tue, 21 Sep 2021 17:20:23 +0530 -Subject: [PATCH] hostapd: Add 320 MHz support - -Added 320 MHz channel support in 6GHz band (EHT) -as define by IEEE P802.11be/D1.1, July 2021 -section 36.3.23.2. It covers channel bringup, -frequency validation, channel switch and also -across all channel width and frequency manipulation. - -Signed-off-by: Karthikeyan Periyasamy -Signed-off-by: Ramya Gnanasekar ---- - hostapd/ctrl_iface.c | 31 +++++++++++++++++++++++++++++++ - src/ap/drv_callbacks.c | 6 ++++++ - src/ap/hostapd.c | 9 +++++++++ - src/ap/ieee802_11.c | 4 ++++ - src/ap/ieee802_11_eht.c | 4 +++- - src/ap/neighbor_db.c | 9 ++++++--- - src/common/defs.h | 1 + - src/common/hw_features_common.c | 3 +++ - src/common/ieee802_11_common.c | 6 ++++++ - src/common/ieee802_11_defs.h | 6 ++++++ - src/drivers/driver.h | 1 + - src/drivers/driver_common.c | 4 ++++ - src/drivers/driver_nl80211.c | 5 +++++ - src/drivers/driver_nl80211_capa.c | 3 +++ - src/drivers/driver_nl80211_event.c | 6 ++++++ - src/drivers/nl80211_copy.h | 2 ++ - wpa_supplicant/ctrl_iface.c | 2 ++ - 17 files changed, 98 insertions(+), 4 deletions(-) - -Index: b/hostapd/ctrl_iface.c -=================================================================== ---- a/hostapd/ctrl_iface.c 2022-08-30 18:41:54.749138965 +0530 -+++ b/hostapd/ctrl_iface.c 2022-08-30 18:41:54.717139244 +0530 -@@ -2637,7 +2637,7 @@ static int hostapd_ctrl_register_frame(s - #ifdef NEED_AP_MLME - static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params) - { -- int idx, bw, bw_idx[] = { 20, 40, 80, 160 }; -+ int idx, bw, bw_idx[] = { 20, 40, 80, 160, 320 }; - u32 start_freq; - - if (is_6ghz_freq(params->freq)) { -@@ -2749,6 +2749,34 @@ static int hostapd_ctrl_check_freq_param - return -1; - } - break; -+ case 320: -+ if (!params->center_freq1 || params->center_freq2 || -+ !params->sec_channel_offset) -+ return -1; -+ -+ switch (params->sec_channel_offset) { -+ case 1: -+ if (params->freq + 150 != params->center_freq1 && -+ params->freq + 70 != params->center_freq1 && -+ params->freq + 30 != params->center_freq1 && -+ params->freq - 10 != params->center_freq1 && -+ params->freq - 50 != params->center_freq1 && -+ params->freq - 130 != params->center_freq1) -+ return -1; -+ break; -+ case -1: -+ if (params->freq + 130 != params->center_freq1 && -+ params->freq + 50 != params->center_freq1 && -+ params->freq + 10 != params->center_freq1 && -+ params->freq - 30 != params->center_freq1 && -+ params->freq - 70 != params->center_freq1 && -+ params->freq - 150 != params->center_freq1) -+ return -1; -+ break; -+ default: -+ return -1; -+ } -+ break; - default: - return -1; - } -@@ -2872,6 +2900,9 @@ static int hostapd_ctrl_iface_chan_switc - case 160: - bandwidth = CHAN_WIDTH_160; - break; -+ case 320: -+ bandwidth = CHAN_WIDTH_320; -+ break; - default: - bandwidth = CHAN_WIDTH_20; - break; -Index: b/src/ap/drv_callbacks.c -=================================================================== ---- a/src/ap/drv_callbacks.c 2022-08-30 18:41:54.749138965 +0530 -+++ b/src/ap/drv_callbacks.c 2022-08-30 18:41:54.721139209 +0530 -@@ -854,6 +854,9 @@ void hostapd_event_sta_opmode_changed(st - case CHAN_WIDTH_160: - txt = "160"; - break; -+ case CHAN_WIDTH_320: -+ txt = "320"; -+ break; - default: - txt = NULL; - break; -@@ -917,6 +920,9 @@ void hostapd_event_ch_switch(struct host - case CHAN_WIDTH_160: - chwidth = CHANWIDTH_160MHZ; - break; -+ case CHAN_WIDTH_320: -+ chwidth = CHANWIDTH_320MHZ; -+ break; - case CHAN_WIDTH_20_NOHT: - case CHAN_WIDTH_20: - case CHAN_WIDTH_40: -@@ -977,7 +983,8 @@ void hostapd_event_ch_switch(struct host - hapd->iconf->ch_switch_eht_config = 0; - - if (width == CHAN_WIDTH_40 || width == CHAN_WIDTH_80 || -- width == CHAN_WIDTH_80P80 || width == CHAN_WIDTH_160) -+ width == CHAN_WIDTH_80P80 || width == CHAN_WIDTH_160 || -+ width == CHAN_WIDTH_320) - hapd->iconf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET; - else if (width == CHAN_WIDTH_20 || width == CHAN_WIDTH_20_NOHT) - hapd->iconf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET; -Index: b/src/ap/hostapd.c -=================================================================== ---- a/src/ap/hostapd.c 2022-08-30 18:41:54.749138965 +0530 -+++ b/src/ap/hostapd.c 2022-08-30 18:41:54.725139174 +0530 -@@ -3548,6 +3548,7 @@ static int hostapd_change_config_freq(st - case 40: - case 80: - case 160: -+ case 320: - conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET; - break; - default: -@@ -3569,6 +3570,9 @@ static int hostapd_change_config_freq(st - case 160: - hostapd_set_oper_chwidth(conf, CHANWIDTH_160MHZ); - break; -+ case 320: -+ hostapd_set_oper_chwidth(conf, CHANWIDTH_320MHZ); -+ break; - default: - return -1; - } -@@ -3617,6 +3621,9 @@ static int hostapd_fill_csa_settings(str - case 160: - bandwidth = CHANWIDTH_160MHZ; - break; -+ case 320: -+ bandwidth = CHANWIDTH_320MHZ; -+ break; - default: - bandwidth = CHANWIDTH_USE_HT; - break; -@@ -3776,6 +3783,9 @@ hostapd_switch_channel_fallback(struct h - case 160: - bw = CHANWIDTH_160MHZ; - break; -+ case 320: -+ bw = CHANWIDTH_320MHZ; -+ break; - default: - wpa_printf(MSG_WARNING, "Unknown CSA bandwidth: %d", - freq_params->bandwidth); -Index: b/src/ap/ieee802_11_eht.c -=================================================================== ---- a/src/ap/ieee802_11_eht.c 2022-08-30 18:41:54.749138965 +0530 -+++ b/src/ap/ieee802_11_eht.c 2022-08-30 18:41:54.725139174 +0530 -@@ -301,7 +301,9 @@ static int check_valid_eht_mcs(struct ho - u8 mcs_count = 1; - - switch (hapd->iface->conf->eht_oper_chwidth) { -- /* TODO CHANWIDTH_320MHZ */ -+ case CHANWIDTH_320MHZ: -+ mcs_count = 3; -+ break; - case CHANWIDTH_80P80MHZ: - case CHANWIDTH_160MHZ: - mcs_count = 2; -Index: b/src/common/defs.h -=================================================================== ---- a/src/common/defs.h 2022-08-30 18:41:54.749138965 +0530 -+++ b/src/common/defs.h 2022-08-30 18:41:54.725139174 +0530 -@@ -430,6 +430,7 @@ enum chan_width { - CHAN_WIDTH_4320, - CHAN_WIDTH_6480, - CHAN_WIDTH_8640, -+ CHAN_WIDTH_320, - CHAN_WIDTH_UNKNOWN - }; - -Index: b/src/common/hw_features_common.c -=================================================================== ---- a/src/common/hw_features_common.c 2022-08-30 18:41:54.749138965 +0530 -+++ b/src/common/hw_features_common.c 2022-08-30 18:41:54.729139140 +0530 -@@ -413,6 +413,8 @@ int hostapd_set_freq_params(struct hosta - else if (oper_chwidth == CHANWIDTH_160MHZ || - oper_chwidth == CHANWIDTH_80P80MHZ) - data->bandwidth = 160; -+ else if (oper_chwidth == CHANWIDTH_320MHZ) -+ data->bandwidth = 320; - else if (sec_channel_offset) - data->bandwidth = 40; - else -@@ -809,6 +811,9 @@ int chan_bw_allowed(const struct hostapd - case 160: - bw_mask = HOSTAPD_CHAN_WIDTH_160; - break; -+ case 320: -+ bw_mask = HOSTAPD_CHAN_WIDTH_320; -+ break; - default: - bw_mask = 0; - break; -Index: b/src/common/ieee802_11_common.c -=================================================================== ---- a/src/common/ieee802_11_common.c 2022-08-30 18:41:54.749138965 +0530 -+++ b/src/common/ieee802_11_common.c 2022-08-30 18:41:54.729139140 +0530 -@@ -1164,6 +1164,9 @@ int ieee80211_chaninfo_to_channel(unsign - case CHAN_WIDTH_8640: - cw = CHANWIDTH_8640MHZ; - break; -+ case CHAN_WIDTH_320: -+ cw = CHANWIDTH_320MHZ; -+ break; - } - - if (ieee80211_freq_to_channel_ext(freq, sec_channel, cw, op_class, -@@ -2273,6 +2276,9 @@ int center_idx_to_bw_6ghz(u8 idx) - /* channels 15, 47, 79...*/ - if ((idx & 0x1f) == 0xf) - return 3; /* 160 MHz */ -+ /* channels 31, 63, 95, 127, 159, 191. */ -+ if ((idx & 0x1f) == 0x1f) -+ return 4; /* 320 MHz */ - - return -1; - } -Index: b/src/common/ieee802_11_defs.h -=================================================================== ---- a/src/common/ieee802_11_defs.h 2022-08-30 18:41:54.749138965 +0530 -+++ b/src/common/ieee802_11_defs.h 2022-08-30 18:41:54.729139140 +0530 -@@ -2241,6 +2241,7 @@ enum phy_type { - /* - * IEEE P802.11-REVmc/D5.0 Table 9-152 - HT/VHT Operation Information - * subfields. -+ * IEEE P802.11be/D1.1 Table 9-322al - EHT Operation Information subfields. - * Note: These definitions are not the same as other CHANWIDTH_*. - */ - enum nr_chan_width { -Index: b/src/drivers/driver.h -=================================================================== ---- a/src/drivers/driver.h 2022-08-30 18:41:54.749138965 +0530 -+++ b/src/drivers/driver.h 2022-08-30 18:41:54.729139140 +0530 -@@ -67,6 +67,7 @@ enum hostapd_chan_width_attr { - HOSTAPD_CHAN_WIDTH_40M = BIT(3), - HOSTAPD_CHAN_WIDTH_80 = BIT(4), - HOSTAPD_CHAN_WIDTH_160 = BIT(5), -+ HOSTAPD_CHAN_WIDTH_320 = BIT(6), - }; - - /* Filter gratuitous ARP */ -Index: b/src/drivers/driver_common.c -=================================================================== ---- a/src/drivers/driver_common.c 2022-08-30 18:41:54.749138965 +0530 -+++ b/src/drivers/driver_common.c 2022-08-30 18:41:54.733139105 +0530 -@@ -118,6 +118,8 @@ const char * channel_width_to_string(enu - return "80+80 MHz"; - case CHAN_WIDTH_160: - return "160 MHz"; -+ case CHAN_WIDTH_320: -+ return "320 MHz"; - default: - return "unknown"; - } -@@ -137,6 +139,8 @@ int channel_width_to_int(enum chan_width - case CHAN_WIDTH_80P80: - case CHAN_WIDTH_160: - return 160; -+ case CHAN_WIDTH_320: -+ return 320; - default: - return 0; - } -Index: b/src/drivers/driver_nl80211.c -=================================================================== ---- a/src/drivers/driver_nl80211.c 2022-08-30 18:41:54.749138965 +0530 -+++ b/src/drivers/driver_nl80211.c 2022-08-30 18:41:54.737139070 +0530 -@@ -215,6 +215,8 @@ enum chan_width convert2width(int width) - return CHAN_WIDTH_80P80; - case NL80211_CHAN_WIDTH_160: - return CHAN_WIDTH_160; -+ case NL80211_CHAN_WIDTH_320: -+ return CHAN_WIDTH_320; - } - return CHAN_WIDTH_UNKNOWN; - } -@@ -5020,6 +5022,9 @@ static int nl80211_put_freq_params(struc - case 160: - cw = NL80211_CHAN_WIDTH_160; - break; -+ case 320: -+ cw = NL80211_CHAN_WIDTH_320; -+ break; - default: - return -EINVAL; - } -Index: b/src/drivers/driver_nl80211_capa.c -=================================================================== ---- a/src/drivers/driver_nl80211_capa.c 2022-08-30 18:41:54.749138965 +0530 -+++ b/src/drivers/driver_nl80211_capa.c 2022-08-30 18:41:54.737139070 +0530 -@@ -1628,6 +1628,9 @@ static void phy_info_freq(struct hostapd - chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_80; - if (tb_freq[NL80211_FREQUENCY_ATTR_NO_160MHZ]) - chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_160; -+ if (tb_freq[NL80211_FREQUENCY_ATTR_NO_320MHZ]) -+ chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_320; -+ - - if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]) { - enum nl80211_dfs_state state = -Index: b/src/drivers/driver_nl80211_event.c -=================================================================== ---- a/src/drivers/driver_nl80211_event.c 2022-08-30 18:41:54.749138965 +0530 -+++ b/src/drivers/driver_nl80211_event.c 2022-08-30 18:41:54.741139036 +0530 -@@ -675,6 +675,9 @@ static int calculate_chan_offset(int wid - case CHAN_WIDTH_80P80: - freq1 = cf1 - 30; - break; -+ case CHAN_WIDTH_320: -+ freq1 = cf1 - 150; -+ break; - case CHAN_WIDTH_UNKNOWN: - case CHAN_WIDTH_2160: - case CHAN_WIDTH_4320: -@@ -2825,6 +2828,9 @@ static void nl80211_sta_opmode_change_ev - case NL80211_CHAN_WIDTH_160: - ed.sta_opmode.chan_width = CHAN_WIDTH_160; - break; -+ case NL80211_CHAN_WIDTH_320: -+ ed.sta_opmode.chan_width = CHAN_WIDTH_320; -+ break; - default: - ed.sta_opmode.chan_width = CHAN_WIDTH_UNKNOWN; - break; -Index: b/src/drivers/nl80211_copy.h -=================================================================== ---- a/src/drivers/nl80211_copy.h 2022-08-30 18:41:54.749138965 +0530 -+++ b/src/drivers/nl80211_copy.h 2022-08-30 18:42:13.980971726 +0530 -@@ -3947,6 +3947,9 @@ enum nl80211_frequency_attr { - NL80211_FREQUENCY_ATTR_4MHZ, - NL80211_FREQUENCY_ATTR_8MHZ, - NL80211_FREQUENCY_ATTR_16MHZ, -+ NL80211_FREQUENCY_ATTR_PSD, -+ NL80211_FREQUENCY_ATTR_NO_320MHZ, -+ NL80211_FREQUENCY_ATTR_NO_EHT, - - /* keep last */ - __NL80211_FREQUENCY_ATTR_AFTER_LAST, -@@ -4682,6 +4685,7 @@ enum nl80211_chan_width { - NL80211_CHAN_WIDTH_4, - NL80211_CHAN_WIDTH_8, - NL80211_CHAN_WIDTH_16, -+ NL80211_CHAN_WIDTH_320, - - /* keep last */ - __NL80211_CHAN_WIDTH_NUM, -Index: b/wpa_supplicant/ctrl_iface.c -=================================================================== ---- a/wpa_supplicant/ctrl_iface.c 2022-08-30 18:41:54.749138965 +0530 -+++ b/wpa_supplicant/ctrl_iface.c 2022-08-30 18:41:54.745139000 +0530 -@@ -5993,6 +5993,8 @@ static int parse_freq(int chwidth, int f - return CHANWIDTH_80MHZ; - case 160: - return CHANWIDTH_160MHZ; -+ case 320: -+ return CHANWIDTH_320MHZ; - default: - wpa_printf(MSG_DEBUG, "Unknown max oper bandwidth: %d", - chwidth); -Index: b/src/ap/ap_config.h -=================================================================== ---- a/src/ap/ap_config.h 2022-08-30 18:41:54.749138965 +0530 -+++ b/src/ap/ap_config.h 2022-08-30 18:41:54.745139000 +0530 -@@ -1186,7 +1186,8 @@ hostapd_set_oper_chwidth(struct hostapd_ - conf->eht_oper_chwidth = oper_chwidth; - #endif /* CONFIG_IEEE80211BE */ - #ifdef CONFIG_IEEE80211AX -- if (conf->ieee80211ax) -+ if (conf->ieee80211ax && -+ oper_chwidth < CHANWIDTH_320MHZ) - conf->he_oper_chwidth = oper_chwidth; - #endif /* CONFIG_IEEE80211AX */ - conf->vht_oper_chwidth = oper_chwidth; -Index: b/src/ap/ieee802_11_he.c -=================================================================== ---- a/src/ap/ieee802_11_he.c 2022-08-30 18:41:54.749138965 +0530 -+++ b/src/ap/ieee802_11_he.c 2022-08-30 18:41:54.749138965 +0530 -@@ -219,8 +219,8 @@ u8 * hostapd_eid_he_operation(struct hos - pos += 6; /* skip the fixed part */ - - if (is_6ghz_op_class(hapd->iconf->op_class)) { -- u8 seg0 = hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf); -- u8 seg1 = hostapd_get_oper_centr_freq_seg1_idx(hapd->iconf); -+ u8 seg0 = hapd->iface->conf->he_oper_centr_freq_seg0_idx; -+ u8 seg1 = hapd->iface->conf->he_oper_centr_freq_seg1_idx; - - if (hapd->iconf->ru_punct_bitmap) { - hapd->iconf->he_oper_chwidth = diff --git a/feeds/ipq95xx/hostapd/patches/q02-044-02-ACS-Add-ACS-support-for-11be-mode.patch b/feeds/ipq95xx/hostapd/patches/q02-044-02-ACS-Add-ACS-support-for-11be-mode.patch deleted file mode 100644 index 4636abf1..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-044-02-ACS-Add-ACS-support-for-11be-mode.patch +++ /dev/null @@ -1,169 +0,0 @@ -From 6017023786ba26149c18d3f73b3f0b829bab4a61 Mon Sep 17 00:00:00 2001 -From: Sriram R -Date: Mon, 20 Sep 2021 18:49:42 +0530 -Subject: [PATCH] ACS: Add ACS support for 11be mode - -Add ACS support for channels in 11be mode including -320MHz bw support for 6GHz. - -Signed-off-by: Sriram R -Signed-off-by: Ramya Gnanasekar ---- - src/ap/acs.c | 37 +++++++++++++++++++++++++++++++++---- - 1 file changed, 33 insertions(+), 4 deletions(-) - -Index: b/src/ap/acs.c -=================================================================== ---- a/src/ap/acs.c 2022-10-18 16:25:59.609149848 +0530 -+++ b/src/ap/acs.c 2022-10-18 16:26:17.653035183 +0530 -@@ -417,6 +417,18 @@ static int acs_usable_bw160_chan(const s - return 0; - } - -+static int acs_usable_bw320_chan(const struct hostapd_channel_data *chan) -+{ -+ /* Allow start of overlapping 320MHz channels */ -+ const int allowed[] = { 5955, 6115, 6275, 6435, 6595, 6755 }; -+ unsigned int i; -+ -+ for (i = 0; i < ARRAY_SIZE(allowed); i++) -+ if (chan->freq == allowed[i]) -+ return 1; -+ -+ return 0; -+} - - static int acs_survey_is_sufficient(struct freq_survey *survey) - { -@@ -871,7 +883,8 @@ acs_find_ideal_chan_mode(struct hostapd_ - } - - if (mode->mode == HOSTAPD_MODE_IEEE80211A && -- (iface->conf->ieee80211ac || iface->conf->ieee80211ax)) { -+ (iface->conf->ieee80211ac || iface->conf->ieee80211ax || -+ iface->conf->ieee80211be)) { - if (hostapd_get_oper_chwidth(iface->conf) == - CHANWIDTH_80MHZ && - !acs_usable_bw80_chan(chan)) { -@@ -889,6 +902,16 @@ acs_find_ideal_chan_mode(struct hostapd_ - chan->chan); - continue; - } -+ -+ if (iface->conf->ieee80211be && -+ hostapd_get_oper_chwidth(iface->conf) == -+ CHANWIDTH_320MHZ && -+ !acs_usable_bw320_chan(chan)) { -+ wpa_printf(MSG_DEBUG, -+ "ACS: Channel %d: not allowed as primary channel for 320 MHz bandwidth", -+ chan->chan); -+ continue; -+ } - } - - factor = 0; -@@ -1043,7 +1066,8 @@ acs_find_ideal_chan(struct hostapd_iface - iface->conf->secondary_channel) - n_chans = 2; - -- if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) { -+ if (iface->conf->ieee80211ac || iface->conf->ieee80211ax || -+ iface->conf->ieee80211be) { - switch (hostapd_get_oper_chwidth(iface->conf)) { - case CHANWIDTH_80MHZ: - n_chans = 4; -@@ -1051,6 +1075,7 @@ acs_find_ideal_chan(struct hostapd_iface - case CHANWIDTH_160MHZ: - n_chans = 8; - break; -+ /* 320 is supported only in 6GHz 11be mode */ - } - } - -@@ -1095,12 +1120,29 @@ bw_selected: - return rand_chan; - } - -+static int acs_get_center_freq_320mhz(int channel) -+{ -+ if (channel >= 1 && channel <= 45) -+ return 31; -+ else if (channel >= 49 && channel <= 77) -+ return 63; -+ else if (channel >= 81 && channel <= 109) -+ return 95; -+ else if (channel >= 113 && channel <= 141) -+ return 127; -+ else if (channel >= 145 && channel <= 173) -+ return 159; -+ else -+ return 191; -+} - - static void acs_adjust_center_freq(struct hostapd_iface *iface) - { - int psc_chan[] = {37, 53, 69, 85, 101, 117, - 133, 149, 165, 181, 197, 213} ; -- int offset, i; -+ int psc_chan_320_1[] = {69, 85, 133, 149, 197, 213}; -+ int psc_chan_320_2[] = {37, 53, 101, 117, 165, 181, 219}; -+ int offset = 0, i, seg0 = 0; - u8 bw = hostapd_get_oper_chwidth(iface->conf); - bool acs_exclude_6ghz_non_psc = iface->conf->acs_exclude_6ghz_non_psc; - bool is_sec_psc_chan = false; -@@ -1126,6 +1168,27 @@ static void acs_adjust_center_freq(struc - else - offset = 6; - break; -+ case CHANWIDTH_320MHZ: -+ if (acs_exclude_6ghz_non_psc) { -+ for (i = 0; i < ARRAY_SIZE(psc_chan_320_1); i++) { -+ if (psc_chan_320_1[i] == iface->conf->channel) { -+ is_sec_psc_chan = (i%2) ? true : false; -+ offset = is_sec_psc_chan ? 10 : 26; -+ break; -+ } -+ } -+ for (i = 0; i < ARRAY_SIZE(psc_chan_320_2); i++) { -+ if (psc_chan_320_2[i] == iface->conf->channel) { -+ is_sec_psc_chan = (i%2) ? true : false; -+ offset = is_sec_psc_chan ? -22 : -6; -+ break; -+ } -+ } -+ seg0 = iface->conf->channel + offset; -+ } else { -+ seg0 = acs_get_center_freq_320mhz(iface->conf->channel); -+ } -+ /* fallthrough */ - case CHANWIDTH_160MHZ: - /* In 160MHz, if primary 20MHz present in secondary 80MHz, then - * subtract with -6 to find the center frequency of the 160MHz -@@ -1139,12 +1202,16 @@ static void acs_adjust_center_freq(struc - /* TODO: How can this be calculated? Adjust - * acs_find_ideal_chan() */ - wpa_printf(MSG_INFO, -- "ACS: Only VHT20/40/80/160 is supported now"); -+ "ACS: Only VHT20/40/80/160 EHT320 is supported now"); - return; - } - - hostapd_set_oper_centr_freq_seg0_idx(iface->conf, - iface->conf->channel + offset); -+#ifdef CONFIG_IEEE80211BE -+ if (bw == CHANWIDTH_320MHZ) -+ iface->conf->eht_oper_centr_freq_seg0_idx = seg0; -+#endif - } - - -@@ -1201,7 +1268,8 @@ static void acs_study(struct hostapd_ifa - iface->freq = ideal_chan->freq; - iface->conf->ru_punct_bitmap = ideal_chan->ru_punct_bitmap; - -- if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) -+ if (iface->conf->ieee80211ac || iface->conf->ieee80211ax || -+ iface->conf->ieee80211be) - acs_adjust_center_freq(iface); - - err = 0; diff --git a/feeds/ipq95xx/hostapd/patches/q02-044-nl80211-sync-green-ap-changes.patch b/feeds/ipq95xx/hostapd/patches/q02-044-nl80211-sync-green-ap-changes.patch deleted file mode 100644 index 0cd89d9c..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-044-nl80211-sync-green-ap-changes.patch +++ /dev/null @@ -1,68 +0,0 @@ -From d486b8c3149bcaa5dc40182f0d640fe1edec2672 Mon Sep 17 00:00:00 2001 -From: Sivashankari Madhavan -Date: Wed, 4 May 2022 15:09:09 +0530 -Subject: [PATCH] Sync the NL green AP changes to hostapd - -Sync the nl80211 Green ap changes into hostapd nl80211_copy - -Signed-off-by: Sivashankari Madhavan ---- - src/drivers/nl80211_copy.h | 19 ++++++++++++++----- - 1 file changed, 14 insertions(+), 5 deletions(-) - -diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h -index 77c7a84..7c51646 100644 ---- a/src/drivers/nl80211_copy.h -+++ b/src/drivers/nl80211_copy.h -@@ -350,11 +350,13 @@ - * or %NL80211_ATTR_MAC. - * - * @NL80211_CMD_GET_BEACON: (not used) -- * @NL80211_CMD_SET_BEACON: change the beacon on an access point interface -+ * @NL80211_CMD_UPDATE_AP: Update AP parameters which can vary at the -+ * runtime of BSS. change the beacon on an access point interface - * using the %NL80211_ATTR_BEACON_HEAD and %NL80211_ATTR_BEACON_TAIL - * attributes. For drivers that generate the beacon and probe responses -- * internally, the following attributes must be provided: %NL80211_ATTR_IE, -- * %NL80211_ATTR_IE_PROBE_RESP and %NL80211_ATTR_IE_ASSOC_RESP. -+ * internally, the following attributes must be provided for the -+ * beacon update: %NL80211_ATTR_IE, %NL80211_ATTR_IE_PROBE_RESP and -+ * %NL80211_ATTR_IE_ASSOC_RESP. - * @NL80211_CMD_START_AP: Start AP operation on an AP interface, parameters - * are like for %NL80211_CMD_SET_BEACON, and additionally parameters that - * do not change are used, these include %NL80211_ATTR_BEACON_INTERVAL, -@@ -1217,7 +1219,8 @@ enum nl80211_commands { - NL80211_CMD_DEL_KEY, - - NL80211_CMD_GET_BEACON, -- NL80211_CMD_SET_BEACON, -+ NL80211_CMD_UPDATE_AP, -+ NL80211_CMD_SET_BEACON = NL80211_CMD_UPDATE_AP, - NL80211_CMD_START_AP, - NL80211_CMD_NEW_BEACON = NL80211_CMD_START_AP, - NL80211_CMD_STOP_AP, -@@ -2597,6 +2600,11 @@ enum nl80211_commands { - * association request when used with NL80211_CMD_NEW_STATION). Can be set - * only if %NL80211_STA_FLAG_WME is set. - * -+ * @NL80211_ATTR_AP_PS: enable/disable AP power save. -+ * This attribute type is u8 and valid range is 0 to 1. -+ * 0 for disable AP power save mode. -+ * 1 for enable AP power save mode. -+ * - * @NUM_NL80211_ATTR: total number of nl80211_attrs available - * @NL80211_ATTR_MAX: highest attribute number currently defined - * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -3123,7 +3131,8 @@ enum nl80211_attrs { - NL80211_ATTR_RU_PUNCT_SUPP_BW, - NL80211_ATTR_RU_PUNCT_SUPP_HE, - NL80211_ATTR_RU_PUNCT_BITMAP, -- -+ -+ NL80211_ATTR_AP_PS, - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, --- -2.17.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-045-mesh_add_EHT_support.patch b/feeds/ipq95xx/hostapd/patches/q02-045-mesh_add_EHT_support.patch deleted file mode 100644 index ec5232e9..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-045-mesh_add_EHT_support.patch +++ /dev/null @@ -1,345 +0,0 @@ -From d7713b5ca78966dd7ea6a3bdd35511503dc59537 Mon Sep 17 00:00:00 2001 -From: Ramya Gnanasekar -Date: Thu, 14 Apr 2022 12:14:03 +0530 -Subject: [PATCH] mesh: add EHT support - -Add mesh_eht_enabled and eht ssid config to include EHT capability -and EHT operation IEs in mesh PLINK action frames. -Update mesh_eht_enabled from EHT capability advertised for mesh mode. -Support for mesh channelization in 320MHz. - -Signed-off-by: Ramya Gnanasekar -Signed-off-by: Sathishkumar Muruganandam ---- -Index: b/wpa_supplicant/ap.c -=================================================================== ---- a/wpa_supplicant/ap.c 2022-07-08 10:12:42.614954957 +0530 -+++ b/wpa_supplicant/ap.c 2022-07-08 10:12:42.586955263 +0530 -@@ -324,6 +324,14 @@ int wpa_supplicant_conf_ap_ht(struct wpa - - if (mode && is_6ghz_freq(ssid->frequency) && - conf->hw_mode == HOSTAPD_MODE_IEEE80211A) { -+ if (mode->eht_capab[wpas_mode_to_ieee80211_mode( -+ ssid->mode)].eht_supported && -+ ssid->eht) -+ conf->ieee80211be = 1; -+ if (mode->he_capab[wpas_mode_to_ieee80211_mode( -+ ssid->mode)].he_supported && -+ ssid->he) -+ conf->ieee80211ax = 1; - #ifdef CONFIG_P2P - wpas_conf_ap_he_6ghz(wpa_s, mode, ssid, conf); - #endif /* CONFIG_P2P */ -@@ -407,6 +415,10 @@ int wpa_supplicant_conf_ap_ht(struct wpa - ssid->mode)].he_supported && - ssid->he) - conf->ieee80211ax = 1; -+ if (mode->eht_capab[wpas_mode_to_ieee80211_mode( -+ ssid->mode)].eht_supported && -+ ssid->eht) -+ conf->ieee80211be = 1; - - if (mode->vht_capab && ssid->vht) { - conf->ieee80211ac = 1; -Index: b/wpa_supplicant/config.c -=================================================================== ---- a/wpa_supplicant/config.c 2022-07-08 10:12:42.614954957 +0530 -+++ b/wpa_supplicant/config.c 2022-07-08 10:12:42.586955263 +0530 -@@ -2812,6 +2812,7 @@ static const struct parse_data ssid_fiel - { INT_RANGE(disable_40mhz_scan, 0, 1)}, - { INT_RANGE(beacon_tx_mode, 1, 2)}, - { INT_RANGE(enable_160mhz_bw, 0, 1)}, -+ { INT_RANGE(enable_320mhz_bw, 0, 1)}, - }; - - #undef OFFSET -Index: b/wpa_supplicant/mesh.c -=================================================================== ---- a/wpa_supplicant/mesh.c 2022-07-08 10:12:42.614954957 +0530 -+++ b/wpa_supplicant/mesh.c 2022-07-08 10:12:42.586955263 +0530 -@@ -227,7 +227,7 @@ static int wpas_mesh_update_freq_params( - ifmsh->conf->ieee80211n, - ifmsh->conf->ieee80211ac, - ifmsh->conf->ieee80211ax, -- 0, -+ ifmsh->conf->ieee80211be, - ifmsh->conf->secondary_channel, - hostapd_get_oper_chwidth(ifmsh->conf), - hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf), -@@ -468,6 +468,9 @@ static int wpa_supplicant_mesh_init(stru - case 160: - conf->op_class = 134; - break; -+ case 320: -+ conf->op_class = 137; -+ break; - default: - conf->op_class = 131; - break; -@@ -659,6 +662,7 @@ int wpa_supplicant_join_mesh(struct wpa_ - wpa_s->mesh_ht_enabled = !!params->freq.ht_enabled; - wpa_s->mesh_vht_enabled = !!params->freq.vht_enabled; - wpa_s->mesh_he_enabled = !!params->freq.he_enabled; -+ wpa_s->mesh_eht_enabled = !!params->freq.eht_enabled; - if (params->freq.ht_enabled && params->freq.sec_channel_offset) - ssid->ht40 = params->freq.sec_channel_offset; - -@@ -678,6 +682,9 @@ int wpa_supplicant_join_mesh(struct wpa_ - case 160: - ssid->max_oper_chwidth = CHANWIDTH_160MHZ; - break; -+ case 320: -+ ssid->max_oper_chwidth = CHANWIDTH_320MHZ; -+ break; - default: - ssid->max_oper_chwidth = CHANWIDTH_USE_HT; - break; -@@ -685,6 +692,8 @@ int wpa_supplicant_join_mesh(struct wpa_ - } - if (wpa_s->mesh_he_enabled) - ssid->he = 1; -+ if (wpa_s->mesh_eht_enabled) -+ ssid->eht = 1; - if (ssid->beacon_int > 0) - params->beacon_int = ssid->beacon_int; - else if (wpa_s->conf->beacon_int > 0) -Index: b/wpa_supplicant/mesh_mpm.c -=================================================================== ---- a/wpa_supplicant/mesh_mpm.c 2022-07-08 10:12:42.614954957 +0530 -+++ b/wpa_supplicant/mesh_mpm.c 2022-07-08 10:12:42.586955263 +0530 -@@ -257,6 +257,16 @@ static void mesh_mpm_send_plink_action(s - 3 + sizeof(struct ieee80211_he_6ghz_band_cap); - } - #endif /* CONFIG_IEEE80211AX */ -+#ifdef CONFIG_IEEE80211BE -+ if (type != PLINK_CLOSE && wpa_s->mesh_eht_enabled) { -+ buf_len += 3 + -+ EHT_MAC_CAPAB_MAX_LEN + -+ EHT_PHY_CAPAB_MAX_LEN + -+ EHT_MCS_NSS_CAPAB_MAX_LEN + -+ EHT_PPE_THRESH_CAPAB_MAX_LEN; -+ buf_len += 3 + sizeof(struct ieee80211_eht_operation); -+ } -+#endif /* CONFIG_IEEE80211BE */ - if (type != PLINK_CLOSE) - buf_len += conf->rsn_ie_len; /* RSN IE */ - #ifdef CONFIG_OCV -@@ -391,6 +401,20 @@ static void mesh_mpm_send_plink_action(s - wpabuf_put_data(buf, he_capa_oper, pos - he_capa_oper); - } - #endif /* CONFIG_IEEE80211AX */ -+#ifdef CONFIG_IEEE80211BE -+ if (type != PLINK_CLOSE && wpa_s->mesh_eht_enabled) { -+ u8 eht_capa_oper[3 + -+ EHT_MAC_CAPAB_MAX_LEN + -+ EHT_PHY_CAPAB_MAX_LEN + -+ EHT_MCS_NSS_CAPAB_MAX_LEN + -+ EHT_PPE_THRESH_CAPAB_MAX_LEN + -+ 3 + sizeof(struct ieee80211_eht_operation)]; -+ pos = hostapd_eid_eht_capab(bss, eht_capa_oper, -+ IEEE80211_MODE_MESH); -+ pos = hostapd_eid_eht_operation(bss, pos, IEEE80211_MODE_MESH); -+ wpabuf_put_data(buf, eht_capa_oper, pos - eht_capa_oper); -+ } -+#endif /* CONFIG_IEEE80211BE */ - - #ifdef CONFIG_OCV - if (type != PLINK_CLOSE && conf->ocv) { -@@ -760,6 +784,11 @@ static struct sta_info * mesh_mpm_add_pe - copy_sta_he_6ghz_capab(data, sta, elems->he_6ghz_band_cap); - #endif /* CONFIG_IEEE80211AX */ - -+#ifdef CONFIG_IEEE80211BE -+ copy_sta_eht_capab(data, sta, IEEE80211_MODE_MESH, elems->he_capabilities, -+ elems->eht_capabilities, elems->eht_capabilities_len); -+#endif /* CONFIG_IEEE80211BE */ -+ - if (hostapd_get_aid(data, sta) < 0) { - wpa_msg(wpa_s, MSG_ERROR, "No AIDs available"); - ap_free_sta(data, sta); -@@ -780,6 +809,8 @@ static struct sta_info * mesh_mpm_add_pe - params.he_capab = sta->he_capab; - params.he_capab_len = sta->he_capab_len; - params.he_6ghz_capab = sta->he_6ghz_capab; -+ params.eht_capab = sta->eht_capab; -+ params.eht_capab_len = sta->eht_capab_len; - params.flags |= WPA_STA_WMM; - params.flags_mask |= WPA_STA_AUTHENTICATED; - if (conf->security == MESH_CONF_SEC_NONE) { -Index: b/wpa_supplicant/wpa_supplicant.c -=================================================================== ---- a/wpa_supplicant/wpa_supplicant.c 2022-07-08 10:12:42.614954957 +0530 -+++ b/wpa_supplicant/wpa_supplicant.c 2022-07-08 10:14:31.153768442 +0530 -@@ -2478,7 +2478,25 @@ static bool ibss_mesh_is_80mhz_avail(int - return true; - } - -+static int ibss_get_center_320mhz(int channel) -+{ -+ int seg0; -+ -+ if (channel >= 1 && channel <= 45) -+ seg0 = 31; -+ else if (channel >= 49 && channel <= 77) -+ seg0 = 63; -+ else if (channel >= 81 && channel <= 109) -+ seg0 = 95; -+ else if (channel >= 113 && channel <= 141) -+ seg0 = 127; -+ else if (channel >= 145 && channel <= 173) -+ seg0 = 159; -+ else -+ seg0 = 191; - -+ return seg0; -+} - void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, - const struct wpa_ssid *ssid, - struct hostapd_freq_params *freq) -@@ -2500,6 +2518,9 @@ void ibss_mesh_setup_freq(struct wpa_sup - 6595, 6655, 6675, 6735, - 6755, 6815, 6835, 6895, - 6915, 6975, 6995, 7055 }; -+ unsigned int bw_320[] = { 5500, 5720, 5955, 6255, 6115, -+ 6415, 6275, 6575, 6435, 6735, -+ 6595, 6895, 6755, 7055}; - struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL; - u8 channel, chan_80mhz; - int i, chan_idx, ht40 = -1, res, obss_scan = 1; -@@ -2736,8 +2757,9 @@ skip_to_6ghz: - if (!vht_freq.vht_enabled && !is_6ghz) - return; - -- /* Enable HE with VHT for 5 GHz */ -+ /* Enable HE, EHT with VHT for 5 GHz */ - vht_freq.he_enabled = mode->he_capab[ieee80211_mode].he_supported; -+ vht_freq.eht_enabled = mode->eht_capab[ieee80211_mode].eht_supported; - - #ifdef CONFIG_HE_OVERRIDES - if (is_24ghz) -@@ -2801,6 +2823,19 @@ skip_to_6ghz: - } - } - -+ if ((ssid->enable_320mhz_bw) && (mode->eht_capab[ieee80211_mode].phy_cap[EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_IDX] & -+ EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK) && is_6ghz) { -+ -+ for (i = 0; i < ARRAY_SIZE(bw_320); i+=2) { -+ if (freq->freq >= bw_320[i] && -+ freq->freq <= bw_320[i+1]) -+ break; -+ } -+ -+ seg0 = ibss_get_center_320mhz(freq->channel); -+ chwidth = CHANWIDTH_320MHZ; -+ } -+ - if (ssid->max_oper_chwidth == CHANWIDTH_80P80MHZ) { - /* setup center_freq2, bandwidth */ - for (k = 0; k < ARRAY_SIZE(bw_80_160); k++) { -@@ -2870,9 +2905,10 @@ skip_to_6ghz: - freq->channel, ssid->enable_edmg, - ssid->edmg_channel, freq->ht_enabled, - vht_freq.vht_enabled, vht_freq.he_enabled, -- 0, freq->sec_channel_offset, -+ vht_freq.eht_enabled, freq->sec_channel_offset, - chwidth, seg0, seg1, vht_caps, -- &mode->he_capab[ieee80211_mode], NULL, -+ &mode->he_capab[ieee80211_mode], -+ &mode->eht_capab[ieee80211_mode], - 0, freq->ru_punct_bitmap, - freq->ru_punct_ofdma) != 0) - return; -Index: b/wpa_supplicant/wpa_supplicant_i.h -=================================================================== ---- a/wpa_supplicant/wpa_supplicant_i.h 2022-07-08 10:12:42.614954957 +0530 -+++ b/wpa_supplicant/wpa_supplicant_i.h 2022-07-08 10:12:42.598955132 +0530 -@@ -1033,6 +1033,7 @@ struct wpa_supplicant { - unsigned int mesh_ht_enabled:1; - unsigned int mesh_vht_enabled:1; - unsigned int mesh_he_enabled:1; -+ unsigned int mesh_eht_enabled:1; - struct wpa_driver_mesh_join_params *mesh_params; - #ifdef CONFIG_PMKSA_CACHE_EXTERNAL - /* struct external_pmksa_cache::list */ -Index: b/hostapd/config_file.c -=================================================================== ---- a/hostapd/config_file.c 2022-07-08 10:12:42.614954957 +0530 -+++ b/hostapd/config_file.c 2022-07-08 10:12:42.598955132 +0530 -@@ -4266,6 +4266,8 @@ static int hostapd_config_fill(struct ho - } else if (os_strcmp(buf, "wowlan_triggers") == 0) { - os_free(bss->wowlan_triggers); - bss->wowlan_triggers = os_strdup(pos); -+ } else if (os_strcmp(buf, "enable_320mhz_bw") == 0) { -+ conf->enable_320mhz_bw = atoi(pos); - } else if (os_strcmp(buf, "enable_160mhz_bw") == 0) { - conf->enable_160mhz_bw = atoi(pos); - } else if (os_strcmp(buf, "disable_40mhz_scan") == 0) { -Index: b/src/ap/ap_config.h -=================================================================== ---- a/src/ap/ap_config.h 2022-07-08 10:12:42.614954957 +0530 -+++ b/src/ap/ap_config.h 2022-07-08 10:12:42.598955132 +0530 -@@ -1152,6 +1152,7 @@ struct hostapd_config { - u16 ru_punct_bitmap; - u8 ru_punct_ofdma; - u8 ru_punct_acs_threshold; -+ int enable_320mhz_bw; - }; - - static inline u8 hostapd_get_he_6ghz_reg_pwr_type(struct hostapd_config *conf) -Index: b/src/drivers/driver.h -=================================================================== ---- a/src/drivers/driver.h 2022-07-08 10:12:42.614954957 +0530 -+++ b/src/drivers/driver.h 2022-07-08 10:12:42.598955132 +0530 -@@ -1287,6 +1287,10 @@ struct wpa_driver_associate_params { - * Enable 160MHz BW - set it 1 to enable mesh 160MHz 6G - */ - int enable_160mhz_bw; -+ /** -+ * Enable 320MHz BW - set it 1 to enable mesh 320MHz 6G -+ */ -+ int enable_320mhz_bw; - }; - - enum hide_ssid { -Index: b/wpa_supplicant/config_file.c -=================================================================== ---- a/wpa_supplicant/config_file.c 2022-07-08 10:12:42.614954957 +0530 -+++ b/wpa_supplicant/config_file.c 2022-07-08 10:12:42.606955044 +0530 -@@ -893,6 +893,7 @@ static void wpa_config_write_network(FIL - INT(disable_40mhz_scan); - INT(beacon_tx_mode); - INT(enable_160mhz_bw); -+ INT(enable_320mhz_bw); - #undef STR - #undef INT - #undef INT_DEF -Index: b/wpa_supplicant/config_ssid.h -=================================================================== ---- a/wpa_supplicant/config_ssid.h 2022-07-08 10:12:42.614954957 +0530 -+++ b/wpa_supplicant/config_ssid.h 2022-07-08 10:12:42.610955000 +0530 -@@ -1223,6 +1223,10 @@ struct wpa_ssid { - * Enable 160MHz BW - set it 1 to enable mesh 160MHz 6G - */ - int enable_160mhz_bw; -+ /** -+ * Enable 320MHz BW - set it 1 to enable mesh 320MHz 6G -+ */ -+ int enable_320mhz_bw; - }; - - #endif /* CONFIG_SSID_H */ -Index: b/src/drivers/driver_nl80211.c -=================================================================== ---- a/src/drivers/driver_nl80211.c 2022-07-08 10:12:42.614954957 +0530 -+++ b/src/drivers/driver_nl80211.c 2022-07-08 10:12:42.610955000 +0530 -@@ -5002,7 +5002,8 @@ static int nl80211_put_freq_params(struc - is_24ghz = hw_mode == HOSTAPD_MODE_IEEE80211G || - hw_mode == HOSTAPD_MODE_IEEE80211B; - -- if (freq->vht_enabled || (freq->he_enabled && !is_24ghz)) { -+ if (freq->vht_enabled || ((freq->he_enabled || freq->eht_enabled) && -+ !is_24ghz)) { - enum nl80211_chan_width cw; - - wpa_printf(MSG_DEBUG, " * bandwidth=%d", freq->bandwidth); diff --git a/feeds/ipq95xx/hostapd/patches/q02-046-hostapd-Add-5GHz-240MHz-support.patch b/feeds/ipq95xx/hostapd/patches/q02-046-hostapd-Add-5GHz-240MHz-support.patch deleted file mode 100644 index 93f4508e..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-046-hostapd-Add-5GHz-240MHz-support.patch +++ /dev/null @@ -1,253 +0,0 @@ -From 5205496c33b432d7621ffff86df6540d6854fff2 Mon Sep 17 00:00:00 2001 -From: Hari Chandrakanthan -Date: Thu, 8 Sep 2022 21:10:01 +0530 -Subject: [PATCH] hostapd: Add 5GHz 240MHz support - -240MHz is supported in 5GHz for single band from channel -100 - 144 with right hand 80MHz puncturing in 320MHz bandwidth. - -EHT phy capability for advertising 320MHz support in 6GHz is -reused for 5GHz as well if 320MHz is configured. EHT opertional -IE is also used to advertise the bandwidth and the center frequency -of the AP. - -Signed-off-by: Karthik M -Signed-off-by: Ramya Gnanasekar -Signed-off-by: Hari Chandrakanthan ---- - src/ap/beacon.c | 8 +++++++- - src/ap/dfs.c | 19 ++++++++++++++++--- - src/ap/hw_features.c | 6 +++++- - src/ap/ieee802_11_eht.c | 10 +++++++--- - src/common/hw_features_common.c | 16 ++++++++++++++++ - src/common/ieee802_11_common.c | 7 +++++++ - src/common/ieee802_11_common.h | 1 + - src/common/ieee802_11_defs.h | 1 + - 8 files changed, 60 insertions(+), 8 deletions(-) - -diff --git a/src/ap/beacon.c b/src/ap/beacon.c -index 9536e76..e03f343 100644 ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -434,18 +434,24 @@ static u8 * hostapd_eid_ecsa(struct hostapd_data *hapd, u8 *eid) - static u8 * hostapd_eid_supported_op_classes(struct hostapd_data *hapd, u8 *eid) - { - u8 op_class, channel; -+ int ch_width; - - if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA) || - !hapd->iface->freq) - return eid; - -+ ch_width = hostapd_get_oper_chwidth(hapd->iconf); - if (ieee80211_freq_to_channel_ext(hapd->iface->freq, - hapd->iconf->secondary_channel, -- hostapd_get_oper_chwidth(hapd->iconf), -+ ch_width, - &op_class, &channel) == - NUM_HOSTAPD_MODES) - return eid; - -+ /*op_class for 5GHz 320MHz bw is not defined in spec. So use op_class of 160MHz*/ -+ if (is_5ghz_freq(hapd->iface->freq) && ch_width == CHANWIDTH_320MHZ) -+ op_class = 129; -+ - *eid++ = WLAN_EID_SUPPORTED_OPERATING_CLASSES; - *eid++ = 2; - -diff --git a/src/ap/dfs.c b/src/ap/dfs.c -index f8de1c2..12e47a7 100644 ---- a/src/ap/dfs.c -+++ b/src/ap/dfs.c -@@ -411,7 +411,8 @@ static int dfs_get_start_chan_idx(struct hostapd_iface *iface, int *seg1_start) - channel_no -= 4; - - /* VHT/HE */ -- if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) { -+ if (iface->conf->ieee80211ac || iface->conf->ieee80211ax || -+ iface->conf->ieee80211be) { - switch (hostapd_get_oper_chwidth(iface->conf)) { - case CHANWIDTH_USE_HT: - break; -@@ -429,6 +430,10 @@ static int dfs_get_start_chan_idx(struct hostapd_iface *iface, int *seg1_start) - chan_seg1 = hostapd_get_oper_centr_freq_seg1_idx( - iface->conf) - 6; - break; -+ case CHANWIDTH_320MHZ: -+ channel_no = hostapd_get_oper_centr_freq_seg0_idx( -+ iface->conf) - 30; -+ break; - default: - wpa_printf(MSG_INFO, - "DFS only VHT20/40/80/160/80+80 is supported now"); -@@ -722,6 +727,10 @@ static int set_dfs_state(struct hostapd_iface *iface, int freq, int ht_enabled, - n_chans = 8; - frequency = cf1 - 70; - break; -+ case CHAN_WIDTH_320: -+ n_chans = 16; -+ frequency = cf1 - 150; -+ break; - default: - wpa_printf(MSG_INFO, "DFS chan_width %d not supported", - chan_width); -@@ -921,13 +930,14 @@ int hostapd_handle_dfs(struct hostapd_iface *iface) - hostapd_set_state(iface, HAPD_IFACE_DFS); - wpa_printf(MSG_DEBUG, "DFS start CAC on %d MHz", iface->freq); - wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_START -- "freq=%d chan=%d sec_chan=%d, width=%d, seg0=%d, seg1=%d, cac_time=%ds", -+ "freq=%d chan=%d sec_chan=%d, width=%d, seg0=%d, seg1=%d, cac_time=%ds bitmap:0x%04x", - iface->freq, - iface->conf->channel, iface->conf->secondary_channel, - hostapd_get_oper_chwidth(iface->conf), - hostapd_get_oper_centr_freq_seg0_idx(iface->conf), - hostapd_get_oper_centr_freq_seg1_idx(iface->conf), -- iface->dfs_cac_ms / 1000); -+ iface->dfs_cac_ms / 1000, -+ iface->conf->ru_punct_bitmap); - - res = hostapd_start_dfs_cac( - iface, iface->conf->hw_mode, iface->freq, iface->conf->channel, -@@ -1552,6 +1562,9 @@ int hostapd_is_dfs_overlap(struct hostapd_iface *iface, enum chan_width width, - case CHAN_WIDTH_160: - half_width = 80; - break; -+ case CHAN_WIDTH_320: -+ half_width = 160; -+ break; - default: - wpa_printf(MSG_WARNING, "DFS chanwidth %d not supported", - width); -diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c -index f66c649..6a7a655 100644 ---- a/src/ap/hw_features.c -+++ b/src/ap/hw_features.c -@@ -929,7 +929,7 @@ static int hostapd_is_usable_edmg(struct hostapd_iface *iface) - static int hostapd_is_usable_ru_punct_bitmap(struct hostapd_iface *iface) - { - struct hostapd_config *conf = iface->conf; -- u8 bw, start_chan; -+ int bw, start_chan; - - if (!conf->ru_punct_bitmap) { - conf->ru_punct_ofdma = 0; -@@ -971,6 +971,10 @@ static int hostapd_is_usable_ru_punct_bitmap(struct hostapd_iface *iface) - bw = 160; - start_chan = conf->eht_oper_centr_freq_seg0_idx - 14; - break; -+ case 9: -+ bw = 320; -+ start_chan = conf->eht_oper_centr_freq_seg0_idx - 30; -+ break; - default: - return 0; - } -diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c -index 8aca0de..f54fee3 100644 ---- a/src/ap/ieee802_11_eht.c -+++ b/src/ap/ieee802_11_eht.c -@@ -74,8 +74,10 @@ static u8 ieee80211_eht_mcs_set_size(const u8 *he_phy_cap, - sz += EHT_PHYCAP_MCS_NSS_LEN_20MHZ_PLUS; - - if (eht_phy_cap[EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_IDX] & -- EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK) -+ EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK) { - sz += EHT_PHYCAP_MCS_NSS_LEN_20MHZ_PLUS; -+ sz += EHT_PHYCAP_MCS_NSS_LEN_160MHZ; -+ } - - return sz; - } -@@ -110,7 +112,7 @@ u8 * hostapd_eid_eht_capab(struct hostapd_data *hapd, u8 *eid, - struct eht_capabilities *eht_cap; - struct ieee80211_eht_capabilities *cap; - size_t mcs_nss_len, ppe_thresh_len; -- u8 *pos = eid, *length_pos; -+ u8 *pos = eid, *length_pos, chwidth; - - mode = hapd->iface->current_mode; - if (!mode) -@@ -128,8 +130,10 @@ u8 * hostapd_eid_eht_capab(struct hostapd_data *hapd, u8 *eid, - os_memset(cap, 0, sizeof(*cap)); - os_memcpy(cap->mac_cap, eht_cap->mac_cap, EHT_MAC_CAPAB_MAX_LEN); - os_memcpy(cap->phy_cap, eht_cap->phy_cap, EHT_PHY_CAPAB_MAX_LEN); -+ chwidth = hapd->iconf->eht_oper_chwidth; - -- if (!is_6ghz_op_class(hapd->iconf->op_class)) -+ if (!is_6ghz_op_class(hapd->iconf->op_class) && -+ (chwidth != CHANWIDTH_320MHZ)) - cap->phy_cap[EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_IDX] &= - ~EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK; - if (!hapd->iface->conf->eht_phy_capab.su_beamformer) -diff --git a/src/common/hw_features_common.c b/src/common/hw_features_common.c -index 0c7607d..3381d8f 100644 ---- a/src/common/hw_features_common.c -+++ b/src/common/hw_features_common.c -@@ -667,6 +667,22 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data, - return -1; - } - break; -+ case CHANWIDTH_320MHZ: -+ data->bandwidth = 320; -+ if (center_segment1) { -+ wpa_printf(MSG_ERROR, -+ "320 MHz: center segment 1 should not be set"); -+ return -1; -+ } -+ if (channel >= 100 && channel <= 144) { -+ center_segment0 = 130; -+ data->center_freq1 = 5650; -+ } else { -+ wpa_printf(MSG_ERROR, -+ "320 MHz: Configured Channel is not supported"); -+ return -1; -+ } -+ break; - } - - return 0; -diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c -index 1e5c641..e68dca6 100644 ---- a/src/common/ieee802_11_common.c -+++ b/src/common/ieee802_11_common.c -@@ -2284,6 +2284,13 @@ int center_idx_to_bw_6ghz(u8 idx) - return -1; - } - -+bool is_5ghz_freq(int freq) -+{ -+ if ((freq >= 5180 && freq < 5600) || -+ (freq >= 5660 && freq < 5825)) -+ return true; -+ return false; -+} - - bool is_6ghz_freq(int freq) - { -diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h -index 48d66d8..e60afb3 100644 ---- a/src/common/ieee802_11_common.h -+++ b/src/common/ieee802_11_common.h -@@ -268,6 +268,7 @@ u8 country_to_global_op_class(const char *country, u8 op_class); - - const struct oper_class_map * get_oper_class(const char *country, u8 op_class); - int oper_class_bw_to_int(const struct oper_class_map *map); -+bool is_5ghz_freq(int freq); - int center_idx_to_bw_6ghz(u8 idx); - bool is_6ghz_freq(int freq); - bool is_6ghz_op_class(u8 op_class); -diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h -index dad1435..766ec1d 100644 ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -2530,6 +2530,7 @@ struct ieee80211_eht_operation { - #define EHT_NSS_MAX_STREAMS 8 - #define EHT_PHYCAP_MCS_NSS_LEN_20MHZ_ONLY 4 - #define EHT_PHYCAP_MCS_NSS_LEN_20MHZ_PLUS 3 -+#define EHT_PHYCAP_MCS_NSS_LEN_160MHZ 3 - - /* IEEE P802.11be/D1.4, May 2021, 9.4.2.295c.5 EHT PPE Thresholds field */ - #define EHT_PPE_THRES_NSS_SHIFT 0 --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-046-hostapd-DFS-ACS-5GHz-240MHz-support.patch b/feeds/ipq95xx/hostapd/patches/q02-046-hostapd-DFS-ACS-5GHz-240MHz-support.patch deleted file mode 100644 index 1ae17856..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-046-hostapd-DFS-ACS-5GHz-240MHz-support.patch +++ /dev/null @@ -1,260 +0,0 @@ -From 19cb10a62d2cd4507cbe28bf36a1522fd8d5870a Mon Sep 17 00:00:00 2001 -From: Karthik M -Date: Fri, 24 Jun 2022 10:28:31 +0530 -Subject: [PATCH] hostapd: Add ACS and DFS support for 5GHz BW240MHZ - -ACS dynamically punctures the channels based on the -noise levels. Incase of 5G 240MHZ bandwidth, we need -to use static punturing bitmap. - -In case of radar, We have only one channel in 240MHz. -The bandwidth should downgrade to 160MHz -and choose a channel. - -Signed-off-by: Karthik M ---- - src/ap/acs.c | 19 +++++++++++++++---- - src/ap/dfs.c | 34 ++++++++++++++++++++++++++++++---- - 2 files changed, 45 insertions(+), 8 deletions(-) - -Index: b/src/ap/acs.c -=================================================================== ---- a/src/ap/acs.c 2022-09-19 10:33:57.084303028 +0530 -+++ b/src/ap/acs.c 2022-09-19 10:33:57.076303097 +0530 -@@ -420,7 +420,7 @@ static int acs_usable_bw160_chan(const s - static int acs_usable_bw320_chan(const struct hostapd_channel_data *chan) - { - /* Allow start of overlapping 320MHz channels */ -- const int allowed[] = { 5955, 6115, 6275, 6435, 6595, 6755 }; -+ const int allowed[] = { 5500, 5955, 6115, 6275, 6435, 6595, 6755 }; - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(allowed); i++) -@@ -657,6 +657,8 @@ static int is_common_24ghz_chan(int chan - #define ACS_24GHZ_PREFER_1_6_11 0.8 - #endif /* ACS_24GHZ_PREFER_1_6_11 */ - -+#define PUNCTURING_PATTERN_5G_320MHZ 0XF000 -+ - static void acs_update_puncturing_bitmap(struct hostapd_iface *iface, - struct hostapd_hw_modes *mode, u32 bw, - int n_chans, -@@ -669,14 +671,32 @@ static void acs_update_puncturing_bitmap - struct hostapd_config *conf = iface->conf; - long double threshold = factor * conf->ru_punct_acs_threshold / 100; - -+ if (is_24ghz_mode(mode->mode) || (bw < 80)) -+ return; -+ -+ /* -+ * 5GHz 320Mhz operates with static punturing bitmap. Overiding the dynammic -+ * bitmap calculation -+ */ -+ -+ if (!is_6ghz_op_class(iface->conf->op_class) && bw == 320) { -+ if ((conf->ru_punct_bitmap & PUNCTURING_PATTERN_5G_320MHZ) == -+ PUNCTURING_PATTERN_5G_320MHZ) { -+ chan->ru_punct_bitmap = conf->ru_punct_bitmap; -+ goto bitmap_selected; -+ } else { -+ wpa_printf(MSG_DEBUG, "ACS : Invalid ru_punct_bitmap for 5G %X", -+ conf->ru_punct_bitmap); -+ return; -+ } -+ } -+ - /* - * If threshold is 0 or user configured puncturing pattern is - * available then don't add additional puncturing. - */ -- if (!conf->ru_punct_acs_threshold || conf->ru_punct_bitmap) -- return; - -- if (is_24ghz_mode(mode->mode) || (bw < 80)) -+ if (!conf->ru_punct_acs_threshold || conf->ru_punct_bitmap) - return; - - for (i = 0; i < n_chans; i++) { -@@ -701,6 +721,11 @@ static void acs_update_puncturing_bitmap - chan->ru_punct_bitmap |= BIT(i); - } - -+bitmap_selected: -+ wpa_printf(MSG_DEBUG, -+ "ACS: Calculated ru_punct_bitmap is %X and ru_punct_ofdma is %X", -+ chan->ru_punct_bitmap,conf->ru_punct_ofdma); -+ - if (!is_ru_punct_bitmap_valid(bw, - (chan->freq - first_chan->freq) / 20, - chan->ru_punct_bitmap, -@@ -919,6 +944,11 @@ acs_find_ideal_chan_mode(struct hostapd_ - factor = chan->interference_factor; - total_weight = 1; - -+ /* 5GHz is supported for 240Mhz and so reducing number of channels*/ -+ if(!is_6ghz_op_class(iface->conf->op_class) && -+ hostapd_get_oper_chwidth(iface->conf) == CHANWIDTH_320MHZ) -+ n_chans = n_chans - 4; -+ - for (j = 1; j < n_chans; j++) { - adj_chan = acs_find_chan(iface, chan->freq + (j * 20)); - if (!adj_chan) -@@ -1018,7 +1048,7 @@ acs_find_ideal_chan_mode(struct hostapd_ - *ideal_factor = factor; - *ideal_chan = chan; - -- if (iface->conf->ieee80211ax) -+ if (iface->conf->ieee80211ax || iface->conf->ieee80211be) - acs_update_puncturing_bitmap(iface, mode, bw, - n_chans, chan, - factor, 0); -@@ -1075,7 +1105,9 @@ acs_find_ideal_chan(struct hostapd_iface - case CHANWIDTH_160MHZ: - n_chans = 8; - break; -- /* 320 is supported only in 6GHz 11be mode */ -+ case CHANWIDTH_320MHZ: -+ n_chans = 16; -+ break; - } - } - -Index: b/src/ap/dfs.c -=================================================================== ---- a/src/ap/dfs.c 2022-09-19 10:33:57.084303028 +0530 -+++ b/src/ap/dfs.c 2022-09-19 10:42:06.192255486 +0530 -@@ -20,7 +20,6 @@ - #include "beacon.h" - #include "eloop.h" - -- - static int dfs_get_used_n_chans(struct hostapd_iface *iface, int *seg1) - { - int n_chans = 1; -@@ -30,7 +29,8 @@ static int dfs_get_used_n_chans(struct h - if (iface->conf->ieee80211n && iface->conf->secondary_channel) - n_chans = 2; - -- if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) { -+ if (iface->conf->ieee80211ac || iface->conf->ieee80211ax || -+ iface->conf->ieee80211be) { - switch (hostapd_get_oper_chwidth(iface->conf)) { - case CHANWIDTH_USE_HT: - break; -@@ -44,6 +44,9 @@ static int dfs_get_used_n_chans(struct h - n_chans = 4; - *seg1 = 4; - break; -+ case CHANWIDTH_320MHZ: -+ n_chans = 12; -+ break; - default: - break; - } -@@ -94,6 +97,12 @@ static int dfs_is_chan_allowed(struct ho - * 50, 114, 163 - */ - int allowed_160[] = { 36, 100, 149 }; -+ /* -+ * EHT320 valid channels based on center frequency: -+ * 100 -+ */ -+ int allowed_320[] = {100}; -+ - int *allowed = allowed_40; - unsigned int i, allowed_no = 0; - -@@ -110,6 +119,10 @@ static int dfs_is_chan_allowed(struct ho - allowed = allowed_160; - allowed_no = ARRAY_SIZE(allowed_160); - break; -+ case 16: -+ allowed = allowed_320; -+ allowed_no = ARRAY_SIZE(allowed_320); -+ break; - default: - wpa_printf(MSG_DEBUG, "Unknown width for %d channels", n_chans); - break; -@@ -337,7 +350,8 @@ static void dfs_adjust_center_freq(struc - u8 *oper_centr_freq_seg0_idx, - u8 *oper_centr_freq_seg1_idx) - { -- if (!iface->conf->ieee80211ac && !iface->conf->ieee80211ax) -+ if (!iface->conf->ieee80211ac && !iface->conf->ieee80211ax && -+ !iface->conf->ieee80211be) - return; - - if (!chan) -@@ -364,6 +378,9 @@ static void dfs_adjust_center_freq(struc - *oper_centr_freq_seg0_idx = chan->chan + 6; - *oper_centr_freq_seg1_idx = sec_chan_idx_80p80 + 6; - break; -+ case CHANWIDTH_320MHZ: -+ *oper_centr_freq_seg0_idx = chan->chan + 30; -+ break; - - default: - wpa_printf(MSG_INFO, -@@ -711,7 +728,7 @@ static int set_dfs_state(struct hostapd_ - frequency = cf1 - 70; - break; - case CHAN_WIDTH_320: -- n_chans = 16; -+ n_chans = 12; - frequency = cf1 - 150; - break; - default: -@@ -775,6 +792,10 @@ static int dfs_are_channels_overlapped(s - radar_n_chans = 8; - frequency = cf1 - 70; - break; -+ case CHAN_WIDTH_320: -+ radar_n_chans = 12; -+ frequency = cf1 - 150; -+ break; - default: - wpa_printf(MSG_INFO, "DFS chan_width %d not supported", - chan_width); -@@ -1021,6 +1042,7 @@ dfs_downgrade_bandwidth(struct hostapd_i - u8 *oper_centr_freq_seg1_idx, int *skip_radar) - { - struct hostapd_channel_data *channel; -+ int oper_chwidth; - - for (;;) { - channel = dfs_get_valid_channel(iface, secondary_channel, -@@ -1036,7 +1058,6 @@ dfs_downgrade_bandwidth(struct hostapd_i - if (*skip_radar) { - *skip_radar = 0; - } else { -- int oper_chwidth; - - oper_chwidth = hostapd_get_oper_chwidth(iface->conf); - if (oper_chwidth == CHANWIDTH_USE_HT) { -@@ -1047,9 +1068,13 @@ dfs_downgrade_bandwidth(struct hostapd_i - iface->conf->secondary_channel = 0; - *skip_radar = 1; - continue; -+ } else if (oper_chwidth == CHANWIDTH_320MHZ) { -+ oper_chwidth = oper_chwidth - 7; -+ } else { -+ oper_chwidth = oper_chwidth - 1; - } - *skip_radar = 1; -- hostapd_set_oper_chwidth(iface->conf, oper_chwidth - 1); -+ hostapd_set_oper_chwidth(iface->conf, oper_chwidth); - } - } - -Index: b/src/common/hw_features_common.c -=================================================================== ---- a/src/common/hw_features_common.c 2022-09-19 10:33:57.084303028 +0530 -+++ b/src/common/hw_features_common.c 2022-09-19 10:33:57.080303063 +0530 -@@ -794,6 +794,7 @@ u32 num_chan_to_bw(int num_chans) - case 2: - case 4: - case 8: -+ case 16: - return num_chans * 20; - default: - return 20; diff --git a/feeds/ipq95xx/hostapd/patches/q02-046-hostapd-add-support-to-disable-channel-switch-during.patch b/feeds/ipq95xx/hostapd/patches/q02-046-hostapd-add-support-to-disable-channel-switch-during.patch deleted file mode 100644 index 7258227b..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-046-hostapd-add-support-to-disable-channel-switch-during.patch +++ /dev/null @@ -1,283 +0,0 @@ -From 00cada639346750210160441c00b5e953aa57d40 Mon Sep 17 00:00:00 2001 -From: Hari Chandrakanthan -Date: Mon, 11 Jul 2022 22:30:27 +0530 -Subject: [PATCH] hostapd : add support to disable channel switch during radar - detection - -A new config disable_csa_dfs is added. -When the above config is enabled, the usual channel switch during -radar detection is skipped. - -Rather hostapd/wpa_supplicant waits for 500ms for the user to do -the manual channel switch using hostapd_cli/wpa_cli. - -If no channel switch or channel set is issued within 500ms, -the interface is disabled. - -sample channel switch that disables the radar handling timer : -wpa_cli -i wlan2 chan_switch 5 5745 center_freq1=5775 sec_channel_offset=1 -bandwidth=80 vht ht he -hostapd_cli -i wlan3 chan_switch 5 5745 center_freq1=5775 sec_channel_offset=1 -bandwidth=80 vht ht he - -sample set channel cmd that disables the radar handling timer: -hostapd_cli -i wlan0 set channel 100 -wpa_cli -i wlan1 set_network 0 frequency 5500 - -Signed-off-by: Hari Chandrakanthan ---- - hostapd/config_file.c | 2 ++ - hostapd/ctrl_iface.c | 14 ++++++++++++++ - hostapd/hostapd.conf | 4 ++++ - src/ap/ap_config.h | 1 + - src/ap/dfs.c | 22 ++++++++++++++++++++-- - src/ap/dfs.h | 4 +++- - wpa_supplicant/ap.c | 12 +++++++++++- - wpa_supplicant/config.c | 2 ++ - wpa_supplicant/config.h | 1 + - wpa_supplicant/ctrl_iface.c | 12 +++++++++++- - wpa_supplicant/mesh.c | 2 ++ - wpa_supplicant/wpa_supplicant.conf | 4 ++++ - 12 files changed, 75 insertions(+), 5 deletions(-) - -diff --git a/hostapd/config_file.c b/hostapd/config_file.c -index 2aae477..2e4440b 100644 ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -4704,6 +4704,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, - return 1; - } - #endif /* CONFIG_IEEE80211BE */ -+ } else if (os_strcmp(buf, "disable_csa_dfs") == 0) { -+ conf->disable_csa_dfs = atoi(pos); - } else { - wpa_printf(MSG_ERROR, - "Line %d: unknown configuration item '%s'", -diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c -index 1060c48..c053bf3 100644 ---- a/hostapd/ctrl_iface.c -+++ b/hostapd/ctrl_iface.c -@@ -1499,6 +1499,13 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd) - } else if (os_strcasecmp(cmd, "setband") == 0) { - ret = hostapd_ctrl_iface_set_band(hapd, value); - } else { -+ if (hapd->iface->conf->disable_csa_dfs && -+ ((os_strcmp(cmd, "channel") == 0) && -+ ((os_strcmp(value, "acs_survey") != 0) && -+ (atoi(value) != 0)))) { -+ eloop_cancel_timeout(hostapd_dfs_radar_handling_timeout, -+ hapd->iface, NULL); -+ } - ret = hostapd_set_iface(hapd->iconf, hapd->conf, cmd, value); - if (ret) - return ret; -@@ -2876,6 +2883,13 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface, - int bandwidth; - u8 chan; - -+ if (iface->conf->disable_csa_dfs == 1) { -+ wpa_printf(MSG_DEBUG, "chanswitch interface %s : cancel radar" -+ " handling timer", iface->conf->bss[0]->iface); -+ eloop_cancel_timeout(hostapd_dfs_radar_handling_timeout, -+ iface, NULL); -+ } -+ - ret = hostapd_parse_csa_settings(pos, &settings); - if (ret) - return ret; -diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf -index e4328d3..944acd5 100644 ---- a/hostapd/hostapd.conf -+++ b/hostapd/hostapd.conf -@@ -229,6 +229,10 @@ channel=1 - # (default 0, i.e., not constraint) - #min_tx_power=20 - -+# disable_csa_dfs option can be used to skip the channel switch in hostapd -+# during radar detection -+#disable_csa_dfs=1 -+ - # Beacon interval in kus (1.024 ms) (default: 100; range 15..65535) - beacon_int=100 - -diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h -index e16b123..e63b11a 100644 ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -1153,6 +1153,7 @@ struct hostapd_config { - u8 ru_punct_ofdma; - u8 ru_punct_acs_threshold; - int enable_320mhz_bw; -+ int disable_csa_dfs; - }; - - static inline u8 hostapd_get_he_6ghz_reg_pwr_type(struct hostapd_config *conf) -diff --git a/src/ap/dfs.c b/src/ap/dfs.c -index 11bdd38..ea65cb4 100644 ---- a/src/ap/dfs.c -+++ b/src/ap/dfs.c -@@ -1105,6 +1105,17 @@ void hostapd_dfs_test_mode_csa_timeout(void *eloop_data, void *user_data) - ieee802_11_set_beacon(hapd); - } - -+void hostapd_dfs_radar_handling_timeout(void *eloop_data, void *user_data) -+{ -+ struct hostapd_iface *iface = eloop_data; -+ -+ wpa_printf(MSG_INFO, "Disabling interface %s since no channel" -+ " switch is initiated within radar handling timeout", -+ iface->conf->bss[0]->iface); -+ -+ hostapd_disable_iface(iface); -+} -+ - static int hostapd_dfs_testmode_set_beacon_csa(struct hostapd_iface *iface) - { - struct hostapd_data *hapd = iface->bss[0]; -@@ -1361,8 +1372,15 @@ int hostapd_dfs_radar_detected(struct hostapd_iface *iface, int freq, - if (!res) - return 0; - -- /* radar detected while operating, switch the channel. */ -- res = hostapd_dfs_start_channel_switch(iface); -+ if (!iface->conf->disable_csa_dfs) { -+ /* radar detected while operating, switch the channel. */ -+ res = hostapd_dfs_start_channel_switch(iface); -+ } else if (!eloop_is_timeout_registered(hostapd_dfs_radar_handling_timeout, -+ iface, NULL)) { -+ eloop_register_timeout(0, HAPD_DFS_RADAR_CH_SWITCH_WAIT_DUR, -+ hostapd_dfs_radar_handling_timeout, -+ iface, NULL); -+ } - - return res; - } -diff --git a/src/ap/dfs.h b/src/ap/dfs.h -index 3a7c3e4..0cd0ced 100644 ---- a/src/ap/dfs.h -+++ b/src/ap/dfs.h -@@ -11,6 +11,8 @@ - - /* CSA beacon duration in seconds for dfs testing mode */ - #define HOSTAPD_DFS_TEST_MODE_CSA_DUR 1 -+/* Wait duration between radar detection and channel switch*/ -+#define HAPD_DFS_RADAR_CH_SWITCH_WAIT_DUR 500000 - - void hostapd_dfs_test_mode_csa_timeout(void *eloop_data, void *user_data); - -@@ -37,5 +39,5 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq, - int hostapd_handle_dfs_offload(struct hostapd_iface *iface); - int hostapd_is_dfs_overlap(struct hostapd_iface *iface, enum chan_width width, - int center_freq); -- -+void hostapd_dfs_radar_handling_timeout(void *eloop_data, void *user_data); - #endif /* DFS_H */ -diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c -index 2b90019..884a0e2 100644 ---- a/wpa_supplicant/ap.c -+++ b/wpa_supplicant/ap.c -@@ -1624,7 +1624,17 @@ int ap_switch_channel(struct wpa_supplicant *wpa_s, - int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos) - { - struct csa_settings settings; -- int ret = hostapd_parse_csa_settings(pos, &settings); -+ int ret; -+ -+ if (wpa_s->ifmsh && wpa_s->ifmsh->conf->disable_csa_dfs == 1) { -+ wpa_printf(MSG_DEBUG, "wpa chanswitch interface %s :" -+ " cancelling radar handling timeout", -+ wpa_s->ifmsh->conf->bss[0]->iface); -+ eloop_cancel_timeout(hostapd_dfs_radar_handling_timeout, -+ wpa_s->ifmsh, NULL); -+ } -+ -+ ret = hostapd_parse_csa_settings(pos, &settings); - - if (ret) - return ret; -diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c -index 502d3d6..dcc3868 100644 ---- a/wpa_supplicant/config.c -+++ b/wpa_supplicant/config.c -@@ -5456,6 +5456,8 @@ static const struct global_parse_data global_fields[] = { - #endif /* CONFIG_PASN */ - { INT_RANGE(he_6ghz_reg_client_type, 1, 2), - CFG_CHANGED_HE_6GHZ_CLIENT_TYPE}, -+ { INT_RANGE(disable_csa_dfs, 0, 1), 0 }, -+ - }; - - #undef FUNC -diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h -index 7479583..89be860 100644 ---- a/wpa_supplicant/config.h -+++ b/wpa_supplicant/config.h -@@ -1710,6 +1710,7 @@ struct wpa_config { - * 2 = SUBORDINATE CLIENT - */ - u8 he_6ghz_reg_client_type; -+ int disable_csa_dfs; - }; - - -diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c -index 1aff200..61aeea7 100644 ---- a/wpa_supplicant/ctrl_iface.c -+++ b/wpa_supplicant/ctrl_iface.c -@@ -60,6 +60,7 @@ - #include "dpp_supplicant.h" - #include "sme.h" - #include "ap/ieee802_11.h" -+#include "ap/dfs.h" - - #ifdef __NetBSD__ - #include -@@ -3628,7 +3629,16 @@ static int wpa_supplicant_ctrl_iface_set_network( - id, name); - wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value", - (u8 *) value, os_strlen(value)); -- -+#ifdef NEED_AP_MLME -+ if ((os_strcmp(name, "frequency") == 0) && -+ (wpa_s->ifmsh && wpa_s->ifmsh->conf->disable_csa_dfs == 1)) { -+ wpa_printf(MSG_DEBUG, "wpa interface %s :" -+ " cancelling radar handling timeout", -+ wpa_s->ifmsh->conf->bss[0]->iface); -+ eloop_cancel_timeout(hostapd_dfs_radar_handling_timeout, -+ wpa_s->ifmsh, NULL); -+ } -+#endif - ssid = wpa_config_get_network(wpa_s->conf, id); - if (ssid == NULL) { - wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " -diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c -index 0372c08..948f365 100644 ---- a/wpa_supplicant/mesh.c -+++ b/wpa_supplicant/mesh.c -@@ -554,6 +554,8 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, - conf->basic_rates[rate_len] = -1; - } - -+ ifmsh->conf->disable_csa_dfs = wpa_s->conf->disable_csa_dfs; -+ - /* While it can enhance performance to switch the primary channel, which - * is also the secondary channel of another network at the same time), - * to the other primary channel, problems exist with this in mesh -diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf -index 162e81d..29a0fe1 100644 ---- a/wpa_supplicant/wpa_supplicant.conf -+++ b/wpa_supplicant/wpa_supplicant.conf -@@ -1704,6 +1704,10 @@ fast_reauth=1 - #Set 1 to enable 160MHz in Mesh mode - #enable_160mhz_bw=1 - -+# disable_csa_dfs option can be used to skip the channel switch in wpa_supplicant -+# during radar detection -+#disable_csa_dfs=1 -+ - # Example blocks: - - # Simple case: WPA-PSK, PSK as an ASCII passphrase, allow all valid ciphers --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-046-wpa_supplicant-add-RU-puncturing-support.patch b/feeds/ipq95xx/hostapd/patches/q02-046-wpa_supplicant-add-RU-puncturing-support.patch deleted file mode 100644 index ff3dd08d..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-046-wpa_supplicant-add-RU-puncturing-support.patch +++ /dev/null @@ -1,333 +0,0 @@ -From 340c9ab10eabb7a962f16cbb0a3abd492942ef57 Mon Sep 17 00:00:00 2001 -From: Rameshkumar Sundaram -Date: Wed, 25 May 2022 11:32:01 +0530 -Subject: [PATCH] wpa_supplicant: add RU puncturing support - -Retrieve the driver support for RU puncturing which is advertised -using the attribute NL80211_ATTR_RU_PUNCT_SUPP_BW. -Value indicates the bandwidths in which puncturing is supported - -80 MHz, 160 MHz or 320 MHz. -Absence of the attribute or the value 0 means the driver does not -support this feature. - -Add New option 'ru_punct_bitmap' to configure RU puncturing bitmap -and pass the configured bitmap to kernel via frequency params -during join mesh if driver supports puncturing pattern for configured -Bandwidth. -Kernel will validate the pattern against spec allowed patterns -(IEEE P802.11be/D1.5, Table 36-30) - -Parse EHT Operational IE of received mesh beacons and validate & -and send Peer mesh node's RU puncturing pattern as part of station -add command (NL80211_CMD_NEW_STATION). - -Signed-off-by: Rameshkumar Sundaram ---- - src/ap/hw_features.c | 9 +++++++++ - src/drivers/driver.h | 7 +++++++ - src/drivers/driver_nl80211.c | 6 ++++++ - wpa_supplicant/ap.c | 5 +++-- - wpa_supplicant/config.c | 2 ++ - wpa_supplicant/config_file.c | 1 + - wpa_supplicant/config_ssid.h | 6 ++++++ - wpa_supplicant/mesh.c | 4 ++++ - wpa_supplicant/mesh_mpm.c | 41 ++++++++++++++++++++++++++++++++++++++ - wpa_supplicant/wpa_supplicant.c | 26 ++++++++++++++++++++++-- - wpa_supplicant/wpa_supplicant.conf | 7 +++++++ - wpa_supplicant/wpa_supplicant_i.h | 2 ++ - 12 files changed, 112 insertions(+), 4 deletions(-) - -diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c -index 1dcd0d0..f66c649 100644 ---- a/src/ap/hw_features.c -+++ b/src/ap/hw_features.c -@@ -949,6 +949,15 @@ static int hostapd_is_usable_ru_punct_bitmap(struct hostapd_iface *iface) - return 0; - } - -+#ifdef CONFIG_MESH -+ if (iface->mconf != NULL) { -+ wpa_printf(MSG_DEBUG, -+ "%s: Mesh RU bitmap will be validated in kernel while joining the mesh network", -+ iface->bss[0]->conf->iface); -+ return 1; -+ } -+#endif -+ - switch (conf->eht_oper_chwidth) { - case 0: - wpa_printf(MSG_ERROR, -diff --git a/src/drivers/driver.h b/src/drivers/driver.h -index 038379b..3c73e68 100644 ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -1291,6 +1291,12 @@ struct wpa_driver_associate_params { - * Enable 320MHz BW - set it 1 to enable mesh 320MHz 6G - */ - int enable_320mhz_bw; -+ -+ /** -+ * RU puncturing bitmap - Each bit corresponds to a 20 MHz subchannel, -+ * lowest bit for the channel with the lowest frequency. -+ * Bit set to 1 indicates that the subchannel is punctured, otherwise active.*/ -+ u16 ru_punct_bitmap; - }; - - enum hide_ssid { -@@ -2381,6 +2387,7 @@ struct hostapd_sta_add_params { - const u8 *supp_oper_classes; - size_t supp_oper_classes_len; - int support_p2p_ps; -+ u16 ru_punct_bitmap; - }; - - struct mac_address { -diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c -index a89097d..44b4330 100644 ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -5419,6 +5419,12 @@ static int wpa_driver_nl80211_sta_add(void *priv, - nla_nest_end(msg, wme); - } - -+ if (params->ru_punct_bitmap) { -+ wpa_printf(MSG_DEBUG, " * eht ru puncturing bitmap=0x%x", params->ru_punct_bitmap); -+ if (nla_put_u16(msg, NL80211_ATTR_RU_PUNCT_BITMAP, params->ru_punct_bitmap)) -+ goto fail; -+ } -+ - ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL); - msg = NULL; - if (ret) -diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c -index 30f33c4..2c55e95 100644 ---- a/wpa_supplicant/ap.c -+++ b/wpa_supplicant/ap.c -@@ -417,9 +417,10 @@ int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s, - conf->ieee80211ax = 1; - if (mode->eht_capab[wpas_mode_to_ieee80211_mode( - ssid->mode)].eht_supported && -- ssid->eht) -+ ssid->eht) { - conf->ieee80211be = 1; -- -+ conf->ru_punct_bitmap = ssid->ru_punct_bitmap; -+ } - if (mode->vht_capab && ssid->vht) { - conf->ieee80211ac = 1; - conf->vht_capab |= mode->vht_capab; -diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c -index 502d3d6..f8945ee 100644 ---- a/wpa_supplicant/config.c -+++ b/wpa_supplicant/config.c -@@ -2813,6 +2813,7 @@ static const struct parse_data ssid_fields[] = { - { INT_RANGE(beacon_tx_mode, 1, 2)}, - { INT_RANGE(enable_160mhz_bw, 0, 1)}, - { INT_RANGE(enable_320mhz_bw, 0, 1)}, -+ { INT(ru_punct_bitmap) }, - }; - - #undef OFFSET -@@ -3330,6 +3331,7 @@ void wpa_config_set_network_defaults(struct wpa_ssid *ssid) - ssid->mac_addr = -1; - ssid->max_oper_chwidth = DEFAULT_MAX_OPER_CHWIDTH; - ssid->beacon_tx_mode = DEFAULT_BEACON_TX_MODE; -+ ssid->ru_punct_bitmap = 0; - } - - -diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c -index f47973b..f8a519b 100644 ---- a/wpa_supplicant/config_file.c -+++ b/wpa_supplicant/config_file.c -@@ -894,6 +894,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) - INT(beacon_tx_mode); - INT(enable_160mhz_bw); - INT(enable_320mhz_bw); -+ INT(ru_punct_bitmap); - #undef STR - #undef INT - #undef INT_DEF -diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h -index 1704e0d..fdd40f9 100644 ---- a/wpa_supplicant/config_ssid.h -+++ b/wpa_supplicant/config_ssid.h -@@ -1227,6 +1227,12 @@ struct wpa_ssid { - * Enable 320MHz BW - set it 1 to enable mesh 320MHz 6G - */ - int enable_320mhz_bw; -+ -+ /** -+ * RU puncturing bitmap - Each bit corresponds to a 20 MHz subchannel, -+ * lowest bit for the channel with the lowest frequency. -+ * Bit set to 1 indicates that the subchannel is punctured, otherwise active.*/ -+ u16 ru_punct_bitmap; - }; - - #endif /* CONFIG_SSID_H */ -diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c -index 0372c08..231065d 100644 ---- a/wpa_supplicant/mesh.c -+++ b/wpa_supplicant/mesh.c -@@ -411,6 +411,7 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, - ifmsh->num_bss = 1; - ifmsh->enable_iface_cb = wpa_supplicant_mesh_enable_iface_cb; - ifmsh->disable_iface_cb = wpa_supplicant_mesh_disable_iface_cb; -+ ifmsh->ru_punct_supp_bw = wpa_s->ru_punct_supp_bw; - ifmsh->bss = os_calloc(wpa_s->ifmsh->num_bss, - sizeof(struct hostapd_data *)); - if (!ifmsh->bss) -@@ -493,6 +494,9 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, - wpa_s->mesh_params->handle_dfs = true; - } - -+ if (ssid->eht) -+ conf->ru_punct_bitmap = freq->ru_punct_bitmap; -+ - bss->iconf = conf; - ifmsh->conf = conf; - -diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c -index d69af3f..8899434 100644 ---- a/wpa_supplicant/mesh_mpm.c -+++ b/wpa_supplicant/mesh_mpm.c -@@ -728,6 +728,7 @@ static struct sta_info * mesh_mpm_add_peer(struct wpa_supplicant *wpa_s, - struct hostapd_data *data = wpa_s->ifmsh->bss[0]; - struct sta_info *sta; - struct ieee80211_ht_operation *oper; -+ struct ieee80211_eht_operation *eht_oper_ie; - int ret; - - if (elems->mesh_config_len >= 7 && -@@ -811,6 +812,46 @@ static struct sta_info * mesh_mpm_add_peer(struct wpa_supplicant *wpa_s, - params.he_6ghz_capab = sta->he_6ghz_capab; - params.eht_capab = sta->eht_capab; - params.eht_capab_len = sta->eht_capab_len; -+#ifdef CONFIG_IEEE80211BE -+ if (elems->eht_operation && elems->eht_operation_len >= sizeof(*eht_oper_ie)) { -+ u16 bw = 0; -+ u16 start_chan = 0; -+ u16 pri_chan = wpa_s->ifmsh->conf->channel; -+ -+ eht_oper_ie = (struct ieee80211_eht_operation *)elems->eht_operation; -+ if (eht_oper_ie->width >= EHT_OPERATION_CHANNEL_WIDTH_80MHZ && -+ eht_oper_ie->disable_sub_chan_bitmap_present && -+ eht_oper_ie->disabled_subchannel_bitmap) { -+ params.ru_punct_bitmap = eht_oper_ie->disabled_subchannel_bitmap; -+ /* Validate Peer's puncture bitmap and reset if invalid */ -+ switch (eht_oper_ie->width) { -+ case EHT_OPERATION_CHANNEL_WIDTH_80MHZ: -+ bw = 80; -+ start_chan = eht_oper_ie->ccfs - 6; -+ if (!is_ru_punct_bitmap_valid(bw, (pri_chan - start_chan) / 4, -+ params.ru_punct_bitmap, 0)) -+ params.ru_punct_bitmap = 0; -+ break; -+ case EHT_OPERATION_CHANNEL_WIDTH_160MHZ: -+ bw = 160; -+ start_chan = eht_oper_ie->ccfs - 14; -+ if (!is_ru_punct_bitmap_valid(bw, (pri_chan - start_chan) / 4, -+ params.ru_punct_bitmap, 0)) -+ params.ru_punct_bitmap = 0; -+ break; -+ case EHT_OPERATION_CHANNEL_WIDTH_320MHZ: -+ bw = 320; -+ start_chan = eht_oper_ie->ccfs - 30; -+ if (!is_ru_punct_bitmap_valid(bw, (pri_chan - start_chan) / 4, -+ params.ru_punct_bitmap, 0)) -+ params.ru_punct_bitmap = 0; -+ break; -+ default: -+ params.ru_punct_bitmap = 0; -+ } -+ } -+ } -+#endif /* CONFIG_IEEE80211BE */ - params.flags |= WPA_STA_WMM; - params.flags_mask |= WPA_STA_AUTHENTICATED; - if (conf->security == MESH_CONF_SEC_NONE) { -diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c -index 226b1c9..e030f79 100644 ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -2904,6 +2904,27 @@ skip_to_6ghz: - freq->eht_enabled = 0; - } - #endif /* CONFIG_EHT_OVERRIDES */ -+ freq->ru_punct_bitmap = ssid->ru_punct_bitmap; -+ freq->ru_punct_ofdma = 0; /* Default to disabled for mesh. */ -+ -+ if (ssid->ru_punct_bitmap && wpa_s->drv_capa_known) { -+ switch (chwidth) { -+ case CHANWIDTH_320MHZ: -+ break; -+ case CHANWIDTH_160MHZ: -+ if (wpa_s->ru_punct_supp_bw == CHANWIDTH_320MHZ) -+ freq->ru_punct_bitmap = 0; -+ break; -+ case CHANWIDTH_80MHZ: -+ if ((wpa_s->ru_punct_supp_bw == CHANWIDTH_160MHZ) || -+ (wpa_s->ru_punct_supp_bw == CHANWIDTH_320MHZ)) -+ freq->ru_punct_bitmap = 0; -+ break; -+ default: -+ freq->ru_punct_bitmap = 0; -+ } -+ } -+ - if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq, - freq->channel, ssid->enable_edmg, - ssid->edmg_channel, freq->ht_enabled, -@@ -2918,8 +2939,8 @@ skip_to_6ghz: - - *freq = vht_freq; - -- wpa_printf(MSG_DEBUG, "IBSS: VHT setup freq cf1 %d, cf2 %d, bw %d", -- freq->center_freq1, freq->center_freq2, freq->bandwidth); -+ wpa_printf(MSG_DEBUG, "IBSS: VHT setup freq cf1 %d, cf2 %d, bw %d ru_punct_bitmap 0x%x", -+ freq->center_freq1, freq->center_freq2, freq->bandwidth, freq->ru_punct_bitmap); - } - - -@@ -6913,6 +6934,7 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s, - wpa_s->num_multichan_concurrent = - capa.num_multichan_concurrent; - wpa_s->wmm_ac_supported = capa.wmm_ac_supported; -+ wpa_s->ru_punct_supp_bw = capa.ru_punct_supp_bw; - - if (capa.mac_addr_rand_scan_supported) - wpa_s->mac_addr_rand_supported |= MAC_ADDR_RAND_SCAN; -diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf -index 162e81d..325a19d 100644 ---- a/wpa_supplicant/wpa_supplicant.conf -+++ b/wpa_supplicant/wpa_supplicant.conf -@@ -1704,6 +1704,13 @@ fast_reauth=1 - #Set 1 to enable 160MHz in Mesh mode - #enable_160mhz_bw=1 - -+# RU puncturing bitmap (16 bits) where each bit corresponds to -+# a 20 MHz channel in the given bandwidth, bit 0 corresponding to the channel -+# with lowest frequency. -+# Bit set to 1 indicates that the channel is punctured, otherwise active. -+# Default value is 0 indicating that no channel is punctured. -+#ru_punct_bitmap=4 -+ - # Example blocks: - - # Simple case: WPA-PSK, PSK as an ASCII passphrase, allow all valid ciphers -diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h -index 7888c3f..f642c68 100644 ---- a/wpa_supplicant/wpa_supplicant_i.h -+++ b/wpa_supplicant/wpa_supplicant_i.h -@@ -1521,6 +1521,8 @@ struct wpa_supplicant { - unsigned int enable_dscp_policy_capa:1; - unsigned int connection_dscp:1; - unsigned int wait_for_dscp_req:1; -+ /* Minimum bandwidth the driver supports RU puncturing */ -+ u8 ru_punct_supp_bw; - }; - - --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-047-hostapd-Fix-tx-power-envelope-for-non-PSD-countries.patch b/feeds/ipq95xx/hostapd/patches/q02-047-hostapd-Fix-tx-power-envelope-for-non-PSD-countries.patch deleted file mode 100644 index 73d51b50..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-047-hostapd-Fix-tx-power-envelope-for-non-PSD-countries.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 11873ac90db3f8c73088a1d7b4bd44509b832348 Mon Sep 17 00:00:00 2001 -From: Ramya Gnanasekar -Date: Fri, 21 Oct 2022 19:20:46 +0530 -Subject: [PATCH] hostapd: Fix tx power envelope for non PSD countries - -TX power envelope will contain PSD value for countries. -In case of non PSD countries, it is expected to carry -max EIRP for the channel received from FW through reg -rules. -Updated the power value in IE with max EIRP power for -other non PSD countries - -Signed-off-by: Ramya Gnanasekar - -diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c -index b7c55ca..2563a26 100644 ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -7084,6 +7084,7 @@ u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid) - if (i == mode->num_channels) - return eid; - -+ chan = &mode->channels[i]; - /* For now, 6GHz has only support for Indoor AP type - * From IEEE P802.11ax/D7.0: An AP that is an - * Indoor Access Point per regulatory rules shall send at least -@@ -7105,9 +7106,12 @@ u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid) - */ - if (ap_type == AP_TYPE_6GHZ_INDOOR_AP) { - tx_pwr_cat = REG_SUBORDINATE_CLIENT; -- psd = mode->psd_values[NL80211_REG_SUBORDINATE_CLIENT_LPI + ap_type]; -+ psd = mode->psd_values[NL80211_REG_AP_LPI + ap_type]; - #ifdef REG_DOM_SUPPORT_TX_POWER -- tx_pwr = psd * 2; -+ if (psd) -+ tx_pwr = psd * 2; -+ else -+ tx_pwr = chan->max_tx_power; - #else - tx_pwr = (hostapd_get_6g_tx_power(hapd, ap_type, tx_pwr_cat) * 2); - #endif /* REG_DOM_SUPPORT_TX_POWER */ -@@ -7119,7 +7123,10 @@ u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid) - tx_pwr_cat = REG_DEFAULT_CLIENT; - psd = mode->psd_values[NL80211_REG_REGULAR_CLIENT_LPI + ap_type]; - #ifdef REG_DOM_SUPPORT_TX_POWER -- tx_pwr = psd * 2; -+ if (psd) -+ tx_pwr = psd * 2; -+ else -+ tx_pwr = chan->max_tx_power; - #else - tx_pwr = (hostapd_get_6g_tx_power(hapd, ap_type, tx_pwr_cat) * 2); - #endif /* REG_DOM_SUPPORT_TX_POWER */ -@@ -7181,7 +7188,6 @@ u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid) - * channel in Country element and local pwr constraint is specified - * for channel in this Power Constraint element. - */ -- chan = &mode->channels[i]; - max_tx_power = chan->max_tx_power - local_pwr_constraint; - - /* --- -2.17.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-047-wpa_supplicant-Add-5GHz-240MHz-support-for-mesh.patch b/feeds/ipq95xx/hostapd/patches/q02-047-wpa_supplicant-Add-5GHz-240MHz-support-for-mesh.patch deleted file mode 100644 index 5f6503d1..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-047-wpa_supplicant-Add-5GHz-240MHz-support-for-mesh.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 3951d8e0aa5100b8cc7c94f39a67d743f69f2a8b Mon Sep 17 00:00:00 2001 -From: Rameshkumar Sundaram -Date: Wed, 15 Jun 2022 08:29:43 +0530 -Subject: [PATCH] wpa_supplicant: Add 5GHz 240MHz support for mesh - -240MHz can be supported in 5 GHz for from channel -#100 - 144 with right hand 80MHz punctured in 320MHz bandwidth. -Add support to bring up mesh in 5 GHz 320MHz (240+80 Punctrued). -When 320MHz is configured for channel 100-144, static puncturing -pattern bits for higher 80MHz should be set (i.e. pattern & 0xF000) -should result in 0xF000). -EHT phy capability for advertising 320MHz support in 6GHz is reused -for 5GHz as well if 320MHz is configured. -Add the missing 80MHz channels to bw_80_160 array of -ibss_mesh_setup_freq(). - -Signed-off-by: Rameshkumar Sundaram ---- - src/common/ieee802_11_common.c | 3 ++- - wpa_supplicant/ap.c | 5 ++-- - wpa_supplicant/wpa_supplicant.c | 51 ++++++++++++++++++++++++++++------------- - 3 files changed, 40 insertions(+), 19 deletions(-) - -Index: b/src/common/ieee802_11_common.c -=================================================================== ---- a/src/common/ieee802_11_common.c 2022-07-14 14:31:03.057966186 +0530 -+++ b/src/common/ieee802_11_common.c 2022-07-14 14:31:03.049966278 +0530 -@@ -1028,7 +1028,8 @@ enum hostapd_hw_mode ieee80211_freq_to_c - if ((freq - 5000) % 5) - return NUM_HOSTAPD_MODES; - -- if (vht_opclass) -+ /* There is no op class defined for 5 GHz 320MHz, let it be unset */ -+ if (vht_opclass || chanwidth == CHANWIDTH_320MHZ) - *op_class = vht_opclass; - else if (sec_channel == 1) - *op_class = 122; -Index: b/wpa_supplicant/ap.c -=================================================================== ---- a/wpa_supplicant/ap.c 2022-07-14 14:31:03.057966186 +0530 -+++ b/wpa_supplicant/ap.c 2022-07-14 14:31:03.049966278 +0530 -@@ -105,9 +105,10 @@ static void wpas_conf_ap_vht(struct wpa_ - hostapd_set_oper_centr_freq_seg0_idx(conf, freq_seg_idx); - - wpa_printf(MSG_DEBUG, -- "VHT seg0 index %d and seg1 index %d for AP", -+ "VHT seg0 index %d and seg1 index %d BW %d for AP", - hostapd_get_oper_centr_freq_seg0_idx(conf), -- hostapd_get_oper_centr_freq_seg1_idx(conf)); -+ hostapd_get_oper_centr_freq_seg1_idx(conf), -+ hostapd_get_oper_chwidth(conf)); - return; - } - -Index: b/wpa_supplicant/wpa_supplicant.c -=================================================================== ---- a/wpa_supplicant/wpa_supplicant.c 2022-07-14 14:31:03.057966186 +0530 -+++ b/wpa_supplicant/wpa_supplicant.c 2022-07-14 14:33:12.080479343 +0530 -@@ -2509,7 +2509,9 @@ void ibss_mesh_setup_freq(struct wpa_sup - /* bw_80_160 array members are 80MHz start freq, 80MHz end freq and so on - */ - unsigned int bw_80_160[] = { 5180, 5240, 5260, 5320, -- 5500, 5560, 5580, 5660, -+ 5500, 5560, 5580, 5640, -+ 5660, 5720, 0, 0, -+ /* Adding dummy sec80 after channel #144 to keep remining 160MHz array intact */ - 5745, 5805, 5825, 5885, - 5955, 6015, 6035, 6095, - 6115, 6175, 6195, 6255, -@@ -2824,16 +2826,33 @@ skip_to_6ghz: - } - - if ((ssid->enable_320mhz_bw) && (mode->eht_capab[ieee80211_mode].phy_cap[EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_IDX] & -- EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK) && is_6ghz) { -- -- for (i = 0; i < ARRAY_SIZE(bw_320); i+=2) { -- if (freq->freq >= bw_320[i] && -- freq->freq <= bw_320[i+1]) -- break; -+ EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK)) { -+ if (is_6ghz) { -+ for (i = 0; i < ARRAY_SIZE(bw_320); i+=2) { -+ if (freq->freq >= bw_320[i] && -+ freq->freq <= bw_320[i+1]) -+ break; -+ } -+ -+ seg0 = ibss_get_center_320mhz(freq->channel); -+ chwidth = CHANWIDTH_320MHZ; -+ } else { -+ /* There is only one 320MHz(240+80 Punctured) in 5 GHz Band */ -+ u8 start_chan_idx = 100; -+ if (freq->channel >= 100 && freq->channel <= 144 && (ssid->ru_punct_bitmap & 0xF000) == 0xF000) { -+ for (i = start_chan_idx; i <= start_chan_idx + 44; i += 4) { -+ struct hostapd_channel_data *chan; -+ chan = hw_get_channel_chan(mode, i, NULL); -+ if (!chan) -+ return; -+ if (chan->flag & (HOSTAPD_CHAN_DISABLED| -+ HOSTAPD_CHAN_NO_IR)) -+ return; -+ } -+ seg0 = 130; -+ chwidth = CHANWIDTH_320MHZ; -+ } - } -- -- seg0 = ibss_get_center_320mhz(freq->channel); -- chwidth = CHANWIDTH_320MHZ; - } - - if (ssid->max_oper_chwidth == CHANWIDTH_80P80MHZ) { diff --git a/feeds/ipq95xx/hostapd/patches/q02-048-hostapd-Update-11be-EHT-elements-to-Draft-2.0-versio.patch b/feeds/ipq95xx/hostapd/patches/q02-048-hostapd-Update-11be-EHT-elements-to-Draft-2.0-versio.patch deleted file mode 100644 index 56f1fcb2..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-048-hostapd-Update-11be-EHT-elements-to-Draft-2.0-versio.patch +++ /dev/null @@ -1,289 +0,0 @@ -From 7377742385c93887bc125cecc21204387112517d Mon Sep 17 00:00:00 2001 -From: Balamurugan Mahalingam -Date: Tue, 16 Aug 2022 17:53:38 -0700 -Subject: [PATCH] hostapd: Update 11be EHT elements to Draft 2.0 version - -Update the EHT operations elements to Draft 2.0 and fix interop -issues with stations - -Signed-off-by: Balamurugan Mahalingam ---- - hostapd/config_file.c | 2 ++ - src/ap/ap_config.h | 9 +++++++++ - src/ap/beacon.c | 5 +++++ - src/ap/ctrl_iface_ap.c | 6 ++++-- - src/ap/ieee802_11.c | 2 ++ - src/ap/ieee802_11_eht.c | 34 ++++++++++++++++++++++++++++------ - src/common/ieee802_11_defs.h | 35 +++++++++++++++++++++++------------ - wpa_supplicant/mesh_mpm.c | 10 +++++----- - 8 files changed, 78 insertions(+), 25 deletions(-) - -diff --git a/hostapd/config_file.c b/hostapd/config_file.c -index 501d30c..d896d67 100644 ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -4689,6 +4689,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, - conf->eht_oper_chwidth = atoi(pos); - } else if (os_strcmp(buf, "eht_oper_centr_freq_seg0_idx") == 0) { - conf->eht_oper_centr_freq_seg0_idx = atoi(pos); -+ } else if (os_strcmp(buf, "eht_oper_centr_freq_seg1_idx") == 0) { -+ conf->eht_oper_centr_freq_seg1_idx = atoi(pos); - } else if (os_strcmp(buf, "eht_su_beamformer") == 0) { - conf->eht_phy_capab.su_beamformer = atoi(pos); - } else if (os_strcmp(buf, "eht_su_beamformee") == 0) { -diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h -index f6d1d56..83ba76c 100644 ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -1144,6 +1144,7 @@ struct hostapd_config { - #ifdef CONFIG_IEEE80211BE - u8 eht_oper_chwidth; - u8 eht_oper_centr_freq_seg0_idx; -+ u8 eht_oper_centr_freq_seg1_idx; - struct eht_phy_capabilities_info eht_phy_capab; - #endif /* CONFIG_IEEE80211BE */ - -@@ -1227,6 +1228,10 @@ hostapd_set_oper_centr_freq_seg0_idx(struct hostapd_config *conf, - static inline u8 - hostapd_get_oper_centr_freq_seg1_idx(struct hostapd_config *conf) - { -+#ifdef CONFIG_IEEE80211BE -+ if (conf->ieee80211be) -+ return conf->eht_oper_centr_freq_seg1_idx; -+#endif /* CONFIG_IEEE80211BE */ - #ifdef CONFIG_IEEE80211AX - if (conf->ieee80211ax) - return conf->he_oper_centr_freq_seg1_idx; -@@ -1238,6 +1243,10 @@ static inline void - hostapd_set_oper_centr_freq_seg1_idx(struct hostapd_config *conf, - u8 oper_centr_freq_seg1_idx) - { -+#ifdef CONFIG_IEEE80211BE -+ if (conf->ieee80211be) -+ conf->eht_oper_centr_freq_seg1_idx = oper_centr_freq_seg1_idx; -+#endif /* CONFIG_IEEE80211BE */ - #ifdef CONFIG_IEEE80211AX - if (conf->ieee80211ax) - conf->he_oper_centr_freq_seg1_idx = oper_centr_freq_seg1_idx; -diff --git a/src/ap/beacon.c b/src/ap/beacon.c -index 023729c..9536e76 100644 ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -643,6 +643,9 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, - if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { - buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP); - buflen += (3 + sizeof(struct ieee80211_eht_operation)); -+ if (hapd->iconf->ru_punct_bitmap) -+ buflen += DISABLED_SUBCHANNEL_BITMAP_BYTES_SIZE; -+ - } - #endif /* CONFIG_IEEE80211BE */ - -@@ -1759,6 +1762,8 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, - if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { - tail_len += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP); - tail_len += (3 + sizeof(struct ieee80211_eht_operation)); -+ if (hapd->iconf->ru_punct_bitmap) -+ tail_len += DISABLED_SUBCHANNEL_BITMAP_BYTES_SIZE; - } - #endif /* CONFIG_IEEE80211BE */ - -diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c -index 62db273..b697ad2 100644 ---- a/src/ap/ctrl_iface_ap.c -+++ b/src/ap/ctrl_iface_ap.c -@@ -1065,9 +1065,11 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf, - if (iface->conf->ieee80211be && !hapd->conf->disable_11be) { - ret = os_snprintf(buf + len, buflen - len, - "eht_oper_chwidth=%d\n" -- "eht_oper_centr_freq_seg0_idx=%d\n", -+ "eht_oper_centr_freq_seg0_idx=%d\n" -+ "eht_oper_centr_freq_seg1_idx=%d\n", - iface->conf->eht_oper_chwidth, -- iface->conf->eht_oper_centr_freq_seg0_idx); -+ iface->conf->eht_oper_centr_freq_seg0_idx, -+ iface->conf->eht_oper_centr_freq_seg1_idx); - if (os_snprintf_error(buflen - len, ret)) - return len; - len += ret; -diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c -index b4efc17..8a6fed8 100644 ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -5106,6 +5106,8 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta, - if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { - buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP); - buflen += (3 + sizeof(struct ieee80211_eht_operation)); -+ if (hapd->iconf->ru_punct_bitmap) -+ buflen += DISABLED_SUBCHANNEL_BITMAP_BYTES_SIZE; - } - #endif /* CONFIG_IEEE80211BE */ - -diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c -index c7586ec..f54fee3 100644 ---- a/src/ap/ieee802_11_eht.c -+++ b/src/ap/ieee802_11_eht.c -@@ -174,6 +174,7 @@ u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid, - { - struct hostapd_hw_modes *mode; - struct ieee80211_eht_operation *oper; -+ struct eht_capabilities *eht_cap; - u8 *pos = eid, oper_size = 0, chwidth; - - mode = hapd->iface->current_mode; -@@ -185,15 +186,26 @@ u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid, - - oper_size = sizeof(struct ieee80211_eht_operation); - *pos++ = WLAN_EID_EXTENSION; -- *pos++ = 1 + oper_size; -+ -+ if (hapd->iconf->ru_punct_bitmap) -+ *pos++ = 1 + oper_size + DISABLED_SUBCHANNEL_BITMAP_BYTES_SIZE; -+ else -+ *pos++ = 1 + oper_size; -+ - *pos++ = WLAN_EID_EXT_EHT_OPERATION; - - oper = (struct ieee80211_eht_operation *) pos; - os_memset(oper, 0, sizeof(*oper)); - -- oper->ccfs = hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf); -- if (!oper->ccfs) -- oper->ccfs = hapd->iconf->channel; -+ eht_cap = &mode->eht_capab[opmode]; -+ oper->ehtop_params |= EHTOP_PARAMS_EHTOP_INFORMATION_PRESENT; -+ oper->ccfs0 = hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf); -+ oper->ccfs1 = hostapd_get_oper_centr_freq_seg1_idx(hapd->iconf); -+ memcpy(&oper->mcs_nss_supported, &eht_cap->mcs, -+ EHT_PHYCAP_MCS_NSS_LEN_20MHZ_ONLY); -+ -+ if (!oper->ccfs0) -+ oper->ccfs0 = hapd->iconf->channel; - - if (is_6ghz_op_class(hapd->iconf->op_class)) - chwidth = op_class_to_ch_width(hapd->iconf->op_class); -@@ -209,6 +221,14 @@ u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid, - switch (chwidth) { - case CHANWIDTH_320MHZ: - oper->width = EHT_OPERATION_CHANNEL_WIDTH_320MHZ; -+ if (!oper->ccfs1) { -+ /* CCFS0 points to center channel frequency in config */ -+ oper->ccfs1 = oper->ccfs0; -+ if (hapd->iconf->channel < oper->ccfs0) -+ oper->ccfs0 = oper->ccfs1 - 16; -+ else -+ oper->ccfs0 = oper->ccfs1 + 16; -+ } - break; - case CHANWIDTH_160MHZ: - oper->width = EHT_OPERATION_CHANNEL_WIDTH_160MHZ; -@@ -246,8 +266,10 @@ u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid, - } - - if (hapd->iconf->ru_punct_bitmap) { -- oper->disable_sub_chan_bitmap_present = 1; -- oper->disabled_subchannel_bitmap = host_to_le16(hapd->iconf->ru_punct_bitmap); -+ oper->ehtop_params |= EHTOP_PARAMS_DISABLED_SUBCHANNEL_BITMAP_PRESENT; -+ oper->disabled_subchannel_bitmap[0] = -+ host_to_le16(hapd->iconf->ru_punct_bitmap); -+ pos += DISABLED_SUBCHANNEL_BITMAP_BYTES_SIZE; - } - - pos += oper_size; -diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h -index 752f65f..766ec1d 100644 ---- a/src/common/ieee802_11_defs.h -+++ b/src/common/ieee802_11_defs.h -@@ -2462,28 +2462,39 @@ struct ieee80211_eht_capabilities { - u8 optional[71]; - } STRUCT_PACKED; - --#define EHT_OPERATION_CCFS_SHIFT 4 - /* - * struct ieee80211_eht_operation - eht operation element - * - * This structure is the "EHT Operation Element" fields as -- * described in P802.11be_D1.4 section 9.4.2.311 -- * -- * FIXME: The spec is unclear how big the fields are, and doesn't -- * indicate the "Disabled Subchannel Bitmap Present" in the -- * structure (Figure 9-1002a) at all ... -+ * described in P802.11be_D2.0 section 9.4.2.311 - */ -+ -+#define EHTOP_PARAMS_EHTOP_INFORMATION_PRESENT BIT(0) -+#define EHTOP_PARAMS_DISABLED_SUBCHANNEL_BITMAP_PRESENT BIT(1) -+#define EHTOP_PARAMS_EHT_DEFAULT_PE_DURATION BIT(2) -+#define EHTOP_PARAMS_GROUP_ADDRESSED_BU_INDICATION_LIMIT BIT(3) -+#define EHTOP_PARAMS_GROUP_ADDRESSED_BU_INDICATION_EXPONENT BIT(4) -+ -+#define DISABLED_SUBCHANNEL_BITMAP_BYTES_SIZE 2 -+ -+struct ieee80211_eht_mcs_nss_set { -+ u8 max_tx_mcs_nss_0_7; -+ u8 max_tx_mcs_nss_8_9; -+ u8 max_tx_mcs_nss_10_11; -+ u8 max_tx_mcs_nss_12_13; -+} STRUCT_PACKED; -+ - struct ieee80211_eht_operation { -+ u8 ehtop_params; -+ struct ieee80211_eht_mcs_nss_set mcs_nss_supported; - u8 width:3, - reserved:5; -- u8 ccfs; -- u8 disable_sub_chan_bitmap_present:1, -- reserved2:7; -- le16 disabled_subchannel_bitmap; -- -- /* Add puncture pattern here when supported */ -+ u8 ccfs0; -+ u8 ccfs1; -+ le16 disabled_subchannel_bitmap[0]; - } STRUCT_PACKED; - -+ - #define EHT_OPERATION_CHANNEL_WIDTH_20MHZ 0 - #define EHT_OPERATION_CHANNEL_WIDTH_40MHZ 1 - #define EHT_OPERATION_CHANNEL_WIDTH_80MHZ 2 -diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c -index b527a77..c56801f 100644 ---- a/wpa_supplicant/mesh_mpm.c -+++ b/wpa_supplicant/mesh_mpm.c -@@ -820,28 +820,28 @@ static struct sta_info * mesh_mpm_add_peer(struct wpa_supplicant *wpa_s, - - eht_oper_ie = (struct ieee80211_eht_operation *)elems->eht_operation; - if (eht_oper_ie->width >= EHT_OPERATION_CHANNEL_WIDTH_80MHZ && -- eht_oper_ie->disable_sub_chan_bitmap_present && -+ eht_oper_ie->ehtop_params & EHTOP_PARAMS_DISABLED_SUBCHANNEL_BITMAP_PRESENT && - eht_oper_ie->disabled_subchannel_bitmap) { -- params.ru_punct_bitmap = eht_oper_ie->disabled_subchannel_bitmap; -+ params.ru_punct_bitmap = eht_oper_ie->disabled_subchannel_bitmap[0]; - /* Validate Peer's puncture bitmap and reset if invalid */ - switch (eht_oper_ie->width) { - case EHT_OPERATION_CHANNEL_WIDTH_80MHZ: - bw = 80; -- start_chan = eht_oper_ie->ccfs - 6; -+ start_chan = eht_oper_ie->ccfs0 - 6; - if (!is_ru_punct_bitmap_valid(bw, (pri_chan - start_chan) / 4, - params.ru_punct_bitmap, 0)) - params.ru_punct_bitmap = 0; - break; - case EHT_OPERATION_CHANNEL_WIDTH_160MHZ: - bw = 160; -- start_chan = eht_oper_ie->ccfs - 14; -+ start_chan = eht_oper_ie->ccfs0 - 14; - if (!is_ru_punct_bitmap_valid(bw, (pri_chan - start_chan) / 4, - params.ru_punct_bitmap, 0)) - params.ru_punct_bitmap = 0; - break; - case EHT_OPERATION_CHANNEL_WIDTH_320MHZ: - bw = 320; -- start_chan = eht_oper_ie->ccfs - 30; -+ start_chan = eht_oper_ie->ccfs0 - 30; - if (!is_ru_punct_bitmap_valid(bw, (pri_chan - start_chan) / 4, - params.ru_punct_bitmap, 0)) - params.ru_punct_bitmap = 0; --- -2.17.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-048-mesh-Enable-80-160MHz-Mesh-DFS-channels.patch b/feeds/ipq95xx/hostapd/patches/q02-048-mesh-Enable-80-160MHz-Mesh-DFS-channels.patch deleted file mode 100644 index 5fe63c5a..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-048-mesh-Enable-80-160MHz-Mesh-DFS-channels.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 6a7437a8bf48538e26924ca0cb3646fdff698883 Mon Sep 17 00:00:00 2001 -From: Hari Chandrakanthan -Date: Sun, 17 Jul 2022 12:26:36 +0530 -Subject: [PATCH] mesh: Enable 80-160MHz Mesh DFS channels - -There are two 80MHz and 160MHz 5G channels are present -in DFS occupied channel list. CAC needs to be performed -before the start of transmission for the DFS channels. -Hostapd CAC check is based on hapd->conf structures. -Hence the center frequency segment index and bandwidth -are added to perform CAC. - -Current implementation of DFS channel validatation for -mesh performs DFS check for only primary 80MHz of 160MHz -has DFS channels present or not. But this approach will -fail for channels having Non DFS channel as primary and -DFS channel for secondary 80MHz of 160MHz Eg: channel 36. -To avoid this issue, added DFS check for both primary 80MHz -and secondary 80MHz channels of 160MHz. - -Signed-off-by: Hari Chandrakanthan -Signed-off-by: P Praneesh ---- - wpa_supplicant/mesh.c | 29 +++++++++++++++++++++++++++-- - 1 file changed, 27 insertions(+), 2 deletions(-) - -diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c -index bb356a4..951a26c 100644 ---- a/wpa_supplicant/mesh.c -+++ b/wpa_supplicant/mesh.c -@@ -393,6 +393,7 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, - int basic_rates_erp[] = { 10, 20, 55, 60, 110, 120, 240, -1 }; - int rate_len; - int frequency; -+ bool is_dfs; - - if (!wpa_s->conf->user_mpm) { - /* not much for us to do here */ -@@ -484,8 +485,32 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, - bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity; - bss->conf->mesh_fwding = wpa_s->conf->mesh_fwding; - -- if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes, -- wpa_s->hw.num_modes) && wpa_s->conf->country[0]) { -+#define WPAS_GET_SEG_IDX(freq) ((freq - 5000)/5) -+ if (wpa_s->mesh_vht_enabled) { -+ if (freq->bandwidth == 80) -+ conf->vht_oper_chwidth = CHANWIDTH_80MHZ; -+ else if (freq->bandwidth == 160) -+ conf->vht_oper_chwidth = CHANWIDTH_160MHZ; -+ conf->vht_oper_centr_freq_seg0_idx = WPAS_GET_SEG_IDX(freq->center_freq1); -+ } -+ -+ if (wpa_s->mesh_he_enabled) { -+ if (freq->bandwidth == 80) -+ conf->he_oper_chwidth = CHANWIDTH_80MHZ; -+ else if (freq->bandwidth == 160) -+ conf->he_oper_chwidth = CHANWIDTH_160MHZ; -+ conf->he_oper_centr_freq_seg0_idx = WPAS_GET_SEG_IDX(freq->center_freq1); -+ } -+ -+ is_dfs = ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes, -+ wpa_s->hw.num_modes); -+ -+ /* Check secondary 80MHz of 160Mhz has DFS channels */ -+ if (!is_dfs && freq->bandwidth == 160) -+ is_dfs = ieee80211_is_dfs((ssid->frequency+80), wpa_s->hw.modes, -+ wpa_s->hw.num_modes); -+ -+ if (is_dfs && wpa_s->conf->country[0]) { - conf->ieee80211h = 1; - conf->ieee80211d = 1; - conf->country[0] = wpa_s->conf->country[0]; --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-049-hostapd-fix-channel-switch-in-eht-40mhz-bandwidth-fa.patch b/feeds/ipq95xx/hostapd/patches/q02-049-hostapd-fix-channel-switch-in-eht-40mhz-bandwidth-fa.patch deleted file mode 100644 index 151b561b..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-049-hostapd-fix-channel-switch-in-eht-40mhz-bandwidth-fa.patch +++ /dev/null @@ -1,30 +0,0 @@ -From e845f59b9ef7b098b3082b7b608ef93f72aff4d6 Mon Sep 17 00:00:00 2001 -From: Pradeep Kumar Chitrapu -Date: Thu, 4 Aug 2022 10:45:58 -0700 -Subject: [PATCH] hostapd: fix channel switch in eht 40mhz bandwidth falling - back to 20mhz - -When EHT is enabled in 2 GHz band with 40MHz bandwidth, channel switch -in 40 MHz is falling back to 20 MHz. so fix that. - -Signed-off-by: Pradeep Kumar Chitrapu ---- - src/drivers/driver_nl80211.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c -index a34012376979..ec8b4b5f8627 100644 ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -5053,7 +5053,7 @@ static int nl80211_put_freq_params(struct nl_msg *msg, - freq->ru_punct_bitmap)) - return -ENOBUFS; - } -- } else if (freq->ht_enabled || (freq->he_enabled && is_24ghz)) { -+ } else if (freq->ht_enabled || ((freq->he_enabled || freq->eht_enabled) && is_24ghz)) { - enum nl80211_channel_type ct; - - wpa_printf(MSG_DEBUG, " * sec_channel_offset=%d", --- -2.17.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-049-hostapd-fix-he40-eht40-bringup-with-acs.patch b/feeds/ipq95xx/hostapd/patches/q02-049-hostapd-fix-he40-eht40-bringup-with-acs.patch deleted file mode 100644 index eca21a43..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-049-hostapd-fix-he40-eht40-bringup-with-acs.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 1aef02a7dcf4206fd231097a4d0b7704b6c95111 Mon Sep 17 00:00:00 2001 -From: Hari Chandrakanthan -Date: Tue, 9 Aug 2022 00:17:18 +0530 -Subject: [PATCH] hostapd : fix he40/eht40 bringup with acs - -when ap is brought up in he40/eht40 with acs, -the ap comes up with 20 Mhz bandwidth. It is expected to -come up with 40 Mhz bandwidth. - -conf->secondary_channel doesnot hold the correct value and it leads -to choosing 20 Mhz in the api hostapd_set_freq_params. - -when the config acs is chosen, the hostapd config -he_oper_centr_freq_seg0_idx is not filled with correct value -as the channel is not known during bring up. - -So using the config he_oper_centr_freq_seg0_idx to fill the -conf->secondary_channel doesnot work with acs. - -So use op_class to determine the bandwidth and based -on the bandwidth fill the conf->secondary_channel. - -Signed-off-by: Hari Chandrakanthan ---- - src/ap/hostapd.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - -diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c -index d9c0f09..86e094a 100644 ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -1725,16 +1725,13 @@ static int configured_fixed_chan_to_freq(struct hostapd_iface *iface) - - static void hostapd_set_6ghz_sec_chan(struct hostapd_iface *iface) - { -- int bw, seg0; -- - if (!is_6ghz_op_class(iface->conf->op_class)) - return; - -- seg0 = hostapd_get_oper_centr_freq_seg0_idx(iface->conf); -- bw = center_idx_to_bw_6ghz(seg0); - /* Assign the secondary channel if absent in config for - * bandwidths > 20 MHz */ -- if (bw > 20 && !iface->conf->secondary_channel) { -+ if (op_class_to_bandwidth(iface->conf->op_class) >= 40 && -+ !iface->conf->secondary_channel) { - if (((iface->conf->channel - 1) / 4) % 2) - iface->conf->secondary_channel = -1; - else --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-050-hostapd-Add-freq-info-in-start-ap.patch b/feeds/ipq95xx/hostapd/patches/q02-050-hostapd-Add-freq-info-in-start-ap.patch deleted file mode 100644 index cd5e901f..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-050-hostapd-Add-freq-info-in-start-ap.patch +++ /dev/null @@ -1,43 +0,0 @@ -From b21976225f55be31bde21b06a6511e12092376c1 Mon Sep 17 00:00:00 2001 -From: Harshitha Prem -Date: Tue, 23 Aug 2022 14:15:08 +0530 -Subject: [PATCH] hostapd: Add frequency info in start ap - -In case of single hw multiple band scenario, when we -bring up multiple virtual interface in various bands -simultaneously then the driver maps a random channel -to the virtual interface when start ap command is sent -as freq info is not present. - -Hence, add the frequency information in start ap netlink -command so that the driver maps the appropriate channel -context by parsing it. - -Signed-off-by: Harshitha Prem - ---- - src/drivers/driver_nl80211.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -171,7 +171,8 @@ static int nl80211_send_frame_cmd(struct - const u16 *csa_offs, size_t csa_offs_len); - static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss, - int report); -- -+static int nl80211_put_freq_params(struct nl_msg *msg, -+ const struct hostapd_freq_params *freq); - #define IFIDX_ANY -1 - - static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx, -@@ -4885,6 +4886,9 @@ static int wpa_driver_nl80211_set_ap(voi - nla_nest_end(msg, spr); - } - -+ if (params->freq && nl80211_put_freq_params(msg, params->freq) < 0) -+ goto fail; -+ - if (params->freq && params->freq->he_enabled) { - struct nlattr *bss_color; - diff --git a/feeds/ipq95xx/hostapd/patches/q02-050-wpa_supplicant-add-wpa_cli-support-for-cac.patch b/feeds/ipq95xx/hostapd/patches/q02-050-wpa_supplicant-add-wpa_cli-support-for-cac.patch deleted file mode 100644 index 9268c647..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-050-wpa_supplicant-add-wpa_cli-support-for-cac.patch +++ /dev/null @@ -1,57 +0,0 @@ -From cea226f19df8cb78086374698d52f30485c2df43 Mon Sep 17 00:00:00 2001 -From: Hari Chandrakanthan -Date: Thu, 11 Aug 2022 10:35:15 +0530 -Subject: [PATCH] wpa_supplicant : add wpa_cli support for cac - -support to display cac inprogress state is added -as part of 'wpa_cli -i wlanx status' command - -Signed-off-by: Hari Chandrakanthan ---- - wpa_supplicant/ctrl_iface.c | 17 ++++++++++++++++- - 1 file changed, 16 insertions(+), 1 deletion(-) - -diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c -index 61aeea7..b96a996 100644 ---- a/wpa_supplicant/ctrl_iface.c -+++ b/wpa_supplicant/ctrl_iface.c -@@ -2205,7 +2205,7 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s, - const char *params, - char *buf, size_t buflen) - { -- char *pos, *end, tmp[30]; -+ char *pos, *end, tmp[30], *tmp_buf; - int res, verbose, wps, ret; - #ifdef CONFIG_HS20 - const u8 *hs20; -@@ -2346,12 +2346,27 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s, - } - #endif /* CONFIG_SAE */ - #endif /* CONFIG_SME */ -+ if (wpa_s->ifmsh) { -+ if(wpa_s->wpa_state == WPA_SCANNING && wpa_s->ifmsh->cac_started) -+ tmp_buf = "inprogress"; -+ else -+ tmp_buf = "N/A"; -+ } else { -+ tmp_buf = "N/A"; -+ } - ret = os_snprintf(pos, end - pos, "wpa_state=%s\n", - wpa_supplicant_state_txt(wpa_s->wpa_state)); - if (os_snprintf_error(end - pos, ret)) - return pos - buf; - pos += ret; - -+ ret = os_snprintf(pos, end - pos, "cac=%s\n", -+ tmp_buf); -+ if (os_snprintf_error(end - pos, ret)) -+ return pos - buf; -+ pos += ret; -+ -+ - if (wpa_s->l2 && - l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) { - ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp); --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-051-hostapd-Add-element-ID-extension-as-part-of-non-inhe.patch b/feeds/ipq95xx/hostapd/patches/q02-051-hostapd-Add-element-ID-extension-as-part-of-non-inhe.patch deleted file mode 100644 index 1bbdca6e..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-051-hostapd-Add-element-ID-extension-as-part-of-non-inhe.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 1adb9ef3ff48623365196c59a98b9a5ac03e012c Mon Sep 17 00:00:00 2001 -Author: Sowmiya Sree Elavalagan -Date: Mon Mar 21 22:02:03 2022 +0530 -Subject: [PATCH] hostapd: Add element ID extension as part of non-inheritance - IE for mbssid. - -Certain clients do not scan all non tx profiles due to absence of -element ID extension list which is mandatory field in non inheritance -IE. Non inheritance Element ID is followed by extension element ID. -Length is expected to be mentioned. Currently we do not support any -extension element and hence filling length as 0. - -Signed-off-by: Sowmiya Sree Elavalagan -Signed-off-by: Ramya Gnanasekar - -diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c -index 8a6fed8..5b814ba 100644 ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -7819,6 +7819,8 @@ static size_t hostapd_eid_mbssid_elem_len(struct hostapd_data *hapd, - if (ie_count) - nontx_profile_len += (4 + ie_count); - -+ nontx_profile_len += 1; /*Extension element ID length */ -+ - if ((len + nontx_profile_len) > 255) - goto mbssid_too_big; - -@@ -7974,11 +7976,16 @@ static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end, - } - if (ie_count) { - *eid++ = WLAN_EID_EXTENSION; -- *eid++ = 2 + ie_count; -+ *eid++ = 3 + ie_count; - *eid++ = WLAN_EID_EXT_NON_INHERITANCE; - *eid++ = ie_count; - os_memcpy(eid, non_inherit_ie, ie_count); - eid += ie_count; -+ /* Element ID extension list is mandatory part of non inheritance IE. -+ * It has a length field followed by extension IEs. Currently no -+ * extension IEs are supported so filling length as 0. -+ */ -+ *eid++ = 0; - } - - *eid_len_pos = (eid - eid_len_pos) - 1; --- -2.17.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-051-hostapd-add-awgn-support-for-320MHz-bw-in-6GHz-band.patch b/feeds/ipq95xx/hostapd/patches/q02-051-hostapd-add-awgn-support-for-320MHz-bw-in-6GHz-band.patch deleted file mode 100644 index 1439eb06..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-051-hostapd-add-awgn-support-for-320MHz-bw-in-6GHz-band.patch +++ /dev/null @@ -1,263 +0,0 @@ -From 856937cfab895f6a20e1fd9d919ad5710077745c Mon Sep 17 00:00:00 2001 -From: Hari Chandrakanthan -Date: Wed, 28 Sep 2022 17:48:40 +0530 -Subject: [PATCH] hostapd : add awgn support for 320MHz bw in 6GHz band - -Add support for awgn handling of 320MHz bw in 6GHz band. - -Signed-off-by: Hari Chandrakanthan ---- - src/ap/interference.c | 147 ++++++++++++++++++++++++++++++++++---------------- - 1 file changed, 100 insertions(+), 47 deletions(-) - -diff --git a/src/ap/interference.c b/src/ap/interference.c -index c51a4bf..4148489 100644 ---- a/src/ap/interference.c -+++ b/src/ap/interference.c -@@ -62,6 +62,7 @@ static int intf_awgn_chan_range_available(struct hostapd_hw_modes *mode, - int allowed_80_6g[] = {1, 17, 33, 49, 65, 81, 97, 113, 129, 145, 161, 177, - 193, 209}; - int allowed_160_6g[] = {1, 33, 65, 97, 129, 161, 193}; -+ int allowed_320_6g[] = {1, 65, 129, 33, 97, 161}; - int chan_idx_match = 0; - int i; - -@@ -97,6 +98,13 @@ static int intf_awgn_chan_range_available(struct hostapd_hw_modes *mode, - break; - } - } -+ } else if (num_chans == 16) { /* 320Mhz channel */ -+ for (i = 0; i < ARRAY_SIZE(allowed_320_6g); i++) { -+ if (first_chan->chan == allowed_320_6g[i]) { -+ chan_idx_match = 1; -+ break; -+ } -+ } - } - - if (chan_idx_match == 1) -@@ -114,6 +122,42 @@ static int is_in_chanlist(struct hostapd_iface *iface, - return freq_range_list_includes(&iface->conf->acs_ch_list, chan->chan); - } - -+#define BASE_6G_FREQ 5950 -+ -+int get_centre_freq_6g(int chan_idx, int chan_width, int *centre_freq) -+{ -+ if (!centre_freq) -+ return -1; -+ -+ *centre_freq = 0; -+ -+ switch (chan_width) { -+ case CHAN_WIDTH_40: -+ if (chan_idx >= 1 && chan_idx <= 229) -+ *centre_freq = ((chan_idx / 8) * 8 + 3) * 5 + BASE_6G_FREQ; -+ break; -+ case CHAN_WIDTH_80: -+ if (chan_idx >= 1 && chan_idx <= 221) -+ *centre_freq = ((chan_idx / 16) * 16 + 7) * 5 + BASE_6G_FREQ; -+ break; -+ case CHAN_WIDTH_160: -+ if (chan_idx >= 1 && chan_idx <= 221) -+ *centre_freq = ((chan_idx / 32) * 32 + 15) * 5 + BASE_6G_FREQ; -+ break; -+ case CHAN_WIDTH_320: -+ if (chan_idx >= 1 && chan_idx <= 221) -+ *centre_freq = ((chan_idx /64) * 64 + 31) * 5 + BASE_6G_FREQ; -+ default: -+ break; -+ } -+ -+ if (*centre_freq == 0) -+ return -1; -+ -+ return 0; -+} -+ -+ - /* - *intf_awgn_find_channel - find the channel that can operate with bandwidth chan_width. - If idx doesn't match with index of any of the existing channel, then the api -@@ -123,11 +167,13 @@ static int is_in_chanlist(struct hostapd_iface *iface, - */ - static int intf_awgn_find_channel(struct hostapd_iface *iface, - struct hostapd_channel_data **ret_chan, -- int idx, int chan_width) -+ int idx, int chan_width, int cs1) - { - struct hostapd_hw_modes *mode = iface->current_mode; - struct hostapd_channel_data *chan; - int i, channel_idx = 0, n_chans; -+ int temp_centre_freq; -+ int ret; - - switch (chan_width) { - case CHAN_WIDTH_20_NOHT: -@@ -144,6 +190,9 @@ static int intf_awgn_find_channel(struct hostapd_iface *iface, - case CHAN_WIDTH_160: - n_chans = 8; - break; -+ case CHAN_WIDTH_320: -+ n_chans = 16; -+ break; - default: - n_chans = 1; - break; -@@ -167,6 +216,24 @@ static int intf_awgn_find_channel(struct hostapd_iface *iface, - continue; - } - -+ if (chan_width == CHAN_WIDTH_320) { -+ ret = get_centre_freq_6g(chan->chan, CHAN_WIDTH_320, -+ &temp_centre_freq); -+ if (ret) { -+ wpa_printf(MSG_ERROR, -+ "AWGN : couldn't find centre freq for chan : %d" -+ " chan_width : %d", chan->chan, CHAN_WIDTH_320); -+ return 0; -+ } -+ -+ if (abs(temp_centre_freq - cs1) < 320) { -+ wpa_printf(MSG_DEBUG, -+ "AWGN: channel %d is a overlapping channel so skipping", -+ chan->freq); -+ continue; -+ } -+ } -+ - if (ret_chan && idx == channel_idx) { - wpa_printf(MSG_DEBUG, "AWGN: Selected channel %d (%d)", - chan->freq, chan->chan); -@@ -182,50 +249,27 @@ static int intf_awgn_find_channel(struct hostapd_iface *iface, - } - - enum chan_seg { -- SEG_PRI20 = 0x1, -- SEG_SEC20 = 0x2, -- SEG_SEC40_LOWER = 0x4, -- SEG_SEC40_UPPER = 0x8, -- SEG_SEC40 = 0xC, -- SEG_SEC80_LOWER = 0x10, -- SEG_SEC80_LOWER_UPPER = 0x20, -- SEG_SEC80_UPPER_LOWER = 0x40, -- SEG_SEC80_UPPER = 0x80, -- SEG_SEC80 = 0xF0, -+ SEG_PRI20 = 0x1, -+ SEG_SEC20 = 0x2, -+ SEG_SEC40_LOW = 0x4, -+ SEG_SEC40_UP = 0x8, -+ SEG_SEC40 = 0xC, -+ SEG_SEC80_LOW = 0x10, -+ SEG_SEC80_LOW_UP = 0x20, -+ SEG_SEC80_UP_LOW = 0x40, -+ SEG_SEC80_UP = 0x80, -+ SEG_SEC80 = 0xF0, -+ SEG_SEC160_LOW = 0x0100, -+ SEG_SEC160_LOW_UP = 0x0200, -+ SEG_SEC160_LOW_UP_UP = 0x0400, -+ SEG_SEC160_LOW_UP_UP_UP = 0x0800, -+ SEG_SEC160_UP_LOW_LOW_LOW = 0x1000, -+ SEG_SEC160_UP_LOW_LOW = 0x2000, -+ SEG_SEC160_UP_LOW = 0x4000, -+ SEG_SEC160_UP = 0x8000, -+ SEG_SEC160 = 0xFF00, - }; - --#define BASE_6G_FREQ 5950 -- --int get_centre_freq_6g(int chan_idx, int chan_width, int *centre_freq) --{ -- if (!centre_freq) -- return -1; -- -- *centre_freq = 0; -- -- switch (chan_width) { -- case CHAN_WIDTH_40: -- if (chan_idx >= 1 && chan_idx <= 229) -- *centre_freq = ((chan_idx / 8) * 8 + 3) * 5 + BASE_6G_FREQ; -- break; -- case CHAN_WIDTH_80: -- if (chan_idx >= 1 && chan_idx <= 221) -- *centre_freq = ((chan_idx / 16) * 16 + 7) * 5 + BASE_6G_FREQ; -- break; -- case CHAN_WIDTH_160: -- if (chan_idx >= 1 && chan_idx <= 221) -- *centre_freq = ((chan_idx / 32) * 32 + 15) * 5 + BASE_6G_FREQ; -- break; -- default: -- break; -- } -- -- if (*centre_freq == 0) -- return -1; -- -- return 0; --} -- - /* - * hostapd_intf_awgn_detected - awgn interference is detected in the operating channel. - * The interference channel information is available as a -@@ -269,7 +313,7 @@ int hostapd_intf_awgn_detected(struct hostapd_iface *iface, int freq, int chan_w - if (channel_switch) { - /* Find a random channel to be switched */ - num_available_chandefs = intf_awgn_find_channel(iface, NULL, 0, -- chan_width); -+ chan_width, cf1); - if (num_available_chandefs == 0) { - wpa_printf(MSG_ERROR, "AWGN: no available_chandefs"); - return 0; -@@ -281,7 +325,7 @@ int hostapd_intf_awgn_detected(struct hostapd_iface *iface, int freq, int chan_w - } - - chan_idx = _rand % num_available_chandefs; -- intf_awgn_find_channel(iface, &chan_data, chan_idx, chan_width); -+ intf_awgn_find_channel(iface, &chan_data, chan_idx, chan_width, cf1); - - if (!chan_data) { - wpa_printf(MSG_ERROR, "AWGN: no random channel found, chan idx : %d", -@@ -295,7 +339,7 @@ int hostapd_intf_awgn_detected(struct hostapd_iface *iface, int freq, int chan_w - */ - chan_data = NULL; - chan_idx = (chan_idx + 1) % num_available_chandefs; -- intf_awgn_find_channel(iface, &chan_data, chan_idx, chan_width); -+ intf_awgn_find_channel(iface, &chan_data, chan_idx, chan_width, cf1); - if (!chan_data) { - wpa_printf(MSG_ERROR, - "AWGN: random channel not found, chan idx : %d", -@@ -319,7 +363,12 @@ int hostapd_intf_awgn_detected(struct hostapd_iface *iface, int freq, int chan_w - return 0; - } - -- if ((chan_width > CHAN_WIDTH_80) && -+ if ((chan_width > CHAN_WIDTH_160) && -+ !(chan_bw_interference_bitmap & SEG_SEC80) && -+ !(chan_bw_interference_bitmap & SEG_SEC40) && -+ !(chan_bw_interference_bitmap & SEG_SEC20)) -+ new_chan_width = CHAN_WIDTH_160; -+ else if ((chan_width > CHAN_WIDTH_80) && - !(chan_bw_interference_bitmap & SEG_SEC40) && - !(chan_bw_interference_bitmap & SEG_SEC20)) - new_chan_width = CHAN_WIDTH_80; -@@ -358,6 +407,9 @@ int hostapd_intf_awgn_detected(struct hostapd_iface *iface, int freq, int chan_w - case CHAN_WIDTH_160: - settings.freq_params.bandwidth = 160; - break; -+ case CHAN_WIDTH_320: -+ settings.freq_params.bandwidth = 320; -+ break; - default: - settings.freq_params.bandwidth = 20; - break; -@@ -367,6 +419,7 @@ int hostapd_intf_awgn_detected(struct hostapd_iface *iface, int freq, int chan_w - settings.freq_params.ht_enabled = iface->conf->ieee80211n; - settings.freq_params.vht_enabled = iface->conf->ieee80211ac; - settings.freq_params.he_enabled = iface->conf->ieee80211ax; -+ settings.freq_params.eht_enabled= iface->conf->ieee80211be; - - for (i = 0; i < iface->num_bss; i++) { - /* Save CHAN_SWITCH VHT and HE config */ --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-051-hostapd-fix-channel-switch-frequency-check.patch b/feeds/ipq95xx/hostapd/patches/q02-051-hostapd-fix-channel-switch-frequency-check.patch deleted file mode 100644 index 4aa9fb1d..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-051-hostapd-fix-channel-switch-frequency-check.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 03ad17e6281ebfd25a9747cea468be428f5af990 Mon Sep 17 00:00:00 2001 -From: Karthik M -Date: Fri, 7 Oct 2022 23:52:15 +0530 -Subject: [PATCH] hostapd: Frequency check during channel switch across BW - -Add the check for verifying the frequency for different BW -received during channel switch. - -Check makes sure that the channel frequency is appropriate -and lies within the center frequency. - -Signed-off-by: Karthik M ---- - hostapd/ctrl_iface.c | 145 +++++++++++++++++++++++-------------------- - 1 file changed, 76 insertions(+), 69 deletions(-) - ---- a/hostapd/ctrl_iface.c -+++ b/hostapd/ctrl_iface.c -@@ -2764,19 +2764,23 @@ static int hostapd_ctrl_check_freq_param - switch (params->sec_channel_offset) { - case 1: - if (params->freq + 150 != params->center_freq1 && -- params->freq + 70 != params->center_freq1 && -- params->freq + 30 != params->center_freq1 && -- params->freq - 10 != params->center_freq1 && -- params->freq - 50 != params->center_freq1 && -+ params->freq + 110 != params->center_freq1 && -+ params->freq + 70 != params->center_freq1 && -+ params->freq + 30 != params->center_freq1 && -+ params->freq - 10 != params->center_freq1 && -+ params->freq - 50 != params->center_freq1 && -+ params->freq - 90 != params->center_freq1 && - params->freq - 130 != params->center_freq1) - return -1; - break; - case -1: - if (params->freq + 130 != params->center_freq1 && -- params->freq + 50 != params->center_freq1 && -- params->freq + 10 != params->center_freq1 && -- params->freq - 30 != params->center_freq1 && -- params->freq - 70 != params->center_freq1 && -+ params->freq + 90 != params->center_freq1 && -+ params->freq + 50 != params->center_freq1 && -+ params->freq + 10 != params->center_freq1 && -+ params->freq - 30 != params->center_freq1 && -+ params->freq - 70 != params->center_freq1 && -+ params->freq - 110 != params->center_freq1 && - params->freq - 150 != params->center_freq1) - return -1; - break; diff --git a/feeds/ipq95xx/hostapd/patches/q02-052-hostapd-make-probe-response-as-broadcast-for-6GHz-ba.patch b/feeds/ipq95xx/hostapd/patches/q02-052-hostapd-make-probe-response-as-broadcast-for-6GHz-ba.patch deleted file mode 100644 index fb3a9229..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-052-hostapd-make-probe-response-as-broadcast-for-6GHz-ba.patch +++ /dev/null @@ -1,42 +0,0 @@ -From ec78b0e8a7ebd3d705b4119a795e044e3437670b Mon Sep 17 00:00:00 2001 -From: Hari Chandrakanthan -Date: Tue, 11 Oct 2022 23:57:00 +0530 -Subject: [PATCH] hostapd : make probe response as broadcast for 6GHz band - -Make probe response as broadcast for 6GHz band as mentioned -in the spec IEEE Std 802.11ax‐2021 section 26.17.2.3.2, -"If a 6 GHz AP receives a Probe Request frame and responds with a Probe -Response frame (per 11.1.4.3.4), the Address 1 field of the Probe -Response frame shall be set to the broadcast address, unless -the AP is not indicating its actual SSID in the SSID element -of its Beacon frames." - -Fixes: I6af7154bddf ("hostapd: Package Upgrade to b26f5c0fe3") - -Signed-off-by: Hari Chandrakanthan ---- - src/ap/beacon.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/src/ap/beacon.c b/src/ap/beacon.c -index 9536e76..011c0fc 100644 ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -664,8 +664,13 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, - - resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, - WLAN_FC_STYPE_PROBE_RESP); -- if (req) -+ -+ if (req && (!is_6ghz_op_class(hapd->iconf->op_class) || -+ hapd->conf->ignore_broadcast_ssid)) - os_memcpy(resp->da, req->sa, ETH_ALEN); -+ else -+ os_memset(resp->da, 0xff, ETH_ALEN); -+ - os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN); - - os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN); --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-053-hostapd-awgn-fix-new-channel-selection-logic.patch b/feeds/ipq95xx/hostapd/patches/q02-053-hostapd-awgn-fix-new-channel-selection-logic.patch deleted file mode 100644 index dd8fc94e..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-053-hostapd-awgn-fix-new-channel-selection-logic.patch +++ /dev/null @@ -1,421 +0,0 @@ -From 0fffe1c539734f9dc26a80fb80eddb7ea1f1af46 Mon Sep 17 00:00:00 2001 -From: Hari Chandrakanthan -Date: Mon, 31 Oct 2022 19:51:32 +0530 -Subject: [PATCH] hostapd : awgn - fix new channel selection logic - -From the list of channels allowed by Australia, -only one 320 MHz operable channel is available. - -So if awgn is detected when operating in 320 MHz, the ap -needs to reduce its bandwidth to next max available bw 160 MHz. - -But with current design if no other 320 Mhz channel is available, -hostapd bails out with a log saying that no channel with 320 MHz is available. -we don't check for next max available bandwidth in our current design and -this leads to ap to remain in the same channel even if awgn is detected. - -So the channel selection logic is changed in a way that the next max -available bandwidth is searched if no new channel is available for current -bandwidth. The search continues till 20 MHz bandwidth. - -This generic logic will help to fix similar issues in future. - -Also optimized the channel selection logic by looping over the list of all -the channels only once. - -Signed-off-by: Hari Chandrakanthan ---- - src/ap/interference.c | 249 ++++++++++++++++++++++++++++++++------------------ - 1 file changed, 160 insertions(+), 89 deletions(-) - -diff --git a/src/ap/interference.c b/src/ap/interference.c -index 4148489..1d66d6f 100644 ---- a/src/ap/interference.c -+++ b/src/ap/interference.c -@@ -46,6 +46,23 @@ - #include "eloop.h" - #include "hw_features.h" - -+static bool is_chan_disabled(struct hostapd_hw_modes *mode, int chan_num) -+{ -+ int chan_disabled = 1; -+ int i; -+ struct hostapd_channel_data *temp_chan; -+ -+ for (i = 0; i < mode->num_channels; i++) { -+ temp_chan = &mode->channels[i]; -+ if (temp_chan->chan == chan_num && -+ (!(temp_chan->flag & HOSTAPD_CHAN_DISABLED))) { -+ chan_disabled = 0; -+ break; -+ } -+ } -+ return chan_disabled; -+} -+ - /* - * intf_awgn_chan_range_available - check whether the channel can operate - * in the given bandwidth in 6Ghz -@@ -63,8 +80,11 @@ static int intf_awgn_chan_range_available(struct hostapd_hw_modes *mode, - 193, 209}; - int allowed_160_6g[] = {1, 33, 65, 97, 129, 161, 193}; - int allowed_320_6g[] = {1, 65, 129, 33, 97, 161}; -+ int allowed_arr_size = 0; -+ int *allowed_arr = NULL; - int chan_idx_match = 0; -- int i; -+ int chan_disabled = 0; -+ int i, j; - - first_chan = &mode->channels[first_chan_idx]; - -@@ -77,33 +97,40 @@ static int intf_awgn_chan_range_available(struct hostapd_hw_modes *mode, - if (num_chans == 1) - return 1; - -- if (num_chans == 2) { /* 40Mhz channel */ -- for (i = 0; i < ARRAY_SIZE(allowed_40_6g); i++) { -- if (first_chan->chan == allowed_40_6g[i]) { -- chan_idx_match = 1; -- break; -- } -- } -- } else if (num_chans == 4) { /* 80Mhz channel */ -- for (i = 0; i < ARRAY_SIZE(allowed_80_6g); i++) { -- if (first_chan->chan == allowed_80_6g[i]) { -- chan_idx_match = 1; -- break; -- } -- } -- } else if (num_chans == 8) { /* 160Mhz channel */ -- for (i = 0; i < ARRAY_SIZE(allowed_160_6g); i++) { -- if (first_chan->chan == allowed_160_6g[i]) { -- chan_idx_match = 1; -- break; -+ switch (num_chans) { -+ case 2: -+ allowed_arr_size = ARRAY_SIZE(allowed_40_6g); -+ allowed_arr = allowed_40_6g; -+ break; -+ case 4: -+ allowed_arr_size = ARRAY_SIZE(allowed_80_6g); -+ allowed_arr = allowed_80_6g; -+ break; -+ case 8: -+ allowed_arr_size = ARRAY_SIZE(allowed_160_6g); -+ allowed_arr = allowed_160_6g; -+ break; -+ case 16: -+ allowed_arr_size = ARRAY_SIZE(allowed_320_6g); -+ allowed_arr = allowed_320_6g; -+ break; -+ default: -+ allowed_arr_size = 0; -+ break; -+ } -+ -+ /* check whether all the 20 MHz channels in the given operating range is enabled */ -+ for (i = 0; i < allowed_arr_size; i++) { -+ if (first_chan->chan == allowed_arr[i]) { -+ for (j = 1; j <= num_chans - 1; j++) { -+ if (is_chan_disabled(mode, first_chan->chan + j * 4)) { -+ chan_disabled = 1; -+ break; -+ } - } -- } -- } else if (num_chans == 16) { /* 320Mhz channel */ -- for (i = 0; i < ARRAY_SIZE(allowed_320_6g); i++) { -- if (first_chan->chan == allowed_320_6g[i]) { -+ if (!chan_disabled) - chan_idx_match = 1; -- break; -- } -+ break; - } - } - -@@ -159,21 +186,28 @@ int get_centre_freq_6g(int chan_idx, int chan_width, int *centre_freq) - - - /* -- *intf_awgn_find_channel - find the channel that can operate with bandwidth chan_width. -- If idx doesn't match with index of any of the existing channel, then the api -- returns the total number of available chandefs that supports the provided bandwidth -- * @idx - index of the channel -- * @chan_width - bandwidth of the channel -+ * intf_awgn_find_channel_list - find the list of channels that can operate with -+ channel width chan_width and not present within the range of current operating range. -+ returns the total number of available chandefs that supports the provided bandwidth -+ * @chan_width - channel width to be checked -+ * @curr_centre_freq - current centre frequency -+ * @curr_chan_width - current channel width -+ * @chandef_list - pointer array to hold the list of valid available chandef - */ --static int intf_awgn_find_channel(struct hostapd_iface *iface, -- struct hostapd_channel_data **ret_chan, -- int idx, int chan_width, int cs1) -+static int intf_awgn_find_channel_list(struct hostapd_iface *iface, -+ int chan_width, int curr_centre_freq, -+ int curr_chan_width, -+ struct hostapd_channel_data ***chandef_list) - { - struct hostapd_hw_modes *mode = iface->current_mode; - struct hostapd_channel_data *chan; - int i, channel_idx = 0, n_chans; -- int temp_centre_freq; -+ int new_centre_freq; - int ret; -+ int curr_start_freq; -+ int curr_end_freq; -+ int new_start_freq; -+ int new_end_freq; - - switch (chan_width) { - case CHAN_WIDTH_20_NOHT: -@@ -198,6 +232,9 @@ static int intf_awgn_find_channel(struct hostapd_iface *iface, - break; - } - -+ curr_start_freq = curr_centre_freq - channel_width_to_int(curr_chan_width) / 2; -+ curr_end_freq = curr_centre_freq + channel_width_to_int(curr_chan_width) / 2; -+ - for (i = 0; i < mode->num_channels; i++) { - chan = &mode->channels[i]; - -@@ -216,44 +253,49 @@ static int intf_awgn_find_channel(struct hostapd_iface *iface, - continue; - } - -- if (chan_width == CHAN_WIDTH_320) { -- ret = get_centre_freq_6g(chan->chan, CHAN_WIDTH_320, -- &temp_centre_freq); -- if (ret) { -- wpa_printf(MSG_ERROR, -- "AWGN : couldn't find centre freq for chan : %d" -- " chan_width : %d", chan->chan, CHAN_WIDTH_320); -- return 0; -- } -- -- if (abs(temp_centre_freq - cs1) < 320) { -- wpa_printf(MSG_DEBUG, -- "AWGN: channel %d is a overlapping channel so skipping", -- chan->freq); -- continue; -- } -+ ret = get_centre_freq_6g(chan->chan, chan_width, -+ &new_centre_freq); -+ if (ret) { -+ wpa_printf(MSG_ERROR, -+ "AWGN : couldn't find centre freq for chan : %d" -+ " chan_width : %d", chan->chan, chan_width); -+ return 0; - } - -- if (ret_chan && idx == channel_idx) { -- wpa_printf(MSG_DEBUG, "AWGN: Selected channel %d (%d)", -- chan->freq, chan->chan); -- *ret_chan = chan; -- return idx; -+ new_start_freq = new_centre_freq - channel_width_to_int(chan_width) / 2; -+ new_end_freq = new_centre_freq + channel_width_to_int(chan_width) / 2; -+ -+ /* check whether new operating range is outside the current -+ * operating range since current operating range contains awgn -+ * interference -+ */ -+ if (((new_start_freq > curr_start_freq) && (new_start_freq < curr_end_freq)) || -+ ((new_end_freq > curr_start_freq) && (new_end_freq < curr_end_freq)) || -+ ((new_centre_freq > curr_start_freq && new_centre_freq < curr_end_freq))) { -+ wpa_printf(MSG_DEBUG, -+ "AWGN : freq range overlap new_start_freq : %d" -+ " new_end_freq : %d curr_start_freq : %d" -+ " curr_end_freq : %d centre_freq : %d", -+ new_start_freq, new_end_freq, curr_start_freq, -+ curr_end_freq, new_centre_freq); -+ continue; - } - -- wpa_printf(MSG_DEBUG, "AWGN: Adding channel %d (%d)", -+ wpa_printf(MSG_DEBUG, "AWGN: Adding channel %d (%d) to valid chandef list", - chan->freq, chan->chan); -+ (*chandef_list)[channel_idx] = chan; - channel_idx++; - } -+ - return channel_idx; - } - - enum chan_seg { -- SEG_PRI20 = 0x1, -- SEG_SEC20 = 0x2, -- SEG_SEC40_LOW = 0x4, -- SEG_SEC40_UP = 0x8, -- SEG_SEC40 = 0xC, -+ SEG_PRI20 = 0x1, -+ SEG_SEC20 = 0x2, -+ SEG_SEC40_LOW = 0x4, -+ SEG_SEC40_UP = 0x8, -+ SEG_SEC40 = 0xC, - SEG_SEC80_LOW = 0x10, - SEG_SEC80_LOW_UP = 0x20, - SEG_SEC80_UP_LOW = 0x40, -@@ -270,6 +312,31 @@ enum chan_seg { - SEG_SEC160 = 0xFF00, - }; - -+int get_next_max_width(int chan_width) -+{ -+ int next_max_width; -+ -+ switch (chan_width) { -+ case CHAN_WIDTH_320: -+ next_max_width = CHAN_WIDTH_160; -+ break; -+ case CHAN_WIDTH_160: -+ next_max_width = CHAN_WIDTH_80; -+ break; -+ case CHAN_WIDTH_80: -+ next_max_width = CHAN_WIDTH_40; -+ break; -+ case CHAN_WIDTH_40: -+ next_max_width = CHAN_WIDTH_20; -+ break; -+ default: -+ next_max_width = CHAN_WIDTH_20_NOHT; -+ break; -+ } -+ -+ return next_max_width; -+} -+ - /* - * hostapd_intf_awgn_detected - awgn interference is detected in the operating channel. - * The interference channel information is available as a -@@ -283,14 +350,16 @@ int hostapd_intf_awgn_detected(struct hostapd_iface *iface, int freq, int chan_w - struct csa_settings settings; - struct hostapd_channel_data *chan_data = NULL; - struct hostapd_channel_data *chan_temp = NULL; -+ struct hostapd_channel_data **available_chandef_list = NULL; - int ret; - unsigned int i; - u32 _rand; - u32 chan_idx; -- int num_available_chandefs; -+ int num_available_chandefs = 0; - u8 channel_switch = 0; - int new_chan_width; - int new_centre_freq; -+ int temp_width; - struct hostapd_hw_modes *mode = iface->current_mode; - - wpa_printf(MSG_DEBUG, -@@ -302,7 +371,7 @@ int hostapd_intf_awgn_detected(struct hostapd_iface *iface, int freq, int chan_w - - if (iface->conf->discard_6g_awgn_event) { - wpa_printf(MSG_DEBUG, "discard_6g_awgn_event set ignoring" -- "AWGN DETECT event from driver"); -+ " AWGN DETECT event from driver"); - return 0; - } - -@@ -310,47 +379,47 @@ int hostapd_intf_awgn_detected(struct hostapd_iface *iface, int freq, int chan_w - if (!chan_bw_interference_bitmap || (chan_bw_interference_bitmap & SEG_PRI20)) - channel_switch = 1; - -+ available_chandef_list = os_zalloc(sizeof(struct hostapd_channel_data *) * -+ mode->num_channels); - if (channel_switch) { -- /* Find a random channel to be switched */ -- num_available_chandefs = intf_awgn_find_channel(iface, NULL, 0, -- chan_width, cf1); -+ /* find a random channel to be switched */ -+ temp_width = chan_width; -+ -+ while (temp_width > CHAN_WIDTH_20_NOHT) { -+ num_available_chandefs = intf_awgn_find_channel_list(iface, -+ temp_width, -+ cf1, chan_width, -+ &available_chandef_list); -+ if (num_available_chandefs == 0) -+ temp_width = get_next_max_width(temp_width); -+ else -+ break; -+ } -+ - if (num_available_chandefs == 0) { - wpa_printf(MSG_ERROR, "AWGN: no available_chandefs"); -- return 0; -+ goto exit; - } - - if (os_get_random((u8 *)&_rand, sizeof(_rand)) < 0) { - wpa_printf(MSG_ERROR, "AWGN: couldn't get random number"); -- return 0; -+ goto exit; - } - - chan_idx = _rand % num_available_chandefs; -- intf_awgn_find_channel(iface, &chan_data, chan_idx, chan_width, cf1); -+ -+ chan_data = available_chandef_list[chan_idx]; - - if (!chan_data) { -- wpa_printf(MSG_ERROR, "AWGN: no random channel found, chan idx : %d", -+ wpa_printf(MSG_ERROR, "AWGN: channel info not available for chan_idx : %d", - chan_idx); -- return 0; -+ goto exit; - } - -- if(chan_data->freq == freq) { -- /* New random channel is same as operating channel -- * so choose another channel -- */ -- chan_data = NULL; -- chan_idx = (chan_idx + 1) % num_available_chandefs; -- intf_awgn_find_channel(iface, &chan_data, chan_idx, chan_width, cf1); -- if (!chan_data) { -- wpa_printf(MSG_ERROR, -- "AWGN: random channel not found, chan idx : %d", -- chan_idx); -- return 0; -- } -- } -+ new_chan_width = temp_width; - - wpa_printf(MSG_DEBUG, "AWGN: got random channel %d (%d)", - chan_data->freq, chan_data->chan); -- new_chan_width = chan_width; - } else { - /* interference is not present in the primary 20Mhz, so reduce bandwidth*/ - for (i = 0; i < mode->num_channels; i++) { -@@ -360,7 +429,7 @@ int hostapd_intf_awgn_detected(struct hostapd_iface *iface, int freq, int chan_w - } - if (!chan_data) { - wpa_printf(MSG_ERROR, "AWGN : no channel found"); -- return 0; -+ goto exit; - } - - if ((chan_width > CHAN_WIDTH_160) && -@@ -386,7 +455,7 @@ int hostapd_intf_awgn_detected(struct hostapd_iface *iface, int freq, int chan_w - wpa_printf(MSG_ERROR, - "AWGN : couldn't find centre freq for chan : %d" - " chan_width : %d", chan_data->chan, new_chan_width); -- return 0; -+ goto exit; - } - } else { - new_centre_freq = chan_data->freq; -@@ -442,5 +511,7 @@ int hostapd_intf_awgn_detected(struct hostapd_iface *iface, int freq, int chan_w - } - } - -+exit: -+ os_free(available_chandef_list); - return 0; - } --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-053-wpa_supplicant-set-interface-state-as-inactive-if-me.patch b/feeds/ipq95xx/hostapd/patches/q02-053-wpa_supplicant-set-interface-state-as-inactive-if-me.patch deleted file mode 100644 index 604d2896..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-053-wpa_supplicant-set-interface-state-as-inactive-if-me.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 462d1e11d742a496d169e4724f6925794f0d7e03 Mon Sep 17 00:00:00 2001 -From: Hari Chandrakanthan -Date: Thu, 13 Oct 2022 03:35:10 +0530 -Subject: [PATCH] wpa_supplicant : set interface state as inactive if mesh - bringup fails - -In the current design, when mesh + ap is brought up, -mesh is brought up first and then ap is brought up. - -There are cases where mesh bring up can fail. -Eg : mesh configured with acs. - -wpa_supplicant doesn't support acs with mesh. -So mesh bring up fails which is expected. - -The interface state is still maintained -as SCANNING even if mesh bring bring-up fails. - -Since ap bringup depends on mesh bringup and mesh interface state -doesnot reflect the correct state during bringup failure, the ap bring -up is not initiated and that leads to the issue where ap interface remains -disabled. - -So make the interface state as INACTIVE if the mesh bring up fails. - -Signed-off-by: Hari Chandrakanthan ---- - wpa_supplicant/wpa_supplicant.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c -index b9b5bdf..c19ec33 100644 ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -2307,6 +2307,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, - ssid->frequency = bss->freq; - if (wpa_supplicant_join_mesh(wpa_s, ssid) < 0) { - wpa_msg(wpa_s, MSG_ERROR, "Could not join mesh"); -+ wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); - return; - } - wpa_s->current_bss = bss; --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-054-hostapd-Disable-6GHz-FILS-and-UBPR-for-mutli-band-AP.patch b/feeds/ipq95xx/hostapd/patches/q02-054-hostapd-Disable-6GHz-FILS-and-UBPR-for-mutli-band-AP.patch deleted file mode 100644 index 652a53e9..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-054-hostapd-Disable-6GHz-FILS-and-UBPR-for-mutli-band-AP.patch +++ /dev/null @@ -1,325 +0,0 @@ -From 10ba7b35020ba6882436483a3b1cd74887ff3b36 Mon Sep 17 00:00:00 2001 -From: Hari Chandrakanthan -Date: Mon, 14 Nov 2022 20:53:31 +0530 -Subject: [PATCH] hostapd: Disable 6GHz FILS and UBPR for multi-band AP - -WFA test plan 2.0 has specification below: -3.3.2.1 Out of Box requirements: -FILS Discovery and Unsolicited Probe Response frames disabled -in the 6 GHz band if the AP simultaneously operates -on multiple bands in its out of box configuration. - -Also Channel access latency in 6GHz gets impacted by 20-33% -when there is FILS/UBPR in-band discovery frames. - -Extra transmissions (FILS, UBPRs) are polluting the spectrum -and increasing the potential to cause interference to the -incumbent systems operating in the 6GHz band. - -Keeping these in-band advertisement frames disabled helps -to optimize this latency. So, the aim to is to keep -FILS/UBPR disabled without impacting discoverability. - -Having OOB advertisement in lower band helps to avoid any -impact in AP discoverability even if FILS/UBPR is -disabled in 6GHz. So, keep them disabled if OOB is -ongoing. - -Re-enable in-band discovery with FILS/20 TU PRBR frames -if OOB gets disabled. - -Signed-off-by: Hari Chandrakanthan -Signed-off-by: Rameshkumar Sundaram ---- - src/ap/ap_config.h | 6 ++++ - src/ap/beacon.c | 30 +++++++++++++++++-- - src/ap/hostapd.c | 70 ++++++++++++++++++++++++++++++++++++++++++-- - src/ap/ieee802_11.c | 13 +++----- - src/ap/ieee802_11.h | 8 ++++- - src/drivers/driver_nl80211.c | 20 ++++++++----- - 6 files changed, 125 insertions(+), 22 deletions(-) - -diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h -index 80721ae..ab81568 100644 ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -913,6 +913,12 @@ struct hostapd_bss_config { - u8 rnr; - int beacon_tx_mode; - bool xrates_supported; -+ enum { -+ FILS_UBPR_USER_DISABLED, -+ FILS_UBPR_FORCE_DISABLED, -+ FILS_UBPR_ENABLED -+ } fils_state, ubpr_state; -+ - }; - - /** -diff --git a/src/ap/beacon.c b/src/ap/beacon.c -index 450f4b4..7d18473 100644 ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -1401,16 +1401,27 @@ static u8 * hostapd_probe_resp_offloads(struct hostapd_data *hapd, - - - #ifdef CONFIG_IEEE80211AX --/* Unsolicited broadcast Probe Response transmission, 6 GHz only */ -+/* Unsolicited broadcast Probe Response(UBPR) transmission, 6 GHz only */ - static u8 * hostapd_unsol_bcast_probe_resp(struct hostapd_data *hapd, - struct wpa_driver_ap_params *params) - { -+ /* Do not enable UBPR in 6GHz AP if colocated with lower band APs */ -+ hapd->conf->ubpr_state = FILS_UBPR_USER_DISABLED; - if (!is_6ghz_op_class(hapd->iconf->op_class)) - return NULL; - -+ if (hapd->conf->unsol_bcast_probe_resp_interval && -+ (get_colocation_mode(hapd) == COLOCATED_6GHZ)) { -+ hapd->conf->ubpr_state = FILS_UBPR_FORCE_DISABLED; -+ return NULL; -+ } -+ - params->unsol_bcast_probe_resp_interval = - hapd->conf->unsol_bcast_probe_resp_interval; - -+ if (params->unsol_bcast_probe_resp_interval) -+ hapd->conf->ubpr_state = FILS_UBPR_ENABLED; -+ - return hostapd_gen_probe_resp(hapd, NULL, 0, - ¶ms->unsol_bcast_probe_resp_tmpl_len, - NULL, 0); -@@ -1693,6 +1704,17 @@ static u8 * hostapd_gen_fils_discovery(struct hostapd_data *hapd, size_t *len) - static u8 * hostapd_fils_discovery(struct hostapd_data *hapd, - struct wpa_driver_ap_params *params) - { -+ /* Do not enable Fils discovery for 6GHz AP if its colocated -+ * with lower band APs. -+ */ -+ -+ if (is_6ghz_op_class(hapd->iconf->op_class) && -+ get_colocation_mode(hapd) == COLOCATED_6GHZ && -+ hapd->conf->fils_discovery_max_int) { -+ hapd->conf->fils_state = FILS_UBPR_FORCE_DISABLED; -+ return NULL; -+ } -+ - params->fd_max_int = hapd->conf->fils_discovery_max_int; - if (is_6ghz_op_class(hapd->iconf->op_class) && - params->fd_max_int > FD_MAX_INTERVAL_6GHZ) -@@ -1702,10 +1724,12 @@ static u8 * hostapd_fils_discovery(struct hostapd_data *hapd, - if (params->fd_min_int > params->fd_max_int) - params->fd_min_int = params->fd_max_int; - -- if (params->fd_max_int) -+ if (params->fd_max_int) { -+ hapd->conf->fils_state = FILS_UBPR_ENABLED; - return hostapd_gen_fils_discovery(hapd, - ¶ms->fd_frame_tmpl_len); -- -+ } -+ hapd->conf->fils_state = FILS_UBPR_USER_DISABLED; - return NULL; - } - -diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c -index 86e094a..44e2f4b 100644 ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -68,7 +68,8 @@ static void hostapd_interface_setup_failure_handler(void *eloop_ctx, - void *timeout_ctx); - static void - hostapd_switch_color_timeout_handler(void *eloop_data, void *user_ctx); -- -+static void -+hostapd_interface_update_fils_ubpr(struct hostapd_iface *iface, bool iface_enabled); - - int hostapd_for_each_interface(struct hapd_interfaces *interfaces, - int (*cb)(struct hostapd_iface *iface, -@@ -2271,6 +2272,8 @@ dfs_offload: - for (j = 0; j < iface->num_bss; j++) - hostapd_neighbor_set_own_report(iface->bss[j]); - -+ hostapd_interface_update_fils_ubpr(iface, true); -+ - return 0; - - fail: -@@ -2504,7 +2507,7 @@ void hostapd_interface_deinit(struct hostapd_iface *iface) - break; - hostapd_bss_deinit(iface->bss[j]); - } -- -+ hostapd_interface_update_fils_ubpr(iface, false); - #ifdef NEED_AP_MLME - hostapd_stop_setup_timers(iface); - eloop_cancel_timeout(ap_ht2040_timeout, iface, NULL); -@@ -2620,6 +2623,68 @@ static int ifname_in_use(struct hapd_interfaces *interfaces, const char *ifname) - return 0; - } - -+/** -+ * hostapd_interface_update_fils_ubpr - Update 6GHz In-band discovery -+ * frames (FILS/UBPR) based on lower band interface state change. -+ * @iface_enabled: Whether lower band AP is enabled or disabled -+ * -+ * This function iterates through interfaces list and updates all 6GHz -+ * APs In-band discovery frames (enable/disable) based on state of lower -+ * band interfaces. -+ * Lower band interfaces going down: Enable FILS/UBPR for all 6GHz APs if config -+ * has it enabled. -+ * Lower band interfaces coming up: Disable FILS/UBPR for all 6GHz APs if not done -+ * already. -+ */ -+ -+static void -+hostapd_interface_update_fils_ubpr(struct hostapd_iface *iface, bool iface_enabled) -+{ -+ int i, j; -+ -+ if (!iface || (iface->interfaces == NULL)) -+ return; -+ -+#ifdef CONFIG_MESH -+ if (iface->mconf != NULL) -+ return; -+#endif -+ -+ if (is_6ghz_op_class(iface->conf->op_class)) -+ return; -+ -+ for (i = 0; i < iface->interfaces->count; i++) { -+ struct hostapd_iface *iface_6g = iface->interfaces->iface[i]; -+ if (iface == iface_6g || !iface_6g || !iface_6g->conf) -+ continue; -+ -+ if (!is_6ghz_op_class(iface_6g->conf->op_class)) -+ continue; -+ -+ for (j = 0; j < iface_6g->num_bss; j++) { -+ if (!iface_6g->bss[j] || !iface_6g->bss[j]->started) -+ continue; -+ -+ /* Lower band interface coming up but fils/ubpr is already disabled */ -+ if (iface_enabled && -+ (iface_6g->bss[j]->conf->fils_state != FILS_UBPR_ENABLED && -+ iface_6g->bss[j]->conf->ubpr_state != FILS_UBPR_ENABLED)) { -+ continue; -+ } -+ /* Lower band interface going down but fils/ubpr is not force disabled */ -+ if (!iface_enabled && -+ (iface_6g->bss[j]->conf->fils_state != FILS_UBPR_FORCE_DISABLED && -+ iface_6g->bss[j]->conf->ubpr_state != FILS_UBPR_FORCE_DISABLED)) { -+ continue; -+ } -+ wpa_printf(MSG_DEBUG, "%s Interface getting %s, check and set 6GHz Interface(%s)" -+ "In-band discovery frames", iface->bss[0]->conf->iface, -+ iface_enabled ? "enabled" : "disabled", iface_6g->bss[j]->conf->iface); -+ ieee802_11_set_beacon(iface_6g->bss[j]); -+ } -+ } -+ return; -+} - - /** - * hostapd_interface_init_bss - Read configuration file and init BSS data -@@ -2899,6 +2964,7 @@ int hostapd_disable_iface(struct hostapd_iface *hapd_iface) - wpa_printf(MSG_DEBUG, "Interface %s disabled", - hapd_iface->bss[0]->conf->iface); - hostapd_set_state(hapd_iface, HAPD_IFACE_DISABLED); -+ hostapd_interface_update_fils_ubpr(hapd_iface, false); - return 0; - } - -diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c -index 0502587..fea45da 100644 ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -7446,15 +7446,7 @@ static size_t hostapd_eid_rnr_iface_len(struct hostapd_data *hapd, - return total_len; - } - -- --enum colocation_mode { -- NO_COLOCATED_6GHZ, -- STANDALONE_6GHZ, -- COLOCATED_6GHZ, -- COLOCATED_LOWER_BAND, --}; -- --static enum colocation_mode get_colocation_mode(struct hostapd_data *hapd) -+enum colocation_mode get_colocation_mode(struct hostapd_data *hapd) - { - u8 i; - bool is_6ghz = is_6ghz_op_class(hapd->iconf->op_class); -@@ -7473,6 +7465,9 @@ static enum colocation_mode get_colocation_mode(struct hostapd_data *hapd) - if (iface == hapd->iface || !iface || !iface->conf) - continue; - -+ if (iface->state == HAPD_IFACE_DISABLED) -+ continue; -+ - is_colocated_6ghz = is_6ghz_op_class(iface->conf->op_class); - if (!is_6ghz && is_colocated_6ghz) - return COLOCATED_LOWER_BAND; -diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h -index 79b0e54..7cdcf81 100644 ---- a/src/ap/ieee802_11.h -+++ b/src/ap/ieee802_11.h -@@ -19,7 +19,13 @@ struct ieee80211_mgmt; - struct radius_sta; - enum ieee80211_op_mode; - struct mac_acl_entry; -- -+enum colocation_mode { -+ NO_COLOCATED_6GHZ, -+ STANDALONE_6GHZ, -+ COLOCATED_6GHZ, -+ COLOCATED_LOWER_BAND, -+}; -+enum colocation_mode get_colocation_mode(struct hostapd_data *hapd); - int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len, - struct hostapd_frame_info *fi); - void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len, -diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c -index 7687a72..d7b9508 100644 ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -4506,10 +4506,13 @@ static int nl80211_fils_discovery(struct i802_bss *bss, struct nl_msg *msg, - struct nlattr *attr; - - if (!bss->drv->fils_discovery) { -- wpa_printf(MSG_ERROR, -- "nl80211: Driver does not support FILS Discovery frame transmission for %s", -- bss->ifname); -- return -1; -+ if (params->fd_max_int) { -+ wpa_printf(MSG_ERROR, -+ "nl80211: Driver does not support FILS Discovery frame transmission for %s", -+ bss->ifname); -+ return -1; -+ } -+ return 0; - } - - attr = nla_nest_start(msg, NL80211_ATTR_FILS_DISCOVERY); -@@ -4537,10 +4540,13 @@ static int nl80211_unsol_bcast_probe_resp(struct i802_bss *bss, - struct nlattr *attr; - - if (!bss->drv->unsol_bcast_probe_resp) { -- wpa_printf(MSG_ERROR, -- "nl80211: Driver does not support unsolicited broadcast Probe Response frame transmission for %s", -+ if (params->unsol_bcast_probe_resp_interval) { -+ wpa_printf(MSG_ERROR, -+ "nl80211: Driver does not support unsolicited broadcast Probe Response frame transmission for %s", - bss->ifname); -- return -1; -+ return -1; -+ } -+ return 0; - } - - wpa_printf(MSG_DEBUG, --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-46-hostapd-Add-support-to-enable-disable-bss-color-coll.patch b/feeds/ipq95xx/hostapd/patches/q02-46-hostapd-Add-support-to-enable-disable-bss-color-coll.patch deleted file mode 100644 index 11a30ddd..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-46-hostapd-Add-support-to-enable-disable-bss-color-coll.patch +++ /dev/null @@ -1,143 +0,0 @@ -From f0ec4fbe637b87e21ae5443318be5e322cc6f895 Mon Sep 17 00:00:00 2001 -From: Dinesh Karthikeyan -Date: Thu, 9 Jun 2022 11:42:34 +0530 -Subject: [PATCH] hostapd: Add support to enable/disable bss color collision - detection - -Add color collision detection parameters to provide user config -option to enable or disable it. - -Signed-off-by: Dinesh Karthikeyan ---- - hostapd/config_file.c | 2 ++ - hostapd/hostapd.conf | 4 ++++ - src/ap/ap_config.c | 1 + - src/ap/ap_config.h | 1 + - src/ap/beacon.c | 2 ++ - src/drivers/driver.h | 6 ++++++ - src/drivers/driver_nl80211.c | 5 ++++- - src/drivers/nl80211_copy.h | 3 +++ - 8 files changed, 23 insertions(+), 1 deletion(-) - -diff --git a/hostapd/config_file.c b/hostapd/config_file.c -index 2aae477..ede28a7 100644 ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -3430,6 +3430,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, - conf->he_op.he_bss_color_disabled = 0; - } else if (os_strcmp(buf, "he_bss_color_partial") == 0) { - conf->he_op.he_bss_color_partial = atoi(pos); -+ } else if (os_strcmp(buf, "he_bss_color_collision_detection") == 0) { -+ conf->he_op.he_bss_color_collision_detection = atoi(pos); - } else if (os_strcmp(buf, "he_default_pe_duration") == 0) { - conf->he_op.he_default_pe_duration = atoi(pos); - } else if (os_strcmp(buf, "he_twt_required") == 0) { -diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf -index e4328d3..426ff97 100644 ---- a/hostapd/hostapd.conf -+++ b/hostapd/hostapd.conf -@@ -846,6 +846,10 @@ wmm_ac_vo_acm=0 - # he_bss_color_partial: BSS color AID equation - #he_bss_color_partial=0 - -+# he_bss_color_collision_detection: disable/enable BSS color collision -+#detection # 0 = disabled # 1 = enabled (default) -+#he_bss_color_collision_detection=1 -+ - #he_default_pe_duration: The duration of PE field in an HE PPDU in us - # Possible values are 0 us (default), 4 us, 8 us, 12 us, and 16 us - #he_default_pe_duration=0 -diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c -index a237e72..aca3420 100644 ---- a/src/ap/ap_config.c -+++ b/src/ap/ap_config.c -@@ -278,6 +278,7 @@ struct hostapd_config * hostapd_config_defaults(void) - conf->he_op.he_bss_color_disabled = 1; - conf->he_op.he_bss_color_partial = 0; - conf->he_op.he_bss_color = os_random() % 63 + 1; -+ conf->he_op.he_bss_color_collision_detection = 1; - conf->he_op.he_twt_responder = 1; - conf->he_6ghz_max_mpdu = 2; - conf->he_6ghz_max_ampdu_len_exp = 7; -diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h -index e16b123..5d12cf5 100644 ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -932,6 +932,7 @@ struct he_operation { - u8 he_bss_color; - u8 he_bss_color_disabled; - u8 he_bss_color_partial; -+ u8 he_bss_color_collision_detection; - u8 he_default_pe_duration; - u8 he_twt_required; - u8 he_twt_responder; -diff --git a/src/ap/beacon.c b/src/ap/beacon.c -index e331f9c..ed4444b 100644 ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -2149,6 +2149,8 @@ static int __ieee802_11_set_beacon(struct hostapd_data *hapd) - params.he_bss_color_partial = - hapd->iface->conf->he_op.he_bss_color_partial; - params.he_bss_color = hapd->iface->conf->he_op.he_bss_color; -+ params.he_bss_color_collision_detection = -+ hapd->iface->conf->he_op.he_bss_color_collision_detection; - params.twt_responder = hostapd_get_he_twt_responder(hapd, - IEEE80211_MODE_AP); - params.unsol_bcast_probe_resp_tmpl = -diff --git a/src/drivers/driver.h b/src/drivers/driver.h -index 038379b..70ec0fc 100644 ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -1625,6 +1625,12 @@ struct wpa_driver_ap_params { - int he_bss_color; - - /** -+ * he_bss_color_collision_detection - Whether the BSS Color collision -+ * detection is enabled -+ */ -+ int he_bss_color_collision_detection; -+ -+ /** - * twt_responder - Whether Target Wait Time responder is enabled - */ - int twt_responder; -diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c -index a89097d..c885489 100644 ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -4895,7 +4895,10 @@ static int wpa_driver_nl80211_set_ap(void *priv, - (params->he_bss_color_partial && - nla_put_flag(msg, NL80211_HE_BSS_COLOR_ATTR_PARTIAL)) || - nla_put_u8(msg, NL80211_HE_BSS_COLOR_ATTR_COLOR, -- params->he_bss_color)) -+ params->he_bss_color) || -+ (!params->he_bss_color_collision_detection && -+ nla_put_flag(msg, -+ NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED))) - goto fail; - nla_nest_end(msg, bss_color); - } -diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h -index e14e3ac..2ba40ba 100644 ---- a/src/drivers/nl80211_copy.h -+++ b/src/drivers/nl80211_copy.h -@@ -7231,6 +7231,8 @@ enum nl80211_obss_pd_attributes { - * @NL80211_HE_BSS_COLOR_ATTR_COLOR: the current BSS Color. - * @NL80211_HE_BSS_COLOR_ATTR_DISABLED: is BSS coloring disabled. - * @NL80211_HE_BSS_COLOR_ATTR_PARTIAL: the AID equation to be used.. -+ * @NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED: is BSS -+ * color collision detection disabled. - * - * @__NL80211_HE_BSS_COLOR_ATTR_LAST: Internal - * @NL80211_HE_BSS_COLOR_ATTR_MAX: highest BSS Color attribute. -@@ -7241,6 +7243,7 @@ enum nl80211_bss_color_attributes { - NL80211_HE_BSS_COLOR_ATTR_COLOR, - NL80211_HE_BSS_COLOR_ATTR_DISABLED, - NL80211_HE_BSS_COLOR_ATTR_PARTIAL, -+ NL80211_HE_BSS_COLOR_ATTR_COLLISION_DETECTION_DISABLED, - - /* keep last */ - __NL80211_HE_BSS_COLOR_ATTR_LAST, --- -2.7.4 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-47-Changes-to-disable-compilation-errors-in-32-bit-arch.patch b/feeds/ipq95xx/hostapd/patches/q02-47-Changes-to-disable-compilation-errors-in-32-bit-arch.patch deleted file mode 100644 index 35cd9255..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-47-Changes-to-disable-compilation-errors-in-32-bit-arch.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 724e708744606d4b8e2a8e5732730e2ff368ff0c Mon Sep 17 00:00:00 2001 -From: Avula Sri Charan -Date: Thu, 27 Oct 2022 10:52:12 +0530 -Subject: [PATCH] Changes to disable compilation errors in 32 bit - -In yocto builds signcontext-32.h will be included for 32 -bit builds and signcontext-64.h for 64 bit builds because -of the absence of linux/types.h in signcontext-32.h we will -face the error __s8 undfined.So adding typedef of __s8 in -linux_wext.h. - -Signed-off-by: Avula Sri Charan ---- - src/drivers/linux_wext.h | 1 + - 1 file changed, 1 insertion(+) - -Index: hostapd-2021-12-13-b26f5c0f/src/drivers/linux_wext.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/drivers/linux_wext.h -+++ hostapd-2021-12-13-b26f5c0f/src/drivers/linux_wext.h -@@ -27,6 +27,7 @@ typedef uint16_t __u16; - typedef int16_t __s16; - typedef uint8_t __u8; - typedef int8_t __s8; -+typedef __signed__ char __s8; - #ifndef __user - #define __user - #endif /* __user */ diff --git a/feeds/ipq95xx/hostapd/patches/q02-50-hostapd-240MHz-Q-Q-vendor-IE-support.patch b/feeds/ipq95xx/hostapd/patches/q02-50-hostapd-240MHz-Q-Q-vendor-IE-support.patch deleted file mode 100644 index 54df819e..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-50-hostapd-240MHz-Q-Q-vendor-IE-support.patch +++ /dev/null @@ -1,532 +0,0 @@ -From e4b73d7748efe3a6fe273a87897254ac9fcebbb1 Mon Sep 17 00:00:00 2001 -From: Ramya Gnanasekar -Date: Wed, 26 Oct 2022 15:19:47 +0530 -Subject: [PATCH] hostapd: 240MHz Q-Q vendor IE support - -240MHz is Q-Q feature and it should be advertised through -vendor IE in beacon, probe request/response and association. - -This patch has changes to add vendor IE to management frames, -parse the IE from STA and copy the capability which is later -advertised to mac80211 through NL attribute. - -Signed-off-by: Ramya Gnanasekar - -Index: hostapd-2021-12-13-b26f5c0f/src/ap/ap_drv_ops.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/ap_drv_ops.c -+++ hostapd-2021-12-13-b26f5c0f/src/ap/ap_drv_ops.c -@@ -419,6 +419,8 @@ int hostapd_sta_add(struct hostapd_data - size_t he_capab_len, size_t eht_capab_len, - const struct ieee80211_he_6ghz_band_cap *he_6ghz_capab, - u32 flags, u8 qosinfo, u8 vht_opmode, int supp_p2p_ps, -+ const struct ieee80211_240mhz_vendor_oper *eht_240mhz_capab, -+ size_t eht_240mhz_len, - int set) - { - struct hostapd_sta_add_params params; -@@ -448,6 +450,8 @@ int hostapd_sta_add(struct hostapd_data - params.qosinfo = qosinfo; - params.support_p2p_ps = supp_p2p_ps; - params.set = set; -+ params.eht_240mhz_capab = eht_240mhz_capab; -+ params.eht_240mhz_len = eht_240mhz_len; - return hapd->driver->sta_add(hapd->drv_priv, ¶ms); - } - -Index: hostapd-2021-12-13-b26f5c0f/src/ap/ap_drv_ops.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/ap_drv_ops.h -+++ hostapd-2021-12-13-b26f5c0f/src/ap/ap_drv_ops.h -@@ -46,6 +46,8 @@ int hostapd_sta_add(struct hostapd_data - size_t he_capab_len, size_t eht_capab_len, - const struct ieee80211_he_6ghz_band_cap *he_6ghz_capab, - u32 flags, u8 qosinfo, u8 vht_opmode, int supp_p2p_ps, -+ const struct ieee80211_240mhz_vendor_oper *eht_240mhz_capab, -+ size_t eht_240mhz_len, - int set); - int hostapd_set_privacy(struct hostapd_data *hapd, int enabled); - int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem, -Index: hostapd-2021-12-13-b26f5c0f/src/ap/beacon.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/beacon.c -+++ hostapd-2021-12-13-b26f5c0f/src/ap/beacon.c -@@ -651,6 +651,10 @@ static u8 * hostapd_gen_probe_resp(struc - buflen += (3 + sizeof(struct ieee80211_eht_operation)); - if (hapd->iconf->ru_punct_bitmap) - buflen += DISABLED_SUBCHANNEL_BITMAP_BYTES_SIZE; -+ /* QCN Vendor IE for 240MHz */ -+ if (is_5ghz_freq(hapd->iface->freq)) -+ buflen += (6 + 2 + 4 + -+ sizeof(struct ieee80211_240mhz_vendor_oper)); - - } - #endif /* CONFIG_IEEE80211BE */ -@@ -809,6 +813,7 @@ static u8 * hostapd_gen_probe_resp(struc - if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { - pos = hostapd_eid_eht_capab(hapd, pos, IEEE80211_MODE_AP); - pos = hostapd_eid_eht_operation(hapd, pos, IEEE80211_MODE_AP); -+ pos = hostapd_eid_vendor_240mhz(hapd, pos, IEEE80211_MODE_AP); - } - #endif /* CONFIG_IEEE80211BE */ - -@@ -1802,6 +1807,9 @@ int ieee802_11_build_ap_params(struct ho - tail_len += (3 + sizeof(struct ieee80211_eht_operation)); - if (hapd->iconf->ru_punct_bitmap) - tail_len += DISABLED_SUBCHANNEL_BITMAP_BYTES_SIZE; -+ if (is_5ghz_freq(hapd->iface->freq)) -+ tail_len += (6 + 2 + 4 + -+ sizeof(struct ieee80211_240mhz_vendor_oper)); - } - #endif /* CONFIG_IEEE80211BE */ - -@@ -1965,6 +1973,8 @@ int ieee802_11_build_ap_params(struct ho - IEEE80211_MODE_AP); - tailpos = hostapd_eid_eht_operation(hapd, tailpos, - IEEE80211_MODE_AP); -+ tailpos = hostapd_eid_vendor_240mhz(hapd, tailpos, -+ IEEE80211_MODE_AP); - } - #endif /* CONFIG_IEEE80211BE */ - -Index: hostapd-2021-12-13-b26f5c0f/src/ap/ieee802_11.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/ieee802_11.c -+++ hostapd-2021-12-13-b26f5c0f/src/ap/ieee802_11.c -@@ -4607,6 +4607,9 @@ static int check_assoc_ies(struct hostap - elems.he_capabilities, - elems.eht_capabilities, - elems.eht_capabilities_len); -+ resp = copy_sta_eht_240mhz_capab(hapd, sta, IEEE80211_MODE_AP, -+ elems.eht_240mhz_capab, -+ elems.eht_240mhz_len); - if (resp != WLAN_STATUS_SUCCESS) - return resp; - } -@@ -4983,6 +4986,7 @@ static int add_associated_sta(struct hos - struct ieee80211_vht_capabilities vht_cap; - struct ieee80211_he_capabilities he_cap; - struct ieee80211_eht_capabilities eht_cap; -+ struct ieee80211_240mhz_vendor_oper eht_240mhz_cap; - int set = 1; - - /* -@@ -5043,6 +5047,8 @@ static int add_associated_sta(struct hos - if (sta->flags & WLAN_STA_EXT_EHT) { - hostapd_get_eht_capab(hapd, sta->eht_capab, &eht_cap, - sta->eht_capab_len); -+ hostapd_get_eht_240mhz_capab(hapd, sta->eht_240mhz_capab, &eht_240mhz_cap, -+ sta->eht_240mhz_len); - } - #endif /* CONFIG_IEEE80211BE */ - -@@ -5063,6 +5069,8 @@ static int add_associated_sta(struct hos - sta->he_6ghz_capab, - sta->flags | WLAN_STA_ASSOC, sta->qosinfo, - sta->vht_opmode, sta->p2p_ie ? 1 : 0, -+ sta->flags_ext & WLAN_STA_EXT_EHT? sta->eht_240mhz_capab : NULL, -+ sta->flags_ext & WLAN_STA_EXT_EHT? sta->eht_240mhz_len : 0, - set)) { - hostapd_logger(hapd, sta->addr, - HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_NOTICE, -@@ -5116,6 +5124,9 @@ static u16 send_assoc_resp(struct hostap - buflen += (3 + sizeof(struct ieee80211_eht_operation)); - if (hapd->iconf->ru_punct_bitmap) - buflen += DISABLED_SUBCHANNEL_BITMAP_BYTES_SIZE; -+ if (is_5ghz_freq(hapd->iface->freq)) -+ buflen += (6 + 2 + 4 + -+ sizeof(struct ieee80211_240mhz_vendor_oper)); - } - #endif /* CONFIG_IEEE80211BE */ - -@@ -5237,6 +5248,7 @@ static u16 send_assoc_resp(struct hostap - if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { - p = hostapd_eid_eht_capab(hapd, p, IEEE80211_MODE_AP); - p = hostapd_eid_eht_operation(hapd, p, IEEE80211_MODE_AP); -+ p = hostapd_eid_vendor_240mhz(hapd, p, IEEE80211_MODE_AP); - } - #endif /* CONFIG_IEEE80211BE */ - -Index: hostapd-2021-12-13-b26f5c0f/src/ap/ieee802_11.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/ieee802_11.h -+++ hostapd-2021-12-13-b26f5c0f/src/ap/ieee802_11.h -@@ -97,6 +97,10 @@ void hostapd_get_eht_capab(struct hostap - const struct ieee80211_eht_capabilities *src, - struct ieee80211_eht_capabilities *dest, - size_t len); -+void hostapd_get_eht_240mhz_capab(struct hostapd_data *hapd, -+ const struct ieee80211_240mhz_vendor_oper *src, -+ struct ieee80211_240mhz_vendor_oper *dest, -+ size_t len); - int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta); - u16 copy_sta_ht_capab(struct hostapd_data *hapd, struct sta_info *sta, - const u8 *ht_capab); -@@ -231,8 +235,13 @@ u8 * hostapd_eid_eht_capab(struct hostap - enum ieee80211_op_mode opmode); - u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid, - enum ieee80211_op_mode opmode); -+u8 * hostapd_eid_vendor_240mhz(struct hostapd_data *hapd, u8 *eid, -+ enum ieee80211_op_mode opmode); - u16 copy_sta_eht_capab(struct hostapd_data *hapd, struct sta_info *sta, - enum ieee80211_op_mode opmode, const u8 *he_capab, - const u8 *eht_capab, size_t eht_capab_len); -+u16 copy_sta_eht_240mhz_capab(struct hostapd_data *hapd, struct sta_info *sta, -+ enum ieee80211_op_mode opmode, -+ const u8 *eht_240mhz_capab, size_t eht_240mhz_len); - void ru_punct_update_bw(u16 bitmap, u8 pri_chan, u8 *width, u8 *seg0, u8 *seg1); - #endif /* IEEE802_11_H */ -Index: hostapd-2021-12-13-b26f5c0f/src/ap/ieee802_11_eht.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/ieee802_11_eht.c -+++ hostapd-2021-12-13-b26f5c0f/src/ap/ieee802_11_eht.c -@@ -18,6 +18,7 @@ - - #include "utils/includes.h" - #include "utils/common.h" -+#include "common/qca-vendor.h" - #include "hostapd.h" - #include "ieee802_11.h" - #include "sta_info.h" -@@ -112,7 +113,7 @@ u8 * hostapd_eid_eht_capab(struct hostap - struct eht_capabilities *eht_cap; - struct ieee80211_eht_capabilities *cap; - size_t mcs_nss_len, ppe_thresh_len; -- u8 *pos = eid, *length_pos, chwidth; -+ u8 *pos = eid, *length_pos; - - mode = hapd->iface->current_mode; - if (!mode) -@@ -130,10 +131,8 @@ u8 * hostapd_eid_eht_capab(struct hostap - os_memset(cap, 0, sizeof(*cap)); - os_memcpy(cap->mac_cap, eht_cap->mac_cap, EHT_MAC_CAPAB_MAX_LEN); - os_memcpy(cap->phy_cap, eht_cap->phy_cap, EHT_PHY_CAPAB_MAX_LEN); -- chwidth = hapd->iconf->eht_oper_chwidth; - -- if (!is_6ghz_op_class(hapd->iconf->op_class) && -- (chwidth != CHANWIDTH_320MHZ)) -+ if (!is_6ghz_op_class(hapd->iconf->op_class)) - cap->phy_cap[EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_IDX] &= - ~EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK; - if (!hapd->iface->conf->eht_phy_capab.su_beamformer) -@@ -289,6 +288,70 @@ u8 * hostapd_eid_eht_operation(struct ho - return pos; - } - -+u8 * hostapd_eid_vendor_240mhz(struct hostapd_data *hapd, u8 *eid, -+ enum ieee80211_op_mode opmode) -+{ -+ struct hostapd_hw_modes *mode; -+ u8 *pos = eid; -+ struct eht_capabilities *eht_cap; -+ struct ieee80211_240mhz_vendor_oper *eht_240_cap; -+ u8 ccfs0,ccfs1; -+ -+ mode = hapd->iface->current_mode; -+ if (!mode || is_6ghz_op_class(hapd->iconf->op_class) || -+ hapd->iconf->eht_oper_chwidth != CHANWIDTH_320MHZ) -+ return eid; -+ -+ eht_cap = &mode->eht_capab[opmode]; -+ -+ if (!eht_cap->eht_supported) -+ return eid; -+ ccfs0 = hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf); -+ ccfs1 = ccfs0 - 16; -+ -+ *pos++ = WLAN_EID_VENDOR_SPECIFIC; -+ *pos++ = 6 + /* Element ID, Length, OUI, OUI Type */ -+ 4 + /* QCN version Attribute size */ -+ sizeof(struct ieee80211_240mhz_vendor_oper); -+ WPA_PUT_BE24(pos, OUI_QCN); -+ pos += 3; -+ *pos++ = 1; /* QCN_OUI_TYPE */ -+ -+ /* QCN Version Attribute*/ -+ *pos++ = 1; /* QCN_ATTRIB_VERSION */ -+ *pos++ = 2; /* Length */ -+ *pos++ = 1; /* QCN_VER_ATTR_VER */ -+ *pos++ = 0; /* QCN_VER_ATTR_SUBVERSION */ -+ -+ /* QCN Attirbute */ -+ *pos++ = QCN_ATTRIB_HE_240_MHZ_SUPP; /*QCN_ATTRIB_HE_240_MHZ_SUPP*/ -+ *pos++ = sizeof(struct ieee80211_240mhz_vendor_oper); -+ -+ /* 240Mhz fields */ -+ eht_240_cap = (struct ieee80211_240mhz_vendor_oper*)pos; -+ os_memset(eht_240_cap, 0, sizeof(struct ieee80211_240mhz_vendor_oper)); -+ -+ eht_240_cap->ccfs1 = ccfs1; -+ eht_240_cap->ccfs0 = hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf); -+ eht_240_cap->ru_punct_bitmap = hapd->iconf->ru_punct_bitmap; -+ eht_240_cap->phy_cap_320mhz = eht_cap->phy_cap[EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_IDX] & -+ EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK; -+ eht_240_cap->phy_cap_320mhz |= eht_cap->phy_cap[EHT_PHYCAP_BEAMFORMEE_SS_320MHZ_IDX] & -+ EHT_PHYCAP_BEAMFORMEE_SS_320MHZ_MASK; -+ eht_240_cap->phy_cap_320mhz |= (eht_cap->phy_cap[EHT_PHYCAP_NUM_SOUND_DIM_320MHZ_IDX] & -+ EHT_PHYCAP_NUM_SOUND_DIM_320MHZ_MASK) | -+ (eht_cap->phy_cap[EHT_PHYCAP_NUM_SOUND_DIM_320MHZ_IDX_1] & -+ EHT_PHYCAP_NUM_SOUND_DIM_320MHZ_MASK); -+ eht_240_cap->phy_cap_320mhz |= eht_cap->phy_cap[EHT_PHYCAP_NON_OFDMA_UL_MUMIMO_320MHZ_IDX] & -+ EHT_PHYCAP_NON_OFDMA_UL_MUMIMO_320MHZ_MASK; -+ eht_240_cap->phy_cap_320mhz |= eht_cap->phy_cap[EHT_PHYCAP_MU_CAPABILITY_IDX] & -+ EHT_PHYCAP_MU_BEAMFORMER_MASK; -+ -+ memcpy(&eht_240_cap->mcs_map_320mhz, &eht_cap->mcs, EHT_PHYCAP_MCS_NSS_LEN_160MHZ); -+ pos += sizeof(struct ieee80211_240mhz_vendor_oper); -+ -+ return pos; -+} - - static int check_valid_eht_mcs_nss(struct hostapd_data *hapd, const u8 *ap_mcs, - const u8 *sta_mcs, u8 mcs_count, u8 map_len) -@@ -426,3 +489,41 @@ void hostapd_get_eht_capab(struct hostap - - os_memcpy(dest, src, len); - } -+ -+u16 copy_sta_eht_240mhz_capab(struct hostapd_data *hapd, struct sta_info *sta, -+ enum ieee80211_op_mode opmode, -+ const u8 *eht_240mhz_capab, size_t eht_240mhz_capab_len) -+{ -+ if (!eht_240mhz_capab || !hapd->iconf->ieee80211be || -+ hapd->conf->disable_11be) { -+ os_free(sta->eht_240mhz_capab); -+ sta->eht_240mhz_capab = NULL; -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ if (!sta->eht_240mhz_capab) { -+ sta->eht_240mhz_capab = os_zalloc(eht_240mhz_capab_len); -+ if (!sta->eht_240mhz_capab) -+ return WLAN_STATUS_UNSPECIFIED_FAILURE; -+ } -+ -+ os_memcpy(sta->eht_240mhz_capab, eht_240mhz_capab, eht_240mhz_capab_len); -+ sta->eht_240mhz_len = eht_240mhz_capab_len; -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+ -+void hostapd_get_eht_240mhz_capab(struct hostapd_data *hapd, -+ const struct ieee80211_240mhz_vendor_oper *src, -+ struct ieee80211_240mhz_vendor_oper *dest, -+ size_t len) -+{ -+ if (!src || !dest) -+ return; -+ -+ if (len > sizeof(*dest)) -+ len = sizeof(*dest); -+ -+ os_memcpy(dest, src, len); -+} -Index: hostapd-2021-12-13-b26f5c0f/src/ap/sta_info.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/sta_info.c -+++ hostapd-2021-12-13-b26f5c0f/src/ap/sta_info.c -@@ -359,6 +359,7 @@ void ap_free_sta(struct hostapd_data *ha - os_free(sta->he_capab); - os_free(sta->he_6ghz_capab); - os_free(sta->eht_capab); -+ os_free(sta->eht_240mhz_capab); - hostapd_free_psk_list(sta->psk); - os_free(sta->identity); - os_free(sta->radius_cui); -@@ -1579,7 +1580,7 @@ int ap_sta_re_add(struct hostapd_data *h - sta->supported_rates, - sta->supported_rates_len, - 0, NULL, NULL, NULL, NULL, 0, 0, NULL, -- sta->flags, 0, 0, 0, 0)) { -+ sta->flags, 0, 0, 0, NULL, 0, 0)) { - hostapd_logger(hapd, sta->addr, - HOSTAPD_MODULE_IEEE80211, - HOSTAPD_LEVEL_NOTICE, -Index: hostapd-2021-12-13-b26f5c0f/src/ap/sta_info.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/ap/sta_info.h -+++ hostapd-2021-12-13-b26f5c0f/src/ap/sta_info.h -@@ -340,6 +340,8 @@ struct sta_info { - struct pasn_data *pasn; - #endif /* CONFIG_PASN */ - int signal_mgmt; -+ struct ieee80211_240mhz_vendor_oper *eht_240mhz_capab; -+ size_t eht_240mhz_len; - }; - - -Index: hostapd-2021-12-13-b26f5c0f/src/common/ieee802_11_common.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/common/ieee802_11_common.c -+++ hostapd-2021-12-13-b26f5c0f/src/common/ieee802_11_common.c -@@ -22,6 +22,7 @@ static int ieee802_11_parse_vendor_speci - int show_errors) - { - unsigned int oui; -+ u8 len, updated_len; - - /* first 3 bytes in vendor specific information element are the IEEE - * OUI of the vendor. The following byte is used a vendor specific -@@ -187,6 +188,36 @@ static int ieee802_11_parse_vendor_speci - } - break; - -+ case OUI_QCN: -+ len = updated_len = 0; -+ if (pos[3] == 0x1 ) { /* QCN_OUI_TYPE */ -+ updated_len += 4; -+ pos = pos + 4; /* Move OUI(3) and OUI_TYPE (1) */ -+ while (elen > updated_len) { -+ switch(pos[0]) { -+ case QCN_ATTRIB_HE_240_MHZ_SUPP: -+ elems->eht_240mhz_len = pos[1]; -+ if (elems->eht_240mhz_len > QCN_HE_240_MHZ_MAX_ELEM_LEN) { -+ wpa_printf(MSG_DEBUG, "Length %d for 240MHz Vendor IE exceeded", -+ elems->eht_240mhz_len); -+ elems->eht_240mhz_len = 0; -+ continue; -+ } -+ len = elems->eht_240mhz_len; -+ pos = pos + 2; -+ elems->eht_240mhz_capab = pos; -+ pos += len; -+ updated_len += len + 2; -+ break; -+ default: -+ len = pos[1]; -+ updated_len += len + 2; -+ pos += len + 2; -+ break; -+ } -+ } -+ } -+ break; - default: - wpa_printf(MSG_EXCESSIVE, "unknown vendor specific " - "information element ignored (vendor OUI " -@@ -427,6 +458,7 @@ ParseRes ieee802_11_parse_elems(const u8 - elems->ext_supp_rates_len = elen; - break; - case WLAN_EID_VENDOR_SPECIFIC: -+ - if (ieee802_11_parse_vendor_specific(pos, elen, - elems, - show_errors)) -Index: hostapd-2021-12-13-b26f5c0f/src/common/ieee802_11_common.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/common/ieee802_11_common.h -+++ hostapd-2021-12-13-b26f5c0f/src/common/ieee802_11_common.h -@@ -121,6 +121,7 @@ struct ieee802_11_elems { - const u8 *mbssid_known_bss; - const u8 *eht_capabilities; - const u8 *eht_operation; -+ const u8 *eht_240mhz_capab; - - u8 ssid_len; - u8 supp_rates_len; -@@ -178,6 +179,7 @@ struct ieee802_11_elems { - u8 mbssid_known_bss_len; - u8 eht_capabilities_len; - u8 eht_operation_len; -+ u8 eht_240mhz_len; - - struct mb_ies_info mb_ies; - struct frag_ies_info frag_ies; -Index: hostapd-2021-12-13-b26f5c0f/src/common/ieee802_11_defs.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/common/ieee802_11_defs.h -+++ hostapd-2021-12-13-b26f5c0f/src/common/ieee802_11_defs.h -@@ -2494,6 +2494,13 @@ struct ieee80211_eht_operation { - le16 disabled_subchannel_bitmap[0]; - } STRUCT_PACKED; - -+struct ieee80211_240mhz_vendor_oper { -+ u8 ccfs1; -+ u8 ccfs0; -+ u16 ru_punct_bitmap; -+ u16 phy_cap_320mhz; -+ u8 mcs_map_320mhz[3]; -+} STRUCT_PACKED; - - #define EHT_OPERATION_CHANNEL_WIDTH_20MHZ 0 - #define EHT_OPERATION_CHANNEL_WIDTH_40MHZ 1 -@@ -2526,6 +2533,19 @@ struct ieee80211_eht_operation { - EHT_PHYCAP_MU_BEAMFORMER_160MHZ | \ - EHT_PHYCAP_MU_BEAMFORMER_320MHZ) - -+#define EHT_PHYCAP_BEAMFORMEE_SS_320MHZ_IDX 3 -+#define EHT_PHYCAP_BEAMFORMEE_SS_320MHZ_MASK ((u8) (BIT(0) | BIT(1) | \ -+ BIT(2) | BIT(3))) -+ -+#define EHT_PHYCAP_NUM_SOUND_DIM_320MHZ_IDX 1 -+#define EHT_PHYCAP_NUM_SOUND_DIM_320MHZ_MASK ((u8) (BIT(0) | BIT(2) | \ -+ BIT(3))) -+#define EHT_PHYCAP_NUM_SOUND_DIM_320MHZ_IDX_1 2 -+#define EHT_PHYCAP_NUM_SOUND_DIM_320MHZ_MASK_1 ((u8) (BIT(0)) -+ -+#define EHT_PHYCAP_NON_OFDMA_UL_MUMIMO_320MHZ_IDX 6 -+#define EHT_PHYCAP_NON_OFDMA_UL_MUMIMO_320MHZ_MASK ((u8) BIT(3)) -+ - /* - * IEEE P802.11be/D1.0, May 2021, - * section 9.4.2.295c.4 Supported EHT-MCS And NSS Set field -Index: hostapd-2021-12-13-b26f5c0f/src/common/qca-vendor.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/common/qca-vendor.h -+++ hostapd-2021-12-13-b26f5c0f/src/common/qca-vendor.h -@@ -18,6 +18,10 @@ - */ - - #define OUI_QCA 0x001374 -+#define OUI_QCN 0x8cfdf0 -+ -+#define QCN_ATTRIB_HE_240_MHZ_SUPP 0X0B -+#define QCN_HE_240_MHZ_MAX_ELEM_LEN 9 - - #ifndef BIT - #define BIT(x) (1U << (x)) -Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/drivers/driver.h -+++ hostapd-2021-12-13-b26f5c0f/src/drivers/driver.h -@@ -2398,6 +2398,8 @@ struct hostapd_sta_add_params { - size_t supp_oper_classes_len; - int support_p2p_ps; - u16 ru_punct_bitmap; -+ const struct ieee80211_240mhz_vendor_oper *eht_240mhz_capab; -+ size_t eht_240mhz_len; - }; - - struct mac_address { -Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211.c -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/drivers/driver_nl80211.c -+++ hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211.c -@@ -5285,6 +5285,14 @@ static int wpa_driver_nl80211_sta_add(vo - goto fail; - } - -+ if (params->eht_240mhz_capab) { -+ wpa_hexdump(MSG_DEBUG, " * 240mhz_capab", -+ (u8 *)params->eht_240mhz_capab, params->eht_240mhz_len); -+ if (nla_put(msg, NL80211_ATTR_EHT_240MHZ_CAPABILITY, -+ params->eht_240mhz_len, params->eht_240mhz_capab)) -+ goto fail; -+ } -+ - if (params->ext_capab) { - wpa_hexdump(MSG_DEBUG, " * ext_capab", - params->ext_capab, params->ext_capab_len); -Index: hostapd-2021-12-13-b26f5c0f/src/drivers/nl80211_copy.h -=================================================================== ---- hostapd-2021-12-13-b26f5c0f.orig/src/drivers/nl80211_copy.h -+++ hostapd-2021-12-13-b26f5c0f/src/drivers/nl80211_copy.h -@@ -3137,6 +3137,7 @@ enum nl80211_attrs { - NL80211_ATTR_RU_PUNCT_BITMAP, - - NL80211_ATTR_AP_PS, -+ NL80211_ATTR_EHT_240MHZ_CAPABILITY, - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, diff --git a/feeds/ipq95xx/hostapd/patches/q02-51-hostapd-Fix-WDS-Repeater-assoc-fail-on-6G-with-160MH.patch b/feeds/ipq95xx/hostapd/patches/q02-51-hostapd-Fix-WDS-Repeater-assoc-fail-on-6G-with-160MH.patch deleted file mode 100644 index a2030b70..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-51-hostapd-Fix-WDS-Repeater-assoc-fail-on-6G-with-160MH.patch +++ /dev/null @@ -1,47 +0,0 @@ -From abec20dcfc7e4f38c6b9a90d95914d11a27d114c Mon Sep 17 00:00:00 2001 -From: Sivashankari Madhavan -Date: Sat, 26 Nov 2022 11:26:37 +0530 -Subject: [PATCH] hostapd: Fix WDS Repeater assoc fail on 6G with 160MHz - -While trying to connect the STA with WDS AP, filling the chandef info -in the driver. In the Problematic case, receiving the EHT160 center -frequency is invalid. Due to this chandef validation getting fail and -returns a failure message. - -[ 6340.667455] wlan1: authenticate with 00:03:7f:01:58:33 -[ 6340.667502] wlan1: HE 6GHz operation resulted in invalid chandef: 6195 MHz/5/0 MHz/0 MHz -[ 6340.671605] wlan1: Rejecting non-HE 6/7 GHz connection -[ 6343.937592] wlan1: authenticate with 00:03:7f:01:58:33 - -From the analysis, didn't update the EHT160 center frequency information -in hostapd. - -Fix it by updating the EHT160 center frequency information. - -Signed-off-by: Sivashankari Madhavan ---- - src/ap/ieee802_11_eht.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c -index e208352..ac88c2a 100644 ---- a/src/ap/ieee802_11_eht.c -+++ b/src/ap/ieee802_11_eht.c -@@ -243,6 +243,14 @@ u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid, - break; - case CHANWIDTH_160MHZ: - oper->width = EHT_OPERATION_CHANNEL_WIDTH_160MHZ; -+ if (!oper->ccfs1) { -+ /* CCFS0 points to center channel frequency in config */ -+ oper->ccfs1 = oper->ccfs0; -+ if (hapd->iconf->channel < oper->ccfs0) -+ oper->ccfs0 = oper->ccfs1 - 8; -+ else -+ oper->ccfs0 = oper->ccfs1 + 8; -+ } - if (hapd->iconf->ru_punct_bitmap && - hapd->iface->ru_punct_supp_bw == CHANWIDTH_320MHZ) { - hapd->iconf->ru_punct_bitmap = 0; --- -2.17.1 - diff --git a/feeds/ipq95xx/hostapd/patches/q02-51-hostapd-Set-duplicate-beacon-bit-in-HE-oper-IE.patch b/feeds/ipq95xx/hostapd/patches/q02-51-hostapd-Set-duplicate-beacon-bit-in-HE-oper-IE.patch deleted file mode 100644 index e0a687f2..00000000 --- a/feeds/ipq95xx/hostapd/patches/q02-51-hostapd-Set-duplicate-beacon-bit-in-HE-oper-IE.patch +++ /dev/null @@ -1,65 +0,0 @@ -From b14445ec68225d41ee4176ec0ed9f22f9e627498 Mon Sep 17 00:00:00 2001 -From: Ramya Gnanasekar -Date: Tue, 22 Nov 2022 13:26:22 +0530 -Subject: [PATCH] hostapd: Set duplicate beacon bit in HE oper IE - -When APUT operates in non-psc channels, duplicate beacons -will be sent in psc channels. Hence duplicate beacon field -to be updated in the same scenario. - -Signed-off-by: Ramya Gnanasekar - -Index: b/src/ap/ieee802_11_he.c -=================================================================== ---- a/src/ap/ieee802_11_he.c 2022-11-23 09:22:12.722659415 +0530 -+++ b/src/ap/ieee802_11_he.c 2022-11-23 09:23:10.334202383 +0530 -@@ -168,12 +168,26 @@ u8 * hostapd_eid_he_capab(struct hostapd - return pos; - } - -+bool is_psc_channel(int channel) -+{ -+ int psc_chan[] = {37, 53, 69, 85, 101, 117, -+ 133, 149, 165, 181, 197, 213} ; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(psc_chan); i++) { -+ if (psc_chan[i] == channel) { -+ return true; -+ break; -+ } -+ } -+ return false; -+} - - u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid) - { - struct ieee80211_he_operation *oper; - u8 *pos = eid; -- int oper_size = 6; -+ int oper_size = 6, he_control; - u32 params = 0; - - if (!hapd->iface->current_mode) -@@ -261,13 +275,19 @@ u8 * hostapd_eid_he_operation(struct hos - u8 ap_type = hostapd_get_he_6ghz_reg_pwr_type(hapd->iconf); - - if (seg1) -- *pos++ = 3 | (IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO & -+ he_control = 3 | (IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO & - (ap_type << IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO_LSB)); - else -- *pos++ = center_idx_to_bw_6ghz(seg0) | -+ he_control = center_idx_to_bw_6ghz(seg0) | - (IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO & - (ap_type << IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO_LSB)); - -+ if (center_idx_to_bw_6ghz(seg0) && -+ !is_psc_channel(hapd->iconf->channel)) -+ he_control |= HE_6GHZ_OPER_INFO_CTRL_DUP_BEACON; -+ -+ *pos++ = he_control; -+ - /* Channel Center Freq Seg0/Seg1 */ - if (hapd->iconf->he_oper_chwidth == 2) { - /* diff --git a/feeds/ipq95xx/hostapd/src/hostapd/radius.c b/feeds/ipq95xx/hostapd/src/hostapd/radius.c new file mode 100644 index 00000000..362a22c2 --- /dev/null +++ b/feeds/ipq95xx/hostapd/src/hostapd/radius.c @@ -0,0 +1,715 @@ +#include "utils/includes.h" +#include "utils/common.h" +#include "utils/eloop.h" +#include "crypto/crypto.h" +#include "crypto/tls.h" + +#include "ap/ap_config.h" +#include "eap_server/eap.h" +#include "radius/radius.h" +#include "radius/radius_server.h" +#include "eap_register.h" + +#include +#include +#include +#include +#include + +#include +#include + +#define VENDOR_ID_WISPR 14122 +#define VENDOR_ATTR_SIZE 6 + +struct radius_parse_attr_data { + unsigned int vendor; + u8 type; + int size; + char format; + const char *data; +}; + +struct radius_parse_attr_state { + struct hostapd_radius_attr *prev; + struct hostapd_radius_attr *attr; + struct wpabuf *buf; + void *attrdata; +}; + +struct radius_user_state { + struct avl_node node; + struct eap_user data; +}; + +struct radius_user_data { + struct kvlist users; + struct avl_tree user_state; + struct blob_attr *wildcard; +}; + +struct radius_state { + struct radius_server_data *radius; + struct eap_config eap; + + struct radius_user_data phase1, phase2; + const char *user_file; + time_t user_file_ts; + + int n_attrs; + struct hostapd_radius_attr *attrs; +}; + +struct radius_config { + struct tls_connection_params tls; + struct radius_server_conf radius; +}; + +enum { + USER_ATTR_PASSWORD, + USER_ATTR_HASH, + USER_ATTR_SALT, + USER_ATTR_METHODS, + USER_ATTR_RADIUS, + USER_ATTR_VLAN, + USER_ATTR_MAX_RATE_UP, + USER_ATTR_MAX_RATE_DOWN, + __USER_ATTR_MAX +}; + +static void radius_tls_event(void *ctx, enum tls_event ev, + union tls_event_data *data) +{ + switch (ev) { + case TLS_CERT_CHAIN_SUCCESS: + wpa_printf(MSG_DEBUG, "radius: remote certificate verification success"); + break; + case TLS_CERT_CHAIN_FAILURE: + wpa_printf(MSG_INFO, "radius: certificate chain failure: reason=%d depth=%d subject='%s' err='%s'", + data->cert_fail.reason, + data->cert_fail.depth, + data->cert_fail.subject, + data->cert_fail.reason_txt); + break; + case TLS_PEER_CERTIFICATE: + wpa_printf(MSG_DEBUG, "radius: peer certificate: depth=%d serial_num=%s subject=%s", + data->peer_cert.depth, + data->peer_cert.serial_num ? data->peer_cert.serial_num : "N/A", + data->peer_cert.subject); + break; + case TLS_ALERT: + if (data->alert.is_local) + wpa_printf(MSG_DEBUG, "radius: local TLS alert: %s", + data->alert.description); + else + wpa_printf(MSG_DEBUG, "radius: remote TLS alert: %s", + data->alert.description); + break; + case TLS_UNSAFE_RENEGOTIATION_DISABLED: + /* Not applicable to TLS server */ + break; + } +} + +static void radius_userdata_init(struct radius_user_data *u) +{ + kvlist_init(&u->users, kvlist_blob_len); + avl_init(&u->user_state, avl_strcmp, false, NULL); +} + +static void radius_userdata_free(struct radius_user_data *u) +{ + struct radius_user_state *s, *tmp; + + kvlist_free(&u->users); + free(u->wildcard); + u->wildcard = NULL; + avl_remove_all_elements(&u->user_state, s, node, tmp) + free(s); +} + +static void +radius_userdata_load(struct radius_user_data *u, struct blob_attr *data) +{ + enum { + USERSTATE_USERS, + USERSTATE_WILDCARD, + __USERSTATE_MAX, + }; + static const struct blobmsg_policy policy[__USERSTATE_MAX] = { + [USERSTATE_USERS] = { "users", BLOBMSG_TYPE_TABLE }, + [USERSTATE_WILDCARD] = { "wildcard", BLOBMSG_TYPE_ARRAY }, + }; + struct blob_attr *tb[__USERSTATE_MAX], *cur; + int rem; + + if (!data) + return; + + blobmsg_parse(policy, __USERSTATE_MAX, tb, blobmsg_data(data), blobmsg_len(data)); + + blobmsg_for_each_attr(cur, tb[USERSTATE_USERS], rem) + kvlist_set(&u->users, blobmsg_name(cur), cur); + + if (tb[USERSTATE_WILDCARD]) + u->wildcard = blob_memdup(tb[USERSTATE_WILDCARD]); +} + +static void +load_userfile(struct radius_state *s) +{ + enum { + USERDATA_PHASE1, + USERDATA_PHASE2, + __USERDATA_MAX + }; + static const struct blobmsg_policy policy[__USERDATA_MAX] = { + [USERDATA_PHASE1] = { "phase1", BLOBMSG_TYPE_TABLE }, + [USERDATA_PHASE2] = { "phase2", BLOBMSG_TYPE_TABLE }, + }; + struct blob_attr *tb[__USERDATA_MAX], *cur; + static struct blob_buf b; + struct stat st; + int rem; + + if (stat(s->user_file, &st)) + return; + + if (s->user_file_ts == st.st_mtime) + return; + + s->user_file_ts = st.st_mtime; + radius_userdata_free(&s->phase1); + radius_userdata_free(&s->phase2); + + blob_buf_init(&b, 0); + blobmsg_add_json_from_file(&b, s->user_file); + blobmsg_parse(policy, __USERDATA_MAX, tb, blob_data(b.head), blob_len(b.head)); + radius_userdata_load(&s->phase1, tb[USERDATA_PHASE1]); + radius_userdata_load(&s->phase2, tb[USERDATA_PHASE2]); + + blob_buf_free(&b); +} + +static struct blob_attr * +radius_user_get(struct radius_user_data *s, const char *name) +{ + struct blob_attr *cur; + int rem; + + cur = kvlist_get(&s->users, name); + if (cur) + return cur; + + blobmsg_for_each_attr(cur, s->wildcard, rem) { + static const struct blobmsg_policy policy = { + "name", BLOBMSG_TYPE_STRING + }; + struct blob_attr *pattern; + + if (blobmsg_type(cur) != BLOBMSG_TYPE_TABLE) + continue; + + blobmsg_parse(&policy, 1, &pattern, blobmsg_data(cur), blobmsg_len(cur)); + if (!name) + continue; + + if (!fnmatch(blobmsg_get_string(pattern), name, 0)) + return cur; + } + + return NULL; +} + +static struct radius_parse_attr_data * +radius_parse_attr(struct blob_attr *attr) +{ + static const struct blobmsg_policy policy[4] = { + { .type = BLOBMSG_TYPE_INT32 }, + { .type = BLOBMSG_TYPE_INT32 }, + { .type = BLOBMSG_TYPE_STRING }, + { .type = BLOBMSG_TYPE_STRING }, + }; + static struct radius_parse_attr_data data; + struct blob_attr *tb[4]; + const char *format; + + blobmsg_parse_array(policy, ARRAY_SIZE(policy), tb, blobmsg_data(attr), blobmsg_len(attr)); + + if (!tb[0] || !tb[1] || !tb[2] || !tb[3]) + return NULL; + + format = blobmsg_get_string(tb[2]); + if (strlen(format) != 1) + return NULL; + + data.vendor = blobmsg_get_u32(tb[0]); + data.type = blobmsg_get_u32(tb[1]); + data.format = format[0]; + data.data = blobmsg_get_string(tb[3]); + data.size = strlen(data.data); + + switch (data.format) { + case 's': + break; + case 'x': + if (data.size & 1) + return NULL; + data.size /= 2; + break; + case 'd': + data.size = 4; + break; + default: + return NULL; + } + + return &data; +} + +static void +radius_count_attrs(struct blob_attr **tb, int *n_attr, size_t *attr_size) +{ + struct blob_attr *data = tb[USER_ATTR_RADIUS]; + struct blob_attr *cur; + int rem; + + blobmsg_for_each_attr(cur, data, rem) { + struct radius_parse_attr_data *data; + size_t prev = *attr_size; + + data = radius_parse_attr(cur); + if (!data) + continue; + + *attr_size += data->size; + if (data->vendor) + *attr_size += VENDOR_ATTR_SIZE; + + (*n_attr)++; + } + + *n_attr += !!tb[USER_ATTR_VLAN] * 3 + + !!tb[USER_ATTR_MAX_RATE_UP] + + !!tb[USER_ATTR_MAX_RATE_DOWN]; + *attr_size += !!tb[USER_ATTR_VLAN] * (4 + 4 + 5) + + !!tb[USER_ATTR_MAX_RATE_UP] * (4 + VENDOR_ATTR_SIZE) + + !!tb[USER_ATTR_MAX_RATE_DOWN] * (4 + VENDOR_ATTR_SIZE); +} + +static void * +radius_add_attr(struct radius_parse_attr_state *state, + u32 vendor, u8 type, u8 len) +{ + struct hostapd_radius_attr *attr; + struct wpabuf *buf; + void *val; + + val = state->attrdata; + + buf = state->buf++; + buf->buf = val; + + attr = state->attr++; + attr->val = buf; + attr->type = type; + + if (state->prev) + state->prev->next = attr; + state->prev = attr; + + if (vendor) { + u8 *vendor_hdr = val + 4; + + WPA_PUT_BE32(val, vendor); + vendor_hdr[0] = type; + vendor_hdr[1] = len + 2; + + len += VENDOR_ATTR_SIZE; + val += VENDOR_ATTR_SIZE; + attr->type = RADIUS_ATTR_VENDOR_SPECIFIC; + } + + buf->size = buf->used = len; + state->attrdata += len; + + return val; +} + +static void +radius_parse_attrs(struct blob_attr **tb, struct radius_parse_attr_state *state) +{ + struct blob_attr *data = tb[USER_ATTR_RADIUS]; + struct hostapd_radius_attr *prev = NULL; + struct blob_attr *cur; + int len, rem; + void *val; + + if ((cur = tb[USER_ATTR_VLAN]) != NULL && blobmsg_get_u32(cur) < 4096) { + char buf[5]; + + val = radius_add_attr(state, 0, RADIUS_ATTR_TUNNEL_TYPE, 4); + WPA_PUT_BE32(val, RADIUS_TUNNEL_TYPE_VLAN); + + val = radius_add_attr(state, 0, RADIUS_ATTR_TUNNEL_MEDIUM_TYPE, 4); + WPA_PUT_BE32(val, RADIUS_TUNNEL_MEDIUM_TYPE_802); + + len = snprintf(buf, sizeof(buf), "%d", blobmsg_get_u32(cur)); + val = radius_add_attr(state, 0, RADIUS_ATTR_TUNNEL_PRIVATE_GROUP_ID, len); + memcpy(val, buf, len); + } + + if ((cur = tb[USER_ATTR_MAX_RATE_UP]) != NULL) { + val = radius_add_attr(state, VENDOR_ID_WISPR, 7, 4); + WPA_PUT_BE32(val, blobmsg_get_u32(cur)); + } + + if ((cur = tb[USER_ATTR_MAX_RATE_DOWN]) != NULL) { + val = radius_add_attr(state, VENDOR_ID_WISPR, 8, 4); + WPA_PUT_BE32(val, blobmsg_get_u32(cur)); + } + + blobmsg_for_each_attr(cur, data, rem) { + struct radius_parse_attr_data *data; + void *val; + int size; + + data = radius_parse_attr(cur); + if (!data) + continue; + + val = radius_add_attr(state, data->vendor, data->type, data->size); + switch (data->format) { + case 's': + memcpy(val, data->data, data->size); + break; + case 'x': + hexstr2bin(data->data, val, data->size); + break; + case 'd': + WPA_PUT_BE32(val, atoi(data->data)); + break; + } + } +} + +static void +radius_user_parse_methods(struct eap_user *eap, struct blob_attr *data) +{ + struct blob_attr *cur; + int rem, n = 0; + + if (!data) + return; + + blobmsg_for_each_attr(cur, data, rem) { + const char *method; + + if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING) + continue; + + if (n == EAP_MAX_METHODS) + break; + + method = blobmsg_get_string(cur); + eap->methods[n].method = eap_server_get_type(method, &eap->methods[n].vendor); + if (eap->methods[n].vendor == EAP_VENDOR_IETF && + eap->methods[n].method == EAP_TYPE_NONE) { + if (!strcmp(method, "TTLS-PAP")) { + eap->ttls_auth |= EAP_TTLS_AUTH_PAP; + continue; + } + if (!strcmp(method, "TTLS-CHAP")) { + eap->ttls_auth |= EAP_TTLS_AUTH_CHAP; + continue; + } + if (!strcmp(method, "TTLS-MSCHAP")) { + eap->ttls_auth |= EAP_TTLS_AUTH_MSCHAP; + continue; + } + if (!strcmp(method, "TTLS-MSCHAPV2")) { + eap->ttls_auth |= EAP_TTLS_AUTH_MSCHAPV2; + continue; + } + } + n++; + } +} + +static struct eap_user * +radius_user_get_state(struct radius_user_data *u, struct blob_attr *data, + const char *id) +{ + static const struct blobmsg_policy policy[__USER_ATTR_MAX] = { + [USER_ATTR_PASSWORD] = { "password", BLOBMSG_TYPE_STRING }, + [USER_ATTR_HASH] = { "hash", BLOBMSG_TYPE_STRING }, + [USER_ATTR_SALT] = { "salt", BLOBMSG_TYPE_STRING }, + [USER_ATTR_METHODS] = { "methods", BLOBMSG_TYPE_ARRAY }, + [USER_ATTR_RADIUS] = { "radius", BLOBMSG_TYPE_ARRAY }, + [USER_ATTR_VLAN] = { "vlan-id", BLOBMSG_TYPE_INT32 }, + [USER_ATTR_MAX_RATE_UP] = { "max-rate-up", BLOBMSG_TYPE_INT32 }, + [USER_ATTR_MAX_RATE_DOWN] = { "max-rate-down", BLOBMSG_TYPE_INT32 }, + }; + struct blob_attr *tb[__USER_ATTR_MAX], *cur; + char *password_buf, *salt_buf, *name_buf; + struct radius_parse_attr_state astate = {}; + struct hostapd_radius_attr *attr; + struct radius_user_state *state; + int pw_len = 0, salt_len = 0; + struct eap_user *eap; + struct wpabuf *val; + size_t attrsize = 0; + void *attrdata; + int n_attr = 0; + + state = avl_find_element(&u->user_state, id, state, node); + if (state) + return &state->data; + + blobmsg_parse(policy, __USER_ATTR_MAX, tb, blobmsg_data(data), blobmsg_len(data)); + + if ((cur = tb[USER_ATTR_SALT]) != NULL) + salt_len = strlen(blobmsg_get_string(cur)) / 2; + if ((cur = tb[USER_ATTR_HASH]) != NULL) + pw_len = strlen(blobmsg_get_string(cur)) / 2; + else if ((cur = tb[USER_ATTR_PASSWORD]) != NULL) + pw_len = blobmsg_len(cur) - 1; + radius_count_attrs(tb, &n_attr, &attrsize); + + state = calloc_a(sizeof(*state), &name_buf, strlen(id) + 1, + &password_buf, pw_len, + &salt_buf, salt_len, + &astate.attr, n_attr * sizeof(*astate.attr), + &astate.buf, n_attr * sizeof(*astate.buf), + &astate.attrdata, attrsize); + eap = &state->data; + eap->salt = salt_len ? salt_buf : NULL; + eap->salt_len = salt_len; + eap->password = pw_len ? password_buf : NULL; + eap->password_len = pw_len; + eap->force_version = -1; + + if ((cur = tb[USER_ATTR_SALT]) != NULL) + hexstr2bin(blobmsg_get_string(cur), salt_buf, salt_len); + if ((cur = tb[USER_ATTR_PASSWORD]) != NULL) + memcpy(password_buf, blobmsg_get_string(cur), pw_len); + else if ((cur = tb[USER_ATTR_HASH]) != NULL) { + hexstr2bin(blobmsg_get_string(cur), password_buf, pw_len); + eap->password_hash = 1; + } + radius_user_parse_methods(eap, tb[USER_ATTR_METHODS]); + + if (n_attr > 0) { + cur = tb[USER_ATTR_RADIUS]; + eap->accept_attr = astate.attr; + radius_parse_attrs(tb, &astate); + } + + state->node.key = strcpy(name_buf, id); + avl_insert(&u->user_state, &state->node); + + return &state->data; + +free: + free(state); + return NULL; +} + +static int radius_get_eap_user(void *ctx, const u8 *identity, + size_t identity_len, int phase2, + struct eap_user *user) +{ + struct radius_state *s = ctx; + struct radius_user_data *u = phase2 ? &s->phase2 : &s->phase1; + struct blob_attr *entry; + struct eap_user *data; + char *id; + + if (identity_len > 512) + return -1; + + load_userfile(s); + + id = alloca(identity_len + 1); + memcpy(id, identity, identity_len); + id[identity_len] = 0; + + entry = radius_user_get(u, id); + if (!entry) + return -1; + + if (!user) + return 0; + + data = radius_user_get_state(u, entry, id); + if (!data) + return -1; + + *user = *data; + if (user->password_len > 0) + user->password = os_memdup(user->password, user->password_len); + if (user->salt_len > 0) + user->salt = os_memdup(user->salt, user->salt_len); + user->phase2 = phase2; + + return 0; +} + +static int radius_setup(struct radius_state *s, struct radius_config *c) +{ + struct eap_config *eap = &s->eap; + struct tls_config conf = { + .event_cb = radius_tls_event, + .tls_flags = TLS_CONN_DISABLE_TLSv1_3, + .cb_ctx = s, + }; + + eap->eap_server = 1; + eap->max_auth_rounds = 100; + eap->max_auth_rounds_short = 50; + eap->ssl_ctx = tls_init(&conf); + if (!eap->ssl_ctx) { + wpa_printf(MSG_INFO, "TLS init failed\n"); + return 1; + } + + if (tls_global_set_params(eap->ssl_ctx, &c->tls)) { + wpa_printf(MSG_INFO, "failed to set TLS parameters\n"); + return 1; + } + + c->radius.eap_cfg = eap; + c->radius.conf_ctx = s; + c->radius.get_eap_user = radius_get_eap_user; + s->radius = radius_server_init(&c->radius); + if (!s->radius) { + wpa_printf(MSG_INFO, "failed to initialize radius server\n"); + return 1; + } + + return 0; +} + +static int radius_init(struct radius_state *s) +{ + memset(s, 0, sizeof(*s)); + radius_userdata_init(&s->phase1); + radius_userdata_init(&s->phase2); +} + +static void radius_deinit(struct radius_state *s) +{ + if (s->radius) + radius_server_deinit(s->radius); + + if (s->eap.ssl_ctx) + tls_deinit(s->eap.ssl_ctx); + + radius_userdata_free(&s->phase1); + radius_userdata_free(&s->phase2); +} + +static int usage(const char *progname) +{ + fprintf(stderr, "Usage: %s \n", + progname); +} + +int radius_main(int argc, char **argv) +{ + static struct radius_state state = {}; + static struct radius_config config = {}; + const char *progname = argv[0]; + int ret = 0; + int ch; + + wpa_debug_setup_stdout(); + wpa_debug_level = 0; + + if (eloop_init()) { + wpa_printf(MSG_ERROR, "Failed to initialize event loop"); + return 1; + } + + eap_server_register_methods(); + radius_init(&state); + + while ((ch = getopt(argc, argv, "6C:c:d:i:k:K:p:P:s:u:")) != -1) { + switch (ch) { + case '6': + config.radius.ipv6 = 1; + break; + case 'C': + config.tls.ca_cert = optarg; + break; + case 'c': + if (config.tls.client_cert2) + return usage(progname); + + if (config.tls.client_cert) + config.tls.client_cert2 = optarg; + else + config.tls.client_cert = optarg; + break; + case 'd': + config.tls.dh_file = optarg; + break; + case 'i': + state.eap.server_id = optarg; + state.eap.server_id_len = strlen(optarg); + break; + case 'k': + if (config.tls.private_key2) + return usage(progname); + + if (config.tls.private_key) + config.tls.private_key2 = optarg; + else + config.tls.private_key = optarg; + break; + case 'K': + if (config.tls.private_key_passwd2) + return usage(progname); + + if (config.tls.private_key_passwd) + config.tls.private_key_passwd2 = optarg; + else + config.tls.private_key_passwd = optarg; + break; + case 'p': + config.radius.auth_port = atoi(optarg); + break; + case 'P': + config.radius.acct_port = atoi(optarg); + break; + case 's': + config.radius.client_file = optarg; + break; + case 'u': + state.user_file = optarg; + break; + default: + return usage(progname); + } + } + + if (!config.tls.client_cert || !config.tls.private_key || + !config.radius.client_file || !state.eap.server_id || + !state.user_file) { + wpa_printf(MSG_INFO, "missing options\n"); + goto out; + } + + ret = radius_setup(&state, &config); + if (ret) + goto out; + + load_userfile(&state); + eloop_run(); + +out: + radius_deinit(&state); + os_program_deinit(); + + return ret; +} diff --git a/feeds/ipq95xx/hostapd/src/src/ap/ubus.c b/feeds/ipq95xx/hostapd/src/src/ap/ubus.c index 3ef443d4..ae620988 100644 --- a/feeds/ipq95xx/hostapd/src/src/ap/ubus.c +++ b/feeds/ipq95xx/hostapd/src/src/ap/ubus.c @@ -153,7 +153,7 @@ hostapd_bss_ban_client(struct hostapd_data *hapd, u8 *addr, int time) } } - eloop_register_timeout(time, 0, hostapd_bss_del_ban, ban, hapd); + eloop_register_timeout(0, time * 1000, hostapd_bss_del_ban, ban, hapd); } static int @@ -275,10 +275,24 @@ hostapd_bss_get_clients(struct ubus_context *ctx, struct ubus_object *obj, blobmsg_add_u8(&b, sta_flags[i].name, !!(sta->flags & sta_flags[i].flag)); +#ifdef CONFIG_MBO + blobmsg_add_u8(&b, "mbo", !!(sta->cell_capa)); +#endif + r = blobmsg_open_array(&b, "rrm"); for (i = 0; i < ARRAY_SIZE(sta->rrm_enabled_capa); i++) blobmsg_add_u32(&b, "", sta->rrm_enabled_capa[i]); blobmsg_close_array(&b, r); + + r = blobmsg_open_array(&b, "extended_capabilities"); + /* Check if client advertises extended capabilities */ + if (sta->ext_capability && sta->ext_capability[0] > 0) { + for (i = 0; i < sta->ext_capability[0]; i++) { + blobmsg_add_u32(&b, "", sta->ext_capability[1 + i]); + } + } + blobmsg_close_array(&b, r); + blobmsg_add_u32(&b, "aid", sta->aid); #ifdef CONFIG_TAXONOMY r = blobmsg_alloc_string_buffer(&b, "signature", 1024); @@ -305,42 +319,7 @@ hostapd_bss_get_clients(struct ubus_context *ctx, struct ubus_object *obj, blobmsg_add_u32(&b, "rx", sta_driver_data.current_rx_rate * 100); blobmsg_add_u32(&b, "tx", sta_driver_data.current_tx_rate * 100); blobmsg_close_table(&b, r); - blobmsg_add_u32(&b, "retries", sta_driver_data.tx_retry_count); - blobmsg_add_u32(&b, "failed", sta_driver_data.tx_retry_failed); blobmsg_add_u32(&b, "signal", sta_driver_data.signal); - - r = blobmsg_open_table(&b, "mcs"); - if (sta_driver_data.rx_hemcs) { - blobmsg_add_u32(&b, "he", 1); - blobmsg_add_u32(&b, "rx", sta_driver_data.rx_hemcs); - blobmsg_add_u32(&b, "tx", sta_driver_data.tx_hemcs); - } else if (sta_driver_data.rx_vhtmcs) { - blobmsg_add_u32(&b, "vht", 1); - blobmsg_add_u32(&b, "rx", sta_driver_data.rx_vhtmcs); - blobmsg_add_u32(&b, "tx", sta_driver_data.tx_vhtmcs); - } else { - blobmsg_add_u32(&b, "rx", sta_driver_data.rx_mcs); - blobmsg_add_u32(&b, "tx", sta_driver_data.tx_mcs); - } - blobmsg_close_table(&b, r); - - r = blobmsg_open_table(&b, "nss"); - if (sta_driver_data.rx_he_nss) { - blobmsg_add_u32(&b, "he", 1); - blobmsg_add_u32(&b, "rx", sta_driver_data.rx_he_nss); - blobmsg_add_u32(&b, "tx", sta_driver_data.tx_he_nss); - } else if (sta_driver_data.rx_vht_nss) { - blobmsg_add_u32(&b, "vht", 1); - blobmsg_add_u32(&b, "rx", sta_driver_data.rx_vht_nss); - blobmsg_add_u32(&b, "tx", sta_driver_data.tx_vht_nss); - } else { - blobmsg_add_u32(&b, "rx", sta_driver_data.rx_mcs); - blobmsg_add_u32(&b, "tx", sta_driver_data.tx_mcs); - } - blobmsg_close_table(&b, r); - - if (sta->signal_mgmt) - blobmsg_add_u32(&b, "signal_mgmt", sta->signal_mgmt); } hostapd_parse_capab_blobmsg(sta); @@ -368,32 +347,6 @@ hostapd_bss_get_features(struct ubus_context *ctx, struct ubus_object *obj, return 0; } -/* Imported from iw/util.c - * https://git.kernel.org/pub/scm/linux/kernel/git/jberg/iw.git/tree/util.c?id=4b25ae3537af48dbf9d0abf94132e5ba01b32c18#n200 - */ -int ieee80211_frequency_to_channel(int freq) -{ - /* see 802.11-2007 17.3.8.3.2 and Annex J */ - if (freq == 2484) - return 14; - /* see 802.11ax D6.1 27.3.23.2 and Annex E */ - else if (freq == 5935) - return 2; - else if (freq < 2484) - return (freq - 2407) / 5; - else if (freq >= 4910 && freq <= 4980) - return (freq - 4000) / 5; - else if (freq < 5950) - return (freq - 5000) / 5; - else if (freq <= 45000) /* DMG band lower limit */ - /* see 802.11ax D6.1 27.3.23.2 */ - return (freq - 5950) / 5; - else if (freq >= 58320 && freq <= 70200) - return (freq - 56160) / 2160; - else - return 0; -} - static int hostapd_bss_get_status(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, @@ -416,7 +369,6 @@ hostapd_bss_get_status(struct ubus_context *ctx, struct ubus_object *obj, &op_class, &channel); blob_buf_init(&b, 0); - blobmsg_add_string(&b, "driver", hapd->driver->name); blobmsg_add_string(&b, "status", hostapd_state_text(hapd->iface->state)); blobmsg_printf(&b, "bssid", MACSTR, MAC2STR(hapd->conf->bssid)); @@ -428,6 +380,12 @@ hostapd_bss_get_status(struct ubus_context *ctx, struct ubus_object *obj, blobmsg_add_u32(&b, "channel", channel); blobmsg_add_u32(&b, "op_class", op_class); blobmsg_add_u32(&b, "beacon_interval", hapd->iconf->beacon_int); +#ifdef CONFIG_IEEE80211AX + blobmsg_add_u32(&b, "bss_color", hapd->iface->conf->he_op.he_bss_color_disabled ? -1 : + hapd->iface->conf->he_op.he_bss_color); +#else + blobmsg_add_u32(&b, "bss_color", -1); +#endif snprintf(phy_name, 17, "%s", hapd->iface->phy); blobmsg_add_string(&b, "phy", phy_name); @@ -460,12 +418,6 @@ hostapd_bss_get_status(struct ubus_context *ctx, struct ubus_object *obj, hapd->iface->cac_started ? hapd->iface->dfs_cac_ms / 1000 - now.sec : 0); blobmsg_close_table(&b, dfs_table); - if (hapd->conf->uci_section) - blobmsg_add_string(&b, "uci_section", hapd->conf->uci_section); - - if (hapd->signal_mgmt) - blobmsg_add_u32(&b, "signal_mgmt", hapd->signal_mgmt); - ubus_send_reply(ctx, req, b.head); return 0; @@ -815,12 +767,17 @@ hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj, css.freq_params.ht_enabled, css.freq_params.vht_enabled, css.freq_params.he_enabled, - 0, + css.freq_params.eht_enabled, css.freq_params.sec_channel_offset, chwidth, seg0, seg1, iconf->vht_capab, - mode ? &mode->he_capab[IEEE80211_MODE_AP] : 0, - 0, 0, 0, 0); + mode ? &mode->he_capab[IEEE80211_MODE_AP] : + NULL, + mode ? &mode->eht_capab[IEEE80211_MODE_AP] : + NULL, + iconf->he_6ghz_reg_pwr_type, + iconf->ru_punct_bitmap, + iconf->ru_punct_ofdma); for (i = 0; i < hapd->iface->num_bss; i++) { struct hostapd_data *bss = hapd->iface->bss[i]; @@ -923,6 +880,7 @@ hostapd_rrm_print_nr(struct hostapd_neighbor_entry *nr) enum { BSS_MGMT_EN_NEIGHBOR, BSS_MGMT_EN_BEACON, + BSS_MGMT_EN_LINK_MEASUREMENT, #ifdef CONFIG_WNM_AP BSS_MGMT_EN_BSS_TRANSITION, #endif @@ -950,6 +908,14 @@ __hostapd_bss_mgmt_enable_f(struct hostapd_data *hapd, int flag) WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE | WLAN_RRM_CAPS_BEACON_REPORT_TABLE; + if (bss->radio_measurements[0] & flags == flags) + return false; + + bss->radio_measurements[0] |= (u8) flags; + return true; + case BSS_MGMT_EN_LINK_MEASUREMENT: + flags = WLAN_RRM_CAPS_LINK_MEASUREMENT; + if (bss->radio_measurements[0] & flags == flags) return false; @@ -987,6 +953,7 @@ __hostapd_bss_mgmt_enable(struct hostapd_data *hapd, uint32_t flags) static const struct blobmsg_policy bss_mgmt_enable_policy[__BSS_MGMT_EN_MAX] = { [BSS_MGMT_EN_NEIGHBOR] = { "neighbor_report", BLOBMSG_TYPE_BOOL }, [BSS_MGMT_EN_BEACON] = { "beacon_report", BLOBMSG_TYPE_BOOL }, + [BSS_MGMT_EN_LINK_MEASUREMENT] = { "link_measurement", BLOBMSG_TYPE_BOOL }, #ifdef CONFIG_WNM_AP [BSS_MGMT_EN_BSS_TRANSITION] = { "bss_transition", BLOBMSG_TYPE_BOOL }, #endif @@ -1015,6 +982,8 @@ hostapd_bss_mgmt_enable(struct ubus_context *ctx, struct ubus_object *obj, } __hostapd_bss_mgmt_enable(hapd, flags); + + return 0; } @@ -1265,13 +1234,105 @@ hostapd_rrm_beacon_req(struct ubus_context *ctx, struct ubus_object *obj, return 0; } +enum { + LM_REQ_ADDR, + LM_REQ_TX_POWER_USED, + LM_REQ_TX_POWER_MAX, + __LM_REQ_MAX, +}; + +static const struct blobmsg_policy lm_req_policy[__LM_REQ_MAX] = { + [LM_REQ_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, + [LM_REQ_TX_POWER_USED] = { "tx-power-used", BLOBMSG_TYPE_INT32 }, + [LM_REQ_TX_POWER_MAX] = { "tx-power-max", BLOBMSG_TYPE_INT32 }, +}; + +static int +hostapd_rrm_lm_req(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *ureq, const char *method, + struct blob_attr *msg) +{ + struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); + struct blob_attr *tb[__LM_REQ_MAX]; + struct wpabuf *buf; + u8 addr[ETH_ALEN]; + int ret; + int8_t txp_used, txp_max; + + txp_used = 0; + txp_max = 0; + + blobmsg_parse(lm_req_policy, __LM_REQ_MAX, tb, blob_data(msg), blob_len(msg)); + + if (!tb[LM_REQ_ADDR]) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (tb[LM_REQ_TX_POWER_USED]) + txp_used = (int8_t) blobmsg_get_u32(tb[LM_REQ_TX_POWER_USED]); + + if (tb[LM_REQ_TX_POWER_MAX]) + txp_max = (int8_t) blobmsg_get_u32(tb[LM_REQ_TX_POWER_MAX]); + + if (hwaddr_aton(blobmsg_data(tb[LM_REQ_ADDR]), addr)) + return UBUS_STATUS_INVALID_ARGUMENT; + + buf = wpabuf_alloc(5); + if (!buf) + return UBUS_STATUS_UNKNOWN_ERROR; + + wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT); + wpabuf_put_u8(buf, WLAN_RRM_LINK_MEASUREMENT_REQUEST); + wpabuf_put_u8(buf, 1); + /* TX-Power used */ + wpabuf_put_u8(buf, txp_used); + /* Max TX Power */ + wpabuf_put_u8(buf, txp_max); + + ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr, + wpabuf_head(buf), wpabuf_len(buf)); + + wpabuf_free(buf); + if (ret < 0) + return -ret; + + return 0; +} + + +void hostapd_ubus_handle_link_measurement(struct hostapd_data *hapd, const u8 *data, size_t len) +{ + const struct ieee80211_mgmt *mgmt = (const struct ieee80211_mgmt *) data; + const u8 *pos, *end; + u8 token; + + end = data + len; + token = mgmt->u.action.u.rrm.dialog_token; + pos = mgmt->u.action.u.rrm.variable; + + if (end - pos < 8) + return; + + if (!hapd->ubus.obj.has_subscribers) + return; + + blob_buf_init(&b, 0); + blobmsg_add_macaddr(&b, "address", mgmt->sa); + blobmsg_add_u16(&b, "dialog-token", token); + blobmsg_add_u16(&b, "rx-antenna-id", pos[4]); + blobmsg_add_u16(&b, "tx-antenna-id", pos[5]); + blobmsg_add_u16(&b, "rcpi", pos[6]); + blobmsg_add_u16(&b, "rsni", pos[7]); + + ubus_notify(ctx, &hapd->ubus.obj, "link-measurement-report", b.head, -1); +} + #ifdef CONFIG_WNM_AP static int hostapd_bss_tr_send(struct hostapd_data *hapd, u8 *addr, bool disassoc_imminent, bool abridged, u16 disassoc_timer, u8 validity_period, u8 dialog_token, - struct blob_attr *neighbors) + struct blob_attr *neighbors, u8 mbo_reason, u8 cell_pref, u8 reassoc_delay) { struct blob_attr *cur; struct sta_info *sta; @@ -1279,6 +1340,8 @@ hostapd_bss_tr_send(struct hostapd_data *hapd, u8 *addr, bool disassoc_imminent, int rem; u8 *nr = NULL; u8 req_mode = 0; + u8 mbo[10]; + size_t mbo_len = 0; sta = ap_get_sta(hapd, addr); if (!sta) @@ -1330,8 +1393,37 @@ hostapd_bss_tr_send(struct hostapd_data *hapd, u8 *addr, bool disassoc_imminent, if (disassoc_imminent) req_mode |= WNM_BSS_TM_REQ_DISASSOC_IMMINENT; +#ifdef CONFIG_MBO + u8 *mbo_pos = mbo; + + if (mbo_reason > MBO_TRANSITION_REASON_PREMIUM_AP) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (cell_pref != 0 && cell_pref != 1 && cell_pref != 255) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (reassoc_delay > 65535 || (reassoc_delay && !disassoc_imminent)) + return UBUS_STATUS_INVALID_ARGUMENT; + + *mbo_pos++ = MBO_ATTR_ID_TRANSITION_REASON; + *mbo_pos++ = 1; + *mbo_pos++ = mbo_reason; + *mbo_pos++ = MBO_ATTR_ID_CELL_DATA_PREF; + *mbo_pos++ = 1; + *mbo_pos++ = cell_pref; + + if (reassoc_delay) { + *mbo_pos++ = MBO_ATTR_ID_ASSOC_RETRY_DELAY; + *mbo_pos++ = 2; + WPA_PUT_LE16(mbo_pos, reassoc_delay); + mbo_pos += 2; + } + + mbo_len = mbo_pos - mbo; +#endif + if (wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer, validity_period, NULL, - dialog_token, NULL, nr, nr_len, NULL, 0)) + dialog_token, NULL, nr, nr_len, mbo_len ? mbo : NULL, mbo_len)) return UBUS_STATUS_UNKNOWN_ERROR; return 0; @@ -1345,6 +1437,11 @@ enum { BSS_TR_NEIGHBORS, BSS_TR_ABRIDGED, BSS_TR_DIALOG_TOKEN, +#ifdef CONFIG_MBO + BSS_TR_MBO_REASON, + BSS_TR_CELL_PREF, + BSS_TR_REASSOC_DELAY, +#endif __BSS_TR_DISASSOC_MAX }; @@ -1356,6 +1453,11 @@ static const struct blobmsg_policy bss_tr_policy[__BSS_TR_DISASSOC_MAX] = { [BSS_TR_NEIGHBORS] = { "neighbors", BLOBMSG_TYPE_ARRAY }, [BSS_TR_ABRIDGED] = { "abridged", BLOBMSG_TYPE_BOOL }, [BSS_TR_DIALOG_TOKEN] = { "dialog_token", BLOBMSG_TYPE_INT32 }, +#ifdef CONFIG_MBO + [BSS_TR_MBO_REASON] = { "mbo_reason", BLOBMSG_TYPE_INT32 }, + [BSS_TR_CELL_PREF] = { "cell_pref", BLOBMSG_TYPE_INT32 }, + [BSS_TR_REASSOC_DELAY] = { "reassoc_delay", BLOBMSG_TYPE_INT32 }, +#endif }; static int @@ -1372,6 +1474,9 @@ hostapd_bss_transition_request(struct ubus_context *ctx, struct ubus_object *obj u32 dialog_token = 1; bool abridged; bool da_imminent; + u8 mbo_reason; + u8 cell_pref; + u8 reassoc_delay; blobmsg_parse(bss_tr_policy, __BSS_TR_DISASSOC_MAX, tb, blob_data(msg), blob_len(msg)); @@ -1393,52 +1498,19 @@ hostapd_bss_transition_request(struct ubus_context *ctx, struct ubus_object *obj da_imminent = !!(tb[BSS_TR_DA_IMMINENT] && blobmsg_get_bool(tb[BSS_TR_DA_IMMINENT])); abridged = !!(tb[BSS_TR_ABRIDGED] && blobmsg_get_bool(tb[BSS_TR_ABRIDGED])); +#ifdef CONFIG_MBO + if (tb[BSS_TR_MBO_REASON]) + mbo_reason = blobmsg_get_u32(tb[BSS_TR_MBO_REASON]); + + if (tb[BSS_TR_CELL_PREF]) + cell_pref = blobmsg_get_u32(tb[BSS_TR_CELL_PREF]); + + if (tb[BSS_TR_REASSOC_DELAY]) + reassoc_delay = blobmsg_get_u32(tb[BSS_TR_REASSOC_DELAY]); +#endif + return hostapd_bss_tr_send(hapd, addr, da_imminent, abridged, da_timer, valid_period, - dialog_token, tb[BSS_TR_NEIGHBORS]); -} - -enum { - WNM_DISASSOC_ADDR, - WNM_DISASSOC_DURATION, - WNM_DISASSOC_NEIGHBORS, - WNM_DISASSOC_ABRIDGED, - __WNM_DISASSOC_MAX, -}; - -static const struct blobmsg_policy wnm_disassoc_policy[__WNM_DISASSOC_MAX] = { - [WNM_DISASSOC_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, - [WNM_DISASSOC_DURATION] { "duration", BLOBMSG_TYPE_INT32 }, - [WNM_DISASSOC_NEIGHBORS] { "neighbors", BLOBMSG_TYPE_ARRAY }, - [WNM_DISASSOC_ABRIDGED] { "abridged", BLOBMSG_TYPE_BOOL }, -}; - -static int -hostapd_wnm_disassoc_imminent(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *ureq, const char *method, - struct blob_attr *msg) -{ - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - struct blob_attr *tb[__WNM_DISASSOC_MAX]; - struct sta_info *sta; - int duration = 10; - u8 addr[ETH_ALEN]; - bool abridged; - - blobmsg_parse(wnm_disassoc_policy, __WNM_DISASSOC_MAX, tb, blob_data(msg), blob_len(msg)); - - if (!tb[WNM_DISASSOC_ADDR]) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (hwaddr_aton(blobmsg_data(tb[WNM_DISASSOC_ADDR]), addr)) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (tb[WNM_DISASSOC_DURATION]) - duration = blobmsg_get_u32(tb[WNM_DISASSOC_DURATION]); - - abridged = !!(tb[WNM_DISASSOC_ABRIDGED] && blobmsg_get_bool(tb[WNM_DISASSOC_ABRIDGED])); - - return hostapd_bss_tr_send(hapd, addr, true, abridged, duration, duration, - 1, tb[WNM_DISASSOC_NEIGHBORS]); + dialog_token, tb[BSS_TR_NEIGHBORS], mbo_reason, cell_pref, reassoc_delay); } #endif @@ -1495,10 +1567,61 @@ hostapd_bss_update_airtime(struct ubus_context *ctx, struct ubus_object *obj, } #endif +#ifdef CONFIG_TAXONOMY +static const struct blobmsg_policy addr_policy[] = { + { "address", BLOBMSG_TYPE_STRING } +}; + +static bool +hostapd_add_b64_data(const char *name, const struct wpabuf *buf) +{ + char *str; + + if (!buf) + return false; + + str = blobmsg_alloc_string_buffer(&b, name, B64_ENCODE_LEN(wpabuf_len(buf))); + b64_encode(wpabuf_head(buf), wpabuf_len(buf), str, B64_ENCODE_LEN(wpabuf_len(buf))); + blobmsg_add_string_buffer(&b); + + return true; +} + +static int +hostapd_bss_get_sta_ies(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); + struct blob_attr *tb; + struct sta_info *sta; + u8 addr[ETH_ALEN]; + + blobmsg_parse(addr_policy, 1, &tb, blobmsg_data(msg), blobmsg_len(msg)); + + if (!tb || hwaddr_aton(blobmsg_data(tb), addr)) + return UBUS_STATUS_INVALID_ARGUMENT; + + sta = ap_get_sta(hapd, addr); + if (!sta || (!sta->probe_ie_taxonomy && !sta->assoc_ie_taxonomy)) + return UBUS_STATUS_NOT_FOUND; + + blob_buf_init(&b, 0); + hostapd_add_b64_data("probe_ie", sta->probe_ie_taxonomy); + hostapd_add_b64_data("assoc_ie", sta->assoc_ie_taxonomy); + ubus_send_reply(ctx, req, b.head); + + return 0; +} +#endif + static const struct ubus_method bss_methods[] = { UBUS_METHOD_NOARG("reload", hostapd_bss_reload), UBUS_METHOD_NOARG("get_clients", hostapd_bss_get_clients), +#ifdef CONFIG_TAXONOMY + UBUS_METHOD("get_sta_ies", hostapd_bss_get_sta_ies, addr_policy), +#endif UBUS_METHOD_NOARG("get_status", hostapd_bss_get_status), UBUS_METHOD("del_client", hostapd_bss_del_client, del_policy), #ifdef CONFIG_AIRTIME_POLICY @@ -1522,8 +1645,8 @@ static const struct ubus_method bss_methods[] = { UBUS_METHOD_NOARG("rrm_nr_list", hostapd_rrm_nr_list), UBUS_METHOD("rrm_nr_set", hostapd_rrm_nr_set, nr_set_policy), UBUS_METHOD("rrm_beacon_req", hostapd_rrm_beacon_req, beacon_req_policy), + UBUS_METHOD("link_measurement_req", hostapd_rrm_lm_req, lm_req_policy), #ifdef CONFIG_WNM_AP - UBUS_METHOD("wnm_disassoc_imminent", hostapd_wnm_disassoc_imminent, wnm_disassoc_policy), UBUS_METHOD("bss_transition_request", hostapd_bss_transition_request, bss_tr_policy), #endif }; @@ -1536,85 +1659,6 @@ static int avl_compare_macaddr(const void *k1, const void *k2, void *ptr) return memcmp(k1, k2, ETH_ALEN); } -static int -hostapd_wired_get_clients(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - struct hostap_sta_driver_data sta_driver_data; - struct sta_info *sta; - void *list, *c; - char mac_buf[20]; - static const struct { - const char *name; - uint32_t flag; - } sta_flags[] = { - { "authorized", WLAN_STA_AUTHORIZED }, - }; - - blob_buf_init(&b, 0); - list = blobmsg_open_table(&b, "clients"); - for (sta = hapd->sta_list; sta; sta = sta->next) { - void *r; - int i; - - sprintf(mac_buf, MACSTR, MAC2STR(sta->addr)); - c = blobmsg_open_table(&b, mac_buf); - for (i = 0; i < ARRAY_SIZE(sta_flags); i++) - blobmsg_add_u8(&b, sta_flags[i].name, - !!(sta->flags & sta_flags[i].flag)); - - blobmsg_close_table(&b, c); - } - blobmsg_close_array(&b, list); - ubus_send_reply(ctx, req, b.head); - - return 0; -} - -static int -hostapd_wired_get_status(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - char iface_name[17]; - - blob_buf_init(&b, 0); - blobmsg_add_string(&b, "driver", hapd->driver->name); - blobmsg_add_string(&b, "status", hostapd_state_text(hapd->iface->state)); - - snprintf(iface_name, 17, "%s", hapd->iface->phy); - blobmsg_add_string(&b, "iface", iface_name); - - ubus_send_reply(ctx, req, b.head); - - return 0; -} - -static int -hostapd_wired_del_clients(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - - hostapd_free_stas(hapd); - - return 0; -} - -static const struct ubus_method wired_methods[] = { - UBUS_METHOD_NOARG("reload", hostapd_bss_reload), - UBUS_METHOD_NOARG("get_clients", hostapd_wired_get_clients), - UBUS_METHOD_NOARG("del_clients", hostapd_wired_del_clients), - UBUS_METHOD_NOARG("get_status", hostapd_wired_get_status), -}; - -static struct ubus_object_type wired_object_type = - UBUS_OBJECT_TYPE("hostapd_wired", wired_methods); - void hostapd_ubus_add_bss(struct hostapd_data *hapd) { struct ubus_object *obj = &hapd->ubus.obj; @@ -1634,15 +1678,9 @@ void hostapd_ubus_add_bss(struct hostapd_data *hapd) avl_init(&hapd->ubus.banned, avl_compare_macaddr, false, NULL); obj->name = name; - if (!strcmp(hapd->driver->name, "wired")) { - obj->type = &wired_object_type; - obj->methods = wired_object_type.methods; - obj->n_methods = wired_object_type.n_methods; - } else { - obj->type = &bss_object_type; - obj->methods = bss_object_type.methods; - obj->n_methods = bss_object_type.n_methods; - } + obj->type = &bss_object_type; + obj->methods = bss_object_type.methods; + obj->n_methods = bss_object_type.n_methods; ret = ubus_add_object(ctx, obj); hostapd_ubus_ref_inc(); } @@ -1725,7 +1763,6 @@ int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_req [HOSTAPD_UBUS_PROBE_REQ] = "probe", [HOSTAPD_UBUS_AUTH_REQ] = "auth", [HOSTAPD_UBUS_ASSOC_REQ] = "assoc", - [HOSTAPD_UBUS_COA] = "coa", }; const char *type = "mgmt"; struct ubus_event_req ureq = {}; @@ -1795,7 +1832,7 @@ int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_req } } - if (!hapd->ubus.notify_response && req->type != HOSTAPD_UBUS_COA) { + if (!hapd->ubus.notify_response) { ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1); return WLAN_STATUS_SUCCESS; } @@ -1822,40 +1859,20 @@ void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 * blob_buf_init(&b, 0); blobmsg_add_macaddr(&b, "address", addr); - blobmsg_add_string(&b, "ifname", hapd->conf->iface); ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1); } -void hostapd_ubus_notify_csa(struct hostapd_data *hapd, int freq) -{ - if (!hapd->ubus.obj.has_subscribers) - return; - - blob_buf_init(&b, 0); - blobmsg_add_string(&b, "ifname", hapd->conf->iface); - blobmsg_add_u32(&b, "freq", freq); - blobmsg_printf(&b, "bssid", MACSTR, MAC2STR(hapd->conf->bssid)); - - ubus_notify(ctx, &hapd->ubus.obj, "channel-switch", b.head, -1); -} - - -void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta) +void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta, + const char *auth_alg) { if (!hapd->ubus.obj.has_subscribers) return; blob_buf_init(&b, 0); blobmsg_add_macaddr(&b, "address", sta->addr); - blobmsg_add_string(&b, "ifname", hapd->conf->iface); - if (sta->bandwidth[0] || sta->bandwidth[1]) { - void *r = blobmsg_open_array(&b, "rate-limit"); - - blobmsg_add_u32(&b, "", sta->bandwidth[0]); - blobmsg_add_u32(&b, "", sta->bandwidth[1]); - blobmsg_close_array(&b, r); - } + if (auth_alg) + blobmsg_add_string(&b, "auth-alg", auth_alg); ubus_notify(ctx, &hapd->ubus.obj, "sta-authorized", b.head, -1); } @@ -1882,6 +1899,7 @@ void hostapd_ubus_notify_beacon_report( blobmsg_add_macaddr(&b, "bssid", rep->bssid); blobmsg_add_u16(&b, "antenna-id", rep->antenna_id); blobmsg_add_u16(&b, "parent-tsf", rep->parent_tsf); + blobmsg_add_u16(&b, "rep-mode", rep_mode); ubus_notify(ctx, &hapd->ubus.obj, "beacon-report", b.head, -1); } diff --git a/feeds/ipq95xx/hostapd/src/src/ap/ubus.c.orig b/feeds/ipq95xx/hostapd/src/src/ap/ubus.c.orig deleted file mode 100644 index befa3bc8..00000000 --- a/feeds/ipq95xx/hostapd/src/src/ap/ubus.c.orig +++ /dev/null @@ -1,1845 +0,0 @@ -/* - * hostapd / ubus support - * Copyright (c) 2013, Felix Fietkau - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#include "utils/includes.h" -#include "utils/common.h" -#include "utils/eloop.h" -#include "utils/wpabuf.h" -#include "common/ieee802_11_defs.h" -#include "common/hw_features_common.h" -#include "hostapd.h" -#include "neighbor_db.h" -#include "wps_hostapd.h" -#include "sta_info.h" -#include "ubus.h" -#include "ap_drv_ops.h" -#include "beacon.h" -#include "rrm.h" -#include "wnm_ap.h" -#include "taxonomy.h" -#include "airtime_policy.h" -#include "hw_features.h" - -static struct ubus_context *ctx; -static struct blob_buf b; -static int ctx_ref; - -static inline struct hostapd_data *get_hapd_from_object(struct ubus_object *obj) -{ - return container_of(obj, struct hostapd_data, ubus.obj); -} - -struct ubus_banned_client { - struct avl_node avl; - u8 addr[ETH_ALEN]; -}; - -static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) -{ - if (ubus_reconnect(ctx, NULL)) { - eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); - return; - } - - ubus_add_uloop(ctx); -} - -static void hostapd_ubus_connection_lost(struct ubus_context *ctx) -{ - uloop_fd_delete(&ctx->sock); - eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); -} - -static bool hostapd_ubus_init(void) -{ - if (ctx) - return true; - - eloop_add_uloop(); - ctx = ubus_connect(NULL); - if (!ctx) - return false; - - ctx->connection_lost = hostapd_ubus_connection_lost; - ubus_add_uloop(ctx); - - return true; -} - -static void hostapd_ubus_ref_inc(void) -{ - ctx_ref++; -} - -static void hostapd_ubus_ref_dec(void) -{ - ctx_ref--; - if (!ctx) - return; - - if (ctx_ref) - return; - - uloop_fd_delete(&ctx->sock); - ubus_free(ctx); - ctx = NULL; -} - -void hostapd_ubus_add_iface(struct hostapd_iface *iface) -{ - if (!hostapd_ubus_init()) - return; -} - -void hostapd_ubus_free_iface(struct hostapd_iface *iface) -{ - if (!ctx) - return; -} - -static void hostapd_notify_ubus(struct ubus_object *obj, char *bssname, char *event) -{ - char *event_type; - - if (!ctx || !obj) - return; - - if (asprintf(&event_type, "bss.%s", event) < 0) - return; - - blob_buf_init(&b, 0); - blobmsg_add_string(&b, "name", bssname); - ubus_notify(ctx, obj, event_type, b.head, -1); - free(event_type); -} - -static void -hostapd_bss_del_ban(void *eloop_data, void *user_ctx) -{ - struct ubus_banned_client *ban = eloop_data; - struct hostapd_data *hapd = user_ctx; - - avl_delete(&hapd->ubus.banned, &ban->avl); - free(ban); -} - -static void -hostapd_bss_ban_client(struct hostapd_data *hapd, u8 *addr, int time) -{ - struct ubus_banned_client *ban; - - if (time < 0) - time = 0; - - ban = avl_find_element(&hapd->ubus.banned, addr, ban, avl); - if (!ban) { - if (!time) - return; - - ban = os_zalloc(sizeof(*ban)); - memcpy(ban->addr, addr, sizeof(ban->addr)); - ban->avl.key = ban->addr; - avl_insert(&hapd->ubus.banned, &ban->avl); - } else { - eloop_cancel_timeout(hostapd_bss_del_ban, ban, hapd); - if (!time) { - hostapd_bss_del_ban(ban, hapd); - return; - } - } - - eloop_register_timeout(0, time * 1000, hostapd_bss_del_ban, ban, hapd); -} - -static int -hostapd_bss_reload(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - - return hostapd_reload_config(hapd->iface); -} - - -static void -hostapd_parse_vht_map_blobmsg(uint16_t map) -{ - char label[4]; - int16_t val; - int i; - - for (i = 0; i < 8; i++) { - snprintf(label, 4, "%dss", i + 1); - - val = (map & (BIT(1) | BIT(0))) + 7; - blobmsg_add_u16(&b, label, val == 10 ? -1 : val); - map = map >> 2; - } -} - -static void -hostapd_parse_vht_capab_blobmsg(struct ieee80211_vht_capabilities *vhtc) -{ - void *supported_mcs; - void *map; - int i; - - static const struct { - const char *name; - uint32_t flag; - } vht_capas[] = { - { "su_beamformee", VHT_CAP_SU_BEAMFORMEE_CAPABLE }, - { "mu_beamformee", VHT_CAP_MU_BEAMFORMEE_CAPABLE }, - }; - - for (i = 0; i < ARRAY_SIZE(vht_capas); i++) - blobmsg_add_u8(&b, vht_capas[i].name, - !!(vhtc->vht_capabilities_info & vht_capas[i].flag)); - - supported_mcs = blobmsg_open_table(&b, "mcs_map"); - - /* RX map */ - map = blobmsg_open_table(&b, "rx"); - hostapd_parse_vht_map_blobmsg(le_to_host16(vhtc->vht_supported_mcs_set.rx_map)); - blobmsg_close_table(&b, map); - - /* TX map */ - map = blobmsg_open_table(&b, "tx"); - hostapd_parse_vht_map_blobmsg(le_to_host16(vhtc->vht_supported_mcs_set.tx_map)); - blobmsg_close_table(&b, map); - - blobmsg_close_table(&b, supported_mcs); -} - -static void -hostapd_parse_capab_blobmsg(struct sta_info *sta) -{ - void *r, *v; - - v = blobmsg_open_table(&b, "capabilities"); - - if (sta->vht_capabilities) { - r = blobmsg_open_table(&b, "vht"); - hostapd_parse_vht_capab_blobmsg(sta->vht_capabilities); - blobmsg_close_table(&b, r); - } - - /* ToDo: Add HT / HE capability parsing */ - - blobmsg_close_table(&b, v); -} - -static int -hostapd_bss_get_clients(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - struct hostap_sta_driver_data sta_driver_data; - struct sta_info *sta; - void *list, *c; - char mac_buf[20]; - static const struct { - const char *name; - uint32_t flag; - } sta_flags[] = { - { "auth", WLAN_STA_AUTH }, - { "assoc", WLAN_STA_ASSOC }, - { "authorized", WLAN_STA_AUTHORIZED }, - { "preauth", WLAN_STA_PREAUTH }, - { "wds", WLAN_STA_WDS }, - { "wmm", WLAN_STA_WMM }, - { "ht", WLAN_STA_HT }, - { "vht", WLAN_STA_VHT }, - { "he", WLAN_STA_HE }, - { "wps", WLAN_STA_WPS }, - { "mfp", WLAN_STA_MFP }, - }; - - blob_buf_init(&b, 0); - blobmsg_add_u32(&b, "freq", hapd->iface->freq); - list = blobmsg_open_table(&b, "clients"); - for (sta = hapd->sta_list; sta; sta = sta->next) { - void *r; - int i; - - sprintf(mac_buf, MACSTR, MAC2STR(sta->addr)); - c = blobmsg_open_table(&b, mac_buf); - for (i = 0; i < ARRAY_SIZE(sta_flags); i++) - blobmsg_add_u8(&b, sta_flags[i].name, - !!(sta->flags & sta_flags[i].flag)); - - r = blobmsg_open_array(&b, "rrm"); - for (i = 0; i < ARRAY_SIZE(sta->rrm_enabled_capa); i++) - blobmsg_add_u32(&b, "", sta->rrm_enabled_capa[i]); - blobmsg_close_array(&b, r); - blobmsg_add_u32(&b, "aid", sta->aid); -#ifdef CONFIG_TAXONOMY - r = blobmsg_alloc_string_buffer(&b, "signature", 1024); - if (retrieve_sta_taxonomy(hapd, sta, r, 1024) > 0) - blobmsg_add_string_buffer(&b); -#endif - - /* Driver information */ - if (hostapd_drv_read_sta_data(hapd, &sta_driver_data, sta->addr) >= 0) { - r = blobmsg_open_table(&b, "bytes"); - blobmsg_add_u64(&b, "rx", sta_driver_data.rx_bytes); - blobmsg_add_u64(&b, "tx", sta_driver_data.tx_bytes); - blobmsg_close_table(&b, r); - r = blobmsg_open_table(&b, "airtime"); - blobmsg_add_u64(&b, "rx", sta_driver_data.rx_airtime); - blobmsg_add_u64(&b, "tx", sta_driver_data.tx_airtime); - blobmsg_close_table(&b, r); - r = blobmsg_open_table(&b, "packets"); - blobmsg_add_u32(&b, "rx", sta_driver_data.rx_packets); - blobmsg_add_u32(&b, "tx", sta_driver_data.tx_packets); - blobmsg_close_table(&b, r); - r = blobmsg_open_table(&b, "rate"); - /* Rate in kbits */ - blobmsg_add_u32(&b, "rx", sta_driver_data.current_rx_rate * 100); - blobmsg_add_u32(&b, "tx", sta_driver_data.current_tx_rate * 100); - blobmsg_close_table(&b, r); - blobmsg_add_u32(&b, "signal", sta_driver_data.signal); - } - - hostapd_parse_capab_blobmsg(sta); - - blobmsg_close_table(&b, c); - } - blobmsg_close_array(&b, list); - ubus_send_reply(ctx, req, b.head); - - return 0; -} - -static int -hostapd_bss_get_features(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - - blob_buf_init(&b, 0); - blobmsg_add_u8(&b, "ht_supported", ht_supported(hapd->iface->hw_features)); - blobmsg_add_u8(&b, "vht_supported", vht_supported(hapd->iface->hw_features)); - ubus_send_reply(ctx, req, b.head); - - return 0; -} - -/* Imported from iw/util.c - * https://git.kernel.org/pub/scm/linux/kernel/git/jberg/iw.git/tree/util.c?id=4b25ae3537af48dbf9d0abf94132e5ba01b32c18#n200 - */ -int ieee80211_frequency_to_channel(int freq) -{ - /* see 802.11-2007 17.3.8.3.2 and Annex J */ - if (freq == 2484) - return 14; - /* see 802.11ax D6.1 27.3.23.2 and Annex E */ - else if (freq == 5935) - return 2; - else if (freq < 2484) - return (freq - 2407) / 5; - else if (freq >= 4910 && freq <= 4980) - return (freq - 4000) / 5; - else if (freq < 5950) - return (freq - 5000) / 5; - else if (freq <= 45000) /* DMG band lower limit */ - /* see 802.11ax D6.1 27.3.23.2 */ - return (freq - 5950) / 5; - else if (freq >= 58320 && freq <= 70200) - return (freq - 56160) / 2160; - else - return 0; -} - -static int -hostapd_bss_get_status(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - void *airtime_table, *dfs_table, *rrm_table, *wnm_table; - struct os_reltime now; - char ssid[SSID_MAX_LEN + 1]; - char phy_name[17]; - size_t ssid_len = SSID_MAX_LEN; - u8 channel = 0, op_class = 0; - - if (hapd->conf->ssid.ssid_len < SSID_MAX_LEN) - ssid_len = hapd->conf->ssid.ssid_len; - - ieee80211_freq_to_channel_ext(hapd->iface->freq, - hapd->iconf->secondary_channel, - hostapd_get_oper_chwidth(hapd->iconf), - &op_class, &channel); - - blob_buf_init(&b, 0); - blobmsg_add_string(&b, "status", hostapd_state_text(hapd->iface->state)); - blobmsg_printf(&b, "bssid", MACSTR, MAC2STR(hapd->conf->bssid)); - - memset(ssid, 0, SSID_MAX_LEN + 1); - memcpy(ssid, hapd->conf->ssid.ssid, ssid_len); - blobmsg_add_string(&b, "ssid", ssid); - - blobmsg_add_u32(&b, "freq", hapd->iface->freq); - blobmsg_add_u32(&b, "channel", channel); - blobmsg_add_u32(&b, "op_class", op_class); - blobmsg_add_u32(&b, "beacon_interval", hapd->iconf->beacon_int); - - snprintf(phy_name, 17, "%s", hapd->iface->phy); - blobmsg_add_string(&b, "phy", phy_name); - - /* RRM */ - rrm_table = blobmsg_open_table(&b, "rrm"); - blobmsg_add_u64(&b, "neighbor_report_tx", hapd->openwrt_stats.rrm.neighbor_report_tx); - blobmsg_close_table(&b, rrm_table); - - /* WNM */ - wnm_table = blobmsg_open_table(&b, "wnm"); - blobmsg_add_u64(&b, "bss_transition_query_rx", hapd->openwrt_stats.wnm.bss_transition_query_rx); - blobmsg_add_u64(&b, "bss_transition_request_tx", hapd->openwrt_stats.wnm.bss_transition_request_tx); - blobmsg_add_u64(&b, "bss_transition_response_rx", hapd->openwrt_stats.wnm.bss_transition_response_rx); - blobmsg_close_table(&b, wnm_table); - - /* Airtime */ - airtime_table = blobmsg_open_table(&b, "airtime"); - blobmsg_add_u64(&b, "time", hapd->iface->last_channel_time); - blobmsg_add_u64(&b, "time_busy", hapd->iface->last_channel_time_busy); - blobmsg_add_u16(&b, "utilization", hapd->iface->channel_utilization); - blobmsg_close_table(&b, airtime_table); - - /* DFS */ - dfs_table = blobmsg_open_table(&b, "dfs"); - blobmsg_add_u32(&b, "cac_seconds", hapd->iface->dfs_cac_ms / 1000); - blobmsg_add_u8(&b, "cac_active", !!(hapd->iface->cac_started)); - os_reltime_age(&hapd->iface->dfs_cac_start, &now); - blobmsg_add_u32(&b, "cac_seconds_left", - hapd->iface->cac_started ? hapd->iface->dfs_cac_ms / 1000 - now.sec : 0); - blobmsg_close_table(&b, dfs_table); - - ubus_send_reply(ctx, req, b.head); - - return 0; -} - -enum { - NOTIFY_RESPONSE, - __NOTIFY_MAX -}; - -static const struct blobmsg_policy notify_policy[__NOTIFY_MAX] = { - [NOTIFY_RESPONSE] = { "notify_response", BLOBMSG_TYPE_INT32 }, -}; - -static int -hostapd_notify_response(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct blob_attr *tb[__NOTIFY_MAX]; - struct hostapd_data *hapd = get_hapd_from_object(obj); - struct wpabuf *elems; - const char *pos; - size_t len; - - blobmsg_parse(notify_policy, __NOTIFY_MAX, tb, - blob_data(msg), blob_len(msg)); - - if (!tb[NOTIFY_RESPONSE]) - return UBUS_STATUS_INVALID_ARGUMENT; - - hapd->ubus.notify_response = blobmsg_get_u32(tb[NOTIFY_RESPONSE]); - - return UBUS_STATUS_OK; -} - -enum { - DEL_CLIENT_ADDR, - DEL_CLIENT_REASON, - DEL_CLIENT_DEAUTH, - DEL_CLIENT_BAN_TIME, - __DEL_CLIENT_MAX -}; - -static const struct blobmsg_policy del_policy[__DEL_CLIENT_MAX] = { - [DEL_CLIENT_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, - [DEL_CLIENT_REASON] = { "reason", BLOBMSG_TYPE_INT32 }, - [DEL_CLIENT_DEAUTH] = { "deauth", BLOBMSG_TYPE_INT8 }, - [DEL_CLIENT_BAN_TIME] = { "ban_time", BLOBMSG_TYPE_INT32 }, -}; - -static int -hostapd_bss_del_client(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct blob_attr *tb[__DEL_CLIENT_MAX]; - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - struct sta_info *sta; - bool deauth = false; - int reason; - u8 addr[ETH_ALEN]; - - blobmsg_parse(del_policy, __DEL_CLIENT_MAX, tb, blob_data(msg), blob_len(msg)); - - if (!tb[DEL_CLIENT_ADDR]) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (hwaddr_aton(blobmsg_data(tb[DEL_CLIENT_ADDR]), addr)) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (tb[DEL_CLIENT_REASON]) - reason = blobmsg_get_u32(tb[DEL_CLIENT_REASON]); - - if (tb[DEL_CLIENT_DEAUTH]) - deauth = blobmsg_get_bool(tb[DEL_CLIENT_DEAUTH]); - - sta = ap_get_sta(hapd, addr); - if (sta) { - if (deauth) { - hostapd_drv_sta_deauth(hapd, addr, reason); - ap_sta_deauthenticate(hapd, sta, reason); - } else { - hostapd_drv_sta_disassoc(hapd, addr, reason); - ap_sta_disassociate(hapd, sta, reason); - } - } - - if (tb[DEL_CLIENT_BAN_TIME]) - hostapd_bss_ban_client(hapd, addr, blobmsg_get_u32(tb[DEL_CLIENT_BAN_TIME])); - - return 0; -} - -static void -blobmsg_add_macaddr(struct blob_buf *buf, const char *name, const u8 *addr) -{ - char *s; - - s = blobmsg_alloc_string_buffer(buf, name, 20); - sprintf(s, MACSTR, MAC2STR(addr)); - blobmsg_add_string_buffer(buf); -} - -static int -hostapd_bss_list_bans(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - struct ubus_banned_client *ban; - void *c; - - blob_buf_init(&b, 0); - c = blobmsg_open_array(&b, "clients"); - avl_for_each_element(&hapd->ubus.banned, ban, avl) - blobmsg_add_macaddr(&b, NULL, ban->addr); - blobmsg_close_array(&b, c); - ubus_send_reply(ctx, req, b.head); - - return 0; -} - -#ifdef CONFIG_WPS -static int -hostapd_bss_wps_start(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - int rc; - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - - rc = hostapd_wps_button_pushed(hapd, NULL); - - if (rc != 0) - return UBUS_STATUS_NOT_SUPPORTED; - - return 0; -} - - -static const char * pbc_status_enum_str(enum pbc_status status) -{ - switch (status) { - case WPS_PBC_STATUS_DISABLE: - return "Disabled"; - case WPS_PBC_STATUS_ACTIVE: - return "Active"; - case WPS_PBC_STATUS_TIMEOUT: - return "Timed-out"; - case WPS_PBC_STATUS_OVERLAP: - return "Overlap"; - default: - return "Unknown"; - } -} - -static int -hostapd_bss_wps_status(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - int rc; - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - - blob_buf_init(&b, 0); - - blobmsg_add_string(&b, "pbc_status", pbc_status_enum_str(hapd->wps_stats.pbc_status)); - blobmsg_add_string(&b, "last_wps_result", - (hapd->wps_stats.status == WPS_STATUS_SUCCESS ? - "Success": - (hapd->wps_stats.status == WPS_STATUS_FAILURE ? - "Failed" : "None"))); - - /* If status == Failure - Add possible Reasons */ - if(hapd->wps_stats.status == WPS_STATUS_FAILURE && - hapd->wps_stats.failure_reason > 0) - blobmsg_add_string(&b, "reason", wps_ei_str(hapd->wps_stats.failure_reason)); - - if (hapd->wps_stats.status) - blobmsg_printf(&b, "peer_address", MACSTR, MAC2STR(hapd->wps_stats.peer_addr)); - - ubus_send_reply(ctx, req, b.head); - - return 0; -} - -static int -hostapd_bss_wps_cancel(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - int rc; - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - - rc = hostapd_wps_cancel(hapd); - - if (rc != 0) - return UBUS_STATUS_NOT_SUPPORTED; - - return 0; -} -#endif /* CONFIG_WPS */ - -static int -hostapd_bss_update_beacon(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - int rc; - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - - rc = ieee802_11_set_beacon(hapd); - - if (rc != 0) - return UBUS_STATUS_NOT_SUPPORTED; - - return 0; -} - -enum { - CONFIG_IFACE, - CONFIG_FILE, - __CONFIG_MAX -}; - -enum { - CSA_FREQ, - CSA_BCN_COUNT, - CSA_CENTER_FREQ1, - CSA_CENTER_FREQ2, - CSA_BANDWIDTH, - CSA_SEC_CHANNEL_OFFSET, - CSA_HT, - CSA_VHT, - CSA_HE, - CSA_BLOCK_TX, - CSA_FORCE, - __CSA_MAX -}; - -static const struct blobmsg_policy csa_policy[__CSA_MAX] = { - [CSA_FREQ] = { "freq", BLOBMSG_TYPE_INT32 }, - [CSA_BCN_COUNT] = { "bcn_count", BLOBMSG_TYPE_INT32 }, - [CSA_CENTER_FREQ1] = { "center_freq1", BLOBMSG_TYPE_INT32 }, - [CSA_CENTER_FREQ2] = { "center_freq2", BLOBMSG_TYPE_INT32 }, - [CSA_BANDWIDTH] = { "bandwidth", BLOBMSG_TYPE_INT32 }, - [CSA_SEC_CHANNEL_OFFSET] = { "sec_channel_offset", BLOBMSG_TYPE_INT32 }, - [CSA_HT] = { "ht", BLOBMSG_TYPE_BOOL }, - [CSA_VHT] = { "vht", BLOBMSG_TYPE_BOOL }, - [CSA_HE] = { "he", BLOBMSG_TYPE_BOOL }, - [CSA_BLOCK_TX] = { "block_tx", BLOBMSG_TYPE_BOOL }, - [CSA_FORCE] = { "force", BLOBMSG_TYPE_BOOL }, -}; - - -static void switch_chan_fallback_cb(void *eloop_data, void *user_ctx) -{ - struct hostapd_iface *iface = eloop_data; - struct hostapd_freq_params *freq_params = user_ctx; - - hostapd_switch_channel_fallback(iface, freq_params); -} - -#ifdef NEED_AP_MLME -static int -hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct blob_attr *tb[__CSA_MAX]; - struct hostapd_data *hapd = get_hapd_from_object(obj); - struct hostapd_config *iconf = hapd->iface->conf; - struct hostapd_freq_params *freq_params; - struct hostapd_hw_modes *mode = hapd->iface->current_mode; - struct csa_settings css = { - .freq_params = { - .ht_enabled = iconf->ieee80211n, - .vht_enabled = iconf->ieee80211ac, - .he_enabled = iconf->ieee80211ax, - .sec_channel_offset = iconf->secondary_channel, - } - }; - u8 chwidth = hostapd_get_oper_chwidth(iconf); - u8 seg0 = 0, seg1 = 0; - int ret = UBUS_STATUS_OK; - int i; - - blobmsg_parse(csa_policy, __CSA_MAX, tb, blob_data(msg), blob_len(msg)); - - if (!tb[CSA_FREQ]) - return UBUS_STATUS_INVALID_ARGUMENT; - - switch (iconf->vht_oper_chwidth) { - case CHANWIDTH_USE_HT: - if (iconf->secondary_channel) - css.freq_params.bandwidth = 40; - else - css.freq_params.bandwidth = 20; - break; - case CHANWIDTH_160MHZ: - css.freq_params.bandwidth = 160; - break; - default: - css.freq_params.bandwidth = 80; - break; - } - - css.freq_params.freq = blobmsg_get_u32(tb[CSA_FREQ]); - -#define SET_CSA_SETTING(name, field, type) \ - do { \ - if (tb[name]) \ - css.field = blobmsg_get_ ## type(tb[name]); \ - } while(0) - - SET_CSA_SETTING(CSA_BCN_COUNT, cs_count, u32); - SET_CSA_SETTING(CSA_CENTER_FREQ1, freq_params.center_freq1, u32); - SET_CSA_SETTING(CSA_CENTER_FREQ2, freq_params.center_freq2, u32); - SET_CSA_SETTING(CSA_BANDWIDTH, freq_params.bandwidth, u32); - SET_CSA_SETTING(CSA_SEC_CHANNEL_OFFSET, freq_params.sec_channel_offset, u32); - SET_CSA_SETTING(CSA_HT, freq_params.ht_enabled, bool); - SET_CSA_SETTING(CSA_VHT, freq_params.vht_enabled, bool); - SET_CSA_SETTING(CSA_HE, freq_params.he_enabled, bool); - SET_CSA_SETTING(CSA_BLOCK_TX, block_tx, bool); - - css.freq_params.channel = hostapd_hw_get_channel(hapd, css.freq_params.freq); - if (!css.freq_params.channel) - return UBUS_STATUS_NOT_SUPPORTED; - - switch (css.freq_params.bandwidth) { - case 160: - chwidth = CHANWIDTH_160MHZ; - break; - case 80: - chwidth = css.freq_params.center_freq2 ? CHANWIDTH_80P80MHZ : CHANWIDTH_80MHZ; - break; - default: - chwidth = CHANWIDTH_USE_HT; - break; - } - - hostapd_set_freq_params(&css.freq_params, iconf->hw_mode, - css.freq_params.freq, - css.freq_params.channel, iconf->enable_edmg, - iconf->edmg_channel, - css.freq_params.ht_enabled, - css.freq_params.vht_enabled, - css.freq_params.he_enabled, - css.freq_params.sec_channel_offset, - chwidth, seg0, seg1, - iconf->vht_capab, - mode ? &mode->he_capab[IEEE80211_MODE_AP] : - NULL); - - for (i = 0; i < hapd->iface->num_bss; i++) { - struct hostapd_data *bss = hapd->iface->bss[i]; - - if (hostapd_switch_channel(bss, &css) != 0) - ret = UBUS_STATUS_NOT_SUPPORTED; - } - - if (!ret || !tb[CSA_FORCE] || !blobmsg_get_bool(tb[CSA_FORCE])) - return ret; - - freq_params = malloc(sizeof(*freq_params)); - memcpy(freq_params, &css.freq_params, sizeof(*freq_params)); - eloop_register_timeout(0, 1, switch_chan_fallback_cb, - hapd->iface, freq_params); - - return 0; -#undef SET_CSA_SETTING -} -#endif - -enum { - VENDOR_ELEMENTS, - __VENDOR_ELEMENTS_MAX -}; - -static const struct blobmsg_policy ve_policy[__VENDOR_ELEMENTS_MAX] = { - /* vendor elements are provided as hex-string */ - [VENDOR_ELEMENTS] = { "vendor_elements", BLOBMSG_TYPE_STRING }, -}; - -static int -hostapd_vendor_elements(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct blob_attr *tb[__VENDOR_ELEMENTS_MAX]; - struct hostapd_data *hapd = get_hapd_from_object(obj); - struct hostapd_bss_config *bss = hapd->conf; - struct wpabuf *elems; - const char *pos; - size_t len; - - blobmsg_parse(ve_policy, __VENDOR_ELEMENTS_MAX, tb, - blob_data(msg), blob_len(msg)); - - if (!tb[VENDOR_ELEMENTS]) - return UBUS_STATUS_INVALID_ARGUMENT; - - pos = blobmsg_data(tb[VENDOR_ELEMENTS]); - len = os_strlen(pos); - if (len & 0x01) - return UBUS_STATUS_INVALID_ARGUMENT; - - len /= 2; - if (len == 0) { - wpabuf_free(bss->vendor_elements); - bss->vendor_elements = NULL; - return 0; - } - - elems = wpabuf_alloc(len); - if (elems == NULL) - return 1; - - if (hexstr2bin(pos, wpabuf_put(elems, len), len)) { - wpabuf_free(elems); - return UBUS_STATUS_INVALID_ARGUMENT; - } - - wpabuf_free(bss->vendor_elements); - bss->vendor_elements = elems; - - /* update beacons if vendor elements were set successfully */ - if (ieee802_11_update_beacons(hapd->iface) != 0) - return UBUS_STATUS_NOT_SUPPORTED; - return UBUS_STATUS_OK; -} - -static void -hostapd_rrm_print_nr(struct hostapd_neighbor_entry *nr) -{ - const u8 *data; - char *str; - int len; - - blobmsg_printf(&b, "", MACSTR, MAC2STR(nr->bssid)); - - str = blobmsg_alloc_string_buffer(&b, "", nr->ssid.ssid_len + 1); - memcpy(str, nr->ssid.ssid, nr->ssid.ssid_len); - str[nr->ssid.ssid_len] = 0; - blobmsg_add_string_buffer(&b); - - len = wpabuf_len(nr->nr); - str = blobmsg_alloc_string_buffer(&b, "", 2 * len + 1); - wpa_snprintf_hex(str, 2 * len + 1, wpabuf_head_u8(nr->nr), len); - blobmsg_add_string_buffer(&b); -} - -enum { - BSS_MGMT_EN_NEIGHBOR, - BSS_MGMT_EN_BEACON, -#ifdef CONFIG_WNM_AP - BSS_MGMT_EN_BSS_TRANSITION, -#endif - __BSS_MGMT_EN_MAX -}; - -static bool -__hostapd_bss_mgmt_enable_f(struct hostapd_data *hapd, int flag) -{ - struct hostapd_bss_config *bss = hapd->conf; - uint32_t flags; - - switch (flag) { - case BSS_MGMT_EN_NEIGHBOR: - if (bss->radio_measurements[0] & - WLAN_RRM_CAPS_NEIGHBOR_REPORT) - return false; - - bss->radio_measurements[0] |= - WLAN_RRM_CAPS_NEIGHBOR_REPORT; - hostapd_neighbor_set_own_report(hapd); - return true; - case BSS_MGMT_EN_BEACON: - flags = WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE | - WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE | - WLAN_RRM_CAPS_BEACON_REPORT_TABLE; - - if (bss->radio_measurements[0] & flags == flags) - return false; - - bss->radio_measurements[0] |= (u8) flags; - return true; -#ifdef CONFIG_WNM_AP - case BSS_MGMT_EN_BSS_TRANSITION: - if (bss->bss_transition) - return false; - - bss->bss_transition = 1; - return true; -#endif - } -} - -static void -__hostapd_bss_mgmt_enable(struct hostapd_data *hapd, uint32_t flags) -{ - bool update = false; - int i; - - for (i = 0; i < __BSS_MGMT_EN_MAX; i++) { - if (!(flags & (1 << i))) - continue; - - update |= __hostapd_bss_mgmt_enable_f(hapd, i); - } - - if (update) - ieee802_11_update_beacons(hapd->iface); -} - - -static const struct blobmsg_policy bss_mgmt_enable_policy[__BSS_MGMT_EN_MAX] = { - [BSS_MGMT_EN_NEIGHBOR] = { "neighbor_report", BLOBMSG_TYPE_BOOL }, - [BSS_MGMT_EN_BEACON] = { "beacon_report", BLOBMSG_TYPE_BOOL }, -#ifdef CONFIG_WNM_AP - [BSS_MGMT_EN_BSS_TRANSITION] = { "bss_transition", BLOBMSG_TYPE_BOOL }, -#endif -}; - -static int -hostapd_bss_mgmt_enable(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) - -{ - struct hostapd_data *hapd = get_hapd_from_object(obj); - struct blob_attr *tb[__BSS_MGMT_EN_MAX]; - struct blob_attr *cur; - uint32_t flags = 0; - int i; - bool neigh = false, beacon = false; - - blobmsg_parse(bss_mgmt_enable_policy, __BSS_MGMT_EN_MAX, tb, blob_data(msg), blob_len(msg)); - - for (i = 0; i < ARRAY_SIZE(tb); i++) { - if (!tb[i] || !blobmsg_get_bool(tb[i])) - continue; - - flags |= (1 << i); - } - - __hostapd_bss_mgmt_enable(hapd, flags); -} - - -static void -hostapd_rrm_nr_enable(struct hostapd_data *hapd) -{ - __hostapd_bss_mgmt_enable(hapd, 1 << BSS_MGMT_EN_NEIGHBOR); -} - -static int -hostapd_rrm_nr_get_own(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct hostapd_data *hapd = get_hapd_from_object(obj); - struct hostapd_neighbor_entry *nr; - void *c; - - hostapd_rrm_nr_enable(hapd); - - nr = hostapd_neighbor_get(hapd, hapd->own_addr, NULL); - if (!nr) - return UBUS_STATUS_NOT_FOUND; - - blob_buf_init(&b, 0); - - c = blobmsg_open_array(&b, "value"); - hostapd_rrm_print_nr(nr); - blobmsg_close_array(&b, c); - - ubus_send_reply(ctx, req, b.head); - - return 0; -} - -static int -hostapd_rrm_nr_list(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct hostapd_data *hapd = get_hapd_from_object(obj); - struct hostapd_neighbor_entry *nr; - void *c; - - hostapd_rrm_nr_enable(hapd); - blob_buf_init(&b, 0); - - c = blobmsg_open_array(&b, "list"); - dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry, list) { - void *cur; - - if (!memcmp(nr->bssid, hapd->own_addr, ETH_ALEN)) - continue; - - cur = blobmsg_open_array(&b, NULL); - hostapd_rrm_print_nr(nr); - blobmsg_close_array(&b, cur); - } - blobmsg_close_array(&b, c); - - ubus_send_reply(ctx, req, b.head); - - return 0; -} - -enum { - NR_SET_LIST, - __NR_SET_LIST_MAX -}; - -static const struct blobmsg_policy nr_set_policy[__NR_SET_LIST_MAX] = { - [NR_SET_LIST] = { "list", BLOBMSG_TYPE_ARRAY }, -}; - - -static void -hostapd_rrm_nr_clear(struct hostapd_data *hapd) -{ - struct hostapd_neighbor_entry *nr; - -restart: - dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry, list) { - if (!memcmp(nr->bssid, hapd->own_addr, ETH_ALEN)) - continue; - - hostapd_neighbor_remove(hapd, nr->bssid, &nr->ssid); - goto restart; - } -} - -static int -hostapd_rrm_nr_set(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - static const struct blobmsg_policy nr_e_policy[] = { - { .type = BLOBMSG_TYPE_STRING }, - { .type = BLOBMSG_TYPE_STRING }, - { .type = BLOBMSG_TYPE_STRING }, - }; - struct hostapd_data *hapd = get_hapd_from_object(obj); - struct blob_attr *tb_l[__NR_SET_LIST_MAX]; - struct blob_attr *tb[ARRAY_SIZE(nr_e_policy)]; - struct blob_attr *cur; - int rem; - - hostapd_rrm_nr_enable(hapd); - - blobmsg_parse(nr_set_policy, __NR_SET_LIST_MAX, tb_l, blob_data(msg), blob_len(msg)); - if (!tb_l[NR_SET_LIST]) - return UBUS_STATUS_INVALID_ARGUMENT; - - hostapd_rrm_nr_clear(hapd); - blobmsg_for_each_attr(cur, tb_l[NR_SET_LIST], rem) { - struct wpa_ssid_value ssid; - struct wpabuf *data; - u8 bssid[ETH_ALEN]; - char *s, *nr_s; - - blobmsg_parse_array(nr_e_policy, ARRAY_SIZE(nr_e_policy), tb, blobmsg_data(cur), blobmsg_data_len(cur)); - if (!tb[0] || !tb[1] || !tb[2]) - goto invalid; - - /* Neighbor Report binary */ - nr_s = blobmsg_get_string(tb[2]); - data = wpabuf_parse_bin(nr_s); - if (!data) - goto invalid; - - /* BSSID */ - s = blobmsg_get_string(tb[0]); - if (strlen(s) == 0) { - /* Copy BSSID from neighbor report */ - if (hwaddr_compact_aton(nr_s, bssid)) - goto invalid; - } else if (hwaddr_aton(s, bssid)) { - goto invalid; - } - - /* SSID */ - s = blobmsg_get_string(tb[1]); - if (strlen(s) == 0) { - /* Copy SSID from hostapd BSS conf */ - memcpy(&ssid, &hapd->conf->ssid, sizeof(ssid)); - } else { - ssid.ssid_len = strlen(s); - if (ssid.ssid_len > sizeof(ssid.ssid)) - goto invalid; - - memcpy(&ssid, s, ssid.ssid_len); - } - - hostapd_neighbor_set(hapd, bssid, &ssid, data, NULL, NULL, 0, 0); - wpabuf_free(data); - continue; - -invalid: - return UBUS_STATUS_INVALID_ARGUMENT; - } - - return 0; -} - -enum { - BEACON_REQ_ADDR, - BEACON_REQ_MODE, - BEACON_REQ_OP_CLASS, - BEACON_REQ_CHANNEL, - BEACON_REQ_DURATION, - BEACON_REQ_BSSID, - BEACON_REQ_SSID, - __BEACON_REQ_MAX, -}; - -static const struct blobmsg_policy beacon_req_policy[__BEACON_REQ_MAX] = { - [BEACON_REQ_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, - [BEACON_REQ_OP_CLASS] { "op_class", BLOBMSG_TYPE_INT32 }, - [BEACON_REQ_CHANNEL] { "channel", BLOBMSG_TYPE_INT32 }, - [BEACON_REQ_DURATION] { "duration", BLOBMSG_TYPE_INT32 }, - [BEACON_REQ_MODE] { "mode", BLOBMSG_TYPE_INT32 }, - [BEACON_REQ_BSSID] { "bssid", BLOBMSG_TYPE_STRING }, - [BEACON_REQ_SSID] { "ssid", BLOBMSG_TYPE_STRING }, -}; - -static int -hostapd_rrm_beacon_req(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *ureq, const char *method, - struct blob_attr *msg) -{ - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - struct blob_attr *tb[__BEACON_REQ_MAX]; - struct blob_attr *cur; - struct wpabuf *req; - u8 bssid[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - u8 addr[ETH_ALEN]; - int mode, rem, ret; - int buf_len = 13; - - blobmsg_parse(beacon_req_policy, __BEACON_REQ_MAX, tb, blob_data(msg), blob_len(msg)); - - if (!tb[BEACON_REQ_ADDR] || !tb[BEACON_REQ_MODE] || !tb[BEACON_REQ_DURATION] || - !tb[BEACON_REQ_OP_CLASS] || !tb[BEACON_REQ_CHANNEL]) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (tb[BEACON_REQ_SSID]) - buf_len += blobmsg_data_len(tb[BEACON_REQ_SSID]) + 2 - 1; - - mode = blobmsg_get_u32(tb[BEACON_REQ_MODE]); - if (hwaddr_aton(blobmsg_data(tb[BEACON_REQ_ADDR]), addr)) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (tb[BEACON_REQ_BSSID] && - hwaddr_aton(blobmsg_data(tb[BEACON_REQ_BSSID]), bssid)) - return UBUS_STATUS_INVALID_ARGUMENT; - - req = wpabuf_alloc(buf_len); - if (!req) - return UBUS_STATUS_UNKNOWN_ERROR; - - /* 1: regulatory class */ - wpabuf_put_u8(req, blobmsg_get_u32(tb[BEACON_REQ_OP_CLASS])); - - /* 2: channel number */ - wpabuf_put_u8(req, blobmsg_get_u32(tb[BEACON_REQ_CHANNEL])); - - /* 3-4: randomization interval */ - wpabuf_put_le16(req, 0); - - /* 5-6: duration */ - wpabuf_put_le16(req, blobmsg_get_u32(tb[BEACON_REQ_DURATION])); - - /* 7: mode */ - wpabuf_put_u8(req, blobmsg_get_u32(tb[BEACON_REQ_MODE])); - - /* 8-13: BSSID */ - wpabuf_put_data(req, bssid, ETH_ALEN); - - if ((cur = tb[BEACON_REQ_SSID]) != NULL) { - wpabuf_put_u8(req, WLAN_EID_SSID); - wpabuf_put_u8(req, blobmsg_data_len(cur) - 1); - wpabuf_put_data(req, blobmsg_data(cur), blobmsg_data_len(cur) - 1); - } - - ret = hostapd_send_beacon_req(hapd, addr, 0, req); - if (ret < 0) - return -ret; - - return 0; -} - - -#ifdef CONFIG_WNM_AP - -static int -hostapd_bss_tr_send(struct hostapd_data *hapd, u8 *addr, bool disassoc_imminent, bool abridged, - u16 disassoc_timer, u8 validity_period, u8 dialog_token, - struct blob_attr *neighbors) -{ - struct blob_attr *cur; - struct sta_info *sta; - int nr_len = 0; - int rem; - u8 *nr = NULL; - u8 req_mode = 0; - - sta = ap_get_sta(hapd, addr); - if (!sta) - return UBUS_STATUS_NOT_FOUND; - - if (neighbors) { - u8 *nr_cur; - - if (blobmsg_check_array(neighbors, - BLOBMSG_TYPE_STRING) < 0) - return UBUS_STATUS_INVALID_ARGUMENT; - - blobmsg_for_each_attr(cur, neighbors, rem) { - int len = strlen(blobmsg_get_string(cur)); - - if (len % 2) - return UBUS_STATUS_INVALID_ARGUMENT; - - nr_len += (len / 2) + 2; - } - - if (nr_len) { - nr = os_zalloc(nr_len); - if (!nr) - return UBUS_STATUS_UNKNOWN_ERROR; - } - - nr_cur = nr; - blobmsg_for_each_attr(cur, neighbors, rem) { - int len = strlen(blobmsg_get_string(cur)) / 2; - - *nr_cur++ = WLAN_EID_NEIGHBOR_REPORT; - *nr_cur++ = (u8) len; - if (hexstr2bin(blobmsg_data(cur), nr_cur, len)) { - free(nr); - return UBUS_STATUS_INVALID_ARGUMENT; - } - - nr_cur += len; - } - } - - if (nr) - req_mode |= WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED; - - if (abridged) - req_mode |= WNM_BSS_TM_REQ_ABRIDGED; - - if (disassoc_imminent) - req_mode |= WNM_BSS_TM_REQ_DISASSOC_IMMINENT; - - if (wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer, validity_period, NULL, - dialog_token, NULL, nr, nr_len, NULL, 0)) - return UBUS_STATUS_UNKNOWN_ERROR; - - return 0; -} - -enum { - BSS_TR_ADDR, - BSS_TR_DA_IMMINENT, - BSS_TR_DA_TIMER, - BSS_TR_VALID_PERIOD, - BSS_TR_NEIGHBORS, - BSS_TR_ABRIDGED, - BSS_TR_DIALOG_TOKEN, - __BSS_TR_DISASSOC_MAX -}; - -static const struct blobmsg_policy bss_tr_policy[__BSS_TR_DISASSOC_MAX] = { - [BSS_TR_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, - [BSS_TR_DA_IMMINENT] = { "disassociation_imminent", BLOBMSG_TYPE_BOOL }, - [BSS_TR_DA_TIMER] = { "disassociation_timer", BLOBMSG_TYPE_INT32 }, - [BSS_TR_VALID_PERIOD] = { "validity_period", BLOBMSG_TYPE_INT32 }, - [BSS_TR_NEIGHBORS] = { "neighbors", BLOBMSG_TYPE_ARRAY }, - [BSS_TR_ABRIDGED] = { "abridged", BLOBMSG_TYPE_BOOL }, - [BSS_TR_DIALOG_TOKEN] = { "dialog_token", BLOBMSG_TYPE_INT32 }, -}; - -static int -hostapd_bss_transition_request(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *ureq, const char *method, - struct blob_attr *msg) -{ - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - struct blob_attr *tb[__BSS_TR_DISASSOC_MAX]; - struct sta_info *sta; - u32 da_timer = 0; - u32 valid_period = 0; - u8 addr[ETH_ALEN]; - u32 dialog_token = 1; - bool abridged; - bool da_imminent; - - blobmsg_parse(bss_tr_policy, __BSS_TR_DISASSOC_MAX, tb, blob_data(msg), blob_len(msg)); - - if (!tb[BSS_TR_ADDR]) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (hwaddr_aton(blobmsg_data(tb[BSS_TR_ADDR]), addr)) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (tb[BSS_TR_DA_TIMER]) - da_timer = blobmsg_get_u32(tb[BSS_TR_DA_TIMER]); - - if (tb[BSS_TR_VALID_PERIOD]) - valid_period = blobmsg_get_u32(tb[BSS_TR_VALID_PERIOD]); - - if (tb[BSS_TR_DIALOG_TOKEN]) - dialog_token = blobmsg_get_u32(tb[BSS_TR_DIALOG_TOKEN]); - - da_imminent = !!(tb[BSS_TR_DA_IMMINENT] && blobmsg_get_bool(tb[BSS_TR_DA_IMMINENT])); - abridged = !!(tb[BSS_TR_ABRIDGED] && blobmsg_get_bool(tb[BSS_TR_ABRIDGED])); - - return hostapd_bss_tr_send(hapd, addr, da_imminent, abridged, da_timer, valid_period, - dialog_token, tb[BSS_TR_NEIGHBORS]); -} - -enum { - WNM_DISASSOC_ADDR, - WNM_DISASSOC_DURATION, - WNM_DISASSOC_NEIGHBORS, - WNM_DISASSOC_ABRIDGED, - __WNM_DISASSOC_MAX, -}; - -static const struct blobmsg_policy wnm_disassoc_policy[__WNM_DISASSOC_MAX] = { - [WNM_DISASSOC_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, - [WNM_DISASSOC_DURATION] { "duration", BLOBMSG_TYPE_INT32 }, - [WNM_DISASSOC_NEIGHBORS] { "neighbors", BLOBMSG_TYPE_ARRAY }, - [WNM_DISASSOC_ABRIDGED] { "abridged", BLOBMSG_TYPE_BOOL }, -}; - -static int -hostapd_wnm_disassoc_imminent(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *ureq, const char *method, - struct blob_attr *msg) -{ - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - struct blob_attr *tb[__WNM_DISASSOC_MAX]; - struct sta_info *sta; - int duration = 10; - u8 addr[ETH_ALEN]; - bool abridged; - - blobmsg_parse(wnm_disassoc_policy, __WNM_DISASSOC_MAX, tb, blob_data(msg), blob_len(msg)); - - if (!tb[WNM_DISASSOC_ADDR]) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (hwaddr_aton(blobmsg_data(tb[WNM_DISASSOC_ADDR]), addr)) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (tb[WNM_DISASSOC_DURATION]) - duration = blobmsg_get_u32(tb[WNM_DISASSOC_DURATION]); - - abridged = !!(tb[WNM_DISASSOC_ABRIDGED] && blobmsg_get_bool(tb[WNM_DISASSOC_ABRIDGED])); - - return hostapd_bss_tr_send(hapd, addr, true, abridged, duration, duration, - 1, tb[WNM_DISASSOC_NEIGHBORS]); -} -#endif - -#ifdef CONFIG_AIRTIME_POLICY -enum { - UPDATE_AIRTIME_STA, - UPDATE_AIRTIME_WEIGHT, - __UPDATE_AIRTIME_MAX, -}; - - -static const struct blobmsg_policy airtime_policy[__UPDATE_AIRTIME_MAX] = { - [UPDATE_AIRTIME_STA] = { "sta", BLOBMSG_TYPE_STRING }, - [UPDATE_AIRTIME_WEIGHT] = { "weight", BLOBMSG_TYPE_INT32 }, -}; - -static int -hostapd_bss_update_airtime(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *ureq, const char *method, - struct blob_attr *msg) -{ - struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - struct blob_attr *tb[__UPDATE_AIRTIME_MAX]; - struct sta_info *sta = NULL; - u8 addr[ETH_ALEN]; - int weight; - - blobmsg_parse(airtime_policy, __UPDATE_AIRTIME_MAX, tb, blob_data(msg), blob_len(msg)); - - if (!tb[UPDATE_AIRTIME_WEIGHT]) - return UBUS_STATUS_INVALID_ARGUMENT; - - weight = blobmsg_get_u32(tb[UPDATE_AIRTIME_WEIGHT]); - - if (!tb[UPDATE_AIRTIME_STA]) { - if (!weight) - return UBUS_STATUS_INVALID_ARGUMENT; - - hapd->conf->airtime_weight = weight; - return 0; - } - - if (hwaddr_aton(blobmsg_data(tb[UPDATE_AIRTIME_STA]), addr)) - return UBUS_STATUS_INVALID_ARGUMENT; - - sta = ap_get_sta(hapd, addr); - if (!sta) - return UBUS_STATUS_NOT_FOUND; - - sta->dyn_airtime_weight = weight; - airtime_policy_new_sta(hapd, sta); - - return 0; -} -#endif - - -static const struct ubus_method bss_methods[] = { - UBUS_METHOD_NOARG("reload", hostapd_bss_reload), - UBUS_METHOD_NOARG("get_clients", hostapd_bss_get_clients), - UBUS_METHOD_NOARG("get_status", hostapd_bss_get_status), - UBUS_METHOD("del_client", hostapd_bss_del_client, del_policy), -#ifdef CONFIG_AIRTIME_POLICY - UBUS_METHOD("update_airtime", hostapd_bss_update_airtime, airtime_policy), -#endif - UBUS_METHOD_NOARG("list_bans", hostapd_bss_list_bans), -#ifdef CONFIG_WPS - UBUS_METHOD_NOARG("wps_start", hostapd_bss_wps_start), - UBUS_METHOD_NOARG("wps_status", hostapd_bss_wps_status), - UBUS_METHOD_NOARG("wps_cancel", hostapd_bss_wps_cancel), -#endif - UBUS_METHOD_NOARG("update_beacon", hostapd_bss_update_beacon), - UBUS_METHOD_NOARG("get_features", hostapd_bss_get_features), -#ifdef NEED_AP_MLME - UBUS_METHOD("switch_chan", hostapd_switch_chan, csa_policy), -#endif - UBUS_METHOD("set_vendor_elements", hostapd_vendor_elements, ve_policy), - UBUS_METHOD("notify_response", hostapd_notify_response, notify_policy), - UBUS_METHOD("bss_mgmt_enable", hostapd_bss_mgmt_enable, bss_mgmt_enable_policy), - UBUS_METHOD_NOARG("rrm_nr_get_own", hostapd_rrm_nr_get_own), - UBUS_METHOD_NOARG("rrm_nr_list", hostapd_rrm_nr_list), - UBUS_METHOD("rrm_nr_set", hostapd_rrm_nr_set, nr_set_policy), - UBUS_METHOD("rrm_beacon_req", hostapd_rrm_beacon_req, beacon_req_policy), -#ifdef CONFIG_WNM_AP - UBUS_METHOD("wnm_disassoc_imminent", hostapd_wnm_disassoc_imminent, wnm_disassoc_policy), - UBUS_METHOD("bss_transition_request", hostapd_bss_transition_request, bss_tr_policy), -#endif -}; - -static struct ubus_object_type bss_object_type = - UBUS_OBJECT_TYPE("hostapd_bss", bss_methods); - -static int avl_compare_macaddr(const void *k1, const void *k2, void *ptr) -{ - return memcmp(k1, k2, ETH_ALEN); -} - -void hostapd_ubus_add_bss(struct hostapd_data *hapd) -{ - struct ubus_object *obj = &hapd->ubus.obj; - char *name; - int ret; - -#ifdef CONFIG_MESH - if (hapd->conf->mesh & MESH_ENABLED) - return; -#endif - - if (!hostapd_ubus_init()) - return; - - if (asprintf(&name, "hostapd.%s", hapd->conf->iface) < 0) - return; - - avl_init(&hapd->ubus.banned, avl_compare_macaddr, false, NULL); - obj->name = name; - obj->type = &bss_object_type; - obj->methods = bss_object_type.methods; - obj->n_methods = bss_object_type.n_methods; - ret = ubus_add_object(ctx, obj); - hostapd_ubus_ref_inc(); -} - -void hostapd_ubus_free_bss(struct hostapd_data *hapd) -{ - struct ubus_object *obj = &hapd->ubus.obj; - char *name = (char *) obj->name; - -#ifdef CONFIG_MESH - if (hapd->conf->mesh & MESH_ENABLED) - return; -#endif - - if (!ctx) - return; - - if (obj->id) { - ubus_remove_object(ctx, obj); - hostapd_ubus_ref_dec(); - } - - free(name); -} - -static void -hostapd_ubus_vlan_action(struct hostapd_data *hapd, struct hostapd_vlan *vlan, - const char *action) -{ - struct vlan_description *desc = &vlan->vlan_desc; - void *c; - int i; - - if (!hapd->ubus.obj.has_subscribers) - return; - - blob_buf_init(&b, 0); - blobmsg_add_string(&b, "ifname", vlan->ifname); - blobmsg_add_string(&b, "bridge", vlan->bridge); - blobmsg_add_u32(&b, "vlan_id", vlan->vlan_id); - - if (desc->notempty) { - blobmsg_add_u32(&b, "untagged", desc->untagged); - c = blobmsg_open_array(&b, "tagged"); - for (i = 0; i < ARRAY_SIZE(desc->tagged) && desc->tagged[i]; i++) - blobmsg_add_u32(&b, "", desc->tagged[i]); - blobmsg_close_array(&b, c); - } - - ubus_notify(ctx, &hapd->ubus.obj, action, b.head, -1); -} - -void hostapd_ubus_add_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan) -{ - hostapd_ubus_vlan_action(hapd, vlan, "vlan_add"); -} - -void hostapd_ubus_remove_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan) -{ - hostapd_ubus_vlan_action(hapd, vlan, "vlan_remove"); -} - -struct ubus_event_req { - struct ubus_notify_request nreq; - int resp; -}; - -static void -ubus_event_cb(struct ubus_notify_request *req, int idx, int ret) -{ - struct ubus_event_req *ureq = container_of(req, struct ubus_event_req, nreq); - - ureq->resp = ret; -} - -int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req) -{ - struct ubus_banned_client *ban; - const char *types[HOSTAPD_UBUS_TYPE_MAX] = { - [HOSTAPD_UBUS_PROBE_REQ] = "probe", - [HOSTAPD_UBUS_AUTH_REQ] = "auth", - [HOSTAPD_UBUS_ASSOC_REQ] = "assoc", - }; - const char *type = "mgmt"; - struct ubus_event_req ureq = {}; - const u8 *addr; - - if (req->mgmt_frame) - addr = req->mgmt_frame->sa; - else - addr = req->addr; - - ban = avl_find_element(&hapd->ubus.banned, addr, ban, avl); - if (ban) - return WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; - - if (!hapd->ubus.obj.has_subscribers) - return WLAN_STATUS_SUCCESS; - - if (req->type < ARRAY_SIZE(types)) - type = types[req->type]; - - blob_buf_init(&b, 0); - blobmsg_add_macaddr(&b, "address", addr); - if (req->mgmt_frame) - blobmsg_add_macaddr(&b, "target", req->mgmt_frame->da); - if (req->ssi_signal) - blobmsg_add_u32(&b, "signal", req->ssi_signal); - blobmsg_add_u32(&b, "freq", hapd->iface->freq); - - if (req->elems) { - if(req->elems->ht_capabilities) - { - struct ieee80211_ht_capabilities *ht_capabilities; - void *ht_cap, *ht_cap_mcs_set, *mcs_set; - - - ht_capabilities = (struct ieee80211_ht_capabilities*) req->elems->ht_capabilities; - ht_cap = blobmsg_open_table(&b, "ht_capabilities"); - blobmsg_add_u16(&b, "ht_capabilities_info", ht_capabilities->ht_capabilities_info); - ht_cap_mcs_set = blobmsg_open_table(&b, "supported_mcs_set"); - blobmsg_add_u16(&b, "a_mpdu_params", ht_capabilities->a_mpdu_params); - blobmsg_add_u16(&b, "ht_extended_capabilities", ht_capabilities->ht_extended_capabilities); - blobmsg_add_u32(&b, "tx_bf_capability_info", ht_capabilities->tx_bf_capability_info); - blobmsg_add_u16(&b, "asel_capabilities", ht_capabilities->asel_capabilities); - mcs_set = blobmsg_open_array(&b, "supported_mcs_set"); - for (int i = 0; i < 16; i++) { - blobmsg_add_u16(&b, NULL, (u16) ht_capabilities->supported_mcs_set[i]); - } - blobmsg_close_array(&b, mcs_set); - blobmsg_close_table(&b, ht_cap_mcs_set); - blobmsg_close_table(&b, ht_cap); - } - if(req->elems->vht_capabilities) - { - struct ieee80211_vht_capabilities *vht_capabilities; - void *vht_cap, *vht_cap_mcs_set; - - vht_capabilities = (struct ieee80211_vht_capabilities*) req->elems->vht_capabilities; - vht_cap = blobmsg_open_table(&b, "vht_capabilities"); - blobmsg_add_u32(&b, "vht_capabilities_info", vht_capabilities->vht_capabilities_info); - vht_cap_mcs_set = blobmsg_open_table(&b, "vht_supported_mcs_set"); - blobmsg_add_u16(&b, "rx_map", vht_capabilities->vht_supported_mcs_set.rx_map); - blobmsg_add_u16(&b, "rx_highest", vht_capabilities->vht_supported_mcs_set.rx_highest); - blobmsg_add_u16(&b, "tx_map", vht_capabilities->vht_supported_mcs_set.tx_map); - blobmsg_add_u16(&b, "tx_highest", vht_capabilities->vht_supported_mcs_set.tx_highest); - blobmsg_close_table(&b, vht_cap_mcs_set); - blobmsg_close_table(&b, vht_cap); - } - } - - if (!hapd->ubus.notify_response) { - ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1); - return WLAN_STATUS_SUCCESS; - } - - if (ubus_notify_async(ctx, &hapd->ubus.obj, type, b.head, &ureq.nreq)) - return WLAN_STATUS_SUCCESS; - - ureq.nreq.status_cb = ubus_event_cb; - ubus_complete_request(ctx, &ureq.nreq.req, 100); - - if (ureq.resp) - return ureq.resp; - - return WLAN_STATUS_SUCCESS; -} - -void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *addr) -{ - if (!hapd->ubus.obj.has_subscribers) - return; - - if (!addr) - return; - - blob_buf_init(&b, 0); - blobmsg_add_macaddr(&b, "address", addr); - blobmsg_add_string(&b, "ifname", hapd->conf->iface); - - ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1); -} - - -void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta) -{ - if (!hapd->ubus.obj.has_subscribers) - return; - - blob_buf_init(&b, 0); - blobmsg_add_macaddr(&b, "address", sta->addr); - blobmsg_add_string(&b, "ifname", hapd->conf->iface); - if (sta->bandwidth[0] || sta->bandwidth[1]) { - void *r = blobmsg_open_array(&b, "rate-limit"); - - blobmsg_add_u32(&b, "", sta->bandwidth[0]); - blobmsg_add_u32(&b, "", sta->bandwidth[1]); - blobmsg_close_array(&b, r); - } - - ubus_notify(ctx, &hapd->ubus.obj, "sta-authorized", b.head, -1); -} - -void hostapd_ubus_notify_beacon_report( - struct hostapd_data *hapd, const u8 *addr, u8 token, u8 rep_mode, - struct rrm_measurement_beacon_report *rep, size_t len) -{ - if (!hapd->ubus.obj.has_subscribers) - return; - - if (!addr || !rep) - return; - - blob_buf_init(&b, 0); - blobmsg_add_macaddr(&b, "address", addr); - blobmsg_add_u16(&b, "op-class", rep->op_class); - blobmsg_add_u16(&b, "channel", rep->channel); - blobmsg_add_u64(&b, "start-time", rep->start_time); - blobmsg_add_u16(&b, "duration", rep->duration); - blobmsg_add_u16(&b, "report-info", rep->report_info); - blobmsg_add_u16(&b, "rcpi", rep->rcpi); - blobmsg_add_u16(&b, "rsni", rep->rsni); - blobmsg_add_macaddr(&b, "bssid", rep->bssid); - blobmsg_add_u16(&b, "antenna-id", rep->antenna_id); - blobmsg_add_u16(&b, "parent-tsf", rep->parent_tsf); - - ubus_notify(ctx, &hapd->ubus.obj, "beacon-report", b.head, -1); -} - -void hostapd_ubus_notify_radar_detected(struct hostapd_iface *iface, int frequency, - int chan_width, int cf1, int cf2) -{ - struct hostapd_data *hapd; - int i; - - blob_buf_init(&b, 0); - blobmsg_add_u16(&b, "frequency", frequency); - blobmsg_add_u16(&b, "width", chan_width); - blobmsg_add_u16(&b, "center1", cf1); - blobmsg_add_u16(&b, "center2", cf2); - - for (i = 0; i < iface->num_bss; i++) { - hapd = iface->bss[i]; - ubus_notify(ctx, &hapd->ubus.obj, "radar-detected", b.head, -1); - } -} - -#ifdef CONFIG_WNM_AP -static void hostapd_ubus_notify_bss_transition_add_candidate_list( - const u8 *candidate_list, u16 candidate_list_len) -{ - char *cl_str; - int i; - - if (candidate_list_len == 0) - return; - - cl_str = blobmsg_alloc_string_buffer(&b, "candidate-list", candidate_list_len * 2 + 1); - for (i = 0; i < candidate_list_len; i++) - snprintf(&cl_str[i*2], 3, "%02X", candidate_list[i]); - blobmsg_add_string_buffer(&b); - -} -#endif - -void hostapd_ubus_notify_bss_transition_response( - struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 status_code, - u8 bss_termination_delay, const u8 *target_bssid, - const u8 *candidate_list, u16 candidate_list_len) -{ -#ifdef CONFIG_WNM_AP - u16 i; - - if (!hapd->ubus.obj.has_subscribers) - return; - - if (!addr) - return; - - blob_buf_init(&b, 0); - blobmsg_add_macaddr(&b, "address", addr); - blobmsg_add_u8(&b, "dialog-token", dialog_token); - blobmsg_add_u8(&b, "status-code", status_code); - blobmsg_add_u8(&b, "bss-termination-delay", bss_termination_delay); - if (target_bssid) - blobmsg_add_macaddr(&b, "target-bssid", target_bssid); - - hostapd_ubus_notify_bss_transition_add_candidate_list(candidate_list, candidate_list_len); - - ubus_notify(ctx, &hapd->ubus.obj, "bss-transition-response", b.head, -1); -#endif -} - -int hostapd_ubus_notify_bss_transition_query( - struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 reason, - const u8 *candidate_list, u16 candidate_list_len) -{ -#ifdef CONFIG_WNM_AP - struct ubus_event_req ureq = {}; - char *cl_str; - u16 i; - - if (!hapd->ubus.obj.has_subscribers) - return 0; - - if (!addr) - return 0; - - blob_buf_init(&b, 0); - blobmsg_add_macaddr(&b, "address", addr); - blobmsg_add_u8(&b, "dialog-token", dialog_token); - blobmsg_add_u8(&b, "reason", reason); - hostapd_ubus_notify_bss_transition_add_candidate_list(candidate_list, candidate_list_len); - - if (!hapd->ubus.notify_response) { - ubus_notify(ctx, &hapd->ubus.obj, "bss-transition-query", b.head, -1); - return 0; - } - - if (ubus_notify_async(ctx, &hapd->ubus.obj, "bss-transition-query", b.head, &ureq.nreq)) - return 0; - - ureq.nreq.status_cb = ubus_event_cb; - ubus_complete_request(ctx, &ureq.nreq.req, 100); - - return ureq.resp; -#endif -} diff --git a/feeds/ipq95xx/hostapd/src/src/ap/ubus.h b/feeds/ipq95xx/hostapd/src/src/ap/ubus.h index ce23ee3a..b0f7c44a 100644 --- a/feeds/ipq95xx/hostapd/src/src/ap/ubus.h +++ b/feeds/ipq95xx/hostapd/src/src/ap/ubus.h @@ -47,8 +47,8 @@ void hostapd_ubus_add_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan) void hostapd_ubus_remove_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan); int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req); +void hostapd_ubus_handle_link_measurement(struct hostapd_data *hapd, const u8 *data, size_t len); void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *mac); -void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta); void hostapd_ubus_notify_beacon_report(struct hostapd_data *hapd, const u8 *addr, u8 token, u8 rep_mode, struct rrm_measurement_beacon_report *rep, @@ -65,7 +65,8 @@ void hostapd_ubus_free(struct hapd_interfaces *interfaces); int hostapd_ubus_notify_bss_transition_query( struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 reason, const u8 *candidate_list, u16 candidate_list_len); -void hostapd_ubus_notify_csa(struct hostapd_data *hapd, int freq); +void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta, + const char *auth_alg); #else @@ -100,6 +101,10 @@ static inline int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct ho return 0; } +static inline void hostapd_ubus_handle_link_measurement(struct hostapd_data *hapd, const u8 *data, size_t len) +{ +} + static inline void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *mac) { } @@ -137,6 +142,13 @@ static inline int hostapd_ubus_notify_bss_transition_query( { return 0; } + +static inline void +hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta, + const char *auth_alg) +{ +} + #endif #endif diff --git a/feeds/ipq95xx/hostapd/src/src/ap/ucode.c b/feeds/ipq95xx/hostapd/src/src/ap/ucode.c index 25219b64..6c6cdf7a 100644 --- a/feeds/ipq95xx/hostapd/src/src/ap/ucode.c +++ b/feeds/ipq95xx/hostapd/src/src/ap/ucode.c @@ -509,6 +509,7 @@ static uc_value_t * uc_hostapd_iface_start(uc_vm_t *vm, size_t nargs) { struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface"); + struct hostapd_hw_modes *cmode = iface->current_mode; uc_value_t *info = uc_fn_arg(0); struct hostapd_config *conf; bool changed = false; diff --git a/feeds/ipq95xx/hostapd/src/src/utils/ucode.c b/feeds/ipq95xx/hostapd/src/src/utils/ucode.c index 998cf557..2beeb9a7 100644 --- a/feeds/ipq95xx/hostapd/src/src/utils/ucode.c +++ b/feeds/ipq95xx/hostapd/src/src/utils/ucode.c @@ -52,12 +52,12 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs) uc_value_t *sec = uc_fn_arg(1); int width = ucv_uint64_get(uc_fn_arg(2)); int freq_val, center_idx, center_ofs; + enum oper_chan_width chanwidth; enum hostapd_hw_mode hw_mode; u8 op_class, channel, tmp_channel; const char *modestr; int sec_channel = 0; uc_value_t *ret; - int chanwidth; if (ucv_type(freq) != UC_INTEGER) return NULL; @@ -77,13 +77,13 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs) switch (width) { case 0: - chanwidth = CHANWIDTH_USE_HT; + chanwidth = CONF_OPER_CHWIDTH_USE_HT; break; case 1: - chanwidth = CHANWIDTH_80MHZ; + chanwidth = CONF_OPER_CHWIDTH_80MHZ; break; case 2: - chanwidth = CHANWIDTH_160MHZ; + chanwidth = CONF_OPER_CHWIDTH_160MHZ; break; default: return NULL; diff --git a/feeds/ipq95xx/hostapd/src/wpa_supplicant/ucode.c b/feeds/ipq95xx/hostapd/src/wpa_supplicant/ucode.c index 55d22584..6cba73dc 100644 --- a/feeds/ipq95xx/hostapd/src/wpa_supplicant/ucode.c +++ b/feeds/ipq95xx/hostapd/src/wpa_supplicant/ucode.c @@ -136,6 +136,7 @@ static uc_value_t * uc_wpas_add_iface(uc_vm_t *vm, size_t nargs) { uc_value_t *info = uc_fn_arg(0); + uc_value_t *driver = ucv_object_get(info, "driver", NULL); uc_value_t *ifname = ucv_object_get(info, "iface", NULL); uc_value_t *bridge = ucv_object_get(info, "bridge", NULL); uc_value_t *config = ucv_object_get(info, "config", NULL); @@ -154,6 +155,22 @@ uc_wpas_add_iface(uc_vm_t *vm, size_t nargs) .ctrl_interface = ucv_string_get(ctrl), }; + if (driver) { + const char *drvname; + if (ucv_type(driver) != UC_STRING) + goto out; + + iface.driver = NULL; + drvname = ucv_string_get(driver); + for (int i = 0; wpa_drivers[i]; i++) { + if (!strcmp(drvname, wpa_drivers[i]->name)) + iface.driver = wpa_drivers[i]->name; + } + + if (!iface.driver) + goto out; + } + if (!iface.ifname || !iface.confname) goto out;