@@ -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);
}
@@ -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)
@@ -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);
@@ -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];
@@ -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;
@@ -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;
}
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(-)