xref: /freebsd/contrib/wpa/src/ap/neighbor_db.c (revision a90b9d0159070121c221b966469c3e36d912bf82)
1780fb4a2SCy Schubert /*
2780fb4a2SCy Schubert  * hostapd / Neighboring APs DB
3780fb4a2SCy Schubert  * Copyright(c) 2013 - 2016 Intel Mobile Communications GmbH.
4780fb4a2SCy Schubert  * Copyright(c) 2011 - 2016 Intel Corporation. All rights reserved.
5780fb4a2SCy Schubert  *
6780fb4a2SCy Schubert  * This software may be distributed under the terms of the BSD license.
7780fb4a2SCy Schubert  * See README for more details.
8780fb4a2SCy Schubert  */
9780fb4a2SCy Schubert 
10780fb4a2SCy Schubert #include "utils/includes.h"
11780fb4a2SCy Schubert 
12780fb4a2SCy Schubert #include "utils/common.h"
134b72b91aSCy Schubert #include "utils/crc32.h"
14780fb4a2SCy Schubert #include "hostapd.h"
154bc52338SCy Schubert #include "ieee802_11.h"
16780fb4a2SCy Schubert #include "neighbor_db.h"
17780fb4a2SCy Schubert 
18780fb4a2SCy Schubert 
19780fb4a2SCy Schubert struct hostapd_neighbor_entry *
hostapd_neighbor_get(struct hostapd_data * hapd,const u8 * bssid,const struct wpa_ssid_value * ssid)20780fb4a2SCy Schubert hostapd_neighbor_get(struct hostapd_data *hapd, const u8 *bssid,
21780fb4a2SCy Schubert 		     const struct wpa_ssid_value *ssid)
22780fb4a2SCy Schubert {
23780fb4a2SCy Schubert 	struct hostapd_neighbor_entry *nr;
24780fb4a2SCy Schubert 
25780fb4a2SCy Schubert 	dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
26780fb4a2SCy Schubert 			 list) {
27*a90b9d01SCy Schubert 		if (ether_addr_equal(bssid, nr->bssid) &&
28780fb4a2SCy Schubert 		    (!ssid ||
29780fb4a2SCy Schubert 		     (ssid->ssid_len == nr->ssid.ssid_len &&
30780fb4a2SCy Schubert 		      os_memcmp(ssid->ssid, nr->ssid.ssid,
31780fb4a2SCy Schubert 				ssid->ssid_len) == 0)))
32780fb4a2SCy Schubert 			return nr;
33780fb4a2SCy Schubert 	}
34780fb4a2SCy Schubert 	return NULL;
35780fb4a2SCy Schubert }
36780fb4a2SCy Schubert 
37780fb4a2SCy Schubert 
hostapd_neighbor_show(struct hostapd_data * hapd,char * buf,size_t buflen)38c1d255d3SCy Schubert int hostapd_neighbor_show(struct hostapd_data *hapd, char *buf, size_t buflen)
39c1d255d3SCy Schubert {
40c1d255d3SCy Schubert 	struct hostapd_neighbor_entry *nr;
41c1d255d3SCy Schubert 	char *pos, *end;
42c1d255d3SCy Schubert 
43c1d255d3SCy Schubert 	pos = buf;
44c1d255d3SCy Schubert 	end = buf + buflen;
45c1d255d3SCy Schubert 
46c1d255d3SCy Schubert 	dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
47c1d255d3SCy Schubert 			 list) {
48c1d255d3SCy Schubert 		int ret;
49c1d255d3SCy Schubert 		char nrie[2 * 255 + 1];
50c1d255d3SCy Schubert 		char lci[2 * 255 + 1];
51c1d255d3SCy Schubert 		char civic[2 * 255 + 1];
52c1d255d3SCy Schubert 		char ssid[SSID_MAX_LEN * 2 + 1];
53c1d255d3SCy Schubert 
54c1d255d3SCy Schubert 		ssid[0] = '\0';
55c1d255d3SCy Schubert 		wpa_snprintf_hex(ssid, sizeof(ssid), nr->ssid.ssid,
56c1d255d3SCy Schubert 				 nr->ssid.ssid_len);
57c1d255d3SCy Schubert 
58c1d255d3SCy Schubert 		nrie[0] = '\0';
59c1d255d3SCy Schubert 		if (nr->nr)
60c1d255d3SCy Schubert 			wpa_snprintf_hex(nrie, sizeof(nrie),
61c1d255d3SCy Schubert 					 wpabuf_head(nr->nr),
62c1d255d3SCy Schubert 					 wpabuf_len(nr->nr));
63c1d255d3SCy Schubert 
64c1d255d3SCy Schubert 		lci[0] = '\0';
65c1d255d3SCy Schubert 		if (nr->lci)
66c1d255d3SCy Schubert 			wpa_snprintf_hex(lci, sizeof(lci),
67c1d255d3SCy Schubert 					 wpabuf_head(nr->lci),
68c1d255d3SCy Schubert 					 wpabuf_len(nr->lci));
69c1d255d3SCy Schubert 
70c1d255d3SCy Schubert 		civic[0] = '\0';
71c1d255d3SCy Schubert 		if (nr->civic)
72c1d255d3SCy Schubert 			wpa_snprintf_hex(civic, sizeof(civic),
73c1d255d3SCy Schubert 					 wpabuf_head(nr->civic),
74c1d255d3SCy Schubert 					 wpabuf_len(nr->civic));
75c1d255d3SCy Schubert 
76c1d255d3SCy Schubert 		ret = os_snprintf(pos, end - pos, MACSTR
77c1d255d3SCy Schubert 				  " ssid=%s%s%s%s%s%s%s%s\n",
78c1d255d3SCy Schubert 				  MAC2STR(nr->bssid), ssid,
79c1d255d3SCy Schubert 				  nr->nr ? " nr=" : "", nrie,
80c1d255d3SCy Schubert 				  nr->lci ? " lci=" : "", lci,
81c1d255d3SCy Schubert 				  nr->civic ? " civic=" : "", civic,
82c1d255d3SCy Schubert 				  nr->stationary ? " stat" : "");
83c1d255d3SCy Schubert 		if (os_snprintf_error(end - pos, ret))
84c1d255d3SCy Schubert 			break;
85c1d255d3SCy Schubert 		pos += ret;
86c1d255d3SCy Schubert 	}
87c1d255d3SCy Schubert 
88c1d255d3SCy Schubert 	return pos - buf;
89c1d255d3SCy Schubert }
90c1d255d3SCy Schubert 
91c1d255d3SCy Schubert 
hostapd_neighbor_clear_entry(struct hostapd_neighbor_entry * nr)92780fb4a2SCy Schubert static void hostapd_neighbor_clear_entry(struct hostapd_neighbor_entry *nr)
93780fb4a2SCy Schubert {
94780fb4a2SCy Schubert 	wpabuf_free(nr->nr);
95780fb4a2SCy Schubert 	nr->nr = NULL;
96780fb4a2SCy Schubert 	wpabuf_free(nr->lci);
97780fb4a2SCy Schubert 	nr->lci = NULL;
98780fb4a2SCy Schubert 	wpabuf_free(nr->civic);
99780fb4a2SCy Schubert 	nr->civic = NULL;
100780fb4a2SCy Schubert 	os_memset(nr->bssid, 0, sizeof(nr->bssid));
101780fb4a2SCy Schubert 	os_memset(&nr->ssid, 0, sizeof(nr->ssid));
102*a90b9d01SCy Schubert 	os_memset(&nr->lci_date, 0, sizeof(nr->lci_date));
10385732ac8SCy Schubert 	nr->stationary = 0;
104*a90b9d01SCy Schubert 	nr->short_ssid = 0;
105*a90b9d01SCy Schubert 	nr->bss_parameters = 0;
106780fb4a2SCy Schubert }
107780fb4a2SCy Schubert 
108780fb4a2SCy Schubert 
109780fb4a2SCy Schubert static struct hostapd_neighbor_entry *
hostapd_neighbor_add(struct hostapd_data * hapd)110780fb4a2SCy Schubert hostapd_neighbor_add(struct hostapd_data *hapd)
111780fb4a2SCy Schubert {
112780fb4a2SCy Schubert 	struct hostapd_neighbor_entry *nr;
113780fb4a2SCy Schubert 
114780fb4a2SCy Schubert 	nr = os_zalloc(sizeof(struct hostapd_neighbor_entry));
115780fb4a2SCy Schubert 	if (!nr)
116780fb4a2SCy Schubert 		return NULL;
117780fb4a2SCy Schubert 
118780fb4a2SCy Schubert 	dl_list_add(&hapd->nr_db, &nr->list);
119780fb4a2SCy Schubert 
120780fb4a2SCy Schubert 	return nr;
121780fb4a2SCy Schubert }
122780fb4a2SCy Schubert 
123780fb4a2SCy Schubert 
hostapd_neighbor_set(struct hostapd_data * hapd,const u8 * bssid,const struct wpa_ssid_value * ssid,const struct wpabuf * nr,const struct wpabuf * lci,const struct wpabuf * civic,int stationary,u8 bss_parameters)124780fb4a2SCy Schubert int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid,
125780fb4a2SCy Schubert 			 const struct wpa_ssid_value *ssid,
126780fb4a2SCy Schubert 			 const struct wpabuf *nr, const struct wpabuf *lci,
1274b72b91aSCy Schubert 			 const struct wpabuf *civic, int stationary,
1284b72b91aSCy Schubert 			 u8 bss_parameters)
129780fb4a2SCy Schubert {
130780fb4a2SCy Schubert 	struct hostapd_neighbor_entry *entry;
131780fb4a2SCy Schubert 
132780fb4a2SCy Schubert 	entry = hostapd_neighbor_get(hapd, bssid, ssid);
133780fb4a2SCy Schubert 	if (!entry)
134780fb4a2SCy Schubert 		entry = hostapd_neighbor_add(hapd);
135780fb4a2SCy Schubert 	if (!entry)
136780fb4a2SCy Schubert 		return -1;
137780fb4a2SCy Schubert 
138780fb4a2SCy Schubert 	hostapd_neighbor_clear_entry(entry);
139780fb4a2SCy Schubert 
140780fb4a2SCy Schubert 	os_memcpy(entry->bssid, bssid, ETH_ALEN);
141780fb4a2SCy Schubert 	os_memcpy(&entry->ssid, ssid, sizeof(entry->ssid));
142*a90b9d01SCy Schubert 	entry->short_ssid = ieee80211_crc32(ssid->ssid, ssid->ssid_len);
143780fb4a2SCy Schubert 
144780fb4a2SCy Schubert 	entry->nr = wpabuf_dup(nr);
145780fb4a2SCy Schubert 	if (!entry->nr)
146780fb4a2SCy Schubert 		goto fail;
147780fb4a2SCy Schubert 
14885732ac8SCy Schubert 	if (lci && wpabuf_len(lci)) {
149780fb4a2SCy Schubert 		entry->lci = wpabuf_dup(lci);
150780fb4a2SCy Schubert 		if (!entry->lci || os_get_time(&entry->lci_date))
151780fb4a2SCy Schubert 			goto fail;
152780fb4a2SCy Schubert 	}
153780fb4a2SCy Schubert 
15485732ac8SCy Schubert 	if (civic && wpabuf_len(civic)) {
155780fb4a2SCy Schubert 		entry->civic = wpabuf_dup(civic);
156780fb4a2SCy Schubert 		if (!entry->civic)
157780fb4a2SCy Schubert 			goto fail;
158780fb4a2SCy Schubert 	}
159780fb4a2SCy Schubert 
16085732ac8SCy Schubert 	entry->stationary = stationary;
1614b72b91aSCy Schubert 	entry->bss_parameters = bss_parameters;
16285732ac8SCy Schubert 
163780fb4a2SCy Schubert 	return 0;
164780fb4a2SCy Schubert 
165780fb4a2SCy Schubert fail:
166780fb4a2SCy Schubert 	hostapd_neighbor_remove(hapd, bssid, ssid);
167780fb4a2SCy Schubert 	return -1;
168780fb4a2SCy Schubert }
169780fb4a2SCy Schubert 
170780fb4a2SCy Schubert 
hostapd_neighbor_free(struct hostapd_neighbor_entry * nr)171*a90b9d01SCy Schubert static void hostapd_neighbor_free(struct hostapd_neighbor_entry *nr)
172*a90b9d01SCy Schubert {
173*a90b9d01SCy Schubert 	hostapd_neighbor_clear_entry(nr);
174*a90b9d01SCy Schubert 	dl_list_del(&nr->list);
175*a90b9d01SCy Schubert 	os_free(nr);
176*a90b9d01SCy Schubert }
177*a90b9d01SCy Schubert 
178*a90b9d01SCy Schubert 
hostapd_neighbor_remove(struct hostapd_data * hapd,const u8 * bssid,const struct wpa_ssid_value * ssid)179780fb4a2SCy Schubert int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
180780fb4a2SCy Schubert 			    const struct wpa_ssid_value *ssid)
181780fb4a2SCy Schubert {
182780fb4a2SCy Schubert 	struct hostapd_neighbor_entry *nr;
183780fb4a2SCy Schubert 
184780fb4a2SCy Schubert 	nr = hostapd_neighbor_get(hapd, bssid, ssid);
185780fb4a2SCy Schubert 	if (!nr)
186780fb4a2SCy Schubert 		return -1;
187780fb4a2SCy Schubert 
188*a90b9d01SCy Schubert 	hostapd_neighbor_free(nr);
189780fb4a2SCy Schubert 
190780fb4a2SCy Schubert 	return 0;
191780fb4a2SCy Schubert }
192780fb4a2SCy Schubert 
193780fb4a2SCy Schubert 
hostapd_free_neighbor_db(struct hostapd_data * hapd)1944bc52338SCy Schubert void hostapd_free_neighbor_db(struct hostapd_data *hapd)
195780fb4a2SCy Schubert {
196780fb4a2SCy Schubert 	struct hostapd_neighbor_entry *nr, *prev;
197780fb4a2SCy Schubert 
198780fb4a2SCy Schubert 	dl_list_for_each_safe(nr, prev, &hapd->nr_db,
199780fb4a2SCy Schubert 			      struct hostapd_neighbor_entry, list) {
200*a90b9d01SCy Schubert 		hostapd_neighbor_free(nr);
201780fb4a2SCy Schubert 	}
202780fb4a2SCy Schubert }
2034bc52338SCy Schubert 
2044bc52338SCy Schubert 
2054bc52338SCy Schubert #ifdef NEED_AP_MLME
hostapd_get_nr_chan_width(struct hostapd_data * hapd,int ht,int vht,int he)2064bc52338SCy Schubert static enum nr_chan_width hostapd_get_nr_chan_width(struct hostapd_data *hapd,
207206b73d0SCy Schubert 						    int ht, int vht, int he)
2084bc52338SCy Schubert {
209*a90b9d01SCy Schubert 	enum oper_chan_width oper_chwidth;
210*a90b9d01SCy Schubert 
211*a90b9d01SCy Schubert 	oper_chwidth = hostapd_get_oper_chwidth(hapd->iconf);
212206b73d0SCy Schubert 
213206b73d0SCy Schubert 	if (!ht && !vht && !he)
2144bc52338SCy Schubert 		return NR_CHAN_WIDTH_20;
2154bc52338SCy Schubert 	if (!hapd->iconf->secondary_channel)
2164bc52338SCy Schubert 		return NR_CHAN_WIDTH_20;
217*a90b9d01SCy Schubert 	if ((!vht && !he) || oper_chwidth == CONF_OPER_CHWIDTH_USE_HT)
2184bc52338SCy Schubert 		return NR_CHAN_WIDTH_40;
219*a90b9d01SCy Schubert 	if (oper_chwidth == CONF_OPER_CHWIDTH_80MHZ)
2204bc52338SCy Schubert 		return NR_CHAN_WIDTH_80;
221*a90b9d01SCy Schubert 	if (oper_chwidth == CONF_OPER_CHWIDTH_160MHZ)
2224bc52338SCy Schubert 		return NR_CHAN_WIDTH_160;
223*a90b9d01SCy Schubert 	if (oper_chwidth == CONF_OPER_CHWIDTH_80P80MHZ)
2244bc52338SCy Schubert 		return NR_CHAN_WIDTH_80P80;
2254bc52338SCy Schubert 	return NR_CHAN_WIDTH_20;
2264bc52338SCy Schubert }
2274bc52338SCy Schubert #endif /* NEED_AP_MLME */
2284bc52338SCy Schubert 
2294bc52338SCy Schubert 
hostapd_neighbor_set_own_report(struct hostapd_data * hapd)2304bc52338SCy Schubert void hostapd_neighbor_set_own_report(struct hostapd_data *hapd)
2314bc52338SCy Schubert {
2324bc52338SCy Schubert #ifdef NEED_AP_MLME
2334bc52338SCy Schubert 	u16 capab = hostapd_own_capab_info(hapd);
2344bc52338SCy Schubert 	int ht = hapd->iconf->ieee80211n && !hapd->conf->disable_11n;
2354bc52338SCy Schubert 	int vht = hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac;
236c1d255d3SCy Schubert 	int he = hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax;
237*a90b9d01SCy Schubert 	bool eht = he && hapd->iconf->ieee80211be && !hapd->conf->disable_11be;
2384bc52338SCy Schubert 	struct wpa_ssid_value ssid;
2394bc52338SCy Schubert 	u8 channel, op_class;
2404bc52338SCy Schubert 	u8 center_freq1_idx = 0, center_freq2_idx = 0;
2414bc52338SCy Schubert 	enum nr_chan_width width;
2424bc52338SCy Schubert 	u32 bssid_info;
2434bc52338SCy Schubert 	struct wpabuf *nr;
2444bc52338SCy Schubert 
2454bc52338SCy Schubert 	if (!(hapd->conf->radio_measurements[0] &
2464bc52338SCy Schubert 	      WLAN_RRM_CAPS_NEIGHBOR_REPORT))
2474bc52338SCy Schubert 		return;
2484bc52338SCy Schubert 
2494bc52338SCy Schubert 	bssid_info = 3; /* AP is reachable */
2504bc52338SCy Schubert 	bssid_info |= NEI_REP_BSSID_INFO_SECURITY; /* "same as the AP" */
2514bc52338SCy Schubert 	bssid_info |= NEI_REP_BSSID_INFO_KEY_SCOPE; /* "same as the AP" */
2524bc52338SCy Schubert 
2534bc52338SCy Schubert 	if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT)
2544bc52338SCy Schubert 		bssid_info |= NEI_REP_BSSID_INFO_SPECTRUM_MGMT;
2554bc52338SCy Schubert 
2564bc52338SCy Schubert 	bssid_info |= NEI_REP_BSSID_INFO_RM; /* RRM is supported */
2574bc52338SCy Schubert 
2584bc52338SCy Schubert 	if (hapd->conf->wmm_enabled) {
2594bc52338SCy Schubert 		bssid_info |= NEI_REP_BSSID_INFO_QOS;
2604bc52338SCy Schubert 
2614bc52338SCy Schubert 		if (hapd->conf->wmm_uapsd &&
2624bc52338SCy Schubert 		    (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_UAPSD))
2634bc52338SCy Schubert 			bssid_info |= NEI_REP_BSSID_INFO_APSD;
2644bc52338SCy Schubert 	}
2654bc52338SCy Schubert 
2664bc52338SCy Schubert 	if (ht) {
2674bc52338SCy Schubert 		bssid_info |= NEI_REP_BSSID_INFO_HT |
2684bc52338SCy Schubert 			NEI_REP_BSSID_INFO_DELAYED_BA;
2694bc52338SCy Schubert 
2704bc52338SCy Schubert 		/* VHT bit added in IEEE P802.11-REVmc/D4.3 */
2714bc52338SCy Schubert 		if (vht)
2724bc52338SCy Schubert 			bssid_info |= NEI_REP_BSSID_INFO_VHT;
2734bc52338SCy Schubert 	}
2744bc52338SCy Schubert 
275*a90b9d01SCy Schubert 	if (he)
276*a90b9d01SCy Schubert 		bssid_info |= NEI_REP_BSSID_INFO_HE;
277*a90b9d01SCy Schubert 	if (eht)
278*a90b9d01SCy Schubert 		bssid_info |= NEI_REP_BSSID_INFO_EHT;
2794bc52338SCy Schubert 	/* TODO: Set NEI_REP_BSSID_INFO_MOBILITY_DOMAIN if MDE is set */
2804bc52338SCy Schubert 
2814bc52338SCy Schubert 	if (ieee80211_freq_to_channel_ext(hapd->iface->freq,
2824bc52338SCy Schubert 					  hapd->iconf->secondary_channel,
283206b73d0SCy Schubert 					  hostapd_get_oper_chwidth(hapd->iconf),
2844bc52338SCy Schubert 					  &op_class, &channel) ==
2854bc52338SCy Schubert 	    NUM_HOSTAPD_MODES)
2864bc52338SCy Schubert 		return;
287206b73d0SCy Schubert 	width = hostapd_get_nr_chan_width(hapd, ht, vht, he);
2884bc52338SCy Schubert 	if (vht) {
289206b73d0SCy Schubert 		center_freq1_idx = hostapd_get_oper_centr_freq_seg0_idx(
290206b73d0SCy Schubert 			hapd->iconf);
2914bc52338SCy Schubert 		if (width == NR_CHAN_WIDTH_80P80)
2924bc52338SCy Schubert 			center_freq2_idx =
293206b73d0SCy Schubert 				hostapd_get_oper_centr_freq_seg1_idx(
294206b73d0SCy Schubert 					hapd->iconf);
2954bc52338SCy Schubert 	} else if (ht) {
2964bc52338SCy Schubert 		ieee80211_freq_to_chan(hapd->iface->freq +
2974bc52338SCy Schubert 				       10 * hapd->iconf->secondary_channel,
2984bc52338SCy Schubert 				       &center_freq1_idx);
2994bc52338SCy Schubert 	}
3004bc52338SCy Schubert 
3014bc52338SCy Schubert 	ssid.ssid_len = hapd->conf->ssid.ssid_len;
3024bc52338SCy Schubert 	os_memcpy(ssid.ssid, hapd->conf->ssid.ssid, ssid.ssid_len);
3034bc52338SCy Schubert 
3044bc52338SCy Schubert 	/*
3054bc52338SCy Schubert 	 * Neighbor Report element size = BSSID + BSSID info + op_class + chan +
3064bc52338SCy Schubert 	 * phy type + wide bandwidth channel subelement.
3074bc52338SCy Schubert 	 */
3084bc52338SCy Schubert 	nr = wpabuf_alloc(ETH_ALEN + 4 + 1 + 1 + 1 + 5);
3094bc52338SCy Schubert 	if (!nr)
3104bc52338SCy Schubert 		return;
3114bc52338SCy Schubert 
3124bc52338SCy Schubert 	wpabuf_put_data(nr, hapd->own_addr, ETH_ALEN);
3134bc52338SCy Schubert 	wpabuf_put_le32(nr, bssid_info);
3144bc52338SCy Schubert 	wpabuf_put_u8(nr, op_class);
3154bc52338SCy Schubert 	wpabuf_put_u8(nr, channel);
3164bc52338SCy Schubert 	wpabuf_put_u8(nr, ieee80211_get_phy_type(hapd->iface->freq, ht, vht));
3174bc52338SCy Schubert 
3184bc52338SCy Schubert 	/*
3194bc52338SCy Schubert 	 * Wide Bandwidth Channel subelement may be needed to allow the
3204bc52338SCy Schubert 	 * receiving STA to send packets to the AP. See IEEE P802.11-REVmc/D5.0
3214bc52338SCy Schubert 	 * Figure 9-301.
3224bc52338SCy Schubert 	 */
3234bc52338SCy Schubert 	wpabuf_put_u8(nr, WNM_NEIGHBOR_WIDE_BW_CHAN);
3244bc52338SCy Schubert 	wpabuf_put_u8(nr, 3);
3254bc52338SCy Schubert 	wpabuf_put_u8(nr, width);
3264bc52338SCy Schubert 	wpabuf_put_u8(nr, center_freq1_idx);
3274bc52338SCy Schubert 	wpabuf_put_u8(nr, center_freq2_idx);
3284bc52338SCy Schubert 
3294bc52338SCy Schubert 	hostapd_neighbor_set(hapd, hapd->own_addr, &ssid, nr, hapd->iconf->lci,
3304b72b91aSCy Schubert 			     hapd->iconf->civic, hapd->iconf->stationary_ap, 0);
3314bc52338SCy Schubert 
3324bc52338SCy Schubert 	wpabuf_free(nr);
3334bc52338SCy Schubert #endif /* NEED_AP_MLME */
3344bc52338SCy Schubert }
335*a90b9d01SCy Schubert 
336*a90b9d01SCy Schubert 
337*a90b9d01SCy Schubert static struct hostapd_neighbor_entry *
hostapd_neighbor_get_diff_short_ssid(struct hostapd_data * hapd,const u8 * bssid)338*a90b9d01SCy Schubert hostapd_neighbor_get_diff_short_ssid(struct hostapd_data *hapd, const u8 *bssid)
339*a90b9d01SCy Schubert {
340*a90b9d01SCy Schubert 	struct hostapd_neighbor_entry *nr;
341*a90b9d01SCy Schubert 
342*a90b9d01SCy Schubert 	dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
343*a90b9d01SCy Schubert 			 list) {
344*a90b9d01SCy Schubert 		if (ether_addr_equal(bssid, nr->bssid) &&
345*a90b9d01SCy Schubert 		    nr->short_ssid != hapd->conf->ssid.short_ssid)
346*a90b9d01SCy Schubert 			return nr;
347*a90b9d01SCy Schubert 	}
348*a90b9d01SCy Schubert 	return NULL;
349*a90b9d01SCy Schubert }
350*a90b9d01SCy Schubert 
351*a90b9d01SCy Schubert 
hostapd_neighbor_sync_own_report(struct hostapd_data * hapd)352*a90b9d01SCy Schubert int hostapd_neighbor_sync_own_report(struct hostapd_data *hapd)
353*a90b9d01SCy Schubert {
354*a90b9d01SCy Schubert 	struct hostapd_neighbor_entry *nr;
355*a90b9d01SCy Schubert 
356*a90b9d01SCy Schubert 	nr = hostapd_neighbor_get_diff_short_ssid(hapd, hapd->own_addr);
357*a90b9d01SCy Schubert 	if (!nr)
358*a90b9d01SCy Schubert 		return -1;
359*a90b9d01SCy Schubert 
360*a90b9d01SCy Schubert 	/* Clear old entry due to SSID change */
361*a90b9d01SCy Schubert 	hostapd_neighbor_free(nr);
362*a90b9d01SCy Schubert 
363*a90b9d01SCy Schubert 	hostapd_neighbor_set_own_report(hapd);
364*a90b9d01SCy Schubert 
365*a90b9d01SCy Schubert 	return 0;
366*a90b9d01SCy Schubert }
367