The Reduced Neighbor Report (RNR) element contains channel and other information related to neighbor APs. It is part of the OCE requirement. Signed-off-by: John Crispin <john@xxxxxxxxxxx> --- hostapd/config_file.c | 2 + hostapd/hostapd.conf | 3 ++ src/ap/ap_config.h | 1 + src/ap/beacon.c | 2 + src/ap/ieee802_11.c | 89 ++++++++++++++++++++++++++++++++++++ src/ap/ieee802_11.h | 2 + src/common/ieee802_11_defs.h | 13 ++++++ 7 files changed, 112 insertions(+) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index f54ea02d4..a9faeb3c2 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -4575,6 +4575,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, #endif /* CONFIG_MACSEC */ } else if (os_strcmp(buf, "multiple_bssid") == 0) { conf->multiple_bssid = atoi(pos); + } else if (os_strcmp(buf, "rnr_beacon") == 0) { + bss->rnr_beacon = atoi(pos); } else { wpa_printf(MSG_ERROR, "Line %d: unknown configuration item '%s'", diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 5fc4d5f86..99a4e61b7 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -2772,6 +2772,9 @@ own_ip_addr=127.0.0.1 # that allows sending of such data. Default: 0. #stationary_ap=0 +# Enable reduced neighbour reporting (RNR) +#rnr_beacon=0 + ##### Airtime policy configuration ########################################### # Set the airtime policy operating mode: diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 0f0394f11..7fe418363 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -890,6 +890,7 @@ struct hostapd_bss_config { struct ieee80211_he_mu_edca_parameter_set he_mu_edca; struct spatial_reuse spr; #endif + u8 rnr_beacon; }; /** diff --git a/src/ap/beacon.c b/src/ap/beacon.c index 8c3e80dfb..ed185b284 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -1188,6 +1188,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, tail_len += hostapd_eid_owe_trans_len(hapd); tail_len += hostapd_eid_dpp_cc_len(hapd); tail_len += hostapd_eid_multiple_bssid_len(hapd); + tail_len += hostapd_eid_reduced_neighbor_report_len(hapd); tailpos = tail = os_malloc(tail_len); if (head == NULL || tail == NULL) { @@ -1366,6 +1367,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, tailpos = hostapd_eid_owe_trans(hapd, tailpos, tail + tail_len - tailpos); tailpos = hostapd_eid_dpp_cc(hapd, tailpos, tail + tail_len - tailpos); + tailpos = hostapd_eid_reduced_neighbor_report(hapd, tailpos); if (hapd->conf->vendor_elements) { os_memcpy(tailpos, wpabuf_head(hapd->conf->vendor_elements), diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index b0575337b..f85e7c1d9 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -5722,4 +5722,93 @@ u8 * hostapd_eid_multiple_bssid(struct hostapd_data *hapd, u8 *eid, u8 *end) return eid; } + +size_t hostapd_eid_reduced_neighbor_report_len(struct hostapd_data *hapd) +{ + size_t len = 0; + + if (hapd->iface->num_bss > 1) + len += TBTT_HEADER_LENGTH + ((hapd->iface->num_bss - 1) * TBTT_INFO_LENGTH); + if (!dl_list_empty(&hapd->nr_db)) + len += dl_list_len(&hapd->nr_db) * (TBTT_HEADER_LENGTH + TBTT_INFO_LENGTH); + + return len; +} + + +u8 * hostapd_eid_reduced_neighbor_report(struct hostapd_data *hapd, u8 *eid) +{ + size_t len = hostapd_eid_reduced_neighbor_report_len(hapd); + struct hostapd_neighbor_entry *nr; + int i, count = 0; + + if (!len) + return eid; + + *eid++ = WLAN_EID_REDUCED_NEIGHBOR_REPORT; + *eid++ = len; + + if (hapd->iface->num_bss > 1) { + u8 op_class, channel; + + if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA) || + !hapd->iface->freq) + goto nr_db; + + if (ieee80211_freq_to_channel_ext(hapd->iface->freq, + hapd->iconf->secondary_channel, + hostapd_get_oper_chwidth(hapd->iconf), + &op_class, &channel) == + NUM_HOSTAPD_MODES) + goto nr_db; + + *eid++ = TBTT_INFO_COUNT(hapd->iface->num_bss - 2); + *eid++ = TBTT_INFO_LENGTH; + *eid++ = op_class; + *eid++ = hapd->iconf->channel; + for (i = 0; i < hapd->iface->num_bss; i++) { + u8 bss_param = 0; + + if (hapd->iface->bss[i] == hapd) + continue; + *eid++ = TBTT_AP_OFFSET_UNKNOWN; + os_memcpy(eid, hapd->iface->bss[i]->own_addr, ETH_ALEN); + eid += 6; + os_memcpy(eid, &hapd->iface->bss[i]->conf->ssid.short_ssid, 4); + eid += 4; + if (hapd->iface->bss[i]->conf->ssid.short_ssid == + hapd->conf->ssid.short_ssid) + bss_param |= TBTT_BSS_PARAM_SAME_SSID; + if (hapd->iconf->multiple_bssid) + bss_param |= TBTT_BSS_PARAM_MULTIPLE_BSSID; + *eid++ = bss_param; + count++; + } + } + +nr_db: + 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; + *eid++ = 0; + *eid++ = TBTT_INFO_LENGTH; + *eid++ = wpabuf_head_u8(nr->nr)[10]; + *eid++ = wpabuf_head_u8(nr->nr)[11]; + *eid++ = TBTT_AP_OFFSET_UNKNOWN; + os_memcpy(eid, nr->bssid, ETH_ALEN); + eid += 6; + os_memcpy(eid, &nr->short_ssid, 4); + eid += 4; + *eid++ = nr->bss_parameters; + count++; + } + + if (!count) + eid -= 2; + return eid; +} + #endif /* CONFIG_NATIVE_WINDOWS */ diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h index 2c3dea0e9..ce7313af8 100644 --- a/src/ap/ieee802_11.h +++ b/src/ap/ieee802_11.h @@ -122,6 +122,8 @@ void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr); u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid); u8 * hostapd_eid_multiple_bssid(struct hostapd_data *hapd, u8 *eid, u8 *end); int hostapd_eid_multiple_bssid_len(struct hostapd_data *hapd); +u8 * hostapd_eid_reduced_neighbor_report(struct hostapd_data *hapd, u8 *eid); +size_t hostapd_eid_reduced_neighbor_report_len(struct hostapd_data *hapd); int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta); #ifdef CONFIG_SAE diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index e8956eca1..3f7dd271b 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -2344,4 +2344,17 @@ enum edmg_bw_config { /* DPP Public Action frame identifiers - OUI_WFA */ #define DPP_OUI_TYPE 0x1A +/* TBTT Information field defines */ +#define TBTT_HEADER_LENGTH 4 +#define TBTT_INFO_LENGTH 12 +#define TBTT_INFO_FILTERED_NEIGH_AP BIT(2) +#define TBTT_INFO_COUNT(x) (((x) & 0xf) << 4) +#define TBTT_AP_OFFSET_UNKNOWN 255 +#define TBTT_BSS_PARAM_OCT_RECOMMENDED BIT(0) +#define TBTT_BSS_PARAM_SAME_SSID BIT(1) +#define TBTT_BSS_PARAM_MULTIPLE_BSSID BIT(2) +#define TBTT_BSS_PARAM_TRANSMITTED_BSSID BIT(3) +#define TBTT_BSS_PARAM_CO_LOCATED_ESS BIT(4) +#define TBTT_BSS_PARAM_20_TU_PROBE_RESP_ACTIVE BIT(5) + #endif /* IEEE802_11_DEFS_H */ -- 2.25.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap