From 452df4b6cfcf8079308d11a089e0a104b580245f Mon Sep 17 00:00:00 2001 From: Thomas Wu Date: Wed, 31 Jan 2024 20:02:54 -0800 Subject: [PATCH] hostapd: Correct link handling for MLO Disassociation When generating disassociate packet, mlo_link_id was not considered. A default value of -1 is an invalid link_id for driver and will cause driver to assume a non-existing link. Signed-off-by: Thomas Wu --- src/ap/ap_drv_ops.c | 9 ++++++++- src/drivers/driver.h | 3 ++- src/drivers/driver_atheros.c | 2 +- src/drivers/driver_bsd.c | 4 ++-- src/drivers/driver_hostap.c | 2 +- src/drivers/driver_nl80211.c | 8 ++++---- 6 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c index e24df69..66c4e64 100644 --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -923,10 +923,17 @@ int hostapd_drv_sta_deauth(struct hostapd_data *hapd, int hostapd_drv_sta_disassoc(struct hostapd_data *hapd, const u8 *addr, int reason) { + int link_id = -1; + +#ifdef CONFIG_IEEE80211BE + if (hapd->conf->mld_ap) + 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, hapd->own_addr, addr, - reason); + reason, link_id); } diff --git a/src/drivers/driver.h b/src/drivers/driver.h index e1561bc..7b2bc84 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -3777,13 +3777,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 133cf36..9e6bc87 100644 --- a/src/drivers/driver_atheros.c +++ b/src/drivers/driver_atheros.c @@ -780,7 +780,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 e841988..44376fa 100644 --- a/src/drivers/driver_bsd.c +++ b/src/drivers/driver_bsd.c @@ -983,8 +983,8 @@ 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) +bsd_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, 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 8b85622..f9db9f2 100644 --- a/src/drivers/driver_hostap.c +++ b/src/drivers/driver_hostap.c @@ -1080,7 +1080,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 a4b2698..4c9ca58 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -199,7 +199,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); static void nl80211_remove_links(struct i802_bss *bss); @@ -8385,7 +8385,7 @@ 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)) @@ -8409,7 +8409,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; @@ -8431,7 +8431,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); } -- 2.25.1