diff mbox series

[2/2] Basic support for Multi-AP Profile 2 - Assoc changes

Message ID 20211022092646.10016-2-stf_xl@wp.pl
State New
Headers show
Series [1/2] Basic support for Multi-AP Profile 2 - WPS changes | expand

Commit Message

Stanislaw Gruszka Oct. 22, 2021, 9:26 a.m. UTC
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@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 mbox series

Patch

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;