]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AP MLD: Correct link handling for MLO Disassociation
authorManish Dharanenthiran <manish.dharanenthiran@oss.qualcomm.com>
Thu, 29 May 2025 18:07:02 +0000 (23:37 +0530)
committerJouni Malinen <j@w1.fi>
Tue, 3 Jun 2025 15:22:08 +0000 (18:22 +0300)
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 <manish.dharanenthiran@oss.qualcomm.com>
src/ap/ap_drv_ops.c
src/drivers/driver.h
src/drivers/driver_atheros.c
src/drivers/driver_bsd.c
src/drivers/driver_hostap.c
src/drivers/driver_nl80211.c

index b2e930de97cfc6b0d0e0bd8534c0959654c410b2..0bcc83d8b72ff32fe491af09c9e3b7bd9b1fd257 100644 (file)
@@ -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);
 }
 
 
index 56d99f2a13ecf576498b8d763442fa204d96900c..02f8ce458af08eb64acedbb989bc0c8b9bfed392 100644 (file)
@@ -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)
index 8fb23a8026a6b414fa4c81ce60e7ed6e272bd407..94db413eb62dc5a6cfc0bcdf012ace09c25f1ee3 100644 (file)
@@ -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;
index 66155b41c051e67edada34ff21d38e95c399eee5..8e4c0390fd8e07ad02da9eb0ff5789d3546344a6 100644 (file)
@@ -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);
index 74c7767babdc8738ddd53d3b3c8667a7fe44fde7..e2c6c198c8fdc5af339093720874235c344c6598 100644 (file)
@@ -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;
index 68ff649410ac07a0f373dbd3251b70b869f1bb26..7e876dcf80717f7d3cff3efd39825f0c7fc98d0d 100644 (file)
@@ -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);
 }