]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - src/ap/beacon.c
Allow RSNXE to be removed from Beacon frames for testing purposes
[thirdparty/hostap.git] / src / ap / beacon.c
index 711464977330997eeb7d4163c3065b23cd517480..ff760a0d1a9e772ace6f4da02f7f9b99ea96634c 100644 (file)
 #include "hs20.h"
 #include "dfs.h"
 #include "taxonomy.h"
+#include "ieee802_11_auth.h"
 
 
 #ifdef NEED_AP_MLME
 
-static u8 * hostapd_eid_rm_enabled_capab(struct hostapd_data *hapd, u8 *eid,
-                                        size_t len)
-{
-       size_t i;
-
-       for (i = 0; i < RRM_CAPABILITIES_IE_LEN; i++) {
-               if (hapd->conf->radio_measurements[i])
-                       break;
-       }
-
-       if (i == RRM_CAPABILITIES_IE_LEN || len < 2 + RRM_CAPABILITIES_IE_LEN)
-               return eid;
-
-       *eid++ = WLAN_EID_RRM_ENABLED_CAPABILITIES;
-       *eid++ = RRM_CAPABILITIES_IE_LEN;
-       os_memcpy(eid, hapd->conf->radio_measurements, RRM_CAPABILITIES_IE_LEN);
-
-       return eid + RRM_CAPABILITIES_IE_LEN;
-}
-
-
 static u8 * hostapd_eid_bss_load(struct hostapd_data *hapd, u8 *eid, size_t len)
 {
        if (len < 2 + 5)
@@ -286,17 +266,101 @@ static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid,
 }
 
 
-static u8 * hostapd_eid_wpa(struct hostapd_data *hapd, u8 *eid, size_t len)
+static const u8 * hostapd_wpa_ie(struct hostapd_data *hapd, u8 eid)
+{
+       const u8 *ies;
+       size_t ies_len;
+
+       ies = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ies_len);
+       if (!ies)
+               return NULL;
+
+       return get_ie(ies, ies_len, eid);
+}
+
+
+static const u8 * hostapd_vendor_wpa_ie(struct hostapd_data *hapd,
+                                       u32 vendor_type)
+{
+       const u8 *ies;
+       size_t ies_len;
+
+       ies = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ies_len);
+       if (!ies)
+               return NULL;
+
+       return get_vendor_ie(ies, ies_len, vendor_type);
+}
+
+
+static u8 * hostapd_get_rsne(struct hostapd_data *hapd, u8 *pos, size_t len)
 {
        const u8 *ie;
-       size_t ielen;
 
-       ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ielen);
-       if (ie == NULL || ielen > len)
-               return eid;
+       ie = hostapd_wpa_ie(hapd, WLAN_EID_RSN);
+       if (!ie || 2U + ie[1] > len)
+               return pos;
+
+       os_memcpy(pos, ie, 2 + ie[1]);
+       return pos + 2 + ie[1];
+}
+
+
+static u8 * hostapd_get_mde(struct hostapd_data *hapd, u8 *pos, size_t len)
+{
+       const u8 *ie;
+
+       ie = hostapd_wpa_ie(hapd, WLAN_EID_MOBILITY_DOMAIN);
+       if (!ie || 2U + ie[1] > len)
+               return pos;
+
+       os_memcpy(pos, ie, 2 + ie[1]);
+       return pos + 2 + ie[1];
+}
+
+
+static u8 * hostapd_get_rsnxe(struct hostapd_data *hapd, u8 *pos, size_t len)
+{
+       const u8 *ie;
+
+#ifdef CONFIG_TESTING_OPTIONS
+       if (hapd->conf->no_beacon_rsnxe) {
+               wpa_printf(MSG_INFO, "TESTING: Do not add RSNXE into Beacon");
+               return pos;
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
+       ie = hostapd_wpa_ie(hapd, WLAN_EID_RSNX);
+       if (!ie || 2U + ie[1] > len)
+               return pos;
+
+       os_memcpy(pos, ie, 2 + ie[1]);
+       return pos + 2 + ie[1];
+}
+
+
+static u8 * hostapd_get_wpa_ie(struct hostapd_data *hapd, u8 *pos, size_t len)
+{
+       const u8 *ie;
+
+       ie = hostapd_vendor_wpa_ie(hapd, WPA_IE_VENDOR_TYPE);
+       if (!ie || 2U + ie[1] > len)
+               return pos;
+
+       os_memcpy(pos, ie, 2 + ie[1]);
+       return pos + 2 + ie[1];
+}
+
 
-       os_memcpy(eid, ie, ielen);
-       return eid + ielen;
+static u8 * hostapd_get_osen_ie(struct hostapd_data *hapd, u8 *pos, size_t len)
+{
+       const u8 *ie;
+
+       ie = hostapd_vendor_wpa_ie(hapd, OSEN_IE_VENDOR_TYPE);
+       if (!ie || 2U + ie[1] > len)
+               return pos;
+
+       os_memcpy(pos, ie, 2 + ie[1]);
+       return pos + 2 + ie[1];
 }
 
 
@@ -346,7 +410,7 @@ static u8 * hostapd_eid_supported_op_classes(struct hostapd_data *hapd, u8 *eid)
 
        if (ieee80211_freq_to_channel_ext(hapd->iface->freq,
                                          hapd->iconf->secondary_channel,
-                                         hapd->iconf->vht_oper_chwidth,
+                                         hostapd_get_oper_chwidth(hapd->iconf),
                                          &op_class, &channel) ==
            NUM_HOSTAPD_MODES)
                return eid;
@@ -396,7 +460,9 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 #ifdef CONFIG_IEEE80211AX
        if (hapd->iconf->ieee80211ax) {
                buflen += 3 + sizeof(struct ieee80211_he_capabilities) +
-                       3 + sizeof(struct ieee80211_he_operation);
+                       3 + sizeof(struct ieee80211_he_operation) +
+                       3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) +
+                       3 + sizeof(struct ieee80211_spatial_reuse);
        }
 #endif /* CONFIG_IEEE80211AX */
 
