wifi: mac80211: use supported selectors from assoc in ML reconf

For multi-link reconfiguration, we shouldn't have any BSS
membership selectors that are different from the association.
Track the association selectors and use them to check the new
link(s) added during reconfiguration.

Fixes: 36e05b0b8390 ("wifi: mac80211: Support dynamic link addition and removal")
Reviewed-by: Ilan Peer <ilan.peer@intel.com>
Link: https://patch.msgid.link/20250311121004.771de0c36a75.I72f87d048c8693919b99dd9d4eee39833f06d15f@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2025-03-11 12:10:04 +01:00
parent 899da1830d
commit 80834e7d85
2 changed files with 13 additions and 20 deletions

View File

@ -444,8 +444,6 @@ struct ieee80211_mgd_assoc_data {
const u8 *supp_rates;
u8 supp_rates_len;
unsigned long userspace_selectors[BITS_TO_LONGS(128)];
unsigned long timeout;
int tries;
@ -524,6 +522,8 @@ struct ieee80211_if_managed {
struct ieee80211_mgd_auth_data *auth_data;
struct ieee80211_mgd_assoc_data *assoc_data;
unsigned long userspace_selectors[BITS_TO_LONGS(128)];
bool powersave; /* powersave requested for this iface */
bool broken_ap; /* AP is broken -- turn off powersave */

View File

@ -4164,6 +4164,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
ifmgd->epcs.enabled = false;
ifmgd->epcs.dialog_token = 0;
memset(ifmgd->userspace_selectors, 0,
sizeof(ifmgd->userspace_selectors));
}
static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
@ -6136,7 +6139,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
err = ieee80211_prep_channel(sdata, link, link_id, cbss,
true, &link->u.mgd.conn,
assoc_data->userspace_selectors);
sdata->u.mgd.userspace_selectors);
if (err) {
link_info(link, "prep_channel failed\n");
goto out_err;
@ -9400,7 +9403,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
false);
}
ieee80211_parse_cfg_selectors(assoc_data->userspace_selectors,
memset(sdata->u.mgd.userspace_selectors, 0,
sizeof(sdata->u.mgd.userspace_selectors));
ieee80211_parse_cfg_selectors(sdata->u.mgd.userspace_selectors,
req->supported_selectors,
req->supported_selectors_len);
@ -9651,7 +9656,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
err = ieee80211_prep_channel(sdata, NULL, i,
assoc_data->link[i].bss, true,
&assoc_data->link[i].conn,
assoc_data->userspace_selectors);
sdata->u.mgd.userspace_selectors);
if (err) {
req->links[i].error = err;
goto err_clear;
@ -9668,7 +9673,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
req->ap_mld_addr, true,
&assoc_data->link[assoc_link_id].conn,
override,
assoc_data->userspace_selectors);
sdata->u.mgd.userspace_selectors);
if (err)
goto err_clear;
@ -9912,14 +9917,6 @@ void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif)
}
EXPORT_SYMBOL(ieee80211_disable_rssi_reports);
static void ieee80211_ml_reconf_selectors(unsigned long *userspace_selectors)
{
/* these selectors are mandatory for ML reconfiguration */
set_bit(BSS_MEMBERSHIP_SELECTOR_SAE_H2E, userspace_selectors);
set_bit(BSS_MEMBERSHIP_SELECTOR_HE_PHY, userspace_selectors);
set_bit(BSS_MEMBERSHIP_SELECTOR_EHT_PHY, userspace_selectors);
}
void ieee80211_process_ml_reconf_resp(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt, size_t len)
{
@ -9933,7 +9930,6 @@ void ieee80211_process_ml_reconf_resp(struct ieee80211_sub_if_data *sdata,
sdata->u.mgd.reconf.removed_links;
u16 link_mask, valid_links;
unsigned int link_id;
unsigned long userspace_selectors[BITS_TO_LONGS(128)] = {};
size_t orig_len = len;
u8 i, group_key_data_len;
u8 *pos;
@ -10041,7 +10037,6 @@ void ieee80211_process_ml_reconf_resp(struct ieee80211_sub_if_data *sdata,
}
ieee80211_vif_set_links(sdata, valid_links, sdata->vif.dormant_links);
ieee80211_ml_reconf_selectors(userspace_selectors);
link_mask = 0;
for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) {
struct cfg80211_bss *cbss = add_links_data->link[link_id].bss;
@ -10087,7 +10082,7 @@ void ieee80211_process_ml_reconf_resp(struct ieee80211_sub_if_data *sdata,
link->u.mgd.conn = add_links_data->link[link_id].conn;
if (ieee80211_prep_channel(sdata, link, link_id, cbss,
true, &link->u.mgd.conn,
userspace_selectors)) {
sdata->u.mgd.userspace_selectors)) {
link_info(link, "mlo: reconf: prep_channel failed\n");
goto disconnect;
}
@ -10423,7 +10418,6 @@ int ieee80211_mgd_assoc_ml_reconf(struct ieee80211_sub_if_data *sdata,
*/
if (added_links) {
bool uapsd_supported;
unsigned long userspace_selectors[BITS_TO_LONGS(128)] = {};
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data)
@ -10433,7 +10427,6 @@ int ieee80211_mgd_assoc_ml_reconf(struct ieee80211_sub_if_data *sdata,
data->wmm = true;
uapsd_supported = true;
ieee80211_ml_reconf_selectors(userspace_selectors);
for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS;
link_id++) {
struct ieee80211_supported_band *sband;
@ -10509,7 +10502,7 @@ int ieee80211_mgd_assoc_ml_reconf(struct ieee80211_sub_if_data *sdata,
data->link[link_id].bss,
true,
&data->link[link_id].conn,
userspace_selectors);
sdata->u.mgd.userspace_selectors);
if (err)
goto err_free;
}