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;
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);
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;
}
#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);
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);
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);
" 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;
"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 */
return hostapd_gen_probe_resp(hapd, NULL, 0,
¶ms->unsol_bcast_probe_resp_tmpl_len,
- true);
+ true, NULL, 0);
}
#endif /* CONFIG_IEEE80211AX */
}
+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;
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;
/*
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;
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;
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;
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;
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;
}
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;