@@ -452,12 +518,10 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
        /* Extended supported rates */
        pos = hostapd_eid_ext_supp_rates(hapd, pos);
 
-       /* RSN, MDIE, WPA */
-       pos = hostapd_eid_wpa(hapd, pos, epos - pos);
-
+       pos = hostapd_get_rsne(hapd, pos, epos - pos);
        pos = hostapd_eid_bss_load(hapd, pos, epos - pos);
-
        pos = hostapd_eid_rm_enabled_capab(hapd, pos, epos - pos);
+       pos = hostapd_get_mde(hapd, pos, epos - pos);
 
        /* eCSA IE */
        csa_pos = hostapd_eid_ecsa(hapd, pos);
@@ -466,15 +530,8 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
        pos = csa_pos;
 
        pos = hostapd_eid_supported_op_classes(hapd, pos);
-
-#ifdef CONFIG_IEEE80211N
-       /* Secondary Channel Offset element */
-       /* TODO: The standard doesn't specify a position for this element. */
-       pos = hostapd_eid_secondary_channel(hapd, pos);
-
        pos = hostapd_eid_ht_capabilities(hapd, pos);
        pos = hostapd_eid_ht_operation(hapd, pos);
-#endif /* CONFIG_IEEE80211N */
 
        pos = hostapd_eid_ext_capab(hapd, pos);
 
@@ -494,7 +551,8 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 #endif /* CONFIG_FST */
 
 #ifdef CONFIG_IEEE80211AC
