]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
mbssid: Set extended capabilities
authorAloka Dixit <quic_alokad@quicinc.com>
Thu, 1 Dec 2022 03:18:39 +0000 (19:18 -0800)
committerJouni Malinen <j@w1.fi>
Fri, 2 Dec 2022 18:21:11 +0000 (20:21 +0200)
Set extended capabilities as described in IEEE Std 802.11ax-2021,
9.4.2.26. Reset the capability bits to 0 explicitly if MBSSID and/or EMA
is not enabled because otherwise some client devices fail to associate.

Bit 80 (complete list of non-tx profiles) is set for all Probe Response
frames, but for Beacon frames it is set only if EMA is disabled or if
EMA profile periodicity is 1.

Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
Co-developed-by: John Crispin <john@phrozen.org>
Signed-off-by: John Crispin <john@phrozen.org>
src/ap/ap_drv_ops.c
src/ap/beacon.c
src/ap/ieee802_11.c
src/ap/ieee802_11.h
src/ap/ieee802_11_shared.c

index ebc0dba9a1e3ca4c73561c02db6be0edee99958a..1ffc37ff33f5bf26913d0439b9d95e9f0c1ac062 100644 (file)
@@ -92,7 +92,7 @@ int hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
                goto fail;
 
        pos = buf;
-       pos = hostapd_eid_ext_capab(hapd, pos);
+       pos = hostapd_eid_ext_capab(hapd, pos, false);
        if (add_buf_data(&assocresp, buf, pos - buf) < 0)
                goto fail;
        pos = hostapd_eid_interworking(hapd, pos);
index 87d9ed0182229d6f6a70c8559fce266ecafb5655..36e32e1423c18af7767eb6e955b225e5345459d8 100644 (file)
@@ -644,7 +644,9 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
        pos = hostapd_eid_ht_capabilities(hapd, pos);
        pos = hostapd_eid_ht_operation(hapd, pos);
 
-       pos = hostapd_eid_ext_capab(hapd, pos);
+       /* Probe Response frames always include all non-TX profiles */
+       pos = hostapd_eid_ext_capab(hapd, pos,
+                                   hapd->iconf->mbssid >= MBSSID_ENABLED);
 
        pos = hostapd_eid_time_adv(hapd, pos);
        pos = hostapd_eid_time_zone(hapd, pos);
@@ -1576,6 +1578,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 #ifdef NEED_AP_MLME
        u16 capab_info;
        u8 *pos, *tailpos, *tailend, *csa_pos;
+       bool complete = false;
 #endif /* NEED_AP_MLME */
 
        os_memset(params, 0, sizeof(*params));
@@ -1718,16 +1721,21 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
        tailpos = hostapd_eid_ht_capabilities(hapd, tailpos);
        tailpos = hostapd_eid_ht_operation(hapd, tailpos);
 
-       tailpos = hostapd_eid_ext_capab(hapd, tailpos);
-
-       if (hapd->iconf->mbssid && hapd->iconf->num_bss > 1 &&
-           ieee802_11_build_ap_params_mbssid(hapd, params)) {
-               os_free(head);
-               os_free(tail);
-               wpa_printf(MSG_ERROR, "MBSSID: Failed to set beacon data");
-               return -1;
+       if (hapd->iconf->mbssid && hapd->iconf->num_bss > 1) {
+               if (ieee802_11_build_ap_params_mbssid(hapd, params)) {
+                       os_free(head);
+                       os_free(tail);
+                       wpa_printf(MSG_ERROR,
+                                  "MBSSID: Failed to set beacon data");
+                       return -1;
+               }
+               complete = hapd->iconf->mbssid == MBSSID_ENABLED ||
+                       (hapd->iconf->mbssid == ENHANCED_MBSSID_ENABLED &&
+                        params->mbssid_elem_count == 1);
        }
 
+       tailpos = hostapd_eid_ext_capab(hapd, tailpos, complete);
+
        /*
         * TODO: Time Advertisement element should only be included in some
         * DTIM Beacon frames.
index 756f3af9b5d699378167833f84b54f23160d26f2..d8424238bbffdcd1ba4b94203b054ae6775521dd 100644 (file)
@@ -4350,7 +4350,7 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
        }
 #endif /* CONFIG_IEEE80211AX */
 
-       p = hostapd_eid_ext_capab(hapd, p);
+       p = hostapd_eid_ext_capab(hapd, p, false);
        p = hostapd_eid_bss_max_idle_period(hapd, p);
        if (sta && sta->qos_map_enabled)
                p = hostapd_eid_qos_map_set(hapd, p);
index 6fa7cc41d84c6e2da7d6b411559101ca581b9664..1b46440d0c5f1406f8a0be2b9c1e945ea4986027 100644 (file)
@@ -45,7 +45,8 @@ static inline int ieee802_11_get_mib_sta(struct hostapd_data *hapd,
 #endif /* NEED_AP_MLME */
 u16 hostapd_own_capab_info(struct hostapd_data *hapd);
 void ap_ht2040_timeout(void *eloop_data, void *user_data);
-u8 * hostapd_eid_ext_capab(struct hostapd_data *hapd, u8 *eid);
+u8 * hostapd_eid_ext_capab(struct hostapd_data *hapd, u8 *eid,
+                          bool mbssid_complete);
 u8 * hostapd_eid_qos_map_set(struct hostapd_data *hapd, u8 *eid);
 u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid);
 u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid);
