From: Manish Dharanenthiran Date: Thu, 29 May 2025 18:07:02 +0000 (+0530) Subject: AP MLD: Correct link handling for MLO Disassociation X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=12960fc6819f56eb38f7b693a5a2c5dffb9f78c8;p=thirdparty%2Fhostap.git AP MLD: Correct link handling for MLO Disassociation When transmitting a Disassociation frame, MLD link_id was not considered, default value of -1 sent. Because of this, the first link was always used to send Disassociation frames. Address this by sending the corressponding 'mld_link_id' to the driver if the Disassociation frame is sent by an AP MLD. Signed-off-by: Manish Dharanenthiran --- diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c index b2e930de9..0bcc83d8b 100644 --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -924,20 +924,23 @@ int hostapd_drv_sta_disassoc(struct hostapd_data *hapd, const u8 *addr, int reason) { const u8 *own_addr = hapd->own_addr; + int link_id = -1; #ifdef CONFIG_IEEE80211BE if (hapd->conf->mld_ap) { struct sta_info *sta = ap_get_sta(hapd, addr); - if (ap_sta_is_mld(hapd, sta)) + if (ap_sta_is_mld(hapd, sta)) { own_addr = hapd->mld->mld_addr; + link_id = hapd->mld_link_id; + } } #endif /* CONFIG_IEEE80211BE */ if (!hapd->driver || !hapd->driver->sta_disassoc || !hapd->drv_priv) return 0; return hapd->driver->sta_disassoc(hapd->drv_priv, own_addr, addr, - reason); + reason, link_id); } diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 56d99f2a1..02f8ce458 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -3863,13 +3863,14 @@ struct wpa_driver_ops { * @own_addr: Source address and BSSID for the Disassociation frame * @addr: MAC address of the station to disassociate * @reason: Reason code for the Disassociation frame + * @link_id: Link ID to use for Disassociation frame, or -1 if not set * Returns: 0 on success, -1 on failure * * This function requests a specific station to be disassociated and * a Disassociation frame to be sent to it. */ int (*sta_disassoc)(void *priv, const u8 *own_addr, const u8 *addr, - u16 reason); + u16 reason, int link_id); /** * sta_remove - Remove a station entry (AP only) diff --git a/src/drivers/driver_atheros.c b/src/drivers/driver_atheros.c index 8fb23a802..94db413eb 100644 --- a/src/drivers/driver_atheros.c +++ b/src/drivers/driver_atheros.c @@ -783,7 +783,7 @@ atheros_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, static int atheros_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, - u16 reason_code) + u16 reason_code, int link_id) { struct atheros_driver_data *drv = priv; struct ieee80211req_mlme mlme; diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c index 66155b41c..8e4c0390f 100644 --- a/src/drivers/driver_bsd.c +++ b/src/drivers/driver_bsd.c @@ -987,7 +987,7 @@ bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, u16 reason_code, static int bsd_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, - u16 reason_code) + u16 reason_code, int link_id) { return bsd_send_mlme_param(priv, IEEE80211_MLME_DISASSOC, reason_code, addr); diff --git a/src/drivers/driver_hostap.c b/src/drivers/driver_hostap.c index 74c7767ba..e2c6c198c 100644 --- a/src/drivers/driver_hostap.c +++ b/src/drivers/driver_hostap.c @@ -1083,7 +1083,7 @@ static int hostap_set_freq(void *priv, struct hostapd_freq_params *freq) static int hostap_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, - u16 reason) + u16 reason, int link_id) { struct hostap_driver_data *drv = priv; struct ieee80211_mgmt mgmt; diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 68ff64941..7e876dcf8 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -201,7 +201,7 @@ static int nl80211_put_mesh_config(struct nl_msg *msg, struct wpa_driver_mesh_bss_params *params); #endif /* CONFIG_MESH */ static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, - u16 reason); + u16 reason, int link_id); /* Converts nl80211_chan_width to a common format */ @@ -8495,7 +8495,8 @@ static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, HOSTAPD_MODE_IEEE80211AD) { /* Deauthentication is not used in DMG/IEEE 802.11ad; * disassociate the STA instead. */ - return i802_sta_disassoc(priv, own_addr, addr, reason); + return i802_sta_disassoc(priv, own_addr, addr, reason, + link_id); } if (is_mesh_interface(drv->nlmode)) @@ -8519,7 +8520,7 @@ static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, - u16 reason) + u16 reason, int link_id) { struct i802_bss *bss = priv; struct wpa_driver_nl80211_data *drv = bss->drv; @@ -8541,7 +8542,7 @@ static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt, IEEE80211_HDRLEN + sizeof(mgmt.u.disassoc), 0, 0, 0, 0, - 0, NULL, 0, 0, -1); + 0, NULL, 0, 0, link_id); }