diff mbox series

Clear and set own report in nr_db if ssid is changed with ctrl iface SET or SIGHUP

Message ID CY8PR19MB72529EAE087D466FE7BB7FD1DB482@CY8PR19MB7252.namprd19.prod.outlook.com
State Accepted
Headers show
Series Clear and set own report in nr_db if ssid is changed with ctrl iface SET or SIGHUP | expand

Commit Message

Nikita Chernikov Feb. 12, 2024, 10:03 a.m. UTC
From 1644893ce3bda37dbe4ac342f61886d787d0ad96 Mon Sep 17 00:00:00 2001
From: Nikita Chernikov <nchernikov@maxlinear.com>
Date: Thu, 1 Feb 2024 18:05:02 +0200
Subject: [PATCH] Clear and set again own report in nr_db if ssid is changed
 with ctrl iface SET or SIGHUP
To: hostap@lists.infradead.org

From: Nikita Chernikov <ncherikov@maxlinear.com>

short_ssid in own neighbor report may be out of sync, causing advertising
RNR IE with old SSID, when ssid is changed either with ctrl_iface SET
or with SIGHUP. Therefore, own report needs to be synced by removing the
old entry and setting own report again.

Signed-off-by: Nikita Chernikov <nchernikov@maxlinear.com>
---
 hostapd/ctrl_iface.c |  2 ++
 src/ap/hostapd.c     |  3 +++
 src/ap/neighbor_db.c | 32 ++++++++++++++++++++++++++++++++
 src/ap/neighbor_db.h |  1 +
 4 files changed, 38 insertions(+)

Comments

Jouni Malinen March 3, 2024, 7:55 p.m. UTC | #1
On Mon, Feb 12, 2024 at 10:03:43AM +0000, Nikita Chernikov wrote:
> short_ssid in own neighbor report may be out of sync, causing advertising
> RNR IE with old SSID, when ssid is changed either with ctrl_iface SET
> or with SIGHUP. Therefore, own report needs to be synced by removing the
> old entry and setting own report again.

Thanks, applied.
diff mbox series

Patch

diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 015a67aea..ee5dc5c6e 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -1307,6 +1307,8 @@  static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
 			hostapd_disassoc_deny_mac(hapd);
 		} else if (os_strcasecmp(cmd, "accept_mac_file") == 0) {
 			hostapd_disassoc_accept_mac(hapd);
+		} else if (os_strcasecmp(cmd, "ssid") == 0) {
+			hostapd_neighbor_sync_own_report(hapd);
 		} else if (os_strncmp(cmd, "wme_ac_", 7) == 0 ||
 			   os_strncmp(cmd, "wmm_ac_", 7) == 0) {
 			hapd->parameter_set_count++;
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index cb464f670..c3b88a069 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -183,6 +183,9 @@  static void hostapd_reload_bss(struct hostapd_data *hapd)
 		hostapd_set_generic_elem(hapd, (u8 *) "", 0);
 	}
 
+	if(hostapd_neighbor_sync_own_report(hapd))
+		wpa_printf(MSG_DEBUG, "%s: Own neighbor report already in sync", hapd->conf->iface);
+
 	ieee802_11_set_beacon(hapd);
 	hostapd_update_wps(hapd);
 
diff --git a/src/ap/neighbor_db.c b/src/ap/neighbor_db.c
index 2a25ae20e..f97c6e005 100644
--- a/src/ap/neighbor_db.c
+++ b/src/ap/neighbor_db.c
@@ -325,3 +325,35 @@  void hostapd_neighbor_set_own_report(struct hostapd_data *hapd)
 	wpabuf_free(nr);
 #endif /* NEED_AP_MLME */
 }
+
+static struct hostapd_neighbor_entry *
+hostapd_neighbor_get_by_short_ssid(struct hostapd_data *hapd, const u8 *bssid)
+{
+	struct hostapd_neighbor_entry *nr;
+
+	dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
+			 list) {
+		if ((os_memcmp(bssid, nr->bssid, ETH_ALEN) == 0) && 
+			(nr->short_ssid != hapd->conf->ssid.short_ssid))
+			return nr;
+	}
+	return NULL;
+}
+
+int hostapd_neighbor_sync_own_report(struct hostapd_data *hapd)
+{
+	struct hostapd_neighbor_entry *nr;
+
+	nr = hostapd_neighbor_get_by_short_ssid(hapd, hapd->own_addr);
+	if (!nr)
+		return -1;
+
+	/* Clear old entry due to ssid change */
+	hostapd_neighbor_clear_entry(nr);
+	dl_list_del(&nr->list);
+	os_free(nr);
+
+	hostapd_neighbor_set_own_report(hapd);
+
+	return 0;
+}
diff --git a/src/ap/neighbor_db.h b/src/ap/neighbor_db.h
index 992671b62..53f714203 100644
--- a/src/ap/neighbor_db.h
+++ b/src/ap/neighbor_db.h
@@ -20,6 +20,7 @@  int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid,
 			 const struct wpabuf *civic, int stationary,
 			 u8 bss_parameters);
 void hostapd_neighbor_set_own_report(struct hostapd_data *hapd);
+int hostapd_neighbor_sync_own_report(struct hostapd_data *hapd);
 int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
 			    const struct wpa_ssid_value *ssid);
 void hostapd_free_neighbor_db(struct hostapd_data *hapd);