From patchwork Thu Jun 18 04:35:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aloka Dixit X-Patchwork-Id: 1311752 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) 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=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20170209 header.b=lqJUAxhP; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=mg.codeaurora.org header.i=@mg.codeaurora.org header.a=rsa-sha256 header.s=smtp header.b=uXnwjfu7; 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 49nTfT0PPGz9sSF for ; Thu, 18 Jun 2020 14:36:33 +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:References:In-Reply-To: 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: List-Owner; bh=wg3d1YzNvzhhcoqD1pzxNlny6SPij6phNvyRMUZu/Qs=; b=lqJUAxhP1Jkd2O r5B41zX/YLrorYE+OCmeKKgULWWTajBuj0GC4hHwffeyQDCIM2GMC17dEz/LFCTqEAbh/3uAxQcNR LvNNyd35XMNanbIKxNieuyhsJvNwlCXgAApfwpNTCDzPIQPhT4RKgPBkbbgq5Wh24EZuin52FFCFQ 6z4MaU3QNqt8yfQRQrNh4Kdy1C1XrD4I5gi2LKnmRxLQNxynfZ3LDw/d6SU2iKBoF5b/HCqg2Tx6F 9RkvnAZU9KjgiYiplk10yblwtePYKXrtlGp8+uoJ9t/HrW5uxkYVF6SfZnFxGoTInql1eyslrf2gd JromY4PnKHei/9yYy4Ow==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jlmHk-0003Ej-4C; Thu, 18 Jun 2020 04:36:20 +0000 Received: from mail29.static.mailgun.info ([104.130.122.29]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jlmHU-0002x6-SA for hostap@lists.infradead.org; Thu, 18 Jun 2020 04:36:09 +0000 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1592454964; h=Content-Transfer-Encoding: MIME-Version: References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=onnOGCzUhxM/gj9C7NkCX7qcLdBD3XpBVjRMXFCP9OY=; b=uXnwjfu7BsP7/IZ3ZZHXc8IxWN69q3Ub4dokV5A4Sk0+1XYoiRmtLwAOjiLHj8gp1M8IgnF3 /C7pLsZLwiIsiRWmYM/rdmnByQrQ/b1X/LbObblUc1ClIkfrnXA//KOQ6+I24eHogntEhHX0 U/XXdMNK7fl/n/OtNCZ6tRDZWmo= X-Mailgun-Sending-Ip: 104.130.122.29 X-Mailgun-Sid: WyJkMjNkOSIsICJob3N0YXBAbGlzdHMuaW5mcmFkZWFkLm9yZyIsICJiZTllNGEiXQ== Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by smtp-out-n15.prod.us-east-1.postgun.com with SMTP id 5eeaef34567385e8e700ce89 (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Thu, 18 Jun 2020 04:36:04 GMT Received: by smtp.codeaurora.org (Postfix, from userid 1001) id 5662BC433CB; Thu, 18 Jun 2020 04:36:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.0 Received: from alokad-linux.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: alokad) by smtp.codeaurora.org (Postfix) with ESMTPSA id 05EF1C43391; Thu, 18 Jun 2020 04:36:01 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 05EF1C43391 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=alokad@codeaurora.org From: Aloka Dixit To: j@w1.fi Subject: [PATCH 2/3] AP: Add FILS discovery support Date: Wed, 17 Jun 2020 21:35:51 -0700 Message-Id: <20200618043552.26105-3-alokad@codeaurora.org> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200618043552.26105-1-alokad@codeaurora.org> References: <20200618043552.26105-1-alokad@codeaurora.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200617_213605_028402_FD72ABD0 X-CRM114-Status: GOOD ( 18.00 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.4 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 RCVD_IN_MSPIKE_H4 RBL: Very Good reputation (+4) [104.130.122.29 listed in wl.mailspike.net] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [104.130.122.29 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders 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: hostap@lists.infradead.org, Aloka Dixit Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org This patch adds following hostapd configuration options for FILS discovery transmission from IEEE Std 802.11ai-2016, Annex C.3 MIB detail: (1) Minimum interval - default 20 TUs (2) Maximum interval - default 0 TUs (FILS discovery disabled) Signed-off-by: Aloka Dixit --- hostapd/config_file.c | 4 + hostapd/hostapd.conf | 5 + src/ap/ap_config.c | 1 + src/ap/ap_config.h | 2 + src/ap/beacon.c | 253 ++++++++++++++++++++++++++++++++++++++++++ src/drivers/driver.h | 21 ++++ 6 files changed, 286 insertions(+) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 8f7fcd8b762c..870b4e5ef3f4 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -4353,6 +4353,10 @@ static int hostapd_config_fill(struct hostapd_config *conf, bss->dhcp_server_port = atoi(pos); } else if (os_strcmp(buf, "dhcp_relay_port") == 0) { bss->dhcp_relay_port = atoi(pos); + } else if (os_strcmp(buf, "fils_discovery_min_interval") == 0) { + bss->fils_discovery_min_int = atoi(pos); + } else if (os_strcmp(buf, "fils_discovery_max_interval") == 0) { + bss->fils_discovery_max_int = atoi(pos); #endif /* CONFIG_FILS */ } else if (os_strcmp(buf, "multicast_to_unicast") == 0) { bss->multicast_to_unicast = atoi(pos); diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 2b0f762e544e..ac3bddb67695 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1906,6 +1906,11 @@ own_ip_addr=127.0.0.1 # default: 30 TUs (= 30.72 milliseconds) #fils_hlp_wait_time=30 +# FILS discovery transmission minimum and maximum packet interval settings. +# If maximum interval is non-zero, the AP schedules FILS discovery transmission +#fils_discovery_max_interval=0 to 10000 (in TUs). +#fils_discovery_min_interval=0 to 10000 (in TUs). + # Transition Disable indication # The AP can notify authenticated stations to disable transition mode in their # network profiles when the network has completed transition steps, i.e., once diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index 1c6b4a00ec26..6e3dc18e659f 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -131,6 +131,7 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss) bss->fils_hlp_wait_time = 30; bss->dhcp_server_port = DHCP_SERVER_PORT; bss->dhcp_relay_port = DHCP_SERVER_PORT; + bss->fils_discovery_min_int = 20; #endif /* CONFIG_FILS */ bss->broadcast_deauth = 1; diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index b705c378fe28..9661a4b8e123 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -728,6 +728,8 @@ struct hostapd_bss_config { unsigned int fils_hlp_wait_time; u16 dhcp_server_port; u16 dhcp_relay_port; + u32 fils_discovery_min_int; + u32 fils_discovery_max_int; #endif /* CONFIG_FILS */ int multicast_to_unicast; diff --git a/src/ap/beacon.c b/src/ap/beacon.c index b3b33b7faf1d..826058a14a71 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -1124,6 +1124,251 @@ void sta_track_del(struct hostapd_sta_info *info) } +#ifdef CONFIG_FILS +static u8 hostapd_fils_discovery_rsn(struct hostapd_data *hapd, u16 *cap, + u32 *suite_selector_ptr) +{ + const u8 *ie, *start; + u8 len; + u16 cnt; + u32 suite_selector = 0; + + ie = hostapd_wpa_ie(hapd, WLAN_EID_RSN); + if (!ie || ie[1] < 6) + return 0; + + len = ie[1]; + start = &ie[2]; + ie += 4; + do { + /* Group Data Cipher Suite Selector */ + suite_selector = ie[3]; + ie += 4; + + /* Pairwise Cipher Suite Selector */ + if ((ie - start) >= len) + break; + os_memcpy((u8 *) &cnt, ie, 2); + ie += 2; + if (cnt) { + suite_selector |= (((u32) ie[3]) << 12); + ie += (4 * cnt); + } + + /* AKM Cipher Suite Selector */ + if ((ie - start) >= len) + break; + os_memcpy((u8 *) &cnt, ie, 2); + ie += 2; + if (cnt) { + suite_selector |= (((u32) ie[3]) << 18); + ie += (4 * cnt); + } + + /* RSN capabilities */ + if ((ie - start) >= len) + break; + os_memcpy((u8 *) cap, ie, 2); + ie += 2; + + /* Group Management Cipher Suite Selector */ + if ((ie - start) < len) + suite_selector |= (((u32) ie[3]) << 6); + } while (0); + + *suite_selector_ptr = suite_selector; + return 1; +} + + +u16 hostapd_fils_discovery_cap(struct hostapd_data *hapd) +{ + u16 cap_info = 0, nss_mask = 0x0003; + u8 nss = 0; + int i; + + cap_info = FILS_DISCOVERY_CAP_ESS | + (hapd->conf->wpa ? FILS_DISCOVERY_CAP_PRIVACY : 0); + + if (is_6ghz_op_class(hapd->iconf->op_class)) { + cap_info |= ((center_idx_to_bw_6ghz(hapd->iconf->channel) << + FILS_DISCOVERY_CAP_BSS_CHWIDTH_SHIFT) | + (FILS_DISCOVERY_CAP_PHY_INDEX_HE << + FILS_DISCOVERY_CAP_PHY_INDEX_SHIFT)); + } else { + switch (hostapd_get_oper_chwidth(hapd->iconf)) { + case CHANWIDTH_80P80MHZ: + case CHANWIDTH_160MHZ: + cap_info |= FILS_DISCOVERY_CAP_BSS_CHWIDTH_160_8080 << + FILS_DISCOVERY_CAP_BSS_CHWIDTH_SHIFT; + break; + case CHANWIDTH_80MHZ: + cap_info |= FILS_DISCOVERY_CAP_BSS_CHWIDTH_80 << + FILS_DISCOVERY_CAP_BSS_CHWIDTH_SHIFT; + break; + case CHANWIDTH_USE_HT: + if (hapd->iconf->secondary_channel) + cap_info |= FILS_DISCOVERY_CAP_BSS_CHWIDTH_40 << + FILS_DISCOVERY_CAP_BSS_CHWIDTH_SHIFT; + break; + } + + if (hapd->iconf->ieee80211ax) { +#ifdef CONFIG_IEEE80211AX + cap_info |= FILS_DISCOVERY_CAP_PHY_INDEX_HE << + FILS_DISCOVERY_CAP_PHY_INDEX_SHIFT; +#endif /* CONFIG_IEEE80211AX */ + } else if (hapd->conf->vendor_vht) { +#ifdef CONFIG_IEEE80211AC + cap_info |= FILS_DISCOVERY_CAP_PHY_INDEX_VHT << + FILS_DISCOVERY_CAP_PHY_INDEX_SHIFT; +#endif /* CONFIG_IEEE80211AC */ + } else if (hapd->iconf->ieee80211n && + !hapd->conf->disable_11n) { + cap_info |= FILS_DISCOVERY_CAP_PHY_INDEX_HT << + FILS_DISCOVERY_CAP_PHY_INDEX_SHIFT; + } + } + + for (i = 0; i < 8; i++) { + if ((hapd->iconf->he_op.he_basic_mcs_nss_set & nss_mask) != + nss_mask) + nss++; + nss_mask = nss_mask << 2; + } + if (nss > 4) + cap_info |= (4 << FILS_DISCOVERY_CAP_NSS_SHIFT); + else + cap_info |= ((nss - 1) << FILS_DISCOVERY_CAP_NSS_SHIFT); + + /* TODO: FILS minimum rate */ + return cap_info; +} + + +static u8 * hostapd_gen_fils_discovery(struct hostapd_data *hapd, u32 *len) +{ + struct ieee80211_mgmt *head; + const u8 *mobility_domain; + u8 *pos, *length_pos, nss = 0, rsn = 0, buf[200], buf_len; + u16 frm_cntl = 0, cap_info = 0, rsn_cap = 0; + u32 suite_selectors = 0, total_len; + +#define FILS_DISOVERY_TMPL_HEAD_LEN 26 +#define FILS_DISOVERY_TMPL_MIN_LEN 19 + + total_len = FILS_DISOVERY_TMPL_HEAD_LEN + FILS_DISOVERY_TMPL_MIN_LEN; + + /* FILS discovery frame control: 2 bytes */ + frm_cntl = (sizeof(hapd->conf->ssid.short_ssid) - 1) | + FILS_DISCOVERY_FRM_CNTL_CAP_PRESENT | + FILS_DISCOVERY_FRM_CNTL_SHORT_SSID_PRESENT | + FILS_DISCOVERY_FRM_CNTL_LENGTH_PRESENT; + + /* Check for optional subfields and calculate length */ + rsn = hostapd_fils_discovery_rsn(hapd, &rsn_cap, &suite_selectors); + if (rsn) { + frm_cntl |= FILS_DISCOVERY_FRM_CNTL_RSN_INFO_PRESENT; + total_len += 5; + } + + mobility_domain = hostapd_wpa_ie(hapd, WLAN_EID_MOBILITY_DOMAIN); + if (mobility_domain) { + frm_cntl |= FILS_DISCOVERY_FRM_CNTL_MOBILITY_DOMAIN_PRESENT; + total_len += 3; + } + + pos = hostapd_eid_fils_indic(hapd, buf, 0); + buf_len = pos - buf; + total_len += buf_len; + + head = os_zalloc(total_len); + if (!head) + return NULL; + + head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, + WLAN_FC_STYPE_ACTION); + os_memset(head->da, 0xff, ETH_ALEN); + os_memcpy(head->sa, hapd->own_addr, ETH_ALEN); + os_memcpy(head->bssid, hapd->own_addr, ETH_ALEN); + + head->u.action.category = WLAN_ACTION_PUBLIC; + head->u.action.u.public_action.action = WLAN_PA_FILS_DISCOVERY; + + pos = &head->u.action.u.public_action.variable[0]; + *((u16 *) pos) = host_to_le16(frm_cntl); + pos += 2; + + /* hardware or low-level driver will setup timestamp */ + pos += 8; + + /* Beacon interval */ + *((u16 *) pos) = host_to_le16(hapd->iconf->beacon_int); + pos += 2; + + /* Short SSID */ + *((u32 *) pos) = host_to_le32(hapd->conf->ssid.short_ssid); + pos += sizeof(hapd->conf->ssid.short_ssid); + + /* Store position of FILS discovery information element length field */ + length_pos = pos++; + + /* FD Capability : total 2 bytes */ + *((u16 *) pos) = host_to_le16(hostapd_fils_discovery_cap(hapd)); + pos += 2; + + /* RSN */ + if (frm_cntl & FILS_DISCOVERY_FRM_CNTL_RSN_INFO_PRESENT) { + os_memcpy(pos, &rsn_cap, 2); + os_memcpy(&pos[2], &suite_selectors, 3); + pos += 5; + } + + /* Mobility Domain */ + if (frm_cntl & FILS_DISCOVERY_FRM_CNTL_MOBILITY_DOMAIN_PRESENT) { + os_memcpy(pos, &mobility_domain[2], 3); + pos += 3; + } + + /* Fill the FILS discovery information element length */ + *length_pos = pos - (length_pos + 1); + + /* FILS indication element */ + if (buf_len) { + os_memcpy(pos, buf, buf_len); + pos += buf_len; + } + + *len = pos - (u8 *) head; + return ((u8 *) head); +} + + +/* Configure FILS discovery response transmission */ +static u8 * hostapd_fils_discovery(struct hostapd_data *hapd, + struct wpa_driver_ap_params *params) +{ +#define VALID_INTERVAL(x,y) { x = (x > y) ? y : x; } + + params->fils_discovery_max_int = hapd->conf->fils_discovery_max_int; + if (is_6ghz_op_class(hapd->iconf->op_class)) + VALID_INTERVAL(params->fils_discovery_max_int, + FILS_DISCOVERY_MAX_INTERVAL_6GHZ); + + params->fils_discovery_min_int = hapd->conf->fils_discovery_min_int; + VALID_INTERVAL(params->fils_discovery_min_int, + params->fils_discovery_max_int); +#undef VALID_INTERVAL + + if (params->fils_discovery_max_int) + return hostapd_gen_fils_discovery(hapd, + ¶ms->fils_discovery_tmpl_len); + + return NULL; +} +#endif /* CONFIG_FILS */ + + int ieee802_11_build_ap_params(struct hostapd_data *hapd, struct wpa_driver_ap_params *params) { @@ -1461,6 +1706,10 @@ void ieee802_11_free_ap_params(struct wpa_driver_ap_params *params) params->head = NULL; os_free(params->proberesp); params->proberesp = NULL; +#ifdef CONFIG_FILS + os_free(params->fils_discovery_tmpl); + params->fils_discovery_tmpl = NULL; +#endif /* CONFIG_FILS */ } @@ -1508,6 +1757,10 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd) #endif /* CONFIG_IEEE80211AX */ hapd->reenable_beacon = 0; +#ifdef CONFIG_FILS + params.fils_discovery_tmpl = hostapd_fils_discovery(hapd, ¶ms); +#endif /* CONFIG_FILS */ + if (cmode && hostapd_set_freq_params(&freq, iconf->hw_mode, iface->freq, iconf->channel, iconf->enable_edmg, diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 0ecda49dd1df..c0489785637e 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1508,6 +1508,27 @@ struct wpa_driver_ap_params { * twt_responder - Whether Target Wait Time responder is enabled */ int twt_responder; + + /** + * FILS discovery minimum interval + */ + u32 fils_discovery_min_int; + + /** + * FILS discovery maximum interval + */ + u32 fils_discovery_max_int; + + /** + * FILS discovery template data + */ + u8 *fils_discovery_tmpl; + + /** + * FILS discovery template length + */ + size_t fils_discovery_tmpl_len; + }; struct wpa_driver_mesh_bss_params {