]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AP MLD: Link-specific flushing of stations
authorAditya Kumar Singh <quic_adisi@quicinc.com>
Thu, 28 Mar 2024 18:16:48 +0000 (23:46 +0530)
committerJouni Malinen <j@w1.fi>
Sat, 20 Apr 2024 15:31:11 +0000 (18:31 +0300)
Whenever a BSS was set up,hostapd flushed all stations via the flush()
driver operation which maps to NL80211_CMD_DEL_STATION in the nl80211
interface. However, in case of MLO, a station could have been connected
to other links by the time this link is coming up. Since link ID was not
passed to flush(), all those stations entries were also removed in the
driver which is wrong.

Include the link ID along with the command in AP MLD so that the driver
can use this link ID and flush only the stations that use the passed
link ID as one of their links.

Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.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 d09d678ef672a15020b639dc7ee077d9eedf1c55..c47349110e5f27613adf6ed1655a37097ac37d9a 100644 (file)
@@ -627,9 +627,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);
 }
 
 
index 628b7f181c98f4b1467217fd72c60bd468398045..52632154ee4b512e368c97e5ce495b3125bce55c 100644 (file)
@@ -3588,13 +3588,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)
index ae7f0e535c67dc152b66096fa51ca2168707a8fb..71863306afadd88243024e101c7219eab5a805f7 100644 (file)
@@ -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);
index 850637f0db2e012d2633b1a2d80941e84aa385a3..82d8a0186c57615b5f460fd31f690523542a182f 100644 (file)
@@ -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];
 
index d3520aacc9883d46f2cf9ff656f3a2f86d62b6eb..3aa5860bc433eacaccd002bcc549e09ec924ff96 100644 (file)
@@ -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;
index bf38eea68a5e56ccbce33709b679f78f63a017c0..c6af0f02f619eba3adcaa37a697e8d46c237bde1 100644 (file)
@@ -7724,25 +7724,37 @@ 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;
 }