@@ -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
@@ -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'",
@@ -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
@@ -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);
}
@@ -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;
};
/**
@@ -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
@@ -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\"",
@@ -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 */
@@ -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
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@intel.com> --- 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(+)