]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - hostapd/config_file.c
tests: Clean up test case importing
[thirdparty/hostap.git] / hostapd / config_file.c
index 64704fb3dc9e688eae99f1976cda2fc649dab1d6..d30f2fe9f2729e3a689bf8eacc39968e8a53b4bc 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * hostapd / Configuration file parser
- * Copyright (c) 2003-2018, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2024, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -13,6 +13,7 @@
 
 #include "utils/common.h"
 #include "utils/uuid.h"
+#include "utils/crc32.h"
 #include "common/ieee802_11_defs.h"
 #include "common/sae.h"
 #include "crypto/sha256.h"
@@ -117,52 +118,6 @@ static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss,
 #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)
 {
@@ -712,6 +667,10 @@ static int hostapd_config_parse_key_mgmt(int line, const char *value)
                        val |= WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
 #endif /* CONFIG_SHA384 */
 #endif /* CONFIG_IEEE80211R_AP */
+#ifdef CONFIG_SHA384
+               else if (os_strcmp(start, "WPA-EAP-SHA384") == 0)
+                       val |= WPA_KEY_MGMT_IEEE8021X_SHA384;
+#endif /* CONFIG_SHA384 */
                else if (os_strcmp(start, "WPA-PSK-SHA256") == 0)
                        val |= WPA_KEY_MGMT_PSK_SHA256;
                else if (os_strcmp(start, "WPA-EAP-SHA256") == 0)
@@ -719,8 +678,12 @@ static int hostapd_config_parse_key_mgmt(int line, const char *value)
 #ifdef CONFIG_SAE
                else if (os_strcmp(start, "SAE") == 0)
                        val |= WPA_KEY_MGMT_SAE;
+               else if (os_strcmp(start, "SAE-EXT-KEY") == 0)
+                       val |= WPA_KEY_MGMT_SAE_EXT_KEY;
                else if (os_strcmp(start, "FT-SAE") == 0)
                        val |= WPA_KEY_MGMT_FT_SAE;
+               else if (os_strcmp(start, "FT-SAE-EXT-KEY") == 0)
+                       val |= WPA_KEY_MGMT_FT_SAE_EXT_KEY;
 #endif /* CONFIG_SAE */
 #ifdef CONFIG_SUITEB
                else if (os_strcmp(start, "WPA-EAP-SUITE-B") == 0)
@@ -1057,6 +1020,78 @@ static int add_r1kh(struct hostapd_bss_config *bss, char *value)
 
        return 0;
 }
+
+
+int hostapd_config_read_rxkh_file(struct hostapd_bss_config *conf,
+                                 const char *fname)
+{
+       FILE *f;
+       char buf[256], *pos;
+       int line = 0, errors = 0;
+
+       if (!fname)
+               return 0;
+
+       f = fopen(fname, "r");
+       if (!f) {
+               wpa_printf(MSG_ERROR, "rxkh file '%s' not found.", fname);
+               return -1;
+       }
+
+       while (fgets(buf, sizeof(buf), f)) {
+               line++;
+
+               if (buf[0] == '#')
+                       continue;
+               pos = buf;
+               while (*pos != '\0') {
+                       if (*pos == '\n') {
+                               *pos = '\0';
+                               break;
+                       }
+                       pos++;
+               }
+               if (buf[0] == '\0')
+                       continue;
+
+               pos = os_strchr(buf, '=');
+               if (!pos) {
+                       wpa_printf(MSG_ERROR, "Line %d: Invalid line '%s'",
+                                  line, buf);
+                       errors++;
+                       continue;
+               }
+               *pos = '\0';
+               pos++;
+
+               if (os_strcmp(buf, "r0kh") == 0) {
+                       if (add_r0kh(conf, pos) < 0) {
+                               wpa_printf(MSG_ERROR,
+                                          "Line %d: Invalid r0kh '%s'",
+                                          line, pos);
+                               errors++;
+                       }
+               } else if (os_strcmp(buf, "r1kh") == 0) {
+                       if (add_r1kh(conf, pos) < 0) {
+                               wpa_printf(MSG_ERROR,
+                                          "Line %d: Invalid r1kh '%s'",
+                                          line, pos);
+                               errors++;
+                       }
+               }
+       }
+
+       fclose(f);
+
+       if (errors) {
+               wpa_printf(MSG_ERROR,
+                          "%d errors in configuring RxKHs from '%s'",
+                          errors, fname);
+               return -1;
+       }
+       return 0;
+}
+
 #endif /* CONFIG_IEEE80211R_AP */
 
 
