Currently, when sending a NULL frame to probe a station, the band information is derived from the chanctx_conf in the mac80211 vif's bss_conf. However, for AP MLD, chanctx_conf is not assigned to the vif's bss_conf; instead it is assigned on a per-link basis. As a result, for AP MLD, sending a NULL packet to probe will trigger a warning. WARNING: net/mac80211/cfg.c:4635 at ieee80211_probe_client+0x1a8/0x1d8 [mac80211], CPU#2: hostapd/244 Call trace: ieee80211_probe_client+0x1a8/0x1d8 [mac80211] (P) nl80211_probe_client+0xac/0x170 [cfg80211] genl_family_rcv_msg_doit+0xc8/0x134 genl_rcv_msg+0x200/0x280 netlink_rcv_skb+0x38/0xf0 genl_rcv+0x34/0x48 netlink_unicast+0x314/0x3a0 netlink_sendmsg+0x150/0x390 ____sys_sendmsg+0x1f4/0x21c ___sys_sendmsg+0x98/0xc0 __sys_sendmsg+0x74/0xcc __arm64_sys_sendmsg+0x20/0x34 invoke_syscall.constprop.0+0x4c/0xd0 do_el0_svc+0x3c/0xd0 el0_svc+0x28/0xc0 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, since MLD transmissions does not rely on band. Signed-off-by: Suraj P Kizhakkethil --- net/mac80211/cfg.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 5d04d7d550b0..70a210db16cd 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -4631,12 +4631,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 | -- 2.34.1 Currently, for AP MLD, the link ID is not provided when a NULL packet is triggered to probe a station. For non-MLO stations connected to an AP MLD, use the station's default link to send the NULL packets and set addr2 and addr3 to the link address. For MLO stations, set the link ID to unspecified to let the driver select the appropriate link. Co-developed-by: Sriram R 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 | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 70a210db16cd..36f921fd2176 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -4616,7 +4616,9 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_tx_info *info; struct sta_info *sta; struct ieee80211_chanctx_conf *chanctx_conf; + struct ieee80211_bss_conf *conf; enum nl80211_band band; + u8 link_id = 0; int ret; /* the lock is needed to assign the cookie later */ @@ -4632,6 +4634,23 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, qos = sta->sta.wme; if (ieee80211_vif_is_mld(&sdata->vif)) { + if (sta->sta.mlo) { + link_id = IEEE80211_LINK_UNSPECIFIED; + } else { + /* + * For non-MLO clients connected to an AP MLD, band + * information is not used; instead, sta->deflink is + * used to send packets. + */ + 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 { @@ -4668,8 +4687,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); @@ -4678,6 +4702,8 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, IEEE80211_TX_INTFL_NL80211_FRAME_TX; info->band = band; + info->control.flags |= u32_encode_bits(link_id, + IEEE80211_TX_CTRL_MLO_LINK); skb_set_queue_mapping(skb, IEEE80211_AC_VO); skb->priority = 7; if (qos) -- 2.34.1