-       if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
+       if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac &&
+           !is_6ghz_op_class(hapd->iconf->op_class)) {
                pos = hostapd_eid_vht_capabilities(hapd, pos, 0);
                pos = hostapd_eid_vht_operation(hapd, pos);
                pos = hostapd_eid_txpower_envelope(hapd, pos);
@@ -503,11 +561,14 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 #endif /* CONFIG_IEEE80211AC */
 
        pos = hostapd_eid_fils_indic(hapd, pos, 0);
+       pos = hostapd_get_rsnxe(hapd, pos, epos - pos);
 
 #ifdef CONFIG_IEEE80211AX
        if (hapd->iconf->ieee80211ax) {
-               pos = hostapd_eid_he_capab(hapd, 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);
        }
 #endif /* CONFIG_IEEE80211AX */
 
@@ -516,6 +577,10 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
                pos = hostapd_eid_vendor_vht(hapd, pos);
 #endif /* CONFIG_IEEE80211AC */
 
+       /* WPA / OSEN */
+       pos = hostapd_get_wpa_ie(hapd, pos, epos - pos);
+       pos = hostapd_get_osen_ie(hapd, pos, epos - pos);
+
        /* Wi-Fi Alliance WMM */
        pos = hostapd_eid_wmm(hapd, pos);
 
@@ -543,7 +608,6 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 
 #ifdef CONFIG_HS20
        pos = hostapd_eid_hs20_indication(hapd, pos);
-       pos = hostapd_eid_osen(hapd, pos);
 #endif /* CONFIG_HS20 */
 
        pos = hostapd_eid_mbo(hapd, pos, (u8 *) resp + buflen - pos);
@@ -569,7 +633,9 @@ enum ssid_match_result {
 static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
                                         const u8 *ssid, size_t ssid_len,
                                         const u8 *ssid_list,
-                                        size_t ssid_list_len)
+                                        size_t ssid_list_len,
+                                        const u8 *short_ssid_list,
+                                        size_t short_ssid_list_len)
 {
        const u8 *pos, *end;
        int wildcard = 0;
@@ -580,20 +646,30 @@ static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
            os_memcmp(ssid, hapd->conf->ssid.ssid, ssid_len) == 0)
                return EXACT_SSID_MATCH;
 
-       if (ssid_list == NULL)
-               return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH;
+       if (ssid_list) {
+               pos = ssid_list;
+               end = ssid_list + ssid_list_len;
+               while (end - pos >= 2) {
+                       if (2 + pos[1] > end - pos)
+                               break;
+                       if (pos[1] == 0)
+                               wildcard = 1;
+                       if (pos[1] == hapd->conf->ssid.ssid_len &&
+                           os_memcmp(pos + 2, hapd->conf->ssid.ssid,
+                                     pos[1]) == 0)
+                               return EXACT_SSID_MATCH;
+                       pos += 2 + pos[1];
+               }
+       }
 
-       pos = ssid_list;
-       end = ssid_list + ssid_list_len;
-       while (end - pos >= 1) {
-               if (2 + pos[1] > end - pos)
-                       break;
-               if (pos[1] == 0)
-                       wildcard = 1;
-               if (pos[1] == hapd->conf->ssid.ssid_len &&
-                   os_memcmp(pos + 2, hapd->conf->ssid.ssid, pos[1]) == 0)
-                       return EXACT_SSID_MATCH;
-               pos += 2 + pos[1];
+       if (short_ssid_list) {
+               pos = short_ssid_list;
+               end = short_ssid_list + short_ssid_list_len;
+               while (end - pos >= 4) {
+                       if (hapd->conf->ssid.short_ssid == WPA_GET_LE32(pos))
+                               return EXACT_SSID_MATCH;
+                       pos += 4;
+               }
        }
 
        return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH;
@@ -731,6 +807,7 @@ void handle_probe_req(struct hostapd_data *hapd,
        int ret;
        u16 csa_offs[2];
        size_t csa_offs_len;
+       struct radius_sta rad_info;
 
        if (len < IEEE80211_HDRLEN)
                return;
@@ -739,13 +816,22 @@ void handle_probe_req(struct hostapd_data *hapd,
                sta_track_add(hapd->iface, mgmt->sa, ssi_signal);
        ie_len = len - IEEE80211_HDRLEN;
 
+       ret = hostapd_allowed_address(hapd, mgmt->sa, (const u8 *) mgmt, len,
+                                     &rad_info, 1);
+       if (ret == HOSTAPD_ACL_REJECT) {
+               wpa_msg(hapd->msg_ctx, MSG_DEBUG,
+                       "Ignore Probe Request frame from " MACSTR
+                       " due to ACL reject ", MAC2STR(mgmt->sa));
+               return;
+       }
+
        for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++)
                if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
                                            mgmt->sa, mgmt->da, mgmt->bssid,
                                            ie, ie_len, ssi_signal) > 0)
                        return;
 