@@ -2196,6 +2231,7 @@ static int add_airtime_weight(struct hostapd_bss_config *bss, char *value)
 
 
 #ifdef CONFIG_SAE
+
 static int parse_sae_password(struct hostapd_bss_config *bss, const char *val)
 {
        struct sae_password_entry *pw;
@@ -2299,6 +2335,40 @@ fail:
        os_free(pw);
        return -1;
 }
+
+
+static int parse_sae_password_file(struct hostapd_bss_config *bss,
+                                  const char *fname)
+{
+       FILE *f;
+       char buf[500], *pos;
+       unsigned int line = 0;
+
+       f = fopen(fname, "r");
+       if (!f) {
+               wpa_printf(MSG_ERROR, "sae_password_file '%s' not found.",
+                          fname);
+               return -1;
+       }
+
+       while (fgets(buf, sizeof(buf), f)) {
+               pos = os_strchr(buf, '\n');
+               if (pos)
+                       *pos = '\0';
+               line++;
+               if (parse_sae_password(bss, buf)) {
+                       wpa_printf(MSG_ERROR,
+                                  "Invalid SAE password at line %d in '%s'",
+                                  line, fname);
+                       fclose(f);
+                       return -1;
+               }
+       }
+
+       fclose(f);
+       return 0;
+}
+
 #endif /* CONFIG_SAE */
 
 
@@ -2332,6 +2402,40 @@ fail:
 #endif /* CONFIG_DPP2 */
 
 
+static int get_hex_config(u8 *buf, size_t max_len, int line,
+                         const char *field, const char *val)
+{
+       size_t hlen = os_strlen(val), len = hlen / 2;
+       u8 tmp[EXT_CAPA_MAX_LEN];
+
+       os_memset(tmp, 0, EXT_CAPA_MAX_LEN);
+       if (hlen & 1 || len > EXT_CAPA_MAX_LEN || hexstr2bin(val, tmp, len)) {
+               wpa_printf(MSG_ERROR, "Line %d: Invalid %s", line, field);
+               return -1;
+       }
+       os_memcpy(buf, tmp, EXT_CAPA_MAX_LEN);
+       return 0;
+}
+
+
+#ifdef CONFIG_IEEE80211BE
+static int get_u16(const char *pos, int line, u16 *ret_val)
+{
+       char *end;
+       long int val = strtol(pos, &end, 0);
+
+       if (*end || val < 0 || val > 0xffff) {
+               wpa_printf(MSG_ERROR, "Line %d: Invalid value '%s'",
+                          line, pos);
+               return -1;
+       }
+
+       *ret_val = val;
+       return 0;
+}
+#endif /* CONFIG_IEEE80211BE */
+
+
 static int hostapd_config_fill(struct hostapd_config *conf,
                               struct hostapd_bss_config *bss,
                               const char *buf, char *pos, int line)
@@ -2341,6 +2445,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                           sizeof(conf->bss[0]->iface));
        } else if (os_strcmp(buf, "bridge") == 0) {
                os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));
