]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
mbssid: Process Known BSSID element
authorAloka Dixit <quic_alokad@quicinc.com>
Thu, 1 Dec 2022 03:18:41 +0000 (19:18 -0800)
committerJouni Malinen <j@w1.fi>
Fri, 2 Dec 2022 18:45:05 +0000 (20:45 +0200)
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 Request
frames to indicate which of the multiple BSSIDs they have already
discovered. AP should exclude these profiles from the Probe Response
frame.

Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
src/ap/beacon.c
src/ap/ieee802_11.c
src/ap/ieee802_11.h
src/common/ieee802_11_common.c
src/common/ieee802_11_common.h
src/common/ieee802_11_defs.h

index 97c126923258467c4b9472cf2864c2eb3f4605ca..dbc6b062b84122822c0b5d1517ad3181e57d7e0a 100644 (file)
@@ -478,7 +478,8 @@ ieee802_11_build_ap_params_mbssid(struct hostapd_data *hapd,
                goto fail;
 
        tx_bss = hostapd_mbssid_get_tx_bss(hapd);
-       len = hostapd_eid_mbssid_len(tx_bss, WLAN_FC_STYPE_BEACON, &elem_count);
+       len = hostapd_eid_mbssid_len(tx_bss, WLAN_FC_STYPE_BEACON, &elem_count,
+                                    NULL, 0);
        if (!len || (iface->conf->mbssid == ENHANCED_MBSSID_ENABLED &&
                     elem_count > iface->ema_max_periodicity))
                goto fail;
@@ -492,7 +493,7 @@ ieee802_11_build_ap_params_mbssid(struct hostapd_data *hapd,
                goto fail;
 
        end = hostapd_eid_mbssid(tx_bss, elem, elem + len, WLAN_FC_STYPE_BEACON,
-                                elem_count, elem_offset);
+                                elem_count, elem_offset, NULL, 0);
 
        params->mbssid_tx_iface = tx_bss->conf->iface;
        params->mbssid_index = hostapd_mbssid_get_bss_index(hapd);
@@ -532,7 +533,8 @@ static u8 * hostapd_eid_mbssid_config(struct hostapd_data *hapd, u8 *eid,
 static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
                                   const struct ieee80211_mgmt *req,
                                   int is_p2p, size_t *resp_len,
-                                  bool bcast_probe_resp)
+                                  bool bcast_probe_resp, const u8 *known_bss,
+                                  u8 known_bss_len)
 {
        struct ieee80211_mgmt *resp;
        u8 *pos, *epos, *csa_pos;
@@ -586,7 +588,8 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
        }
 #endif /* CONFIG_IEEE80211BE */
 
-       buflen += hostapd_eid_mbssid_len(hapd, WLAN_FC_STYPE_PROBE_RESP, NULL);
+       buflen += hostapd_eid_mbssid_len(hapd, WLAN_FC_STYPE_PROBE_RESP, 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);
@@ -647,7 +650,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
        pos = hostapd_get_rsne(hapd, pos, epos - pos);
        pos = hostapd_eid_bss_load(hapd, pos, epos - pos);
        pos = hostapd_eid_mbssid(hapd, pos, epos, WLAN_FC_STYPE_PROBE_RESP, 0,
-                                NULL);
+                                NULL, known_bss, known_bss_len);
        pos = hostapd_eid_rm_enabled_capab(hapd, pos, epos - pos);
        pos = hostapd_get_mde(hapd, pos, epos - pos);
 
@@ -661,9 +664,11 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
        pos = hostapd_eid_ht_capabilities(hapd, pos);
        pos = hostapd_eid_ht_operation(hapd, pos);
 
-       /* Probe Response frames always include all non-TX profiles */
+       /* Probe Response frames always include all non-TX profiles except
+        * when a list of known BSSes is included in the Probe Request frame. */
        pos = hostapd_eid_ext_capab(hapd, pos,
-                                   hapd->iconf->mbssid >= MBSSID_ENABLED);
+                                   hapd->iconf->mbssid >= MBSSID_ENABLED &&
+                                   !known_bss_len);
 
        pos = hostapd_eid_time_adv(hapd, pos);
        pos = hostapd_eid_time_zone(hapd, pos);
@@ -1225,7 +1230,8 @@ void handle_probe_req(struct hostapd_data *hapd,
                     " signal=%d", MAC2STR(mgmt->sa), ssi_signal);
 
        resp = hostapd_gen_probe_resp(hapd, mgmt, elems.p2p != NULL,
-                                     &resp_len, false);
+                                     &resp_len, false, elems.mbssid_known_bss,
+                                     elems.mbssid_known_bss_len);
        if (resp == NULL)
                return;
 
@@ -1295,7 +1301,7 @@ static u8 * hostapd_probe_resp_offloads(struct hostapd_data *hapd,
                           "this");
 
        /* Generate a Probe Response template for the non-P2P case */
