From 6f285fbafcd1a49a5d24ea5c0dcb26663545e9d7 Mon Sep 17 00:00:00 2001 From: Nikita Chernikov Date: Thu, 1 Feb 2024 18:05:02 +0200 Subject: [PATCH] Update own report in nr_db if SSID is changed short_ssid in the own neighbor report might get out of sync, causing advertising RNR element based on the old SSID, when SSID is changed either with control interface command SET or with SIGHUP. Therefore, sync the own report entry by removing the old entry and setting own report again if the short SSID value has changed. Signed-off-by: Nikita Chernikov --- hostapd/ctrl_iface.c | 2 ++ src/ap/hostapd.c | 2 ++ src/ap/neighbor_db.c | 34 ++++++++++++++++++++++++++++++++++ src/ap/neighbor_db.h | 1 + 4 files changed, 39 insertions(+) diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 23ede0c5a7..8a12fee886 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -1309,6 +1309,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 ddbcabc493..0def1b918a 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -184,6 +184,8 @@ static void hostapd_reload_bss(struct hostapd_data *hapd) hostapd_set_generic_elem(hapd, (u8 *) "", 0); } + hostapd_neighbor_sync_own_report(hapd); + ieee802_11_set_beacon(hapd); hostapd_update_wps(hapd); diff --git a/src/ap/neighbor_db.c b/src/ap/neighbor_db.c index 2a25ae20ee..2eefef0225 100644 --- a/src/ap/neighbor_db.c +++ b/src/ap/neighbor_db.c @@ -325,3 +325,37 @@ 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_diff_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 (ether_addr_equal(bssid, nr->bssid) && + 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_diff_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 992671b626..53f7142032 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); -- 2.47.3