blob: ce4a844155967300a777391915f67c336cc3d87c [file] [log] [blame]
From 8ac142806112477fa012414a2bdea22239e474a4 Mon Sep 17 00:00:00 2001
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
Date: Thu, 28 Mar 2024 23:46:48 +0530
Subject: [PATCH 018/104] hostapd: MLO: send link id during flushing stations
Currently, whenever a BSS is set up, it sends flush all stations via
command - NL80211_CMD_DEL_STATION on its interface. However, in case
of MLO, station could have been connected to other links by the time
this link is coming up. Since there is no link id currently being
passed, all those stations entries are also removed in the driver which is
wrong.
Hence add change to send link id along with the command during MLO so that
the driver can use this link id and flush only those stations which are
using the passed link id as one of its links.
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
---
src/ap/ap_drv_ops.c | 10 +++++++++-
src/drivers/driver.h | 4 +++-
src/drivers/driver_atheros.c | 2 +-
src/drivers/driver_bsd.c | 2 +-
src/drivers/driver_hostap.c | 2 +-
src/drivers/driver_nl80211.c | 17 ++++++++++++++---
6 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
index 0d493b837..32722084d 100644
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -624,9 +624,17 @@ int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
int hostapd_flush(struct hostapd_data *hapd)
{
+ int link_id = -1;
+
if (hapd->driver == NULL || hapd->driver->flush == NULL)
return 0;
- return hapd->driver->flush(hapd->drv_priv);
+
+#ifdef CONFIG_IEEE80211BE
+ if (hapd->conf && hapd->conf->mld_ap)
+ link_id = hapd->mld_link_id;
+#endif /* CONFIG_IEEE80211BE */
+
+ return hapd->driver->flush(hapd->drv_priv, link_id);
}
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index a7455ef6e..e672a1787 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -3578,13 +3578,15 @@ struct wpa_driver_ops {
/**
* flush - Flush all association stations (AP only)
* @priv: Private driver interface data
+ * @link_id: In case of MLO, valid link_id on which all associated stations
+ * will be flushed. -1 otherwise.
* Returns: 0 on success, -1 on failure
*
* This function requests the driver to disassociate all associated
* stations. This function does not need to be implemented if the
* driver does not process association frames internally.
*/
- int (*flush)(void *priv);
+ int (*flush)(void *priv, int link_id);
/**
* set_generic_elem - Add IEs into Beacon/Probe Response frames (AP)
diff --git a/src/drivers/driver_atheros.c b/src/drivers/driver_atheros.c
index ae7f0e535..71863306a 100644
--- a/src/drivers/driver_atheros.c
+++ b/src/drivers/driver_atheros.c
@@ -632,7 +632,7 @@ atheros_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
static int
-atheros_flush(void *priv)
+atheros_flush(void *priv, int link_id)
{
u8 allsta[IEEE80211_ADDR_LEN];
os_memset(allsta, 0xff, IEEE80211_ADDR_LEN);
diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c
index 850637f0d..82d8a0186 100644
--- a/src/drivers/driver_bsd.c
+++ b/src/drivers/driver_bsd.c
@@ -946,7 +946,7 @@ bsd_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
static int
-bsd_flush(void *priv)
+bsd_flush(void *priv, int link_id)
{
u8 allsta[IEEE80211_ADDR_LEN];
diff --git a/src/drivers/driver_hostap.c b/src/drivers/driver_hostap.c
index d3520aacc..3aa5860bc 100644
--- a/src/drivers/driver_hostap.c
+++ b/src/drivers/driver_hostap.c
@@ -572,7 +572,7 @@ static int hostap_set_ssid(void *priv, const u8 *buf, int len)
}
-static int hostap_flush(void *priv)
+static int hostap_flush(void *priv, int link_id)
{
struct hostap_driver_data *drv = priv;
struct prism2_hostapd_param param;
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index e5fa22b59..9ac621ae6 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -7729,25 +7729,36 @@ static int i802_set_frag(void *priv, int frag)
}
-static int i802_flush(void *priv)
+static int i802_flush(void *priv, int link_id)
{
struct i802_bss *bss = priv;
struct nl_msg *msg;
int res;
- wpa_printf(MSG_DEBUG, "nl80211: flush -> DEL_STATION %s (all)",
- bss->ifname);
+ if (link_id == NL80211_DRV_LINK_ID_NA)
+ wpa_printf(MSG_DEBUG, "nl80211: flush -> DEL_STATION %s (all)",
+ bss->ifname);
+ else
+ wpa_printf(MSG_DEBUG, "nl80211: flush -> DEL_STATION %s (with link %d)",
+ bss->ifname, link_id);
/*
* XXX: FIX! this needs to flush all VLANs too
*/
msg = nl80211_bss_msg(bss, 0, NL80211_CMD_DEL_STATION);
+ if (link_id >= 0 && (bss->valid_links & BIT(link_id)) &&
+ nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id))
+ goto fail;
+
res = send_and_recv_cmd(bss->drv, msg);
if (res) {
wpa_printf(MSG_DEBUG, "nl80211: Station flush failed: ret=%d "
"(%s)", res, strerror(-res));
}
return res;
+fail:
+ nlmsg_free(msg);
+ return -1;
}
--
2.39.2