-       return hostapd_gen_probe_resp(hapd, NULL, 0, resp_len, false);
+       return hostapd_gen_probe_resp(hapd, NULL, 0, resp_len, false, NULL, 0);
 }
 
 #endif /* NEED_AP_MLME */
@@ -1314,7 +1320,7 @@ static u8 * hostapd_unsol_bcast_probe_resp(struct hostapd_data *hapd,
 
        return hostapd_gen_probe_resp(hapd, NULL, 0,
                                      &params->unsol_bcast_probe_resp_tmpl_len,
-                                     true);
+                                     true, NULL, 0);
 }
 #endif /* CONFIG_IEEE80211AX */
 
index d8424238bbffdcd1ba4b94203b054ae6775521dd..1a1ccf7fc47439b5a1fba836859ccbc282a55990 100644 (file)
@@ -6725,8 +6725,20 @@ u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type)
 }
 
 
+static bool mbssid_known_bss(unsigned int i, const u8 *known_bss,
+                            size_t known_bss_len)
+{
+       if (!known_bss || known_bss_len <= i / 8)
+               return false;
+       known_bss = &known_bss[i / 8];
+       return *known_bss & (u8) (BIT(i % 8));
+}
+
+
 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;
@@ -6737,7 +6749,8 @@ static size_t hostapd_eid_mbssid_elem_len(struct hostapd_data *hapd,
                size_t nontx_profile_len, auth_len;
                u8 ie_count = 0;
 
-               if (!bss || !bss->conf || !bss->started)
+               if (!bss || !bss->conf || !bss->started ||
+                   mbssid_known_bss(i, known_bss, known_bss_len))
                        continue;
 
                /*
@@ -6786,7 +6799,8 @@ static size_t hostapd_eid_mbssid_elem_len(struct hostapd_data *hapd,
 
 
 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;
 
@@ -6806,7 +6820,8 @@ size_t hostapd_eid_mbssid_len(struct hostapd_data *hapd, u32 frame_type,
 
        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;
@@ -6817,7 +6832,8 @@ size_t hostapd_eid_mbssid_len(struct hostapd_data *hapd, u32 frame_type,
 
 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;
@@ -6836,7 +6852,8 @@ static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end,
                size_t auth_len = 0;
                u16 capab_info;
 
-               if (!bss || !bss->conf || !bss->started)
+               if (!bss || !bss->conf || !bss->started ||
+                   mbssid_known_bss(i, known_bss, known_bss_len))
                        continue;
                conf = bss->conf;
 
@@ -6919,7 +6936,8 @@ static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end,
 
 u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end,
                        unsigned int frame_stype, u8 elem_count,
-                       u8 **elem_offset)
+                       u8 **elem_offset,
+                       const u8 *known_bss, size_t known_bss_len)
 {
        size_t bss_index = 1;
        u8 elem_index = 0;
@@ -6948,7 +6966,8 @@ u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end,
                }
                eid = hostapd_eid_mbssid_elem(hapd, eid, end, frame_stype,
                                              hostapd_max_bssid_indicator(hapd),
-                                             &bss_index, elem_count);
+                                             &bss_index, elem_count,
+                                             known_bss, known_bss_len);
        }
 
        return eid;
index 1b46440d0c5f1406f8a0be2b9c1e945ea4986027..5f443fcb8abba4a8c4f2291cf2db67498530430e 100644 (file)
@@ -216,9 +216,11 @@ u16 copy_sta_eht_capab(struct hostapd_data *hapd, struct sta_info *sta,
                       const u8 *he_capab, size_t he_capab_len,
                       const u8 *eht_capab, size_t eht_capab_len);
 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,
                        unsigned int frame_stype, u8 elem_count,
-                       u8 **elem_offset);
+                       u8 **elem_offset,
+                       const u8 *known_bss, size_t known_bss_len);
 
 #endif /* IEEE802_11_H */
index 924fe24f01c1837459ed99e353e7961ca40615f8..7080412bc31ad1dd788bb8aaab3edc088fa2d288 100644 (file)
@@ -387,6 +387,10 @@ static int ieee802_11_parse_extension(const u8 *pos, size_t elen,
                                         show_errors))
                        return -1;
                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,
index 0d258dfb87095a0d86f20b3ec975772829853433..9a1dbdda884e104cd9a090f002fecf8e569cff54 100644 (file)
@@ -108,6 +108,7 @@ struct ieee802_11_elems {
        const u8 *reconf_mle;
        const u8 *tdls_mle;
        const u8 *prior_access_mle;
+       const u8 *mbssid_known_bss;
 
        u8 ssid_len;
        u8 supp_rates_len;
@@ -169,6 +170,7 @@ struct ieee802_11_elems {
        size_t reconf_mle_len;
        size_t tdls_mle_len;
        size_t prior_access_mle_len;
+       u8 mbssid_known_bss_len;
 
        struct mb_ies_info mb_ies;
 
index 59c3b6a8364b3e51b24e5684e7d66aac2077907b..7ed5f56060211e5f49749bc08c44fe9aac6abcbd 100644 (file)
 #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