Skip to content

Commit a9681ef

Browse files
committed
wifi: mac80211: send extended MLD capa/ops if AP has it
Currently the code only sends extended MLD capa/ops in strict mode, but if the AP has it then it should also be able to parse it. There could be cases where the AP doesn't have it but we would want to advertise it (e.g. if the AP supports nothing but we want to have BTM.), but given the broken deployed APs out there right now this is the best we can do. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Reviewed-by: Ilan Peer <ilan.peer@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://patch.msgid.link/20250609213232.c9b8b3a6ca77.I1153d4283d1fbb9e5db60e7b939cc133a6345db5@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
1 parent ff1ac75 commit a9681ef

File tree

1 file changed

+45
-9
lines changed

1 file changed

+45
-9
lines changed

net/mac80211/mlme.c

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1939,14 +1939,7 @@ ieee80211_assoc_add_ml_elem(struct ieee80211_sub_if_data *sdata,
19391939
}
19401940
skb_put_data(skb, &mld_capa_ops, sizeof(mld_capa_ops));
19411941

1942-
/* Many APs have broken parsing of the extended MLD capa/ops field,
1943-
* dropping (re-)association request frames or replying with association
1944-
* response with a failure status if it's present. Without a clear
1945-
* indication as to whether the AP supports parsing this field or not do
1946-
* not include it in the common information unless strict mode is set.
1947-
*/
1948-
if (ieee80211_hw_check(&local->hw, STRICT) &&
1949-
assoc_data->ext_mld_capa_ops) {
1942+
if (assoc_data->ext_mld_capa_ops) {
19501943
ml_elem->control |=
19511944
cpu_to_le16(IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP);
19521945
common->len += 2;
@@ -9357,6 +9350,39 @@ ieee80211_mgd_get_ap_ht_vht_capa(struct ieee80211_sub_if_data *sdata,
93579350
return err;
93589351
}
93599352

9353+
static bool
9354+
ieee80211_mgd_assoc_bss_has_mld_ext_capa_ops(struct cfg80211_assoc_request *req)
9355+
{
9356+
const struct cfg80211_bss_ies *ies;
9357+
struct cfg80211_bss *bss;
9358+
const struct element *ml;
9359+
9360+
/* not an MLO connection if link_id < 0, so irrelevant */
9361+
if (req->link_id < 0)
9362+
return false;
9363+
9364+
bss = req->links[req->link_id].bss;
9365+
9366+
guard(rcu)();
9367+
ies = rcu_dereference(bss->ies);
9368+
for_each_element_extid(ml, WLAN_EID_EXT_EHT_MULTI_LINK,
9369+
ies->data, ies->len) {
9370+
const struct ieee80211_multi_link_elem *mle;
9371+
9372+
if (!ieee80211_mle_type_ok(ml->data + 1,
9373+
IEEE80211_ML_CONTROL_TYPE_BASIC,
9374+
ml->datalen - 1))
9375+
continue;
9376+
9377+
mle = (void *)(ml->data + 1);
9378+
if (mle->control & cpu_to_le16(IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP))
9379+
return true;
9380+
}
9381+
9382+
return false;
9383+
9384+
}
9385+
93609386
int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
93619387
struct cfg80211_assoc_request *req)
93629388
{
@@ -9409,7 +9435,17 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
94099435
else
94109436
memcpy(assoc_data->ap_addr, cbss->bssid, ETH_ALEN);
94119437

9412-
assoc_data->ext_mld_capa_ops = cpu_to_le16(req->ext_mld_capa_ops);
9438+
/*
9439+
* Many APs have broken parsing of the extended MLD capa/ops field,
9440+
* dropping (re-)association request frames or replying with association
9441+
* response with a failure status if it's present.
9442+
* Set our value from the userspace request only in strict mode or if
9443+
* the AP also had that field present.
9444+
*/
9445+
if (ieee80211_hw_check(&local->hw, STRICT) ||
9446+
ieee80211_mgd_assoc_bss_has_mld_ext_capa_ops(req))
9447+
assoc_data->ext_mld_capa_ops =
9448+
cpu_to_le16(req->ext_mld_capa_ops);
94139449

94149450
if (ifmgd->associated) {
94159451
u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];

0 commit comments

Comments
 (0)