Add configuration option to indicate co-located interfaces. When this configuration is set, the AP will publish Reduced Neighbor Report accordingly. It is possible to configure multiple co-located interfaces. Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@xxxxxxxxx> --- hostapd/Makefile | 1 + hostapd/config_file.c | 24 ++++++++++++ hostapd/hostapd.conf | 6 +++ src/ap/ap_config.c | 4 ++ src/ap/ap_config.h | 6 +++ src/ap/beacon.c | 74 ++++++++++++++++++++++++++++++++++++ src/ap/hostapd.c | 7 ++++ src/common/ieee802_11_defs.h | 15 ++++++++ wpa_supplicant/Makefile | 1 + 9 files changed, 138 insertions(+) diff --git a/hostapd/Makefile b/hostapd/Makefile index a8d77fed36..fbf0ee8535 100644 --- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -157,6 +157,7 @@ OBJS_c += ../src/utils/wpa_debug.o OBJS += ../src/utils/wpabuf.o OBJS += ../src/utils/os_$(CONFIG_OS).o OBJS += ../src/utils/ip_addr.o +OBJS += ../src/utils/crc32.o OBJS += ../src/common/ieee802_11_common.o OBJS += ../src/common/wpa_common.o diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 21671721c0..322afe9115 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -2411,6 +2411,27 @@ fail: } #endif /* CONFIG_SAE */ +static int parse_coloc_iface(struct hostapd_bss_config *bss, char *pos, + int line) +{ + char **n; + + if (bss->n_coloc_ifaces >= MAX_COLOC_IFACES_NUM) + return -1; + + n = os_realloc_array(bss->coloc_ifaces, + bss->n_coloc_ifaces + 1, sizeof(char *)); + if (!n) + return -1; + + bss->coloc_ifaces = n; + bss->coloc_ifaces[bss->n_coloc_ifaces] = os_strdup(pos); + if (!bss->coloc_ifaces[bss->n_coloc_ifaces]) + return -1; + bss->n_coloc_ifaces++; + + return 0; +} #ifdef CONFIG_DPP2 static int hostapd_dpp_controller_parse(struct hostapd_bss_config *bss, @@ -4557,6 +4578,9 @@ static int hostapd_config_fill(struct hostapd_config *conf, } bss->mka_psk_set |= MKA_PSK_SET_CKN; #endif /* CONFIG_MACSEC */ + } else if (os_strcmp(buf, "co_located_iface") == 0) { + if (parse_coloc_iface(bss, pos, line) < 0) + return 1; } else { wpa_printf(MSG_ERROR, "Line %d: unknown configuration item '%s'", diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index a25d3f0092..ae33f0d5d9 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -2666,3 +2666,9 @@ own_ip_addr=127.0.0.1 #bss=wlan0_1 #bssid=00:13:10:95:fe:0b # ... + +# Co-located interfaces +# A list of co-located APs. These APs will be reported in Reduced Neighbor +# Report element in probe responses and beacons. +#co_located_iface=wlan1 +#co_located_iface=wlan2 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index 5f0f2e0da7..b371f87f99 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -788,6 +788,10 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf) } #endif /* CONFIG_AIRTIME_POLICY */ + for (i = 0; i < conf->n_coloc_ifaces; i++) + os_free(conf->coloc_ifaces[i]); + os_free(conf->coloc_ifaces); + os_free(conf); } diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index fc6524c9e9..09e787b4c7 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -88,6 +88,7 @@ typedef enum hostap_security_policy { struct hostapd_ssid { u8 ssid[SSID_MAX_LEN]; size_t ssid_len; + u32 short_ssid; unsigned int ssid_set:1; unsigned int utf8_ssid:1; unsigned int wpa_passphrase_set:1; @@ -820,6 +821,11 @@ struct hostapd_bss_config { */ u8 mka_psk_set; #endif /* CONFIG_MACSEC */ + +#define MAX_COLOC_IFACES_NUM 16 + /* Array of colocated interfaces */ + char **coloc_ifaces; + size_t n_coloc_ifaces; }; /** diff --git a/src/ap/beacon.c b/src/ap/beacon.c index c1aeb03a3d..724e1d8ca5 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -365,6 +365,78 @@ static u8 * hostapd_eid_supported_op_classes(struct hostapd_data *hapd, u8 *eid) } +/* + * Add Reduced Neighbor Report element to Beacons and Probe Responses + */ +static u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid) +{ + u8 *pos = eid; +#ifdef CONFIG_FILS + u8 *len; + size_t i; + + if (!hapd->conf->n_coloc_ifaces || !hapd->iface->interfaces) + return eid; + + *pos++ = WLAN_EID_REDUCED_NEIGHBOR_REPORT; + len = pos++; + for (i = 0; i < hapd->conf->n_coloc_ifaces; i++) { + struct ieee80211_neighbor_ap_info *rnr; + struct hostapd_data *h = + hostapd_get_iface(hapd->iface->interfaces, + hapd->conf->coloc_ifaces[i]); + + if (!h || !h->started || !h->iface->current_mode || h == hapd) + continue; + + rnr = (struct ieee80211_neighbor_ap_info *)pos; + rnr->tbtt_info_hdr = 0; + if (h->conf->ssid.ssid_len == hapd->conf->ssid.ssid_len && + os_memcmp(h->conf->ssid.ssid, hapd->conf->ssid.ssid, + h->conf->ssid.ssid_len) == 0) { + rnr->tbtt_info_hdr |= RNR_TBTT_INFO_HDR_FILTERED; + /* TBTT offset + BSSID */ + rnr->tbtt_info_len = 7; + } else { + /* TBTT offset + BSSID + Short SSID */ + rnr->tbtt_info_len = 11; + } + rnr->tbtt_info_hdr |= RNR_TBTT_INFO_HDR_COLOC; + if (ieee80211_freq_to_channel_ext(h->iface->freq, + h->iconf->secondary_channel, + h->iconf->vht_oper_chwidth, + &rnr->op_class, + &rnr->channel) == + NUM_HOSTAPD_MODES) { + wpa_printf(MSG_DEBUG, + "Skipping colocated iface with invalid channel configuration (%s)", + hapd->conf->coloc_ifaces[i]); + /* It's safe to continue as pos isn't advanced yet */ + continue; + } + rnr->neighbor_ap_tbtt_offset = 255; /* Unknown */ + pos += sizeof(*rnr); + os_memcpy(pos, h->own_addr, ETH_ALEN); + pos += ETH_ALEN; + + /* Include Short SSID if needed */ + if (rnr->tbtt_info_len == 11) { + WPA_PUT_LE32(pos, h->conf->ssid.short_ssid); + pos += 4; + } + } + + *len = pos - eid - 2; + + /* don't add empty IE */ + if (*len == 0) + return eid; +#endif /* CONFIG_FILS */ + + return pos; +} + + static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, const struct ieee80211_mgmt *req, int is_p2p, size_t *resp_len) @@ -508,6 +580,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, } #endif /* CONFIG_IEEE80211AC */ + pos = hostapd_eid_rnr(hapd, pos); pos = hostapd_eid_fils_indic(hapd, pos, 0); #ifdef CONFIG_IEEE80211AX @@ -1224,6 +1297,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, } #endif /* CONFIG_IEEE80211AC */ + tailpos = hostapd_eid_rnr(hapd, tailpos); tailpos = hostapd_eid_fils_indic(hapd, tailpos, 0); #ifdef CONFIG_IEEE80211AX diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index c83fb2a464..5e886a44fd 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -10,6 +10,7 @@ #include "utils/common.h" #include "utils/eloop.h" +#include "utils/crc32.h" #include "common/ieee802_11_defs.h" #include "common/wpa_ctrl.h" #include "common/hw_features_common.h" @@ -1155,6 +1156,12 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first) os_memcpy(conf->ssid.ssid, ssid, conf->ssid.ssid_len); } + /* + * Short SSID calculation is identical to FCS and it is defined in + * IEEE802.11-REVmd/D2.2 9.4.2.170.3 + */ + conf->ssid.short_ssid = crc32(conf->ssid.ssid, conf->ssid.ssid_len); + if (!hostapd_drv_none(hapd)) { wpa_printf(MSG_ERROR, "Using interface %s with hwaddr " MACSTR " and ssid \"%s\"", diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index a1e11c7143..30d81dade4 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -2228,4 +2228,19 @@ struct ieee80211_he_mu_edca_parameter_set { /* DPP Public Action frame identifiers - OUI_WFA */ #define DPP_OUI_TYPE 0x1A +#define RNR_TBTT_INFO_HDR_FILTERED BIT(2) +#define RNR_TBTT_INFO_HDR_COLOC BIT(3) +#define RNR_TBTT_INFO_COUNT_OFFSET 4 + +struct ieee80211_neighbor_ap_info { + u8 tbtt_info_hdr; + u8 tbtt_info_len; + u8 op_class; + u8 channel; + /* The Neighbor AP TBTT Offset subfield is always present */ + u8 neighbor_ap_tbtt_offset; + /* Followed by the rest of the TBTT Information field contents */ + u8 data[0]; +} STRUCT_PACKED; + #endif /* IEEE802_11_DEFS_H */ diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index 348f9015c2..ca83391174 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -891,6 +891,7 @@ OBJS += ../src/ap/utils.o OBJS += ../src/ap/authsrv.o OBJS += ../src/ap/ap_config.o OBJS += ../src/utils/ip_addr.o +OBJS += ../src/utils/crc32.o OBJS += ../src/ap/sta_info.o OBJS += ../src/ap/tkip_countermeasures.o OBJS += ../src/ap/ap_mlme.o -- 2.19.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap