From patchwork Sun Dec 2 22:36:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jouni Malinen X-Patchwork-Id: 1006601 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=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.b="f7fhCtl3"; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=codeaurora.org header.i=@codeaurora.org header.b="Wy5ZuPsy"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="IEgir5Is"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 437NMK0MDCz9s3C for ; Mon, 3 Dec 2018 09:38:37 +1100 (AEDT) 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:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: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=5mHmAgmEyIXsB82en4A+bMV/Aqq0CBB/IC4p+l60zbk=; b=f7fhCtl34H/TxRiHMniWF1txSy a/dBvvJTOkKnKEGQtxqr557oveM476DSgllFxPLEAaiagxu+QAqkTSwHxElujG6z9xq2VO0O14TJK 4uk3UOkjd/tezzmlrMG66vAq/tuFKaBIMqVGWgoC7YNIHqjY55/z5y3ISaSl75qzhy3+JPxJ63QfP iXgrG/burwN9UXaP0ABw7vIVDpa3Ob91KY5bW9bVh8HxZVD6tEvZ2HnEd/HCrTjhWs3Y1hEZZZ/2v grc/9rN2CLD3WBf4YwiYL4Zu5qDv9HdhldqJd339go3Xd8PVLvbNfZJo7ntAhHGC1Yu1Hk2JVA5Xb 24yD4fYw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gTaNX-0001Wa-A5; Sun, 02 Dec 2018 22:38:19 +0000 Received: from smtp.codeaurora.org ([198.145.29.96]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gTaMU-0001QT-HF for hostap@lists.infradead.org; Sun, 02 Dec 2018 22:37:16 +0000 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 7673A607F7; Sun, 2 Dec 2018 22:37:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1543790227; bh=PhMA+a1WniFL0TJxXkvujpA0c/r9YahFSBJnhUKYTF0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Wy5ZuPsywm0orY553l/yORNUnEGVDMMX5rT90NetIduu9vC/SYO3uEptv9q12RiNI /oCQVmDnhtBwT4roKuWuXUcD1we2xsGpb7zyV5eicy5KB6CdHCfj+9MW7kcCsZzRPD rf9E333xEMPnBT9ABRtiEesF4hQyYiCfRoGG/mL4= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on pdx-caf-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=ALL_TRUSTED,BAYES_00, DKIM_INVALID, DKIM_SIGNED autolearn=no autolearn_force=no version=3.4.0 Received: from jouni.codeaurora.org (37-33-76-121.bb.dnainternet.fi [37.33.76.121]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jouni@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id BF2FB60481; Sun, 2 Dec 2018 22:37:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1543790226; bh=PhMA+a1WniFL0TJxXkvujpA0c/r9YahFSBJnhUKYTF0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IEgir5IssO05/7xsJly06Z9O6+qlvQ5l6zadROOfvExWVILCZlNCf4OZmzBKX7eAz 3ew+T+sDYD8Ez2HpGxe45HDVAXuKmYF60ytcY4PIIc4GLyXM1hQqBRhS4fwh2M9MrE WSjFNZJuLA/W1wo1C5pmFiQob23UqJnNkrjadF2Y= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org BF2FB60481 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=jouni@codeaurora.org From: Jouni Malinen To: hostap@lists.infradead.org Subject: [PATCHv2 2/2] wpa_supplicant: Add Multi-AP protocol support to supplicant Date: Mon, 3 Dec 2018 00:36:45 +0200 Message-Id: <1543790205-11616-2-git-send-email-jouni@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1543790205-11616-1-git-send-email-jouni@codeaurora.org> References: <1543790205-11616-1-git-send-email-jouni@codeaurora.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181202_143714_603604_83A3B8C6 X-CRM114-Status: GOOD ( 20.06 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [198.145.29.96 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-Mailman-Approved-At: Sun, 02 Dec 2018 14:38:13 -0800 X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Venkateswara Naralasetty , Jouni Malinen MIME-Version: 1.0 Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Venkateswara Naralasetty Advertise vendor specific Multi-AP IE in (Re)Association request and process Multi-AP IE from (Re)Association response frames if user enable Multi-AP fuctionality. This patch introducing new configuration parameter 'multi_ap_enabled' to enable/disable Multi-AP funtionality from user. Signed-off-by: Venkateswara Naralasetty Signed-off-by: Jouni Malinen --- v2: * changed configuration from multi_ap_enabled to multiap_backhaul_sta * made multiap_backhaul_sta configuration static * used single helper function to build all different cases of Multi-AP IE contents src/drivers/driver.h | 11 ++++++++ src/drivers/driver_nl80211.c | 45 ++++++++++++++++++++++++++++++++ wpa_supplicant/Makefile | 4 +++ wpa_supplicant/config.c | 3 +++ wpa_supplicant/config_ssid.h | 8 ++++++ wpa_supplicant/defconfig | 3 +++ wpa_supplicant/driver_i.h | 10 +++++++ wpa_supplicant/events.c | 53 ++++++++++++++++++++++++++++++++++++++ wpa_supplicant/sme.c | 14 +++++++++- wpa_supplicant/wpa_supplicant.c | 29 +++++++++++++++++++++ wpa_supplicant/wpa_supplicant.conf | 4 +++ wpa_supplicant/wpa_supplicant_i.h | 6 +++++ 12 files changed, 189 insertions(+), 1 deletion(-) diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 4ac9f16..3ae52d4 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -4092,6 +4092,17 @@ struct wpa_driver_ops { */ int (*send_external_auth_status)(void *priv, struct external_auth *params); + +#ifdef CONFIG_MULTI_AP + /** + * set_4addr_mode - Set 4address mode + * @priv: Private driver interface data + * @val: 0 - disabale 4addr mode + * 1 - enable 4addr mode + * @brige_ifname - Bridge interface name + */ + int (*set_4addr_mode)(void *priv, const char *dridge_ifname, int val); +#endif /* CONFIG_MULTI_AP */ }; /** diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 871a5d0..a808bd1 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -10668,6 +10668,48 @@ fail: return ret; } +#ifdef CONFIG_MULTI_AP +static int nl80211_set_4addr_mode(void *priv, const char *bridge_ifname, + int val) +{ + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *msg; + int ret = -ENOBUFS; + + msg = nl80211_cmd_msg(drv->first_bss, 0, NL80211_CMD_SET_INTERFACE); + if (!msg || nla_put_u8(msg, NL80211_ATTR_4ADDR, val)) + goto fail; + + if (bridge_ifname[0] && bss->added_if_into_bridge && !val) { + if (linux_br_del_if(drv->global->ioctl_sock, + bridge_ifname, bss->ifname)) { + wpa_printf(MSG_ERROR, "nl80211: Failed to remove the " + "interface %s to a bridge %s", + bss->ifname, bridge_ifname); + return -1; + } + bss->added_if_into_bridge = 0; + } + + ret = send_and_recv_msgs(drv, msg, NULL, NULL); + msg = NULL; + if (!ret) { + if (bridge_ifname[0] && val) { + if (i802_check_bridge(drv, bss, + bridge_ifname, bss->ifname) < 0) + return -1; + } + return 0; + } + +fail: + nlmsg_free(msg); + wpa_printf(MSG_ERROR, "nl80211: Failed to enable/disable 4addr"); + + return ret; +} +#endif /* CONFIG_MULTI_AP */ const struct wpa_driver_ops wpa_driver_nl80211_ops = { .name = "nl80211", @@ -10797,4 +10839,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = { .get_ext_capab = nl80211_get_ext_capab, .update_connect_params = nl80211_update_connection_params, .send_external_auth_status = nl80211_send_external_auth_status, +#ifdef CONFIG_MULTI_AP + .set_4addr_mode = nl80211_set_4addr_mode, +#endif /* CONFIG_MULTI_AP */ }; diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index c2e93e2..52892ea 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -96,6 +96,10 @@ CONFIG_NO_RANDOM_POOL= CONFIG_OPENSSL_CMAC=y endif +ifdef CONFIG_MULTI_AP +CFLAGS += -DCONFIG_MULTI_AP +endif + OBJS = config.o OBJS += notify.o OBJS += bss.o diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index c439606..bd73bcf 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -2320,6 +2320,9 @@ static const struct parse_data ssid_fields[] = { #endif /* CONFIG_DPP */ { INT_RANGE(owe_group, 0, 65535) }, { INT_RANGE(owe_only, 0, 1) }, +#ifdef CONFIG_MULTI_AP + { INT_RANGE(multiap_backhaul_sta, 0, 1) }, +#endif }; #undef OFFSET diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h index d2a52d7..2dc3fbf 100644 --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h @@ -937,6 +937,14 @@ struct wpa_ssid { * the selection attempts for OWE BSS exceed the configured threshold. */ int owe_transition_bss_select_count; + +#ifdef CONFIG_MULTI_AP + /* + * 0 = normal station + * 1 = backhaul station + */ + int multiap_backhaul_sta; +#endif /* CONFIG_MULTI_AP */ }; #endif /* CONFIG_SSID_H */ diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig index af281e5..e5e96b1 100644 --- a/wpa_supplicant/defconfig +++ b/wpa_supplicant/defconfig @@ -593,3 +593,6 @@ CONFIG_BACKEND=file # Opportunistic Wireless Encryption (OWE) # Experimental implementation of draft-harkins-owe-07.txt #CONFIG_OWE=y + +#Multi-AP protocol support +#CONFIG_MULTI_AP=y diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index 078de23..9c1a26d 100644 --- a/wpa_supplicant/driver_i.h +++ b/wpa_supplicant/driver_i.h @@ -30,6 +30,16 @@ static inline void wpa_drv_deinit(struct wpa_supplicant *wpa_s) wpa_s->driver->deinit(wpa_s->drv_priv); } +#ifdef CONFIG_MULTI_AP +static inline int wpa_drv_set_4addr_mode(struct wpa_supplicant *wpa_s, int val) +{ + if (wpa_s->driver->set_4addr_mode) + return wpa_s->driver->set_4addr_mode(wpa_s->drv_priv, + wpa_s->bridge_ifname, val); + return -1; +} +#endif /* CONFIG_MULTI_AP */ + static inline int wpa_drv_set_param(struct wpa_supplicant *wpa_s, const char *param) { diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 37d429d..272d712 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -2266,6 +2266,55 @@ static void interworking_process_assoc_resp(struct wpa_supplicant *wpa_s, #endif /* CONFIG_INTERWORKING */ +#ifdef CONFIG_MULTI_AP +static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s, + const u8 *ies, size_t ies_len) +{ + struct ieee802_11_elems elems; + const u8 *map_sub_elem, *pos; + size_t len; + + if (!wpa_s->current_ssid->multiap_backhaul_sta) + return; + + if (ies == NULL) + return; + + if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) + return; + + if (elems.multi_ap && (elems.multi_ap_len >= 7)) { + pos = elems.multi_ap + 4; + len = elems.multi_ap_len - 4; + + map_sub_elem = get_ie(pos, len, MULTI_AP_SUB_ELEM_TYPE); + if (!map_sub_elem || map_sub_elem[1] < 1) { + wpa_printf(MSG_INFO, "invalid Multi-AP sub elem type\n"); + goto fail; + } + + if (!(map_sub_elem[2] & MULTI_AP_BACKHAUL_BSS)) { + wpa_printf(MSG_INFO, "AP doesn't support BACKHAUL BSS"); + goto fail; + } + + if (wpa_drv_set_4addr_mode(wpa_s, 1)) { + wpa_printf(MSG_ERROR, "failed to sed 4addr mode\n"); + goto fail; + } + wpa_s->enabled_4addr_mode = 1; + } else { + wpa_printf(MSG_INFO, "AP doesn't support Multi-AP protocol"); + goto fail; + } + + return; + +fail: + wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); + return; +} +#endif /* CONFIG_MULTI_AP */ #ifdef CONFIG_FST static int wpas_fst_update_mbie(struct wpa_supplicant *wpa_s, @@ -2343,6 +2392,10 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s, get_ie(data->assoc_info.resp_ies, data->assoc_info.resp_ies_len, WLAN_EID_VHT_CAP)) wpa_s->ieee80211ac = 1; +#ifdef CONFIG_MULTI_AP + multi_ap_process_assoc_resp(wpa_s, data->assoc_info.resp_ies, + data->assoc_info.resp_ies_len); +#endif /* CONFIG_MULTI_AP */ } if (data->assoc_info.beacon_ies) wpa_hexdump(MSG_DEBUG, "beacon_ies", diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 39c8069..c7b52fd 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -39,7 +39,6 @@ static void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx); static void sme_stop_sa_query(struct wpa_supplicant *wpa_s); #endif /* CONFIG_IEEE80211W */ - #ifdef CONFIG_SAE static int index_within_array(const int *array, int idx) @@ -1554,6 +1553,19 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode, } #endif /* CONFIG_OWE */ +#ifdef CONFIG_MULTI_AP + if (wpa_s->conf->ssid->multiap_backhaul_sta) { + if (wpa_s->sme.assoc_req_ie_len + 9 > + sizeof(wpa_s->sme.assoc_req_ie)) { + wpa_printf(MSG_ERROR, + "Multi-AP: Not enough buffer for Assoc req frame element"); + return; + } + u8 *pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len; + wpa_add_multi_ap_info_ie(pos, &wpa_s->sme.assoc_req_ie_len); + } +#endif /* CONFIG_MULTI_AP */ + params.bssid = bssid; params.ssid = wpa_s->sme.ssid; params.ssid_len = wpa_s->sme.ssid_len; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index e587d7e..b6df53a 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -285,6 +285,23 @@ void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s) wpa_s->last_con_fail_realm_len = 0; } +#ifdef CONFIG_MULTI_AP +void wpa_add_multi_ap_info_ie(u8 *pos, size_t *len) +{ + u8 *buf = pos; + + *buf++ = WLAN_EID_VENDOR_SPECIFIC; + *buf++ = 7; /* len */ + WPA_PUT_BE24(buf, OUI_WFA); + buf += 3; + *buf++ = MULTI_AP_OUI_TYPE; + *buf++ = MULTI_AP_SUB_ELEM_TYPE; + *buf++ = 1; /*sub element len */ + *buf++ = MULTI_AP_BACKHAUL_STA; + + *len += (buf - pos); +} +#endif /* CONFIG_MULTI_AP */ /** * wpa_supplicant_initiate_eapol - Configure EAPOL state machine @@ -2812,6 +2829,11 @@ static u8 * wpas_populate_assoc_ies( } #endif /* CONFIG_IEEE80211R */ +#ifdef CONFIG_MULTI_AP + if (ssid->multiap_backhaul_sta && ((max_wpa_ie_len - wpa_ie_len) > 9)) + wpa_add_multi_ap_info_ie(wpa_ie, &wpa_ie_len); +#endif /* CONFIG_MULTI_AP */ + params->wpa_ie = wpa_ie; params->wpa_ie_len = wpa_ie_len; params->auth_alg = algs; @@ -3290,6 +3312,13 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s, zero_addr = 1; } +#ifdef CONFIG_MULTI_AP + if (wpa_s->enabled_4addr_mode) { + if (wpa_drv_set_4addr_mode(wpa_s, 0)) + wpa_s->enabled_4addr_mode = 0; + } +#endif + #ifdef CONFIG_TDLS wpa_tdls_teardown_peers(wpa_s->wpa); #endif /* CONFIG_TDLS */ diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index 4f59160..1d5c6a1 100644 --- a/wpa_supplicant/wpa_supplicant.conf +++ b/wpa_supplicant/wpa_supplicant.conf @@ -1422,6 +1422,10 @@ fast_reauth=1 # Transitioning between states). #fst_llt=100 +# Set satation to use as BACKHAUL STA. +# default = 0 +# multiap_backhaul_sta = 1 (configure as backhaul STA). + # Example blocks: # Simple case: WPA-PSK, PSK as an ASCII passphrase, allow all valid ciphers diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 8b749f4..0687182 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1234,6 +1234,9 @@ struct wpa_supplicant { unsigned int disable_fils:1; #endif /* CONFIG_FILS */ unsigned int ieee80211ac:1; +#ifdef CONFIG_MULTI_AP + char enabled_4addr_mode; +#endif }; @@ -1493,4 +1496,7 @@ int wpas_ctrl_iface_get_pref_freq_list_override(struct wpa_supplicant *wpa_s, int wpa_is_fils_supported(struct wpa_supplicant *wpa_s); int wpa_is_fils_sk_pfs_supported(struct wpa_supplicant *wpa_s); +#ifdef CONFIG_MULTI_AP +void wpa_add_multi_ap_info_ie(u8 *pos, size_t *len); +#endif #endif /* WPA_SUPPLICANT_I_H */