-       if (!hapd->iconf->send_probe_response)
+       if (!hapd->conf->send_probe_response)
                return;
 
        if (ieee802_11_parse_elems(ie, ie_len, &elems, 0) == ParseFailed) {
@@ -810,7 +896,7 @@ void handle_probe_req(struct hostapd_data *hapd,
 #endif /* CONFIG_P2P */
 
        if (hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0 &&
-           elems.ssid_list_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));
                return;
@@ -842,7 +928,8 @@ void handle_probe_req(struct hostapd_data *hapd,
 #endif /* CONFIG_TAXONOMY */
 
        res = ssid_match(hapd, elems.ssid, elems.ssid_len,
-                        elems.ssid_list, elems.ssid_list_len);
+                        elems.ssid_list, elems.ssid_list_len,
+                        elems.short_ssid_list, elems.short_ssid_list_len);
        if (res == NO_SSID_MATCH) {
                if (!(mgmt->da[0] & 0x01)) {
                        wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
@@ -855,6 +942,12 @@ void handle_probe_req(struct hostapd_data *hapd,
                return;
        }
 
+       if (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;
+       }
+
 #ifdef CONFIG_INTERWORKING
        if (hapd->conf->interworking &&
            elems.interworking && elems.interworking_len >= 1) {
@@ -959,9 +1052,9 @@ void handle_probe_req(struct hostapd_data *hapd,
                                hapd->cs_c_off_ecsa_proberesp;
        }
 
-       ret = hostapd_drv_send_mlme_csa(hapd, resp, resp_len, noack,
-                                       csa_offs_len ? csa_offs : NULL,
-                                       csa_offs_len);
+       ret = hostapd_drv_send_mlme(hapd, resp, resp_len, noack,
+                                   csa_offs_len ? csa_offs : NULL,
+                                   csa_offs_len, 0);
 
        if (ret < 0)
                wpa_printf(MSG_INFO, "handle_probe_req: send failed");
@@ -1032,7 +1125,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
        size_t resp_len = 0;
 #ifdef NEED_AP_MLME
        u16 capab_info;
-       u8 *pos, *tailpos, *csa_pos;
+       u8 *pos, *tailpos, *tailend, *csa_pos;
 
 #define BEACON_HEAD_BUF_SIZE 256
 #define BEACON_TAIL_BUF_SIZE 512
@@ -1063,7 +1156,9 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 #ifdef CONFIG_IEEE80211AX
        if (hapd->iconf->ieee80211ax) {
                tail_len += 3 + sizeof(struct ieee80211_he_capabilities) +
-                       3 + sizeof(struct ieee80211_he_operation);
+                       3 + sizeof(struct ieee80211_he_operation) +
+                       3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) +
+                       3 + sizeof(struct ieee80211_spatial_reuse);
        }
 #endif /* CONFIG_IEEE80211AX */
 
@@ -1077,6 +1172,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
                os_free(tail);
                return -1;
        }
+       tailend = tail + tail_len;
 
        head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
                                           WLAN_FC_STYPE_BEACON);
@@ -1117,8 +1213,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 
        head_len = pos - (u8 *) head;
 
-       tailpos = hostapd_eid_country(hapd, tailpos,
-                                     tail + BEACON_TAIL_BUF_SIZE - tailpos);
+       tailpos = hostapd_eid_country(hapd, tailpos, tailend - tailpos);
 
        /* Power Constraint element */
        tailpos = hostapd_eid_pwr_constraint(hapd, tailpos);
@@ -1135,16 +1230,11 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
        /* Extended supported rates */
        tailpos = hostapd_eid_ext_supp_rates(hapd, tailpos);
 
-       /* RSN, MDIE, WPA */
-       tailpos = hostapd_eid_wpa(hapd, tailpos, tail + BEACON_TAIL_BUF_SIZE -
-                                 tailpos);
-
+       tailpos = hostapd_get_rsne(hapd, tailpos, tailend - tailpos);
+       tailpos = hostapd_eid_bss_load(hapd, tailpos, tailend - tailpos);
        tailpos = hostapd_eid_rm_enabled_capab(hapd, tailpos,
-                                              tail + BEACON_TAIL_BUF_SIZE -
-                                              tailpos);
-
-       tailpos = hostapd_eid_bss_load(hapd, tailpos,
-                                      tail + BEACON_TAIL_BUF_SIZE - tailpos);
+                                              tailend - tailpos);
+       tailpos = hostapd_get_mde(hapd, tailpos, tailend - tailpos);
 
        /* eCSA IE */
        csa_pos = hostapd_eid_ecsa(hapd, tailpos);
