wifi: cfg80211: ignore non-TX BSSs in per-STA profile
If a non-TX BSS is included in a per-STA profile, then we cannot set
transmitted_bss for it. Even worse, if we do things properly we should
be configuring both bssid_index and max_bssid_indicator correctly. We do
not actually have both pieces of information (and, some APs currently
do not include either).
So, ignore any per-STA profile where the RNR says that the BSS is not
transmitted. Also fix transmitted_bss to never be set for per-STA
profiles.
This fixes issues where mac80211 was setting the reference BSSID to an
incorrect value.
Fixes: 2481b5da9c
("wifi: cfg80211: handle BSS data contained in ML probe responses")
Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240318184907.6a0babed655a.Iad447fea417c63f683da793556b97c31d07a4aab@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
c7378d7d8b
commit
97f8df4db4
@ -2211,12 +2211,16 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
|
|||||||
tmp.pub.use_for = data->use_for;
|
tmp.pub.use_for = data->use_for;
|
||||||
tmp.pub.cannot_use_reasons = data->cannot_use_reasons;
|
tmp.pub.cannot_use_reasons = data->cannot_use_reasons;
|
||||||
|
|
||||||
if (data->bss_source != BSS_SOURCE_DIRECT) {
|
switch (data->bss_source) {
|
||||||
|
case BSS_SOURCE_MBSSID:
|
||||||
tmp.pub.transmitted_bss = data->source_bss;
|
tmp.pub.transmitted_bss = data->source_bss;
|
||||||
|
fallthrough;
|
||||||
|
case BSS_SOURCE_STA_PROFILE:
|
||||||
ts = bss_from_pub(data->source_bss)->ts;
|
ts = bss_from_pub(data->source_bss)->ts;
|
||||||
tmp.pub.bssid_index = data->bssid_index;
|
tmp.pub.bssid_index = data->bssid_index;
|
||||||
tmp.pub.max_bssid_indicator = data->max_bssid_indicator;
|
tmp.pub.max_bssid_indicator = data->max_bssid_indicator;
|
||||||
} else {
|
break;
|
||||||
|
case BSS_SOURCE_DIRECT:
|
||||||
ts = jiffies;
|
ts = jiffies;
|
||||||
|
|
||||||
if (channel->band == NL80211_BAND_60GHZ) {
|
if (channel->band == NL80211_BAND_60GHZ) {
|
||||||
@ -2231,6 +2235,7 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
|
|||||||
regulatory_hint_found_beacon(wiphy, channel,
|
regulatory_hint_found_beacon(wiphy, channel,
|
||||||
gfp);
|
gfp);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2660,6 +2665,7 @@ struct tbtt_info_iter_data {
|
|||||||
u8 param_ch_count;
|
u8 param_ch_count;
|
||||||
u32 use_for;
|
u32 use_for;
|
||||||
u8 mld_id, link_id;
|
u8 mld_id, link_id;
|
||||||
|
bool non_tx;
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum cfg80211_rnr_iter_ret
|
static enum cfg80211_rnr_iter_ret
|
||||||
@ -2670,14 +2676,20 @@ cfg802121_mld_ap_rnr_iter(void *_data, u8 type,
|
|||||||
const struct ieee80211_rnr_mld_params *mld_params;
|
const struct ieee80211_rnr_mld_params *mld_params;
|
||||||
struct tbtt_info_iter_data *data = _data;
|
struct tbtt_info_iter_data *data = _data;
|
||||||
u8 link_id;
|
u8 link_id;
|
||||||
|
bool non_tx = false;
|
||||||
|
|
||||||
if (type == IEEE80211_TBTT_INFO_TYPE_TBTT &&
|
if (type == IEEE80211_TBTT_INFO_TYPE_TBTT &&
|
||||||
tbtt_info_len >= offsetofend(struct ieee80211_tbtt_info_ge_11,
|
tbtt_info_len >= offsetofend(struct ieee80211_tbtt_info_ge_11,
|
||||||
mld_params))
|
mld_params)) {
|
||||||
mld_params = (void *)(tbtt_info +
|
const struct ieee80211_tbtt_info_ge_11 *tbtt_info_ge_11 =
|
||||||
offsetof(struct ieee80211_tbtt_info_ge_11,
|
(void *)tbtt_info;
|
||||||
mld_params));
|
|
||||||
else if (type == IEEE80211_TBTT_INFO_TYPE_MLD &&
|
non_tx = (tbtt_info_ge_11->bss_params &
|
||||||
|
(IEEE80211_RNR_TBTT_PARAMS_MULTI_BSSID |
|
||||||
|
IEEE80211_RNR_TBTT_PARAMS_TRANSMITTED_BSSID)) ==
|
||||||
|
IEEE80211_RNR_TBTT_PARAMS_MULTI_BSSID;
|
||||||
|
mld_params = &tbtt_info_ge_11->mld_params;
|
||||||
|
} else if (type == IEEE80211_TBTT_INFO_TYPE_MLD &&
|
||||||
tbtt_info_len >= sizeof(struct ieee80211_rnr_mld_params))
|
tbtt_info_len >= sizeof(struct ieee80211_rnr_mld_params))
|
||||||
mld_params = (void *)tbtt_info;
|
mld_params = (void *)tbtt_info;
|
||||||
else
|
else
|
||||||
@ -2696,6 +2708,7 @@ cfg802121_mld_ap_rnr_iter(void *_data, u8 type,
|
|||||||
data->param_ch_count =
|
data->param_ch_count =
|
||||||
le16_get_bits(mld_params->params,
|
le16_get_bits(mld_params->params,
|
||||||
IEEE80211_RNR_MLD_PARAMS_BSS_CHANGE_COUNT);
|
IEEE80211_RNR_MLD_PARAMS_BSS_CHANGE_COUNT);
|
||||||
|
data->non_tx = non_tx;
|
||||||
|
|
||||||
if (type == IEEE80211_TBTT_INFO_TYPE_TBTT)
|
if (type == IEEE80211_TBTT_INFO_TYPE_TBTT)
|
||||||
data->use_for = NL80211_BSS_USE_FOR_ALL;
|
data->use_for = NL80211_BSS_USE_FOR_ALL;
|
||||||
@ -2707,7 +2720,7 @@ cfg802121_mld_ap_rnr_iter(void *_data, u8 type,
|
|||||||
static u8
|
static u8
|
||||||
cfg80211_rnr_info_for_mld_ap(const u8 *ie, size_t ielen, u8 mld_id, u8 link_id,
|
cfg80211_rnr_info_for_mld_ap(const u8 *ie, size_t ielen, u8 mld_id, u8 link_id,
|
||||||
const struct ieee80211_neighbor_ap_info **ap_info,
|
const struct ieee80211_neighbor_ap_info **ap_info,
|
||||||
u8 *param_ch_count)
|
u8 *param_ch_count, bool *non_tx)
|
||||||
{
|
{
|
||||||
struct tbtt_info_iter_data data = {
|
struct tbtt_info_iter_data data = {
|
||||||
.mld_id = mld_id,
|
.mld_id = mld_id,
|
||||||
@ -2718,6 +2731,7 @@ cfg80211_rnr_info_for_mld_ap(const u8 *ie, size_t ielen, u8 mld_id, u8 link_id,
|
|||||||
|
|
||||||
*ap_info = data.ap_info;
|
*ap_info = data.ap_info;
|
||||||
*param_ch_count = data.param_ch_count;
|
*param_ch_count = data.param_ch_count;
|
||||||
|
*non_tx = data.non_tx;
|
||||||
|
|
||||||
return data.use_for;
|
return data.use_for;
|
||||||
}
|
}
|
||||||
@ -2897,6 +2911,7 @@ cfg80211_parse_ml_elem_sta_data(struct wiphy *wiphy,
|
|||||||
ssize_t profile_len;
|
ssize_t profile_len;
|
||||||
u8 param_ch_count;
|
u8 param_ch_count;
|
||||||
u8 link_id, use_for;
|
u8 link_id, use_for;
|
||||||
|
bool non_tx;
|
||||||
|
|
||||||
if (!ieee80211_mle_basic_sta_prof_size_ok((u8 *)mle->sta_prof[i],
|
if (!ieee80211_mle_basic_sta_prof_size_ok((u8 *)mle->sta_prof[i],
|
||||||
mle->sta_prof_len[i]))
|
mle->sta_prof_len[i]))
|
||||||
@ -2942,10 +2957,24 @@ cfg80211_parse_ml_elem_sta_data(struct wiphy *wiphy,
|
|||||||
tx_data->ielen,
|
tx_data->ielen,
|
||||||
mld_id, link_id,
|
mld_id, link_id,
|
||||||
&ap_info,
|
&ap_info,
|
||||||
¶m_ch_count);
|
¶m_ch_count,
|
||||||
|
&non_tx);
|
||||||
if (!use_for)
|
if (!use_for)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As of 802.11be_D5.0, the specification does not give us any
|
||||||
|
* way of discovering both the MaxBSSID and the Multiple-BSSID
|
||||||
|
* Index. It does seem like the Multiple-BSSID Index element
|
||||||
|
* may be provided, but section 9.4.2.45 explicitly forbids
|
||||||
|
* including a Multiple-BSSID Element (in this case without any
|
||||||
|
* subelements).
|
||||||
|
* Without both pieces of information we cannot calculate the
|
||||||
|
* reference BSSID, so simply ignore the BSS.
|
||||||
|
*/
|
||||||
|
if (non_tx)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* We could sanity check the BSSID is included */
|
/* We could sanity check the BSSID is included */
|
||||||
|
|
||||||
if (!ieee80211_operating_class_to_band(ap_info->op_class,
|
if (!ieee80211_operating_class_to_band(ap_info->op_class,
|
||||||
|
Loading…
Reference in New Issue
Block a user