[PATCH 1/2] BSS Load: Update the Beacon frame only when the element changes

Andrei-Alexandru Bleortu me at andrei-z.com
Fri Oct 16 12:06:12 PDT 2026


Every bss_load_update_period the Beacon frame was rebuilt and handed to
the driver, whether or not the station count or the channel utilization
had changed. With mac80211 each update also reapplies the BSS parameters
(CTS protection, preamble, AP isolation, ...), which a driver with an
offloading firmware turns into a burst of firmware commands and a new
Beacon template for every BSS every few seconds. On a quiet channel two
updates in three carried the same element.

Remember what the current Beacon frame advertises and skip the update
when neither value changed.

Assisted-by: LLM
Signed-off-by: Andrei-Alexandru Bleortu <me at andrei-z.com>
---
 src/ap/beacon.c   | 3 +++
 src/ap/bss_load.c | 7 ++++++-
 src/ap/hostapd.h  | 4 ++++
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index be8e1153d..e1ee097fd 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -2433,6 +2433,9 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 
 	tailpos = hostapd_get_rsne(hapd, tailpos, tailend - tailpos);
 	tailpos = hostapd_eid_bss_load(hapd, tailpos, tailend - tailpos);
+	hapd->beacon_bss_load_set = true;
+	hapd->beacon_bss_load_num_sta = hapd->num_sta;
+	hapd->beacon_bss_load_chan_util = hapd->iface->channel_utilization;
 	tailpos = hostapd_eid_rm_enabled_capab(hapd, tailpos,
 					       tailend - tailpos);
 	tailpos = hostapd_get_mde(hapd, tailpos, tailend - tailpos);
diff --git a/src/ap/bss_load.c b/src/ap/bss_load.c
index e9baafc96..1cc870a82 100644
--- a/src/ap/bss_load.c
+++ b/src/ap/bss_load.c
@@ -55,7 +55,12 @@ static void update_channel_utilization(void *eloop_data, void *user_data)
 		return;
 	}
 
-	ieee802_11_set_beacon_per_bss_only(hapd);
+	/* A Beacon frame update reprograms the whole BSS in the driver; skip
+	 * it when the BSS Load element would not change. */
+	if (!hapd->beacon_bss_load_set ||
+	    hapd->beacon_bss_load_num_sta != hapd->num_sta ||
+	    hapd->beacon_bss_load_chan_util != iface->channel_utilization)
+		ieee802_11_set_beacon_per_bss_only(hapd);
 
 	if (get_bss_load_update_timeout(hapd, &sec, &usec) < 0)
 		return;
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index 6ce29653b..aad13d549 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -191,6 +191,10 @@ struct hostapd_data {
 	u8 own_addr[ETH_ALEN];
 
 	int num_sta; /* number of entries in sta_list */
+	/* BSS Load element contents in the current Beacon frame */
+	bool beacon_bss_load_set;
+	int beacon_bss_load_num_sta;
+	u8 beacon_bss_load_chan_util;
 	struct sta_info *sta_list; /* STA info list head */
 #define STA_HASH_SIZE 256
 #define STA_HASH(sta) (sta[5])
-- 
2.47.3





More information about the Hostap mailing list