Files
wlan-ap/feeds/qca-wifi-7/hostapd/patches/r00-007-hostapd-re-factor-nl80211_remove_links-function.patch
John Crispin 68cf54d9f7 qca-wifi-7: update to ath12.5.5
Signed-off-by: John Crispin <john@phrozen.org>
2025-02-27 12:45:52 +01:00

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);
}