blob: ce4a844155967300a777391915f67c336cc3d87c [file] [log] [blame]
developer66e89bc2024-04-23 14:50:01 +08001From 8ac142806112477fa012414a2bdea22239e474a4 Mon Sep 17 00:00:00 2001
2From: Aditya Kumar Singh <quic_adisi@quicinc.com>
3Date: Thu, 28 Mar 2024 23:46:48 +0530
4Subject: [PATCH 018/104] hostapd: MLO: send link id during flushing stations
5
6Currently, whenever a BSS is set up, it sends flush all stations via
7command - NL80211_CMD_DEL_STATION on its interface. However, in case
8of MLO, station could have been connected to other links by the time
9this link is coming up. Since there is no link id currently being
10passed, all those stations entries are also removed in the driver which is
11wrong.
12
13Hence add change to send link id along with the command during MLO so that
14the driver can use this link id and flush only those stations which are
15using the passed link id as one of its links.
16
17Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
18---
19 src/ap/ap_drv_ops.c | 10 +++++++++-
20 src/drivers/driver.h | 4 +++-
21 src/drivers/driver_atheros.c | 2 +-
22 src/drivers/driver_bsd.c | 2 +-
23 src/drivers/driver_hostap.c | 2 +-
24 src/drivers/driver_nl80211.c | 17 ++++++++++++++---
25 6 files changed, 29 insertions(+), 8 deletions(-)
26
27diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
28index 0d493b837..32722084d 100644
29--- a/src/ap/ap_drv_ops.c
30+++ b/src/ap/ap_drv_ops.c
31@@ -624,9 +624,17 @@ int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
32
33 int hostapd_flush(struct hostapd_data *hapd)
34 {
35+ int link_id = -1;
36+
37 if (hapd->driver == NULL || hapd->driver->flush == NULL)
38 return 0;
39- return hapd->driver->flush(hapd->drv_priv);
40+
41+#ifdef CONFIG_IEEE80211BE
42+ if (hapd->conf && hapd->conf->mld_ap)
43+ link_id = hapd->mld_link_id;
44+#endif /* CONFIG_IEEE80211BE */
45+
46+ return hapd->driver->flush(hapd->drv_priv, link_id);
47 }
48
49
50diff --git a/src/drivers/driver.h b/src/drivers/driver.h
51index a7455ef6e..e672a1787 100644
52--- a/src/drivers/driver.h
53+++ b/src/drivers/driver.h
54@@ -3578,13 +3578,15 @@ struct wpa_driver_ops {
55 /**
56 * flush - Flush all association stations (AP only)
57 * @priv: Private driver interface data
58+ * @link_id: In case of MLO, valid link_id on which all associated stations
59+ * will be flushed. -1 otherwise.
60 * Returns: 0 on success, -1 on failure
61 *
62 * This function requests the driver to disassociate all associated
63 * stations. This function does not need to be implemented if the
64 * driver does not process association frames internally.
65 */
66- int (*flush)(void *priv);
67+ int (*flush)(void *priv, int link_id);
68
69 /**
70 * set_generic_elem - Add IEs into Beacon/Probe Response frames (AP)
71diff --git a/src/drivers/driver_atheros.c b/src/drivers/driver_atheros.c
72index ae7f0e535..71863306a 100644
73--- a/src/drivers/driver_atheros.c
74+++ b/src/drivers/driver_atheros.c
75@@ -632,7 +632,7 @@ atheros_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
76
77
78 static int
79-atheros_flush(void *priv)
80+atheros_flush(void *priv, int link_id)
81 {
82 u8 allsta[IEEE80211_ADDR_LEN];
83 os_memset(allsta, 0xff, IEEE80211_ADDR_LEN);
84diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c
85index 850637f0d..82d8a0186 100644
86--- a/src/drivers/driver_bsd.c
87+++ b/src/drivers/driver_bsd.c
88@@ -946,7 +946,7 @@ bsd_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
89
90
91 static int
92-bsd_flush(void *priv)
93+bsd_flush(void *priv, int link_id)
94 {
95 u8 allsta[IEEE80211_ADDR_LEN];
96
97diff --git a/src/drivers/driver_hostap.c b/src/drivers/driver_hostap.c
98index d3520aacc..3aa5860bc 100644
99--- a/src/drivers/driver_hostap.c
100+++ b/src/drivers/driver_hostap.c
101@@ -572,7 +572,7 @@ static int hostap_set_ssid(void *priv, const u8 *buf, int len)
102 }
103
104
105-static int hostap_flush(void *priv)
106+static int hostap_flush(void *priv, int link_id)
107 {
108 struct hostap_driver_data *drv = priv;
109 struct prism2_hostapd_param param;
110diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
111index e5fa22b59..9ac621ae6 100644
112--- a/src/drivers/driver_nl80211.c
113+++ b/src/drivers/driver_nl80211.c
114@@ -7729,25 +7729,36 @@ static int i802_set_frag(void *priv, int frag)
115 }
116
117
118-static int i802_flush(void *priv)
119+static int i802_flush(void *priv, int link_id)
120 {
121 struct i802_bss *bss = priv;
122 struct nl_msg *msg;
123 int res;
124
125- wpa_printf(MSG_DEBUG, "nl80211: flush -> DEL_STATION %s (all)",
126- bss->ifname);
127+ if (link_id == NL80211_DRV_LINK_ID_NA)
128+ wpa_printf(MSG_DEBUG, "nl80211: flush -> DEL_STATION %s (all)",
129+ bss->ifname);
130+ else
131+ wpa_printf(MSG_DEBUG, "nl80211: flush -> DEL_STATION %s (with link %d)",
132+ bss->ifname, link_id);
133
134 /*
135 * XXX: FIX! this needs to flush all VLANs too
136 */
137 msg = nl80211_bss_msg(bss, 0, NL80211_CMD_DEL_STATION);
138+ if (link_id >= 0 && (bss->valid_links & BIT(link_id)) &&
139+ nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id))
140+ goto fail;
141+
142 res = send_and_recv_cmd(bss->drv, msg);
143 if (res) {
144 wpa_printf(MSG_DEBUG, "nl80211: Station flush failed: ret=%d "
145 "(%s)", res, strerror(-res));
146 }
147 return res;
148+fail:
149+ nlmsg_free(msg);
150+ return -1;
151 }
152
153
154--
1552.39.2
156