Currently, when sending a NULL packet to probe a station, the band information is derived from the chanctx_conf in the mac80211 vif's bss_conf. However, for MLO, chanctx_conf is not assigned to the vif's bss_conf; instead it is assigned on a per-link basis. As a result, for MLO, sending a NULL packet to probe will trigger a warning. WARNING: net/mac80211/cfg.c:4593 at ieee80211_probe_client+0x1a8/0x1e0 [mac80211], CPU#2: hostapd/241 Call trace: ieee80211_probe_client+0x1a8/0x1e0 [mac80211] (P) nl80211_probe_client+0xac/0x170 [cfg80211] genl_family_rcv_msg_doit+0xc8/0x134 genl_rcv_msg+0x200/0x280 netlink_rcv_skb+0x38/0xfc genl_rcv+0x34/0x48 netlink_unicast+0x228/0x334 netlink_sendmsg+0x158/0x364 ____sys_sendmsg+0x1f4/0x21c ___sys_sendmsg+0x98/0xc0 __sys_sendmsg+0x74/0xd0 __arm64_sys_sendmsg+0x20/0x28 invoke_syscall.constprop.0+0x4c/0xd0 do_el0_svc+0x3c/0xd0 el0_svc+0x28/0xb8 el0t_64_sync_handler+0x98/0xdc el0t_64_sync+0x154/0x158 ---[ end trace 0000000000000000 ]--- For NULL packets sent to probe stations, set the band information only for non-MLD case, since MLD transmissions does not rely on band. For MLD connections, set the link ID as unspecified to allow the driver to select the appropriate link. The case specific to non-MLO stations connected to an MLD AP will be addressed in a follow up patch. Signed-off-by: Suraj P Kizhakkethil --- net/mac80211/cfg.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index b51c2c8584ae..9554b25b8fc6 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -4609,12 +4609,17 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, qos = sta->sta.wme; - chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); - if (WARN_ON(!chanctx_conf)) { - ret = -EINVAL; - goto unlock; + if (ieee80211_vif_is_mld(&sdata->vif)) { + /* MLD transmissions must not rely on the band */ + band = 0; + } else { + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); + if (WARN_ON(!chanctx_conf)) { + ret = -EINVAL; + goto unlock; + } + band = chanctx_conf->def.chan->band; } - band = chanctx_conf->def.chan->band; if (qos) { fc = cpu_to_le16(IEEE80211_FTYPE_DATA | @@ -4651,6 +4656,9 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, IEEE80211_TX_INTFL_NL80211_FRAME_TX; info->band = band; + if (ieee80211_vif_is_mld(&sdata->vif)) + info->control.flags |= IEEE80211_TX_CTRL_MLO_LINK_UNSPEC; + skb_set_queue_mapping(skb, IEEE80211_AC_VO); skb->priority = 7; if (qos) -- 2.34.1 Currently, for non-MLO stations connected to an MLD AP, addr2 and addr3 are set to the MLD address when a NULL packet is triggered to probe the station, which is incorrect. Set addr2 and addr3 to the link address for the NULL packets sent to probe non-MLO stations. Signed-off-by: Sriram R Co-developed-by: Rameshkumar Sundaram Signed-off-by: Rameshkumar Sundaram Signed-off-by: Suraj P Kizhakkethil --- net/mac80211/cfg.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 9554b25b8fc6..dc31b1b1ba95 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -4595,6 +4595,8 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, struct sta_info *sta; struct ieee80211_chanctx_conf *chanctx_conf; enum nl80211_band band; + u8 link_id; + struct ieee80211_bss_conf *conf; int ret; /* the lock is needed to assign the cookie later */ @@ -4610,6 +4612,21 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, qos = sta->sta.wme; if (ieee80211_vif_is_mld(&sdata->vif)) { + /* + * For non-MLO clients connected to an MLD AP, band + * information is not used; instead, sta->deflink is + * used to send packets. + */ + if (!sta->sta.mlo) { + link_id = sta->deflink.link_id; + + conf = rcu_dereference(sdata->vif.link_conf[link_id]); + + if (unlikely(!conf)) { + ret = -ENOLINK; + goto unlock; + } + } /* MLD transmissions must not rely on the band */ band = 0; } else { @@ -4646,8 +4663,13 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, nullfunc->frame_control = fc; nullfunc->duration_id = 0; memcpy(nullfunc->addr1, sta->sta.addr, ETH_ALEN); - memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN); - memcpy(nullfunc->addr3, sdata->vif.addr, ETH_ALEN); + if (ieee80211_vif_is_mld(&sdata->vif) && !sta->sta.mlo) { + memcpy(nullfunc->addr2, conf->addr, ETH_ALEN); + memcpy(nullfunc->addr3, conf->addr, ETH_ALEN); + } else { + memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN); + memcpy(nullfunc->addr3, sdata->vif.addr, ETH_ALEN); + } nullfunc->seq_ctrl = 0; info = IEEE80211_SKB_CB(skb); @@ -4656,8 +4678,15 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, IEEE80211_TX_INTFL_NL80211_FRAME_TX; info->band = band; - if (ieee80211_vif_is_mld(&sdata->vif)) - info->control.flags |= IEEE80211_TX_CTRL_MLO_LINK_UNSPEC; + if (ieee80211_vif_is_mld(&sdata->vif)) { + if (sta->sta.mlo) + info->control.flags |= + IEEE80211_TX_CTRL_MLO_LINK_UNSPEC; + else + info->control.flags |= + u32_encode_bits(link_id, + IEEE80211_TX_CTRL_MLO_LINK); + } skb_set_queue_mapping(skb, IEEE80211_AC_VO); skb->priority = 7; -- 2.34.1