@@ -1153,15 +1243,8 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
        tailpos = csa_pos;
 
        tailpos = hostapd_eid_supported_op_classes(hapd, tailpos);
-
-#ifdef CONFIG_IEEE80211N
-       /* Secondary Channel Offset element */
-       /* TODO: The standard doesn't specify a position for this element. */
-       tailpos = hostapd_eid_secondary_channel(hapd, tailpos);
-
        tailpos = hostapd_eid_ht_capabilities(hapd, tailpos);
        tailpos = hostapd_eid_ht_operation(hapd, tailpos);
-#endif /* CONFIG_IEEE80211N */
 
        tailpos = hostapd_eid_ext_capab(hapd, tailpos);
 
@@ -1193,11 +1276,15 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 #endif /* CONFIG_IEEE80211AC */
 
        tailpos = hostapd_eid_fils_indic(hapd, tailpos, 0);
+       tailpos = hostapd_get_rsnxe(hapd, tailpos, tailend - tailpos);
 
 #ifdef CONFIG_IEEE80211AX
        if (hapd->iconf->ieee80211ax) {
-               tailpos = hostapd_eid_he_capab(hapd, tailpos);
+               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);
        }
 #endif /* CONFIG_IEEE80211AX */
 
@@ -1206,6 +1293,10 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
                tailpos = hostapd_eid_vendor_vht(hapd, tailpos);
 #endif /* CONFIG_IEEE80211AC */
 
+       /* WPA / OSEN */
+       tailpos = hostapd_get_wpa_ie(hapd, tailpos, tailend - tailpos);
+       tailpos = hostapd_get_osen_ie(hapd, tailpos, tailend - tailpos);
+
        /* Wi-Fi Alliance WMM */
        tailpos = hostapd_eid_wmm(hapd, tailpos);
 
@@ -1232,7 +1323,6 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 
 #ifdef CONFIG_HS20
        tailpos = hostapd_eid_hs20_indication(hapd, tailpos);
-       tailpos = hostapd_eid_osen(hapd, tailpos);
 #endif /* CONFIG_HS20 */
 
        tailpos = hostapd_eid_mbo(hapd, tailpos, tail + tail_len - tailpos);
@@ -1276,10 +1366,13 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
        params->key_mgmt_suites = hapd->conf->wpa_key_mgmt;
        params->auth_algs = hapd->conf->auth_algs;
        params->wpa_version = hapd->conf->wpa;
