aboutsummaryrefslogtreecommitdiffstats
path: root/package/network/services/hostapd/patches/550-hostapd-Add-Multi-AP-protocol-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/network/services/hostapd/patches/550-hostapd-Add-Multi-AP-protocol-support.patch')
-rw-r--r--package/network/services/hostapd/patches/550-hostapd-Add-Multi-AP-protocol-support.patch306
1 files changed, 306 insertions, 0 deletions
diff --git a/package/network/services/hostapd/patches/550-hostapd-Add-Multi-AP-protocol-support.patch b/package/network/services/hostapd/patches/550-hostapd-Add-Multi-AP-protocol-support.patch
new file mode 100644
index 0000000000..812f794eda
--- /dev/null
+++ b/package/network/services/hostapd/patches/550-hostapd-Add-Multi-AP-protocol-support.patch
@@ -0,0 +1,306 @@
+From 9c06f0f6aed26c1628acaa74df0232dd7b345e9a Mon Sep 17 00:00:00 2001
+From: Venkateswara Naralasetty <vnaralas@codeaurora.org>
+Date: Wed, 5 Dec 2018 11:23:51 +0100
+Subject: [PATCH] hostapd: Add Multi-AP protocol support
+
+The purpose of Multi-AP specification is to enable inter-operability
+across Wi-Fi access points (APs) from different vendors.
+
+This patch introduces one new configuration parameter 'multi_ap' to
+enable Multi-AP functionality and to configure the BSS as a backhaul
+and/or fronthaul BSS.
+
+Advertise vendor specific Multi-AP capabilities in (Re)Association
+Response frame, if Multi-AP functionality is enabled through the
+configuration parameter.
+
+A backhaul AP must support receiving both 3addr and 4addr frames from a
+backhaul STA, so create a VLAN for it just like is done for WDS, i.e.,
+by calling hostapd_set_wds_sta(). Since Multi-AP requires WPA2 (never
+WEP), we can safely call hostapd_set_wds_encryption() as well and we can
+reuse the entire WDS condition.
+
+To parse the Multi-AP Extension subelement, we use get_ie(): even though
+that function is meant for parsing IEs, it works for subelements.
+
+Signed-off-by: Venkateswara Naralasetty <vnaralas@codeaurora.org>
+Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
+Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
+---
+ hostapd/config_file.c | 10 +++++
+ hostapd/hostapd.conf | 7 ++++
+ src/ap/ap_config.h | 4 ++
+ src/ap/ieee802_11.c | 77 +++++++++++++++++++++++++++++++++-
+ src/ap/sta_info.c | 2 +-
+ src/ap/sta_info.h | 1 +
+ src/common/ieee802_11_common.c | 24 +++++++++++
+ src/common/ieee802_11_common.h | 4 ++
+ src/common/ieee802_11_defs.h | 7 ++++
+ 9 files changed, 134 insertions(+), 2 deletions(-)
+
+--- a/hostapd/config_file.c
++++ b/hostapd/config_file.c
+@@ -4115,6 +4115,16 @@ static int hostapd_config_fill(struct ho
+ } else if (os_strcmp(buf, "coloc_intf_reporting") == 0) {
+ bss->coloc_intf_reporting = atoi(pos);
+ #endif /* CONFIG_OWE */
++ } else if (os_strcmp(buf, "multi_ap") == 0) {
++ int val = atoi(pos);
++
++ if (val < 0 || val > 3) {
++ wpa_printf(MSG_ERROR, "Line %d: Invalid multi_ap '%s'",
++ line, buf);
++ return -1;
++ }
++
++ bss->multi_ap = val;
+ } else {
+ wpa_printf(MSG_ERROR,
+ "Line %d: unknown configuration item '%s'",
+--- a/hostapd/hostapd.conf
++++ b/hostapd/hostapd.conf
+@@ -438,6 +438,13 @@ wmm_ac_vo_txop_limit=47
+ wmm_ac_vo_acm=0
+ # Note: for IEEE 802.11b mode: cWmin=3 cWmax=4 burst=102
+
++# Enable Multi-AP functionality
++# 0 = disabled (default)
++# 1 = AP support backhaul BSS
++# 2 = AP support fronthaul BSS
++# 3 = AP supports both backhaul BSS and fronthaul BSS
++#multi_ap=0
++
+ # Static WEP key configuration
+ #
+ # The key number to use when transmitting.
+--- a/src/ap/ap_config.h
++++ b/src/ap/ap_config.h
+@@ -688,6 +688,10 @@ struct hostapd_bss_config {
+ #endif /* CONFIG_OWE */
+
+ int coloc_intf_reporting;
++
++#define BACKHAUL_BSS 1
++#define FRONTHAUL_BSS 2
++ int multi_ap; /* bitmap of BACKHAUL_BSS, FRONTHAUL_BSS */
+ };
+
+ /**
+--- a/src/ap/ieee802_11.c
++++ b/src/ap/ieee802_11.c
+@@ -62,6 +62,22 @@ prepare_auth_resp_fils(struct hostapd_da
+ int *is_pub);
+ #endif /* CONFIG_FILS */
+
++
++u8 * hostapd_eid_multi_ap(struct hostapd_data *hapd, u8 *eid)
++{
++ u8 multi_ap_val = 0;
++
++ if (!hapd->conf->multi_ap)
++ return eid;
++ if (hapd->conf->multi_ap & BACKHAUL_BSS)
++ multi_ap_val |= MULTI_AP_BACKHAUL_BSS;
++ if (hapd->conf->multi_ap & FRONTHAUL_BSS)
++ multi_ap_val |= MULTI_AP_FRONTHAUL_BSS;
++
++ return eid + add_multi_ap_ie(eid, 9, multi_ap_val);
++}
++
++
+ u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
+ {
+ u8 *pos = eid;
+@@ -2210,6 +2226,57 @@ static u16 check_wmm(struct hostapd_data
+ return WLAN_STATUS_SUCCESS;
+ }
+
++static u16 check_multi_ap(struct hostapd_data *hapd, struct sta_info *sta,
++ const u8 *multi_ap_ie, size_t multi_ap_len)
++{
++ u8 multi_ap_value = 0;
++
++ sta->flags &= ~WLAN_STA_MULTI_AP;
++
++ if (!hapd->conf->multi_ap)
++ return WLAN_STATUS_SUCCESS;
++
++ if (multi_ap_ie) {
++ const u8 *multi_ap_subelem;
++
++ multi_ap_subelem = get_ie(multi_ap_ie + 4,
++ multi_ap_len - 4,
++ MULTI_AP_SUB_ELEM_TYPE);
++ if (multi_ap_subelem && multi_ap_subelem[1] == 1) {
++ multi_ap_value = multi_ap_subelem[2];
++ } else {
++ hostapd_logger(hapd, sta->addr,
++ HOSTAPD_MODULE_IEEE80211,
++ HOSTAPD_LEVEL_INFO,
++ "Multi-AP IE has missing or invalid Multi-AP subelement");
++ return WLAN_STATUS_INVALID_IE;
++ }
++ }
++
++ if (multi_ap_value == MULTI_AP_BACKHAUL_STA)
++ sta->flags |= WLAN_STA_MULTI_AP;
++
++ if ((hapd->conf->multi_ap & BACKHAUL_BSS) &&
++ multi_ap_value == MULTI_AP_BACKHAUL_STA)
++ return WLAN_STATUS_SUCCESS;
++
++ if (hapd->conf->multi_ap & FRONTHAUL_BSS) {
++ if (multi_ap_value == MULTI_AP_BACKHAUL_STA) {
++ hostapd_logger(hapd, sta->addr,
++ HOSTAPD_MODULE_IEEE80211,
++ HOSTAPD_LEVEL_INFO,
++ "Backhaul STA tries to associate with fronthaul-only BSS");
++ return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
++ }
++ return WLAN_STATUS_SUCCESS;
++ }
++
++ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
++ HOSTAPD_LEVEL_INFO,
++ "Non-Multi-AP STA tries to associate with backhaul-only BSS");
++ return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
++}
++
+
+ static u16 copy_supp_rates(struct hostapd_data *hapd, struct sta_info *sta,
+ struct ieee802_11_elems *elems)
+@@ -2466,6 +2533,11 @@ static u16 check_assoc_ies(struct hostap
+ resp = copy_supp_rates(hapd, sta, &elems);
+ if (resp != WLAN_STATUS_SUCCESS)
+ return resp;
++
++ resp = check_multi_ap(hapd, sta, elems.multi_ap, elems.multi_ap_len);
++ if (resp != WLAN_STATUS_SUCCESS)
++ return resp;
++
+ #ifdef CONFIG_IEEE80211N
+ resp = copy_sta_ht_capab(hapd, sta, elems.ht_capabilities);
+ if (resp != WLAN_STATUS_SUCCESS)
+@@ -2996,6 +3068,9 @@ static u16 send_assoc_resp(struct hostap
+ }
+ #endif /* CONFIG_WPS */
+
++ if (sta && (sta->flags & WLAN_STA_MULTI_AP))
++ p = hostapd_eid_multi_ap(hapd, p);
++
+ #ifdef CONFIG_P2P
+ if (sta && sta->p2p_ie && hapd->p2p_group) {
+ struct wpabuf *p2p_resp_ie;
+@@ -4236,7 +4311,7 @@ static void handle_assoc_cb(struct hosta
+ sta->flags |= WLAN_STA_WDS;
+ }
+
+- if (sta->flags & WLAN_STA_WDS) {
++ if (sta->flags & (WLAN_STA_WDS | WLAN_STA_MULTI_AP)) {
+ int ret;
+ char ifname_wds[IFNAMSIZ + 1];
+
+--- a/src/ap/sta_info.c
++++ b/src/ap/sta_info.c
+@@ -166,7 +166,7 @@ void ap_free_sta(struct hostapd_data *ha
+ /* just in case */
+ ap_sta_set_authorized(hapd, sta, 0);
+
+- if (sta->flags & WLAN_STA_WDS)
++ if (sta->flags & (WLAN_STA_WDS | WLAN_STA_MULTI_AP))
+ hostapd_set_wds_sta(hapd, NULL, sta->addr, sta->aid, 0);
+
+ if (sta->ipaddr)
+--- a/src/ap/sta_info.h
++++ b/src/ap/sta_info.h
+@@ -36,6 +36,7 @@
+ #define WLAN_STA_VHT_OPMODE_ENABLED BIT(20)
+ #define WLAN_STA_VENDOR_VHT BIT(21)
+ #define WLAN_STA_PENDING_FILS_ERP BIT(22)
++#define WLAN_STA_MULTI_AP BIT(23)
+ #define WLAN_STA_PENDING_DISASSOC_CB BIT(29)
+ #define WLAN_STA_PENDING_DEAUTH_CB BIT(30)
+ #define WLAN_STA_NONERP BIT(31)
+--- a/src/common/ieee802_11_common.c
++++ b/src/common/ieee802_11_common.c
+@@ -126,6 +126,10 @@ static int ieee802_11_parse_vendor_speci
+ elems->roaming_cons_sel = pos;
+ elems->roaming_cons_sel_len = elen;
+ break;
++ case MULTI_AP_OUI_TYPE:
++ elems->multi_ap = pos;
++ elems->multi_ap_len = elen;
++ break;
+ default:
+ wpa_printf(MSG_MSGDUMP, "Unknown WFA "
+ "information element ignored "
+@@ -1519,6 +1523,26 @@ size_t mbo_add_ie(u8 *buf, size_t len, c
+ }
+
+
++size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value)
++{
++ u8 *pos = buf;
++
++ if (len < 9)
++ return 0;
++
++ *pos++ = WLAN_EID_VENDOR_SPECIFIC;
++ *pos++ = 7; /* len */
++ WPA_PUT_BE24(pos, OUI_WFA);
++ pos += 3;
++ *pos++ = MULTI_AP_OUI_TYPE;
++ *pos++ = MULTI_AP_SUB_ELEM_TYPE;
++ *pos++ = 1; /* len */
++ *pos++ = value;
++
++ return pos - buf;
++}
++
++
+ static const struct country_op_class us_op_class[] = {
+ { 1, 115 },
+ { 2, 118 },
+--- a/src/common/ieee802_11_common.h
++++ b/src/common/ieee802_11_common.h
+@@ -84,6 +84,7 @@ struct ieee802_11_elems {
+ const u8 *power_capab;
+ const u8 *roaming_cons_sel;
+ const u8 *password_id;
++ const u8 *multi_ap;
+
+ u8 ssid_len;
+ u8 supp_rates_len;
+@@ -130,6 +131,7 @@ struct ieee802_11_elems {
+ u8 power_capab_len;
+ u8 roaming_cons_sel_len;
+ u8 password_id_len;
++ u8 multi_ap_len;
+
+ struct mb_ies_info mb_ies;
+ };
+@@ -189,6 +191,8 @@ const u8 * get_ie_ext(const u8 *ies, siz
+
+ size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len);
+
++size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value);
++
+ struct country_op_class {
+ u8 country_op_class;
+ u8 global_op_class;
+--- a/src/common/ieee802_11_defs.h
++++ b/src/common/ieee802_11_defs.h
+@@ -1210,6 +1210,13 @@ struct ieee80211_ampe_ie {
+ #define MBO_OUI_TYPE 22
+ #define OWE_IE_VENDOR_TYPE 0x506f9a1c
+ #define OWE_OUI_TYPE 28
++#define MULTI_AP_OUI_TYPE 0x1B
++
++#define MULTI_AP_SUB_ELEM_TYPE 0x06
++#define MULTI_AP_TEAR_DOWN BIT(4)
++#define MULTI_AP_FRONTHAUL_BSS BIT(5)
++#define MULTI_AP_BACKHAUL_BSS BIT(6)
++#define MULTI_AP_BACKHAUL_STA BIT(7)
+
+ #define WMM_OUI_TYPE 2
+ #define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0