[PATCH 2/2] Basic support for Multi-AP Profile 2 - Assoc changes
Stanislaw Gruszka
stf_xl at wp.pl
Fri Oct 22 02:26:46 PDT 2021
Patch adds basic support for additional Multi-AP Profile 2
subelements in (Re)Assoc Request/Response frames.
TODO: passing values via wla_cli and handle
'Profile-1/2 Backhaul STA association disallowed' bits.
Signed-off-by: Stanislaw Gruszka <stf_xl at wp.pl>
---
src/ap/ieee802_11.c | 8 +++++++-
src/common/ieee802_11_common.c | 27 ++++++++++++++++++++++++---
src/common/ieee802_11_common.h | 2 +-
src/common/ieee802_11_defs.h | 6 ++++++
wpa_supplicant/events.c | 14 +++++++++++++-
wpa_supplicant/sme.c | 15 +++++++++------
wpa_supplicant/wpa_supplicant.c | 4 +++-
wpa_supplicant/wpa_supplicant_i.h | 2 ++
8 files changed, 65 insertions(+), 13 deletions(-)
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 71fbefc8e..aeadf38b6 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -91,6 +91,8 @@ static void handle_auth(struct hostapd_data *hapd,
u8 * hostapd_eid_multi_ap(struct hostapd_data *hapd, u8 *eid)
{
u8 multi_ap_val = 0;
+ u16 vlan_id = 0;
+ u8 profile = 1;
if (!hapd->conf->multi_ap)
return eid;
@@ -98,8 +100,12 @@ u8 * hostapd_eid_multi_ap(struct hostapd_data *hapd, u8 *eid)
multi_ap_val |= MULTI_AP_BACKHAUL_BSS;
if (hapd->conf->multi_ap & FRONTHAUL_BSS)
multi_ap_val |= MULTI_AP_FRONTHAUL_BSS;
+ if (hapd->conf->multi_ap_profile > 1) {
+ profile = hapd->conf->multi_ap_profile;
+ vlan_id = hapd->conf->multi_ap_primary_vlan_id;
+ }
- return eid + add_multi_ap_ie(eid, 9, multi_ap_val);
+ return eid + add_multi_ap_ie(eid, 16, multi_ap_val, profile, vlan_id);
}
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index 5b74ddcdf..87daacc47 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -2053,22 +2053,43 @@ 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)
+size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value, u8 profile, u16 vlan_id)
{
+ int ie_len = 9;
u8 *pos = buf;
- if (len < 9)
+ if (profile > 1) {
+ ie_len += 3;
+ if (vlan_id)
+ ie_len += 4;
+ }
+
+ if (len < ie_len)
return 0;
*pos++ = WLAN_EID_VENDOR_SPECIFIC;
- *pos++ = 7; /* len */
+ *pos++ = ie_len - 2; /* 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;
+ if (profile > 1) {
+ *pos++ = MULTI_AP_SUB_ELEM_PROFILE;
+ *pos++ = 1; /* len */
+ *pos++ = profile;
+
+ if (vlan_id) {
+ *pos++ = MULTI_AP_SUB_ELEM_8021Q;
+ *pos++ = 2; /* len */
+ WPA_PUT_LE16(pos, vlan_id);
+ pos += 2;
+ }
+ }
+
return pos - buf;
}
diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h
index e4e4c613e..c2c16903a 100644
--- a/src/common/ieee802_11_common.h
+++ b/src/common/ieee802_11_common.h
@@ -250,7 +250,7 @@ const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type);
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);
+size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value, u8 profile, u16 vlan_id);
struct country_op_class {
u8 country_op_class;
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 24dbfa8bd..2e59ba729 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -1372,6 +1372,12 @@ struct ieee80211_ampe_ie {
#define MULTI_AP_BACKHAUL_BSS BIT(6)
#define MULTI_AP_BACKHAUL_STA BIT(7)
+#define MULTI_AP_SUB_ELEM_PROFILE 0x07
+#define MULTI_AP_PROFILE_1 0x01
+#define MULTI_AP_PROFILE_2 0x02
+
+#define MULTI_AP_SUB_ELEM_8021Q 0x08
+
#define WMM_OUI_TYPE 2
#define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0
#define WMM_OUI_SUBTYPE_PARAMETER_ELEMENT 1
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 878d9bc74..bb88144b2 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2576,10 +2576,12 @@ 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;
+ const u8 *map_sub_elem, *map_profile, *map_8021q, *pos;
size_t len;
wpa_s->multi_ap_ie = 0;
+ wpa_s->multi_ap_profile = 0;
+ wpa_s->multi_ap_primary_vlan_id = 0;
if (!ies ||
ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed ||
@@ -2597,6 +2599,16 @@ static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s,
wpa_s->multi_ap_fronthaul = !!(map_sub_elem[2] &
MULTI_AP_FRONTHAUL_BSS);
wpa_s->multi_ap_ie = 1;
+
+ map_profile = get_ie(pos, len, MULTI_AP_SUB_ELEM_PROFILE);
+ if (!map_profile || map_profile[1] < 1)
+ return;
+ wpa_s->multi_ap_profile = map_profile[2];
+
+ map_8021q = get_ie(pos, len, MULTI_AP_SUB_ELEM_8021Q);
+ if (!map_8021q || map_8021q[1] < 2)
+ return;
+ wpa_s->multi_ap_primary_vlan_id = WPA_GET_LE16(map_8021q + 2);
}
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index f2c42ff35..786536d4b 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -1929,12 +1929,15 @@ mscs_fail:
if (ssid && ssid->multi_ap_backhaul_sta) {
size_t multi_ap_ie_len;
-
- multi_ap_ie_len = add_multi_ap_ie(
- wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
- sizeof(wpa_s->sme.assoc_req_ie) -
- wpa_s->sme.assoc_req_ie_len,
- MULTI_AP_BACKHAUL_STA);
+ u8 profile = ssid->multi_ap_backhaul_sta;
+ u8 *buf = wpa_s->sme.assoc_req_ie +
+ wpa_s->sme.assoc_req_ie_len;
+ int len = sizeof(wpa_s->sme.assoc_req_ie) -
+ wpa_s->sme.assoc_req_ie_len;
+
+ multi_ap_ie_len = add_multi_ap_ie(buf, len,
+ MULTI_AP_BACKHAUL_STA,
+ profile, 0);
if (multi_ap_ie_len == 0) {
wpa_printf(MSG_ERROR,
"Multi-AP: Failed to build Multi-AP IE");
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 0f9db267f..42ab212c5 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -3342,10 +3342,12 @@ mscs_end:
if (ssid->multi_ap_backhaul_sta) {
size_t multi_ap_ie_len;
+ u8 profile = ssid->multi_ap_backhaul_sta;
multi_ap_ie_len = add_multi_ap_ie(wpa_ie + wpa_ie_len,
max_wpa_ie_len - wpa_ie_len,
- MULTI_AP_BACKHAUL_STA);
+ MULTI_AP_BACKHAUL_STA,
+ profile, 0);
if (multi_ap_ie_len == 0) {
wpa_printf(MSG_ERROR,
"Multi-AP: Failed to build Multi-AP IE");
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index cbc955159..4cbd609c3 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1498,6 +1498,8 @@ struct wpa_supplicant {
unsigned int multi_ap_ie:1;
unsigned int multi_ap_backhaul:1;
unsigned int multi_ap_fronthaul:1;
+ u8 multi_ap_profile;
+ u16 multi_ap_primary_vlan_id;
struct robust_av_data robust_av;
bool mscs_setup_done;
--
2.25.1
More information about the Hostap
mailing list