index ad8afff2ac539ba912f51a3ae3e77adf08c99dd1..a7ab3a2d777a3bd3eaed4d1b8993d4345d5ca17f 100644 (file)
@@ -340,7 +340,8 @@ void ieee802_11_sa_query_action(struct hostapd_data *hapd,
 }
 
 
-static void hostapd_ext_capab_byte(struct hostapd_data *hapd, u8 *pos, int idx)
+static void hostapd_ext_capab_byte(struct hostapd_data *hapd, u8 *pos, int idx,
+                                  bool mbssid_complete)
 {
        *pos = 0x00;
 
@@ -364,6 +365,8 @@ static void hostapd_ext_capab_byte(struct hostapd_data *hapd, u8 *pos, int idx)
                        *pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */
                if (hapd->conf->bss_transition)
                        *pos |= 0x08; /* Bit 19 - BSS Transition */
+               if (hapd->iconf->mbssid)
+                       *pos |= 0x40; /* Bit 22 - Multiple BSSID */
                break;
        case 3: /* Bits 24-31 */
 #ifdef CONFIG_WNM_AP
@@ -435,6 +438,11 @@ static void hostapd_ext_capab_byte(struct hostapd_data *hapd, u8 *pos, int idx)
                    (hapd->iface->drv_flags &
                     WPA_DRIVER_FLAGS_BEACON_PROTECTION))
                        *pos |= 0x10; /* Bit 84 - Beacon Protection Enabled */
+               if (hapd->iconf->mbssid == ENHANCED_MBSSID_ENABLED)
+                       *pos |= 0x08; /* Bit 83 - Enhanced multiple BSSID */
+               if (mbssid_complete)
+                       *pos |= 0x01; /* Bit 80 - Complete List of NonTxBSSID
+                                      * Profiles */
                break;
        case 11: /* Bits 88-95 */
 #ifdef CONFIG_SAE_PK
@@ -448,7 +456,8 @@ static void hostapd_ext_capab_byte(struct hostapd_data *hapd, u8 *pos, int idx)
 }
 
 
-u8 * hostapd_eid_ext_capab(struct hostapd_data *hapd, u8 *eid)
+u8 * hostapd_eid_ext_capab(struct hostapd_data *hapd, u8 *eid,
+                          bool mbssid_complete)
 {
        u8 *pos = eid;
        u8 len = EXT_CAPA_MAX_LEN, i;
@@ -459,7 +468,7 @@ u8 * hostapd_eid_ext_capab(struct hostapd_data *hapd, u8 *eid)
        *pos++ = WLAN_EID_EXT_CAPAB;
        *pos++ = len;
        for (i = 0; i < len; i++, pos++) {
-               hostapd_ext_capab_byte(hapd, pos, i);
+               hostapd_ext_capab_byte(hapd, pos, i, mbssid_complete);
 
                if (i < hapd->iface->extended_capa_len) {
                        *pos &= ~hapd->iface->extended_capa_mask[i];
@@ -470,6 +479,13 @@ u8 * hostapd_eid_ext_capab(struct hostapd_data *hapd, u8 *eid)
                        *pos &= ~hapd->conf->ext_capa_mask[i];
                        *pos |= hapd->conf->ext_capa[i];
                }
+
+               /* Clear bits 83 and 22 if EMA and MBSSID are not enabled
+                * otherwise association fails with some clients */
+               if (i == 10 && hapd->iconf->mbssid < ENHANCED_MBSSID_ENABLED)
+                       *pos &= ~0x08;
+               if (i == 2 && !hapd->iconf->mbssid)
+                       *pos &= ~0x40;
        }
 
        while (len > 0 && eid[1 + len] == 0) {