From patchwork Wed Feb 15 23:08:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrei Otcheretianski X-Patchwork-Id: 1743150 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=O2ZRWPVz; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=FqZLrpq4; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PHDPz3N8Rz23yD for ; Thu, 16 Feb 2023 10:12:55 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=s1TvU35x5aVR1T3++BvfY0GJPdqdqLbIMvpKN0obAf8=; b=O2ZRWPVzeN6Mac nvGXCbu2nGLQDAiADLsC8BtgbVZJnWb+8/qjb1r94M6Tf4P64tmY2/OwcI3Ho8k/IgDuYrl4NZz2p 1HEQSjh74CfJTW+INJRLs22i2NRHZ3rRoMzhrYVbWZrc9JzH7SwJi3uawcIFpXIQeYxUrwmnNvlcz Yo75Tbxe7AXtiZqHTSSQs8lq2XBr7ZhBXy/t+MQR3iB+XcbkW1TrLtots0CER4izKwdCNiTuIEYD/ ai/XFyreEoWq7C0FE14d0QnCYPkbpeSJ98jCPr2vqWs2n78oelbIkBQZsnfS4p0fwY4VFFzrANCT9 whWD6+znF6ZN2ayJ/TkA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1pSQwQ-007mPY-7c; Wed, 15 Feb 2023 23:11:58 +0000 Received: from mga03.intel.com ([134.134.136.65]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1pSQu8-007lLy-Ac for hostap@lists.infradead.org; Wed, 15 Feb 2023 23:09:38 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1676502576; x=1708038576; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=/VXzh/FLHo0f80rlmEzIpMEGvLo04e3gN4AJzugK2EY=; b=FqZLrpq4paozoW10be0cfJ0XrSpX89poBLUco7LBTktJGa6VKygYVheR f7Oyjew2AsOZOq+GmJqqHW4vsGT5Plwd2/hDqvIrLUtsLOQehxQElqCBF twhstGatUKqrmQgVof6/jrl/YXiRvwsxzVRtTw5ezKq52LluQ0NC9wxBA GvMHf08MRqK/8tA7msEkCvS1NAfF1DTnvaxSZ5LQoFB5P0zkxWk/qc1Ai Wkf3Iyg6jrNtayDlZ1hp9fgV4S+jTL5LQPAbqi2kD12+PC7r82uovfeii XOJNHg1mNh0W/jysVIEodCPxMd63rcfRDF8x/xR7ymhKXbbI0Khl7IsEp g==; X-IronPort-AV: E=McAfee;i="6500,9779,10622"; a="333719592" X-IronPort-AV: E=Sophos;i="5.97,300,1669104000"; d="scan'208";a="333719592" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2023 15:09:35 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10622"; a="702344168" X-IronPort-AV: E=Sophos;i="5.97,300,1669104000"; d="scan'208";a="702344168" Received: from zfilgut-mobl.ger.corp.intel.com (HELO aotchere-desk.intel.com) ([10.254.144.126]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2023 15:09:34 -0800 From: Andrei Otcheretianski To: hostap@lists.infradead.org Cc: Andrei Otcheretianski , Ilan Peer Subject: [PATCH 09/50] AP: Allow starting multiple interfaces within single MLD Date: Thu, 16 Feb 2023 01:08:23 +0200 Message-Id: <20230215230904.933291-10-andrei.otcheretianski@intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20230215230904.933291-1-andrei.otcheretianski@intel.com> References: <20230215230904.933291-1-andrei.otcheretianski@intel.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230215_150936_428069_8FE3E2C8 X-CRM114-Status: GOOD ( 28.06 ) X-Spam-Score: -2.7 (--) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Add support for including multiple hostapd interfaces in the same AP MLD, i.e., all using the same underlying driver network interface. To do so, when a new hostapd interface is added, if there is already another interface using the same underlying network interface, associate the new interface with the same private data object, inste [...] Content analysis details: (-2.7 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [134.134.136.65 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -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_EF Message has a valid DKIM or DK signature from envelope-from domain -0.2 DKIMWL_WL_HIGH DKIMwl.org - High trust sender X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Add support for including multiple hostapd interfaces in the same AP MLD, i.e., all using the same underlying driver network interface. To do so, when a new hostapd interface is added, if there is already another interface using the same underlying network interface, associate the new interface with the same private data object, instead of creating a new one. As some of the BSS's are non first BSS's, meaning that they reuse the drv_priv of the initial BSS, make sure not to double free it. Currently multiple BSS entries are not supported so always use bss[0] for MLD. Signed-off-by: Andrei Otcheretianski Signed-off-by: Ilan Peer --- hostapd/main.c | 84 +++++++++++++++++++++++++++++++++++++++++++++ src/ap/ap_drv_ops.h | 12 +++++++ src/ap/hostapd.c | 39 +++++++++++++++++---- src/ap/hostapd.h | 2 ++ 4 files changed, 131 insertions(+), 6 deletions(-) diff --git a/hostapd/main.c b/hostapd/main.c index ce2df81c4a..228ee44b1b 100644 --- a/hostapd/main.c +++ b/hostapd/main.c @@ -164,6 +164,59 @@ static int hostapd_driver_init(struct hostapd_iface *iface) return -1; } +#ifdef CONFIG_IEEE80211BE + if (conf->mld_ap) { + for (i = 0; i < iface->interfaces->count; i++) { + struct hostapd_iface *h = iface->interfaces->iface[i]; + struct hostapd_data *h_hapd = h->bss[0]; + struct hostapd_bss_config *hconf = h_hapd->conf; + + if (h == iface) { + wpa_printf(MSG_ERROR, "Skip own iface"); + continue; + } + + if (!hconf->mld_ap || hconf->mld_id != conf->mld_id) { + wpa_printf(MSG_ERROR, + "Skip non matching mld_id"); + continue; + } + + wpa_printf(MSG_DEBUG, "Found matching MLD iface"); + if (!h_hapd->drv_priv) { + wpa_printf(MSG_ERROR, + "Matching MLD BSS not initialized yet"); + continue; + } + + hapd->drv_priv = h_hapd->drv_priv; + + /* + * All interfaces participating in the MLD AP would have + * the same MLD address, which in the interface HW + * address, while the interface address would be + * derived from the original interface address if BSSID + * is not configured, and otherwise it would be the + * configured BSSID. + */ + os_memcpy(hapd->mld_addr, h_hapd->mld_addr, ETH_ALEN); + if (is_zero_ether_addr(b)) { + os_memcpy(hapd->own_addr, h_hapd->mld_addr, ETH_ALEN); + random_mac_addr_keep_oui(hapd->own_addr); + } else { + os_memcpy(hapd->own_addr, b, ETH_ALEN); + } + + /* + * mark the interface as a secondary interface, as this + * is needed for the de-initialization flow + */ + hapd->mld_first_bss = h_hapd; + goto setup_mld; + } + } +#endif /* CONFIG_IEEE80211BE */ + /* Initialize the driver interface */ if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5])) b = NULL; @@ -214,6 +267,20 @@ static int hostapd_driver_init(struct hostapd_iface *iface) return -1; } +#ifdef CONFIG_IEEE80211BE + /* + * This is the first interface added to the MLD AP, so have the + * interface HW address be the MLD address and set a link address to + * this interface + */ + if (hapd->conf->mld_ap) { + os_memcpy(hapd->mld_addr, hapd->own_addr, ETH_ALEN); + random_mac_addr_keep_oui(hapd->own_addr); + } + + setup_mld: +#endif /* CONFIG_IEEE80211BE */ + if (hapd->driver->get_capa && hapd->driver->get_capa(hapd->drv_priv, &capa) == 0) { struct wowlan_triggers *triggs; @@ -246,6 +313,23 @@ static int hostapd_driver_init(struct hostapd_iface *iface) iface->ema_max_periodicity = capa.ema_max_periodicity; } +#ifdef CONFIG_IEEE80211BE + if (hapd->conf->mld_ap) { + if (!(iface->drv_flags2 & WPA_DRIVER_FLAGS2_MLO)) { + wpa_printf(MSG_DEBUG, "MLD: not supported by driver"); + return -1; + } + + wpa_printf(MSG_DEBUG, + "MLD: Set link_id=%u, mld_addr=" MACSTR ", own_addr=" MACSTR, + hapd->conf->mld_link_id, + MAC2STR(hapd->mld_addr), + MAC2STR(hapd->own_addr)); + + hostapd_drv_link_add(hapd, hapd->conf->mld_link_id, + hapd->own_addr); + } +#endif /* CONFIG_IEEE80211BE */ return 0; } diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h index 93b2244990..be280de218 100644 --- a/src/ap/ap_drv_ops.h +++ b/src/ap/ap_drv_ops.h @@ -435,4 +435,16 @@ hostapd_drv_register_frame(struct hostapd_data *hapd, u16 type, } #endif /* CONFIG_TESTING_OPTIONS */ +#ifdef CONFIG_IEEE80211BE +static inline int hostapd_drv_link_add(struct hostapd_data *hapd, + u8 link_id, const u8 *addr) +{ + if (!hapd->driver || !hapd->drv_priv || !hapd->driver->link_add) + return -1; + + return hapd->driver->link_add(hapd->drv_priv, link_id, addr); + +} +#endif /* CONFIG_IEEE80211BE */ + #endif /* AP_DRV_OPS */ diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 58492e51ed..9abfb5fa5f 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -393,6 +393,25 @@ static int hostapd_broadcast_wep_set(struct hostapd_data *hapd) #endif /* CONFIG_WEP */ +static void hostapd_clear_drv_priv(struct hostapd_data *hapd) +{ + u8 i; + + for (i = 0; i < hapd->iface->interfaces->count; i++) { + struct hostapd_iface *iface = hapd->iface->interfaces->iface[i]; + + if (hapd->iface == iface) + continue; + + if (iface->bss && iface->bss[0] && + iface->bss[0]->mld_first_bss == hapd) + iface->bss[0]->drv_priv = NULL; + } + + hapd->drv_priv = NULL; +} + + void hostapd_free_hapd_data(struct hostapd_data *hapd) { os_free(hapd->probereq_cb); @@ -449,7 +468,7 @@ void hostapd_free_hapd_data(struct hostapd_data *hapd) * driver wrapper may have removed its internal instance * and hapd->drv_priv is not valid anymore. */ - hapd->drv_priv = NULL; + hostapd_clear_drv_priv(hapd); } } @@ -2780,8 +2799,9 @@ void hostapd_interface_deinit_free(struct hostapd_iface *iface) wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", __func__, driver, drv_priv); if (driver && driver->hapd_deinit && drv_priv) { - driver->hapd_deinit(drv_priv); - iface->bss[0]->drv_priv = NULL; + if (!iface->bss[0]->mld_first_bss) + driver->hapd_deinit(drv_priv); + hostapd_clear_drv_priv(iface->bss[0]); } hostapd_interface_free(iface); } @@ -2796,13 +2816,14 @@ static void hostapd_deinit_driver(const struct wpa_driver_ops *driver, wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", __func__, driver, drv_priv); if (driver && driver->hapd_deinit && drv_priv) { - driver->hapd_deinit(drv_priv); + if (!hapd_iface->bss[0]->mld_first_bss) + driver->hapd_deinit(drv_priv); for (j = 0; j < hapd_iface->num_bss; j++) { wpa_printf(MSG_DEBUG, "%s:bss[%d]->drv_priv=%p", __func__, (int) j, hapd_iface->bss[j]->drv_priv); if (hapd_iface->bss[j]->drv_priv == drv_priv) { - hapd_iface->bss[j]->drv_priv = NULL; + hostapd_clear_drv_priv(hapd_iface->bss[j]); hapd_iface->extended_capa = NULL; hapd_iface->extended_capa_mask = NULL; hapd_iface->extended_capa_len = 0; @@ -3143,8 +3164,14 @@ int hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf) conf_file = ptr + 7; for (i = 0; i < interfaces->count; i++) { + bool mld_ap = false; + +#ifdef CONFIG_IEEE80211BE + mld_ap = interfaces->iface[i]->conf->bss[0]->mld_ap; +#endif /* CONFIG_IEEE80211BE */ + if (!os_strcmp(interfaces->iface[i]->conf->bss[0]->iface, - buf)) { + buf) && !mld_ap) { wpa_printf(MSG_INFO, "Cannot add interface - it " "already exists"); return -1; diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index ed2ff45877..6c0cece36e 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -174,6 +174,8 @@ struct hostapd_data { unsigned int reenable_beacon:1; u8 own_addr[ETH_ALEN]; + u8 mld_addr[ETH_ALEN]; + struct hostapd_data *mld_first_bss; int num_sta; /* number of entries in sta_list */ struct sta_info *sta_list; /* STA info list head */