-       params->privacy = hapd->conf->ssid.wep.keys_set || hapd->conf->wpa ||
+       params->privacy = hapd->conf->wpa;
+#ifdef CONFIG_WEP
+       params->privacy |= hapd->conf->ssid.wep.keys_set ||
                (hapd->conf->ieee802_1x &&
                 (hapd->conf->default_wep_key_len ||
                  hapd->conf->individual_wep_key_len));
+#endif /* CONFIG_WEP */
        switch (hapd->conf->ignore_broadcast_ssid) {
        case 0:
                params->hide_ssid = NO_SSID_HIDING;
@@ -1292,7 +1385,6 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
                break;
        }
        params->isolate = hapd->conf->isolate;
-       params->smps_mode = hapd->iconf->ht_capab & HT_CAP_INFO_SMPS_MASK;
 #ifdef NEED_AP_MLME
        params->cts_protect = !!(ieee802_11_erp_info(hapd) &
                                ERP_INFO_USE_PROTECTION);
@@ -1327,6 +1419,18 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 #endif /* CONFIG_HS20 */
        params->multicast_to_unicast = hapd->conf->multicast_to_unicast;
        params->pbss = hapd->conf->pbss;
+
+       if (hapd->conf->ftm_responder) {
+               if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_FTM_RESPONDER) {
+                       params->ftm_responder = 1;
+                       params->lci = hapd->iface->conf->lci;
+                       params->civic = hapd->iface->conf->civic;
+               } else {
+                       wpa_printf(MSG_WARNING,
+                                  "Not configuring FTM responder as the driver doesn't advertise support for it");
+               }
+       }
+
        return 0;
 }
 
@@ -1348,6 +1452,7 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd)
        struct hostapd_freq_params freq;
        struct hostapd_iface *iface = hapd->iface;
        struct hostapd_config *iconf = iface->conf;
+       struct hostapd_hw_modes *cmode = iface->current_mode;
        struct wpabuf *beacon, *proberesp, *assocresp;
        int res, ret = -1;
 
@@ -1369,17 +1474,33 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd)
        params.proberesp_ies = proberesp;
        params.assocresp_ies = assocresp;
        params.reenable = hapd->reenable_beacon;
+#ifdef CONFIG_IEEE80211AX
+       params.he_spr = !!hapd->iface->conf->spr.sr_control;
+       params.he_spr_srg_obss_pd_min_offset =
+               hapd->iface->conf->spr.srg_obss_pd_min_offset;
+       params.he_spr_srg_obss_pd_max_offset =
+               hapd->iface->conf->spr.srg_obss_pd_max_offset;
+       params.he_bss_color_disabled =
+               hapd->iface->conf->he_op.he_bss_color_disabled;
+       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.twt_responder = hostapd_get_he_twt_responder(hapd,
+                                                           IEEE80211_MODE_AP);
+#endif /* CONFIG_IEEE80211AX */
        hapd->reenable_beacon = 0;
 
-       if (iface->current_mode &&
+       if (cmode &&
            hostapd_set_freq_params(&freq, iconf->hw_mode, iface->freq,
-                                   iconf->channel, iconf->ieee80211n,
-                                   iconf->ieee80211ac,
+                                   iconf->channel, iconf->enable_edmg,
+                                   iconf->edmg_channel, iconf->ieee80211n,
+                                   iconf->ieee80211ac, iconf->ieee80211ax,
                                    iconf->secondary_channel,
-                                   iconf->vht_oper_chwidth,
-                                   iconf->vht_oper_centr_freq_seg0_idx,
-                                   iconf->vht_oper_centr_freq_seg1_idx,
-                                   iface->current_mode->vht_capab) == 0)
+                                   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]) == 0)
                params.freq = &freq;
 
        res = hostapd_drv_set_ap(hapd, &params);