mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-11-02 11:27:48 +00:00
159 lines
4.5 KiB
Diff
159 lines
4.5 KiB
Diff
From a42135dfd6e0292330c20aa5e6dd8477582bed9d Mon Sep 17 00:00:00 2001
|
|
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
|
Date: Wed, 18 Oct 2023 14:34:07 +0530
|
|
Subject: [PATCH 1/4] hostapd: re-factor nl80211_remove_links() function
|
|
|
|
Currently, nl80211_remove_links() iterates over all active links in the
|
|
given BSS and remove all of them. However, at times it is required to
|
|
remove only one link and not all links.
|
|
|
|
Hence, add a helper function nl80211_remove_link() which will remove just
|
|
the given link_id from the passed BSS. nl80211_remove_links() will use this
|
|
and will call this for each of the active link to be removed.
|
|
|
|
While at it, also make the NL remove link command to be formed per bss
|
|
instead of per drv since the command is expected to be per interface and
|
|
not per wiphy.
|
|
|
|
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
|
---
|
|
src/drivers/driver_nl80211.c | 108 +++++++++++++++++++++++------------
|
|
1 file changed, 70 insertions(+), 38 deletions(-)
|
|
|
|
--- a/src/drivers/driver_nl80211.c
|
|
+++ b/src/drivers/driver_nl80211.c
|
|
@@ -9331,57 +9331,89 @@ fail:
|
|
return -1;
|
|
}
|
|
|
|
-
|
|
-static void nl80211_remove_links(struct i802_bss *bss)
|
|
+static int nl80211_remove_link(struct i802_bss *bss, int link_id)
|
|
{
|
|
struct wpa_driver_nl80211_data *drv = bss->drv;
|
|
+ struct i802_link *link = NULL;
|
|
struct nl_msg *msg;
|
|
- int ret;
|
|
- u8 link_id;
|
|
+ int i, ret;
|
|
+
|
|
+ wpa_printf(MSG_DEBUG, "nl80211: Remove link (ifindex=%d)", bss->ifindex);
|
|
+ wpa_printf(MSG_DEBUG, "nl80211: MLD: remove link_id=%u", link_id);
|
|
+
|
|
+ for (i = 0; i < bss->n_links; i++) {
|
|
+ if (bss->links[i].link_id != link_id)
|
|
+ continue;
|
|
+
|
|
+ link = &bss->links[i];
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (!link) {
|
|
+ wpa_printf(MSG_DEBUG, "nl80211: MLD: remove link: Link not found");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /* Already removed */
|
|
+ if (link->link_id == NL80211_DRV_LINK_ID_NA) {
|
|
+ wpa_printf(MSG_DEBUG, "nl80211: MLD: remove link_id=%u, already removed", link_id);
|
|
+ return 0;
|
|
+ }
|
|
|
|
- while (bss->links[0].link_id != NL80211_DRV_LINK_ID_NA) {
|
|
- struct i802_link *link = &bss->links[0];
|
|
+ /* First remove the link locally. In order to remove a link[i] from links[],
|
|
+ * shift left next all links[j] where j >= i + 1 to max size
|
|
+ */
|
|
+ for (; i < bss->n_links - 1; i++)
|
|
+ os_memcpy(&bss->links[i], &bss->links[i + 1], sizeof(*link));
|
|
+
|
|
+ /* the last element can be memset back to initial values */
|
|
+ os_memset(&bss->links[bss->n_links - 1], 0, sizeof(*link));
|
|
+ bss->links[bss->n_links - 1].link_id = -1;
|
|
+
|
|
+ bss->flink = &bss->links[0];
|
|
+
|
|
+ if (bss->n_links > 1)
|
|
+ bss->n_links--;
|
|
+
|
|
+ /* Remove the link from the kernel */
|
|
+ msg = nl80211_bss_msg(bss, 0, NL80211_CMD_REMOVE_LINK);
|
|
+ if (!msg ||
|
|
+ nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id)) {
|
|
+ nlmsg_free(msg);
|
|
+ wpa_printf(MSG_ERROR,
|
|
+ "nl80211: remove link (%d) failed",
|
|
+ link_id);
|
|
+ return -1;
|
|
+ }
|
|
|
|
- wpa_printf(MSG_DEBUG, "nl80211: MLD: remove link_id=%u",
|
|
- link->link_id);
|
|
+ ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
|
|
+ if (ret)
|
|
+ wpa_printf(MSG_ERROR,
|
|
+ "nl80211: remove link (%d) failed. ret=%d (%s)",
|
|
+ link_id, ret, strerror(-ret));
|
|
|
|
- wpa_driver_nl80211_del_beacon(bss, link);
|
|
-
|
|
- link_id = link->link_id;
|
|
-
|
|
- /* First remove the link locally */
|
|
- if (bss->n_links == 1) {
|
|
- bss->flink->link_id = NL80211_DRV_LINK_ID_NA;
|
|
- os_memcpy(bss->flink->addr, bss->addr, ETH_ALEN);
|
|
- } else {
|
|
- struct i802_link *other = &bss->links[bss->n_links - 1];
|
|
-
|
|
- os_memcpy(link, other, sizeof(*link));
|
|
- other->link_id = NL80211_DRV_LINK_ID_NA;
|
|
- os_memset(other->addr, 0, ETH_ALEN);
|
|
-
|
|
- bss->n_links--;
|
|
- }
|
|
-
|
|
- /* Remove the link from the kernel */
|
|
- msg = nl80211_drv_msg(drv, 0, NL80211_CMD_REMOVE_LINK);
|
|
- if (!msg ||
|
|
- nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id)) {
|
|
- nlmsg_free(msg);
|
|
- wpa_printf(MSG_ERROR,
|
|
- "nl80211: remove link (%d) failed",
|
|
- link_id);
|
|
- return;
|
|
- }
|
|
-
|
|
- ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
|
|
- if (ret) {
|
|
- wpa_printf(MSG_ERROR,
|
|
- "nl80211: remove link (%d) failed. ret=%d (%s)",
|
|
- link_id, ret, strerror(-ret));
|
|
- return;
|
|
- }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static void nl80211_remove_links(struct i802_bss *bss)
|
|
+{
|
|
+ int ret, i;
|
|
+
|
|
+ for (i = bss->n_links - 1; i >= 0; i--) {
|
|
+ if (bss->links[i].link_id == NL80211_DRV_LINK_ID_NA)
|
|
+ continue;
|
|
+
|
|
+ ret = nl80211_remove_link(bss, bss->links[i].link_id);
|
|
+ if (ret)
|
|
+ break;
|
|
}
|
|
+
|
|
+ if (bss->flink)
|
|
+ os_memcpy(bss->flink->addr, bss->addr, ETH_ALEN);
|
|
+
|
|
+ if (i >= 0)
|
|
+ wpa_printf(MSG_DEBUG, "nl80211: failed to remove links, ret=%d",
|
|
+ ret);
|
|
}
|
|
|
|
|