RNR: Add data from neighbor database

Include data from the existing neighbor database in the Reduced Neighbor
Report element in Beacon frames if the configuration option 'rnr' is
enabled for the BSS.

Signed-off-by: John Crispin <john@phrozen.org>
Signed-off-by: Muna Sinada <msinada@codeaurora.org>
Co-developed-by: Aloka Dixit <alokad@codeaurora.org>
Signed-off-by: Aloka Dixit <alokad@codeaurora.org>
This commit is contained in:
John Crispin 2021-07-27 16:42:20 -07:00 committed by Jouni Malinen
parent 847f76760a
commit a7c152d6b8
2 changed files with 127 additions and 0 deletions

View file

@ -7071,4 +7071,129 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid)
return eid; return eid;
} }
static size_t hostapd_eid_nr_db_len(struct hostapd_data *hapd,
size_t *current_len)
{
struct hostapd_neighbor_entry *nr;
size_t total_len = 0, len = *current_len;
dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
list) {
if (!nr->nr || wpabuf_len(nr->nr) < 12)
continue;
if (nr->short_ssid == hapd->conf->ssid.short_ssid)
continue;
/* Start a new element */
if (!len ||
len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
len = RNR_HEADER_LEN;
total_len += RNR_HEADER_LEN;
}
len += RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN;
total_len += RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN;
}
*current_len = len;
return total_len;
}
size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
{
size_t total_len = 0, current_len = 0;
switch (type) {
case WLAN_FC_STYPE_BEACON:
if (hapd->conf->rnr)
total_len += hostapd_eid_nr_db_len(hapd, &current_len);
break;
default:
break;
}
return total_len;
}
static u8 * hostapd_eid_nr_db(struct hostapd_data *hapd, u8 *eid,
size_t *current_len)
{
struct hostapd_neighbor_entry *nr;
size_t len = *current_len;
u8 *size_offset = (eid - len) + 1;
dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
list) {
if (!nr->nr || wpabuf_len(nr->nr) < 12)
continue;
if (nr->short_ssid == hapd->conf->ssid.short_ssid)
continue;
/* Start a new element */
if (!len ||
len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
*eid++ = WLAN_EID_REDUCED_NEIGHBOR_REPORT;
size_offset = eid++;
len = RNR_HEADER_LEN;
}
/* TBTT Information Header subfield (2 octets) */
*eid++ = 0;
/* TBTT Information Length */
*eid++ = RNR_TBTT_INFO_LEN;
/* Operating Class */
*eid++ = wpabuf_head_u8(nr->nr)[10];
/* Channel Number */
*eid++ = wpabuf_head_u8(nr->nr)[11];
len += RNR_TBTT_HEADER_LEN;
/* TBTT Information Set */
/* TBTT Information field */
/* Neighbor AP TBTT Offset */
*eid++ = RNR_NEIGHBOR_AP_OFFSET_UNKNOWN;
/* BSSID */
os_memcpy(eid, nr->bssid, ETH_ALEN);
eid += ETH_ALEN;
/* Short SSID */
os_memcpy(eid, &nr->short_ssid, 4);
eid += 4;
/* BSS parameters */
*eid++ = nr->bss_parameters;
/* 20 MHz PSD */
*eid++ = RNR_20_MHZ_PSD_MAX_TXPOWER - 1;
len += RNR_TBTT_INFO_LEN;
*size_offset = (eid - size_offset) - 1;
}
*current_len = len;
return eid;
}
u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type)
{
u8 *eid_start = eid;
size_t current_len = 0;
switch (type) {
case WLAN_FC_STYPE_BEACON:
if (hapd->conf->rnr)
eid = hostapd_eid_nr_db(hapd, eid, &current_len);
break;
default:
return eid_start;
}
if (eid == eid_start + 2)
return eid_start;
return eid;
}
#endif /* CONFIG_NATIVE_WINDOWS */ #endif /* CONFIG_NATIVE_WINDOWS */

View file

@ -194,5 +194,7 @@ int get_tx_parameters(struct sta_info *sta, int ap_max_chanwidth,
void auth_sae_process_commit(void *eloop_ctx, void *user_ctx); void auth_sae_process_commit(void *eloop_ctx, void *user_ctx);
u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len); u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len);
size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type);
u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type);
#endif /* IEEE802_11_H */ #endif /* IEEE802_11_H */