+       } else if (os_strcmp(buf, "bridge_hairpin") == 0) {
+               bss->bridge_hairpin = atoi(pos);
        } 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) {
@@ -2380,16 +2486,19 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                wpa_printf(MSG_INFO, "Line %d: DEPRECATED: 'dump_file' configuration variable is not used anymore",
                           line);
        } else if (os_strcmp(buf, "ssid") == 0) {
-               bss->ssid.ssid_len = os_strlen(pos);
-               if (bss->ssid.ssid_len > SSID_MAX_LEN ||
-                   bss->ssid.ssid_len < 1) {
+               struct hostapd_ssid *ssid = &bss->ssid;
+
+               ssid->ssid_len = os_strlen(pos);
+               if (ssid->ssid_len > SSID_MAX_LEN || ssid->ssid_len < 1) {
                        wpa_printf(MSG_ERROR, "Line %d: invalid SSID '%s'",
                                   line, pos);
                        return 1;
                }
-               os_memcpy(bss->ssid.ssid, pos, bss->ssid.ssid_len);
-               bss->ssid.ssid_set = 1;
+               os_memcpy(ssid->ssid, pos, ssid->ssid_len);
+               ssid->ssid_set = 1;
+               ssid->short_ssid = ieee80211_crc32(ssid->ssid, ssid->ssid_len);
        } else if (os_strcmp(buf, "ssid2") == 0) {
+               struct hostapd_ssid *ssid = &bss->ssid;
                size_t slen;
                char *str = wpa_config_parse_string(pos, &slen);
                if (str == NULL || slen < 1 || slen > SSID_MAX_LEN) {
@@ -2398,9 +2507,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                        os_free(str);
                        return 1;
                }
-               os_memcpy(bss->ssid.ssid, str, slen);
-               bss->ssid.ssid_len = slen;
-               bss->ssid.ssid_set = 1;
+               os_memcpy(ssid->ssid, str, slen);
+               ssid->ssid_len = slen;
+               ssid->ssid_set = 1;
+               ssid->short_ssid = ieee80211_crc32(ssid->ssid, ssid->ssid_len);
                os_free(str);
        } else if (os_strcmp(buf, "utf8_ssid") == 0) {
                bss->ssid.utf8_ssid = atoi(pos) > 0;
@@ -2439,6 +2549,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                bss->ap_max_inactivity = atoi(pos);
        } else if (os_strcmp(buf, "skip_inactivity_poll") == 0) {
                bss->skip_inactivity_poll = atoi(pos);
+       } else if (os_strcmp(buf, "config_id") == 0) {
+               os_free(bss->config_id);
+               bss->config_id = os_strdup(pos);
        } else if (os_strcmp(buf, "country_code") == 0) {
                if (pos[0] < 'A' || pos[0] > 'Z' ||
                    pos[1] < 'A' || pos[1] > 'Z') {
@@ -2458,12 +2571,13 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                bss->ieee802_1x = atoi(pos);
        } else if (os_strcmp(buf, "eapol_version") == 0) {
                int eapol_version = atoi(pos);
-
 #ifdef CONFIG_MACSEC
-               if (eapol_version < 1 || eapol_version > 3) {
+               int max_ver = 3;
 #else /* CONFIG_MACSEC */
-               if (eapol_version < 1 || eapol_version > 2) {
+               int max_ver = 2;
 #endif /* CONFIG_MACSEC */
+
+               if (eapol_version < 1 || eapol_version > max_ver) {
                        wpa_printf(MSG_ERROR,
                                   "Line %d: invalid EAPOL version (%d): '%s'.",
                                   line, eapol_version, pos);
@@ -2602,6 +2716,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                bss->eap_teap_separate_result = atoi(pos);
        } else if (os_strcmp(buf, "eap_teap_id") == 0) {
                bss->eap_teap_id = atoi(pos);
+       } else if (os_strcmp(buf, "eap_teap_method_sequence") == 0) {
+               bss->eap_teap_method_sequence = atoi(pos);
 #endif /* EAP_SERVER_TEAP */
 #ifdef EAP_SERVER_SIM
        } else if (os_strcmp(buf, "eap_sim_db") == 0) {
@@ -2613,6 +2729,11 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                bss->eap_sim_aka_result_ind = atoi(pos);
        } else if (os_strcmp(buf, "eap_sim_id") == 0) {
                bss->eap_sim_id = atoi(pos);
+       } else if (os_strcmp(buf, "imsi_privacy_key") == 0) {
+               os_free(bss->imsi_privacy_key);
+               bss->imsi_privacy_key = os_strdup(pos);
+       } else if (os_strcmp(buf, "eap_sim_aka_fast_reauth_limit") == 0) {
+               bss->eap_sim_aka_fast_reauth_limit = atoi(pos);
 #endif /* EAP_SERVER_SIM */
 #ifdef EAP_SERVER_TNC
        } else if (os_strcmp(buf, "tnc") == 0) {
@@ -2711,6 +2832,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                        return 1;
                }
                bss->radius->force_client_addr = 1;
+       } else if (os_strcmp(buf, "radius_client_dev") == 0) {
+                       os_free(bss->radius->force_client_dev);
+                       bss->radius->force_client_dev = os_strdup(pos);
        } else if (os_strcmp(buf, "auth_server_addr") == 0) {
                if (hostapd_config_read_radius_addr(
                            &bss->radius->auth_servers,
@@ -2745,6 +2869,37 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                os_free(bss->radius->auth_server->shared_secret);
                bss->radius->auth_server->shared_secret = (u8 *) os_strdup(pos);
                bss->radius->auth_server->shared_secret_len = len;
+       } else if (bss->radius->auth_server &&
+                  os_strcmp(buf, "auth_server_type") == 0) {
+               if (os_strcmp(pos, "UDP") == 0) {
+                       bss->radius->auth_server->tls = false;
+#ifdef CONFIG_RADIUS_TLS
+               } else if (os_strcmp(pos, "TLS") == 0) {
+                       bss->radius->auth_server->tls = true;
+#endif /* CONFIG_RADIUS_TLS */
+               } else {
+                       wpa_printf(MSG_ERROR, "Line %d: unsupported RADIUS type '%s'",
+                                  line, pos);
+                       return 1;
+               }
+#ifdef CONFIG_RADIUS_TLS
+       } else if (bss->radius->auth_server &&
+                  os_strcmp(buf, "auth_server_ca_cert") == 0) {
+               os_free(bss->radius->auth_server->ca_cert);
+               bss->radius->auth_server->ca_cert = os_strdup(pos);
+       } else if (bss->radius->auth_server &&
+                  os_strcmp(buf, "auth_server_client_cert") == 0) {
+               os_free(bss->radius->auth_server->client_cert);
+               bss->radius->auth_server->client_cert = os_strdup(pos);
+       } else if (bss->radius->auth_server &&
+                  os_strcmp(buf, "auth_server_private_key") == 0) {
+               os_free(bss->radius->auth_server->private_key);
+               bss->radius->auth_server->private_key = os_strdup(pos);
+       } else if (bss->radius->auth_server &&
+                  os_strcmp(buf, "auth_server_private_key_passwd") == 0) {
+               os_free(bss->radius->auth_server->private_key_passwd);
+               bss->radius->auth_server->private_key_passwd = os_strdup(pos);
+#endif /* CONFIG_RADIUS_TLS */
        } else if (os_strcmp(buf, "acct_server_addr") == 0) {
                if (hostapd_config_read_radius_addr(
                            &bss->radius->acct_servers,
@@ -2779,6 +2934,37 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                os_free(bss->radius->acct_server->shared_secret);
                bss->radius->acct_server->shared_secret = (u8 *) os_strdup(pos);
                bss->radius->acct_server->shared_secret_len = len;
+       } else if (bss->radius->acct_server &&
+                  os_strcmp(buf, "acct_server_type") == 0) {
+               if (os_strcmp(pos, "UDP") == 0) {
+                       bss->radius->acct_server->tls = false;
+#ifdef CONFIG_RADIUS_TLS
+               } else if (os_strcmp(pos, "TLS") == 0) {
+                       bss->radius->acct_server->tls = true;
+#endif /* CONFIG_RADIUS_TLS */
+               } else {
+                       wpa_printf(MSG_ERROR, "Line %d: unsupported RADIUS type '%s'",
+                                  line, pos);
+                       return 1;
+               }
+#ifdef CONFIG_RADIUS_TLS
+       } else if (bss->radius->acct_server &&
+                  os_strcmp(buf, "acct_server_ca_cert") == 0) {
+               os_free(bss->radius->acct_server->ca_cert);
+               bss->radius->acct_server->ca_cert = os_strdup(pos);
+       } else if (bss->radius->acct_server &&
+                  os_strcmp(buf, "acct_server_client_cert") == 0) {
+               os_free(bss->radius->acct_server->client_cert);
+               bss->radius->acct_server->client_cert = os_strdup(pos);
+       } else if (bss->radius->acct_server &&
+                  os_strcmp(buf, "acct_server_private_key") == 0) {
+               os_free(bss->radius->acct_server->private_key);
+               bss->radius->acct_server->private_key = os_strdup(pos);
+       } else if (bss->radius->acct_server &&
+                  os_strcmp(buf, "acct_server_private_key_passwd") == 0) {
+               os_free(bss->radius->acct_server->private_key_passwd);
+               bss->radius->acct_server->private_key_passwd = os_strdup(pos);
+#endif /* CONFIG_RADIUS_TLS */
        } else if (os_strcmp(buf, "radius_retry_primary_interval") == 0) {
                bss->radius->retry_primary_interval = atoi(pos);
        } else if (os_strcmp(buf, "radius_acct_interim_interval") == 0) {
@@ -2950,7 +3136,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                bss->wpa_psk_radius = atoi(pos);
                if (bss->wpa_psk_radius != PSK_RADIUS_IGNORED &&
                    bss->wpa_psk_radius != PSK_RADIUS_ACCEPTED &&
-                   bss->wpa_psk_radius != PSK_RADIUS_REQUIRED) {
+                   bss->wpa_psk_radius != PSK_RADIUS_REQUIRED &&
+                   bss->wpa_psk_radius != PSK_RADIUS_DURING_4WAY_HS) {
                        wpa_printf(MSG_ERROR,
                                   "Line %d: unknown wpa_psk_radius %d",
                                   line, bss->wpa_psk_radius);
@@ -3047,6 +3234,21 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                                   line, pos);
                        return 1;
                }
+       } else if (os_strcmp(buf, "rxkh_file") == 0) {
+               os_free(bss->rxkh_file);
+               bss->rxkh_file = os_strdup(pos);
+               if (!bss->rxkh_file) {
+                       wpa_printf(MSG_ERROR, "Line %d: allocation failed",
+                                  line);
+                       return 1;
+               }
+               if (hostapd_config_read_rxkh_file(bss, pos)) {
+                       wpa_printf(MSG_DEBUG,
+                                  "Line %d: failed to read rxkh_file '%s'",
+                                  line, pos);
+                       /* Allow the file to be created later and read into
+                        * already operating AP context. */
+               }
        } else if (os_strcmp(buf, "pmk_r1_push") == 0) {
                bss->pmk_r1_push = atoi(pos);
        } else if (os_strcmp(buf, "ft_over_ds") == 0) {
@@ -3114,6 +3316,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                                   line, pos);
                        return 1;
                }
+               conf->hw_mode_set = true;
        } else if (os_strcmp(buf, "wps_rf_bands") == 0) {
                if (os_strcmp(pos, "ad") == 0)
                        bss->wps_rf_bands = WPS_RF_60GHZ;
@@ -3168,6 +3371,18 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                conf->acs_freq_list_present = 1;
        } else if (os_strcmp(buf, "acs_exclude_6ghz_non_psc") == 0) {
                conf->acs_exclude_6ghz_non_psc = atoi(pos);
+       } else if (os_strcmp(buf, "enable_background_radar") == 0) {
+               conf->enable_background_radar = atoi(pos);
+       } else if (os_strcmp(buf, "min_tx_power") == 0) {
+               int val = atoi(pos);
+
+               if (val < 0 || val > 255) {
+                       wpa_printf(MSG_ERROR,
+                                  "Line %d: invalid min_tx_power %d (expected 0..255)",
+                                  line, val);
+                       return 1;
+               }
+               conf->min_tx_power = val;
        } else if (os_strcmp(buf, "beacon_int") == 0) {
                int val = atoi(pos);
                /* MIB defines range as 1..65535, but very small values
@@ -3476,6 +3691,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
 #ifdef CONFIG_IEEE80211AX
        } else if (os_strcmp(buf, "ieee80211ax") == 0) {
                conf->ieee80211ax = atoi(pos);
+       } else if (os_strcmp(buf, "require_he") == 0) {
+               conf->require_he = atoi(pos);
        } else if (os_strcmp(buf, "he_su_beamformer") == 0) {
                conf->he_phy_capab.he_su_beamformer = atoi(pos);
        } else if (os_strcmp(buf, "he_su_beamformee") == 0) {
@@ -3491,8 +3708,12 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                conf->he_op.he_default_pe_duration = atoi(pos);
        } else if (os_strcmp(buf, "he_twt_required") == 0) {
                conf->he_op.he_twt_required = atoi(pos);
+       } else if (os_strcmp(buf, "he_twt_responder") == 0) {
+               conf->he_op.he_twt_responder = atoi(pos);
        } else if (os_strcmp(buf, "he_rts_threshold") == 0) {
                conf->he_op.he_rts_threshold = atoi(pos);
+       } else if (os_strcmp(buf, "he_er_su_disable") == 0) {
+               conf->he_op.he_er_su_disable = atoi(pos);
        } else if (os_strcmp(buf, "he_basic_mcs_nss_set") == 0) {
                conf->he_op.he_basic_mcs_nss_set = atoi(pos);
        } else if (os_strcmp(buf, "he_mu_edca_qos_info_param_count") == 0) {
@@ -3603,6 +3824,20 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                                   line, pos);
                        return 1;
                }
+       } 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 > HE_REG_INFO_6GHZ_AP_TYPE_MAX) {
+                       wpa_printf(MSG_ERROR,
+                                  "Line %d: invalid he_6ghz_reg_pwr_type value",
+                                  line);
+                       return 1;
+               }
+       } else if (os_strcmp(buf, "reg_def_cli_eirp_psd") == 0) {
+               conf->reg_def_cli_eirp_psd = atoi(pos);
+       } else if (os_strcmp(buf, "reg_sub_cli_eirp_psd") == 0) {
+               conf->reg_sub_cli_eirp_psd = atoi(pos);
+       } else if (os_strcmp(buf, "reg_def_cli_eirp") == 0) {
+               conf->reg_def_cli_eirp = 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) {
@@ -3627,6 +3862,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                        return 1;
                }
                bss->unsol_bcast_probe_resp_interval = val;
+       } else if (os_strcmp(buf, "mbssid") == 0) {
+               int mbssid = atoi(pos);
+               if (mbssid < 0 || mbssid > ENHANCED_MBSSID_ENABLED) {
+                       wpa_printf(MSG_ERROR,
+                                  "Line %d: invalid mbssid (%d): '%s'.",
+                                  line, mbssid, pos);
+                       return 1;
+               }
+               conf->mbssid = mbssid;
 #endif /* CONFIG_IEEE80211AX */
        } else if (os_strcmp(buf, "max_listen_interval") == 0) {
                bss->max_listen_interval = atoi(pos);
@@ -4258,6 +4502,20 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                bss->oci_freq_override_fils_assoc = atoi(pos);
        } else if (os_strcmp(buf, "oci_freq_override_wnm_sleep") == 0) {
                bss->oci_freq_override_wnm_sleep = atoi(pos);
+       } else if (os_strcmp(buf, "eap_skip_prot_success") == 0) {
+               bss->eap_skip_prot_success = atoi(pos);
+       } else if (os_strcmp(buf, "delay_eapol_tx") == 0) {
+               conf->delay_eapol_tx = atoi(pos);
+       } else if (os_strcmp(buf, "eapol_m1_elements") == 0) {
+               if (parse_wpabuf_hex(line, buf, &bss->eapol_m1_elements, pos))
+                       return 1;
+       } else if (os_strcmp(buf, "eapol_m3_elements") == 0) {
+               if (parse_wpabuf_hex(line, buf, &bss->eapol_m3_elements, pos))
+                       return 1;
+       } else if (os_strcmp(buf, "eapol_m3_no_encrypt") == 0) {
+               bss->eapol_m3_no_encrypt = atoi(pos);
+       } else if (os_strcmp(buf, "test_assoc_comeback_type") == 0) {
+               bss->test_assoc_comeback_type = atoi(pos);
 #endif /* CONFIG_TESTING_OPTIONS */
 #ifdef CONFIG_SAE
        } else if (os_strcmp(buf, "sae_password") == 0) {
@@ -4266,6 +4524,13 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                                   line);
                        return 1;
                }
+       } else if (os_strcmp(buf, "sae_password_file") == 0) {
+               if (parse_sae_password_file(bss, pos) < 0) {
+                       wpa_printf(MSG_ERROR,
+                                  "Line %d: Invalid sae_password in file",
+                                  line);
+                       return 1;
+               }
 #endif /* CONFIG_SAE */
        } else if (os_strcmp(buf, "vendor_elements") == 0) {
                if (parse_wpabuf_hex(line, buf, &bss->vendor_elements, pos))
@@ -4273,8 +4538,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
        } else if (os_strcmp(buf, "assocresp_elements") == 0) {
                if (parse_wpabuf_hex(line, buf, &bss->assocresp_elements, pos))
                        return 1;
-       } else if (os_strcmp(buf, "sae_anti_clogging_threshold") == 0) {
-               bss->sae_anti_clogging_threshold = atoi(pos);
+       } else if (os_strcmp(buf, "sae_anti_clogging_threshold") == 0 ||
+                  os_strcmp(buf, "anti_clogging_threshold") == 0) {
+               bss->anti_clogging_threshold = atoi(pos);
        } else if (os_strcmp(buf, "sae_sync") == 0) {
                bss->sae_sync = atoi(pos);
        } else if (os_strcmp(buf, "sae_groups") == 0) {
@@ -4440,6 +4706,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
 #endif /* CONFIG_FILS */
        } else if (os_strcmp(buf, "multicast_to_unicast") == 0) {
                bss->multicast_to_unicast = atoi(pos);
+       } else if (os_strcmp(buf, "bridge_multicast_to_unicast") == 0) {
+               bss->bridge_multicast_to_unicast = atoi(pos);
        } else if (os_strcmp(buf, "broadcast_deauth") == 0) {
                bss->broadcast_deauth = atoi(pos);
        } else if (os_strcmp(buf, "notify_mgmt_frames") == 0) {
@@ -4451,6 +4719,12 @@ static int hostapd_config_fill(struct hostapd_config *conf,
        } else if (os_strcmp(buf, "dpp_mud_url") == 0) {
                os_free(bss->dpp_mud_url);
                bss->dpp_mud_url = os_strdup(pos);
+       } else if (os_strcmp(buf, "dpp_extra_conf_req_name") == 0) {
+               os_free(bss->dpp_extra_conf_req_name);
+               bss->dpp_extra_conf_req_name = os_strdup(pos);
+       } else if (os_strcmp(buf, "dpp_extra_conf_req_value") == 0) {
+               os_free(bss->dpp_extra_conf_req_value);
+               bss->dpp_extra_conf_req_value = os_strdup(pos);
        } else if (os_strcmp(buf, "dpp_connector") == 0) {
                os_free(bss->dpp_connector);
                bss->dpp_connector = os_strdup(pos);
@@ -4466,6 +4740,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
        } else if (os_strcmp(buf, "dpp_controller") == 0) {
                if (hostapd_dpp_controller_parse(bss, pos))
                        return 1;
+       } else if (os_strcmp(buf, "dpp_relay_port") == 0) {
+               bss->dpp_relay_port = atoi(pos);
        } else if (os_strcmp(buf, "dpp_configurator_connectivity") == 0) {
                bss->dpp_configurator_connectivity = atoi(pos);
        } else if (os_strcmp(buf, "dpp_pfs") == 0) {
@@ -4601,6 +4877,16 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                bss->macsec_replay_protect = macsec_replay_protect;
        } else if (os_strcmp(buf, "macsec_replay_window") == 0) {
                bss->macsec_replay_window = atoi(pos);
+       } else if (os_strcmp(buf, "macsec_offload") == 0) {
+               int macsec_offload = atoi(pos);
+
+               if (macsec_offload < 0 || macsec_offload > 2) {
+                       wpa_printf(MSG_ERROR,
+                                  "Line %d: invalid macsec_offload (%d): '%s'.",
+                                  line, macsec_offload, pos);
+                       return 1;
+               }
+               bss->macsec_offload = macsec_offload;
        } else if (os_strcmp(buf, "macsec_port") == 0) {
                int macsec_port = atoi(pos);
 
@@ -4621,6 +4907,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);
 
@@ -4657,10 +4953,14 @@ 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);
 #ifdef CONFIG_PASN
 #ifdef CONFIG_TESTING_OPTIONS
        } else if (os_strcmp(buf, "force_kdk_derivation") == 0) {
                bss->force_kdk_derivation = atoi(pos);
+       } else if (os_strcmp(buf, "pasn_corrupt_mic") == 0) {
+               bss->pasn_corrupt_mic = atoi(pos);
 #endif /* CONFIG_TESTING_OPTIONS */
        } else if (os_strcmp(buf, "pasn_groups") == 0) {
                if (hostapd_parse_intlist(&bss->pasn_groups, pos)) {
@@ -4669,7 +4969,69 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                                   line, pos);
                        return 1;
                }
+       } else if (os_strcmp(buf, "pasn_comeback_after") == 0) {
+               bss->pasn_comeback_after = atoi(pos);
+       } else if (os_strcmp(buf, "pasn_noauth") == 0) {
+               bss->pasn_noauth = atoi(pos);
 #endif /* CONFIG_PASN */
+       } else if (os_strcmp(buf, "ext_capa_mask") == 0) {
+               if (get_hex_config(bss->ext_capa_mask, EXT_CAPA_MAX_LEN,
+                                  line, "ext_capa_mask", pos))
+                       return 1;
+       } else if (os_strcmp(buf, "ext_capa") == 0) {
+               if (get_hex_config(bss->ext_capa, EXT_CAPA_MAX_LEN,
+                                  line, "ext_capa", pos))
+                       return 1;
+       } else if (os_strcmp(buf, "rnr") == 0) {
+               bss->rnr = atoi(pos);
+#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);
+       } 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);
+       } else if (os_strcmp(buf, "eht_default_pe_duration") == 0) {
+               conf->eht_default_pe_duration = atoi(pos);
+       } else if (os_strcmp(buf, "punct_bitmap") == 0) {
+               if (get_u16(pos, line, &conf->punct_bitmap))
+                       return 1;
+       } else if (os_strcmp(buf, "punct_acs_threshold") == 0) {
+               int val = atoi(pos);
+
+               if (val < 0 || val > 100) {
+                       wpa_printf(MSG_ERROR,
+                                  "Line %d: punct_acs_threshold must be between 0 and 100",
+                                  line);
+                       return 1;
+               }
+               conf->punct_acs_threshold = val;
+       } else if (os_strcmp(buf, "mld_ap") == 0) {
+               bss->mld_ap = !!atoi(pos);
+       } else if (os_strcmp(buf, "mld_id") == 0) {
+               bss->mld_id = atoi(pos);
+       } else if (os_strcmp(buf, "mld_addr") == 0) {
+               if (hwaddr_aton(pos, bss->mld_addr)) {
+                       wpa_printf(MSG_ERROR, "Line %d: Invalid mld_addr",
+                                  line);
+                       return 1;
+               }
+       } else if (os_strcmp(buf, "eht_bw320_offset") == 0) {
+               conf->eht_bw320_offset = atoi(pos);
+#ifdef CONFIG_TESTING_OPTIONS
+       } else if (os_strcmp(buf, "eht_oper_puncturing_override") == 0) {
+               if (get_u16(pos, line, &bss->eht_oper_puncturing_override))
+                       return 1;
+       } else if (os_strcmp(buf, "mld_indicate_disabled") == 0) {
+               bss->mld_indicate_disabled = atoi(pos);
+#endif /* CONFIG_TESTING_OPTIONS */
+#endif /* CONFIG_IEEE80211BE */
        } else {
                wpa_printf(MSG_ERROR,
                           "Line %d: unknown configuration item '%s'",