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@xxxxx> --- 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 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap