diff mbox series

[09/16] hostapd: MLO: re-factor nl80211_remove_links() function

Message ID 20240306173947.2611965-10-quic_adisi@quicinc.com
State Accepted
Headers show
Series hostapd: scale up MLO flows | expand

Commit Message

Aditya Kumar Singh March 6, 2024, 5:39 p.m. UTC
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->first_bss.

Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
---
 src/drivers/driver_nl80211.c | 100 ++++++++++++++++++++---------------
 1 file changed, 58 insertions(+), 42 deletions(-)
diff mbox series

Patch

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 856c004b27c2..7fa8a155f74d 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -9421,64 +9421,80 @@  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;
 	struct nl_msg *msg;
+	size_t i;
 	int ret;
-	u8 link_id, i;
 
-	for_each_link(bss->valid_links, link_id) {
-		struct i802_link *link = &bss->links[link_id];
-
-		wpa_printf(MSG_DEBUG, "nl80211: MLD: remove link_id=%u",
-			   link_id);
+	wpa_printf(MSG_DEBUG, "nl80211: Remove link (ifindex=%d)", bss->ifindex);
+	wpa_printf(MSG_DEBUG, "nl80211: MLD: remove link_id=%u", link_id);
 
-		wpa_driver_nl80211_del_beacon(bss, link_id);
+	if (!(bss->valid_links & BIT(link_id))) {
+		wpa_printf(MSG_DEBUG, "nl80211: MLD: remove link: Link not found");
+		return -1;
+	}
 
-		/* First remove the link locally */
-		bss->valid_links &= ~BIT(link_id);
-		os_memset(link->addr, 0, ETH_ALEN);
+	link = &bss->links[link_id];
 
-		/* Choose new deflink if we are removing that link */
-		if (bss->flink == link) {
-			for_each_link_default(bss->valid_links, i, 0) {
-				bss->flink = &bss->links[i];
-				break;
-			}
-		}
+	wpa_driver_nl80211_del_beacon(bss, link_id);
 
-		/* If this was the last link, reset default link */
-		if (!bss->valid_links) {
-			/* TODO: Does keeping freq/bandwidth make sense? */
-			if (bss->flink != link)
-				os_memcpy(bss->flink, link, sizeof(*link));
+	/* First remove the link locally */
+	bss->valid_links &= ~BIT(link_id);
+	os_memset(link->addr, 0, ETH_ALEN);
 
-			os_memcpy(bss->flink->addr, bss->addr, ETH_ALEN);
+	/* Choose new deflink if we are removing that link */
+	if (bss->flink == link) {
+		for_each_link_default(bss->valid_links, i, 0) {
+			bss->flink = &bss->links[i];
+			break;
 		}
+	}
 
-		/* 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);
-			continue;
-		}
+	/* If this was the last link, reset default link */
+	if (!bss->valid_links) {
+		/* TODO: Does keeping freq/bandwidth make sense? */
+		if (bss->flink != link)
+			os_memcpy(bss->flink, link, sizeof(*link));
 
-		ret = send_and_recv_cmd(drv, msg);
-		if (ret) {
-			wpa_printf(MSG_ERROR,
-				   "nl80211: remove link (%d) failed. ret=%d (%s)",
-				   link_id, ret, strerror(-ret));
-			continue;
-		}
+		os_memcpy(bss->flink->addr, bss->addr, ETH_ALEN);
 	}
+
+	/* 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;
+	}
+
+	ret = send_and_recv_cmd(drv, msg);
+	if (ret)
+		wpa_printf(MSG_ERROR,
+			   "nl80211: remove link (%d) failed. ret=%d (%s)",
+			   link_id, ret, strerror(-ret));
+
+	return ret;
 }
 
+static void nl80211_remove_links(struct i802_bss *bss)
+{
+	u8 link_id;
+	int ret;
+
+	for_each_link(bss->valid_links, link_id) {
+		ret = nl80211_remove_link(bss, link_id);
+		if (ret)
+			break;
+	}
+
+	if (bss->flink)
+		os_memcpy(bss->flink->addr, bss->addr, ETH_ALEN);
+}
 
 static int wpa_driver_nl80211_deinit_ap(void *priv)
 {