From patchwork Wed Jun 19 12:49:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrei Otcheretianski X-Patchwork-Id: 1118525 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="LeHJ9JRv"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45THPm0yBNz9s6w for ; Wed, 19 Jun 2019 17:58:20 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=ARVIMfbCvVn4RFeC50Eer7ihbTv8sLHtfipkHJQYJug=; b=LeHJ9JRvi8+b9Q QrdEWjHmA//7FL52pr5W4aztLGUSmHGgI8lvIj3Qb0ZI0gVG52sxNBCJZ4yN1M1/Q5wbQxPwsdWz1 rqZigMBdcT7E31t04oiMXkLoL2EwUaaQimGG9b6CbQ+kQviDkOJFKaPq0GpjXZ7JKbPUIqcgH2HOK 0uXpogRnpY2PbH0HuiUjER8B3nSJgiHSKiXFtqJ9P3InX7DmrgDeADjkHXQekCrpONByjQ0BOI2H/ r+HIaiQPhyG0LEsOankfJig+cfpsv34YTBUjFiIrEOVbSpHMZIJMxLo8RTtUykaXL/Ws/3xdbIFYf 1B5xpJO89FVAQYxvvKjw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92 #3 (Red Hat Linux)) id 1hdVU0-0007w4-2d; Wed, 19 Jun 2019 07:58:16 +0000 Received: from mga17.intel.com ([192.55.52.151]) by bombadil.infradead.org with esmtps (Exim 4.92 #3 (Red Hat Linux)) id 1hdVSo-0006ZZ-3v for hostap@lists.infradead.org; Wed, 19 Jun 2019 07:57:04 +0000 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Jun 2019 00:57:02 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.63,392,1557212400"; d="scan'208";a="358537351" Received: from andrei-xps-12-9q33.jer.intel.com ([10.12.190.53]) by fmsmga006.fm.intel.com with ESMTP; 19 Jun 2019 00:57:01 -0700 From: Andrei Otcheretianski To: hostap@lists.infradead.org Subject: [PATCH 5/6] AP: Add support for co-located AP configuration Date: Wed, 19 Jun 2019 15:49:15 +0300 Message-Id: <20190619124916.14150-6-andrei.otcheretianski@intel.com> X-Mailer: git-send-email 2.19.1 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190619_005702_229794_E367A51B X-CRM114-Status: GOOD ( 18.52 ) X-Spam-Score: 0.1 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.1 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [192.55.52.151 listed in list.dnswl.org] 2.4 DATE_IN_FUTURE_03_06 Date: is 3 to 6 hours after Received: date 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrei Otcheretianski Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org 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 --- 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