mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-21 11:22:50 +00:00
Some checks failed
Build OpenWrt/uCentral images / build (cig_wf186h) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf186w) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf188n) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf189) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf196) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cybertan_eww631-a1) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cybertan_eww631-b1) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap101) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap102) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap104) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap105) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap111) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap112) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101-6e) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101e) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101e-6e) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x_2) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x_3) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x_w) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4xe) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4xi) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4xi_w) (push) Has been cancelled
Build OpenWrt/uCentral images / build (indio_um-305ax) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sercomm_ap72tip) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sonicfi_rap630c-311g) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sonicfi_rap630w-211g) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sonicfi_rap630w-311g) (push) Has been cancelled
Build OpenWrt/uCentral images / build (udaya_a6-id2) (push) Has been cancelled
Build OpenWrt/uCentral images / build (udaya_a6-od2) (push) Has been cancelled
Build OpenWrt/uCentral images / build (wallys_dr5018) (push) Has been cancelled
Build OpenWrt/uCentral images / build (wallys_dr6018) (push) Has been cancelled
Build OpenWrt/uCentral images / build (wallys_dr6018-v4) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_ax820) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_ax840) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_fap640) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_fap650) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_fap655) (push) Has been cancelled
Build OpenWrt/uCentral images / trigger-testing (push) Has been cancelled
Build OpenWrt/uCentral images / create-x64_vm-ami (push) Has been cancelled
Signed-off-by: John Crispin <john@phrozen.org>
272 lines
7.5 KiB
Diff
272 lines
7.5 KiB
Diff
From 7537683c937418ec03f2f622445b09b23898d0f1 Mon Sep 17 00:00:00 2001
|
|
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
|
Date: Fri, 29 Dec 2023 12:08:13 +0530
|
|
Subject: [PATCH] hostapd: clean up MLD when not required any further
|
|
|
|
Currently, whenever a new BSS is created, if it is an EHT then it is tied
|
|
to a corresponding MLD structure. If structure does not exist already, a
|
|
new one is created and tied to it. Accordingly link ID is assigned as well.
|
|
However, when BSS is deleted, the MLD structure is not freed and when the
|
|
next time it is again created, it increments the link ID further and gets a
|
|
wrong link ID.
|
|
|
|
For example - 2 GHz SLO AP case.
|
|
First Wifi, link ID 0 would be assigned and mld wlan0 would be created.
|
|
When wifi down is issued, BSS would be deleted but mld wlan0 will not. When
|
|
again wifi is issued, BSS will tie back to mld wlan0 but this time link ID
|
|
will be incremented again and 1 would be assigned. Hence at subsequent wifi
|
|
down/up, link ID keeps on incrementing.
|
|
|
|
Since link ID remains till lifetime of the BSS and MLD, the next link ID
|
|
counter can not be just reset back to 0 when a BSS is deleted. Otherwise,
|
|
in interleaved link enable/disable case, link ID would be changed.
|
|
|
|
Hence to overcome this situation, add changes so that whenever a BSS is
|
|
deleted, if the MLD is not referenced by any other existing BSS, delete the
|
|
MLD structure itself.
|
|
|
|
In order to know how many BSSes are referring a given MLD, introduce a new
|
|
member refcount in MLD. If he value is 0 then it is safe to delete the MLD.
|
|
|
|
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
|
---
|
|
src/ap/hostapd.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++
|
|
src/ap/hostapd.h | 2 +
|
|
2 files changed, 130 insertions(+)
|
|
|
|
--- a/src/ap/hostapd.c
|
|
+++ b/src/ap/hostapd.c
|
|
@@ -75,6 +75,11 @@ static void hostapd_switch_color_timeout
|
|
static void hostapd_interface_update_fils_ubpr(struct hostapd_iface *iface,
|
|
bool iface_enabled);
|
|
|
|
+#ifdef CONFIG_IEEE80211BE
|
|
+static void hostapd_mld_ref_inc(struct hostapd_mld *mld);
|
|
+static void hostapd_mld_ref_dec(struct hostapd_mld *mld);
|
|
+#endif /* CONFIG_IEEE80211BE */
|
|
+
|
|
int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
|
|
int (*cb)(struct hostapd_iface *iface,
|
|
void *ctx), void *ctx)
|
|
@@ -2993,6 +2998,9 @@ void hostapd_interface_free(struct hosta
|
|
for (j = 0; j < iface->num_bss; j++) {
|
|
if (!iface->bss)
|
|
break;
|
|
+#ifdef CONFIG_IEEE80211BE
|
|
+ hostapd_mld_ref_dec(iface->bss[j]->mld);
|
|
+#endif /* CONFIG_IEEE80211BE */
|
|
wpa_printf(MSG_DEBUG, "%s: free hapd %p",
|
|
__func__, iface->bss[j]);
|
|
os_free(iface->bss[j]);
|
|
@@ -3015,6 +3023,34 @@ struct hostapd_iface * hostapd_alloc_ifa
|
|
}
|
|
|
|
#ifdef CONFIG_IEEE80211BE
|
|
+static void hostapd_mld_ref_inc(struct hostapd_mld *mld)
|
|
+{
|
|
+ if (!mld)
|
|
+ return;
|
|
+
|
|
+ if (mld->refcount == HOSTAPD_MLD_MAX_REF_COUNT) {
|
|
+ wpa_printf(MSG_ERROR, "MLD %s: Ref count overflow",
|
|
+ mld->name);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ mld->refcount++;
|
|
+}
|
|
+
|
|
+static void hostapd_mld_ref_dec(struct hostapd_mld *mld)
|
|
+{
|
|
+ if (!mld)
|
|
+ return;
|
|
+
|
|
+ if (!mld->refcount) {
|
|
+ wpa_printf(MSG_ERROR, "MLD %s: Ref count underflow",
|
|
+ mld->name);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ mld->refcount--;
|
|
+}
|
|
+
|
|
static void hostapd_bss_alloc_link_id(struct hostapd_data *hapd)
|
|
{
|
|
hapd->mld_link_id = hapd->mld->next_link_id++;
|
|
@@ -3045,6 +3081,7 @@ static void hostapd_bss_setup_multi_link
|
|
continue;
|
|
|
|
hapd->mld = mld;
|
|
+ hostapd_mld_ref_inc(mld);
|
|
hostapd_bss_alloc_link_id(hapd);
|
|
break;
|
|
}
|
|
@@ -3059,12 +3096,14 @@ static void hostapd_bss_setup_multi_link
|
|
os_strlcpy(mld->name, conf->iface, sizeof(conf->iface));
|
|
mld->next_link_id = 0;
|
|
mld->num_links = 0;
|
|
+ mld->refcount = 0;
|
|
mld->fbss = NULL;
|
|
dl_list_init(&mld->links);
|
|
|
|
wpa_printf(MSG_DEBUG, "MLD %s created", mld->name);
|
|
|
|
hapd->mld = mld;
|
|
+ hostapd_mld_ref_inc(mld);
|
|
hostapd_bss_alloc_link_id(hapd);
|
|
|
|
all_mld = os_realloc_array(interfaces->mld, interfaces->mld_count + 1,
|
|
@@ -3086,6 +3125,79 @@ fail:
|
|
os_free(mld);
|
|
hapd->mld = NULL;
|
|
}
|
|
+
|
|
+static void hostapd_cleanup_unused_mlds(struct hapd_interfaces *interfaces)
|
|
+{
|
|
+ struct hostapd_mld *mld, **all_mld;
|
|
+ int i, j, num_mlds;
|
|
+ bool forced_remove, remove;
|
|
+
|
|
+ if (!interfaces || !interfaces->mld)
|
|
+ return;
|
|
+
|
|
+ num_mlds = interfaces->mld_count;
|
|
+
|
|
+ for (i = 0; i < interfaces->mld_count; i++) {
|
|
+ mld = interfaces->mld[i];
|
|
+ if (!mld)
|
|
+ continue;
|
|
+
|
|
+ remove = forced_remove = false;
|
|
+
|
|
+ if (!mld->refcount)
|
|
+ remove = true;
|
|
+
|
|
+ /* If mld is still being referenced but no. of interfaces are
|
|
+ * zero then it is safe to force delete it. Normally, this
|
|
+ * should not happen but even if it does, let us free the memory
|
|
+ */
|
|
+ if (!remove && !interfaces->count)
|
|
+ forced_remove = true;
|
|
+
|
|
+ if (!remove && !forced_remove)
|
|
+ continue;
|
|
+
|
|
+ wpa_printf(MSG_DEBUG, "MLD %s: freed (forced: %d)", mld->name,
|
|
+ forced_remove);
|
|
+ os_free(mld);
|
|
+ interfaces->mld[i] = NULL;
|
|
+ num_mlds--;
|
|
+ }
|
|
+
|
|
+ if (!num_mlds) {
|
|
+ interfaces->mld_count = 0;
|
|
+ os_free(interfaces->mld);
|
|
+ interfaces->mld = NULL;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ all_mld = os_zalloc(num_mlds * sizeof(struct hostapd_mld *));
|
|
+ if (!all_mld) {
|
|
+ wpa_printf(MSG_DEBUG,
|
|
+ "MLD: failed to re-allocate the MLDs. Expect issues");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ for (i = 0, j = 0; i < interfaces->mld_count; i++) {
|
|
+ mld = interfaces->mld[i];
|
|
+ if (!mld)
|
|
+ continue;
|
|
+
|
|
+ all_mld[j++] = mld;
|
|
+ }
|
|
+
|
|
+ /* should not happen */
|
|
+ if (j != num_mlds) {
|
|
+ wpa_printf(MSG_DEBUG,
|
|
+ "MLD: some error occured while reallocating MLDs. Expect issues.");
|
|
+ os_free(all_mld);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ os_free(interfaces->mld);
|
|
+ interfaces->mld = all_mld;
|
|
+ interfaces->mld_count = num_mlds;
|
|
+}
|
|
#endif /* CONFIG_IEEE80211BE */
|
|
|
|
/**
|
|
@@ -3746,6 +3858,9 @@ int hostapd_add_iface(struct hapd_interf
|
|
__func__, hapd, hapd->conf->iface);
|
|
hostapd_config_free_bss(hapd->conf);
|
|
hapd->conf = NULL;
|
|
+#ifdef CONFIG_IEEE80211BE
|
|
+ hostapd_mld_ref_dec(hapd->mld);
|
|
+#endif /* CONFIG_IEEE80211BE */
|
|
os_free(hapd);
|
|
return -1;
|
|
}
|
|
@@ -3837,6 +3952,9 @@ fail:
|
|
hapd->conf->iface);
|
|
hostapd_bss_link_deinit(hapd);
|
|
hostapd_cleanup(hapd);
|
|
+#ifdef CONFIG_IEEE80211BE
|
|
+ hostapd_mld_ref_dec(hapd->mld);
|
|
+#endif /* CONFIG_IEEE80211BE */
|
|
os_free(hapd);
|
|
hapd_iface->bss[i] = NULL;
|
|
}
|
|
@@ -3846,6 +3964,9 @@ fail:
|
|
if (new_iface) {
|
|
interfaces->count--;
|
|
interfaces->iface[interfaces->count] = NULL;
|
|
+#ifdef CONFIG_IEEE80211BE
|
|
+ hostapd_cleanup_unused_mlds(interfaces);
|
|
+#endif /* CONFIG_IEEE80211BE */
|
|
}
|
|
hostapd_cleanup_iface(hapd_iface);
|
|
}
|
|
@@ -3868,6 +3989,9 @@ static int hostapd_remove_bss(struct hos
|
|
__func__, hapd, hapd->conf->iface);
|
|
hostapd_config_free_bss(hapd->conf);
|
|
hapd->conf = NULL;
|
|
+#ifdef CONFIG_IEEE80211BE
|
|
+ hostapd_mld_ref_dec(hapd->mld);
|
|
+#endif /* CONFIG_IEEE80211BE */
|
|
os_free(hapd);
|
|
|
|
iface->num_bss--;
|
|
@@ -3910,6 +4034,10 @@ int hostapd_remove_iface(struct hapd_int
|
|
k++;
|
|
}
|
|
interfaces->count--;
|
|
+#ifdef CONFIG_IEEE80211BE
|
|
+ hostapd_cleanup_unused_mlds(interfaces);
|
|
+#endif /* CONFIG_IEEE80211BE */
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
--- a/src/ap/hostapd.h
|
|
+++ b/src/ap/hostapd.h
|
|
@@ -572,11 +572,19 @@ struct hostapd_mld {
|
|
u8 mld_addr[ETH_ALEN];
|
|
u8 next_link_id;
|
|
u8 num_links;
|
|
+ /* No. of hostapd_data (hapd) referencing to this. num_links can't
|
|
+ * be used since num_links can go to 0 even when bss is disabled
|
|
+ * and when it is enabled back, the MLD should exist hence it can
|
|
+ * not be freed when it is 0.
|
|
+ */
|
|
+ u8 refcount;
|
|
|
|
struct hostapd_data *fbss;
|
|
struct dl_list links; /* List HEAD of all affiliated links */
|
|
struct dl_list ft_ds_ml_stas;
|
|
};
|
|
+
|
|
+#define HOSTAPD_MLD_MAX_REF_COUNT 0xFF
|
|
#endif /* CONFIG_IEEE80211BE */
|
|
|
|
/**
|