diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 2f9c9286a..e9f0c5ca2 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -4822,6 +4822,16 @@ static int hostapd_config_fill(struct hostapd_config *conf, return -1; } bss->multi_ap_client_disallow = val; + } else if (os_strcmp(buf, "multi_ap_vlanid") == 0) { + int val = atoi(pos); + + if (val < 0 || val > MAX_VLAN_ID) { + wpa_printf(MSG_ERROR, + "Line %d: Invalid multi_ap_vlan_id '%s'", + line, buf); + return -1; + } + bss->multi_ap_vlanid = val; } else if (os_strcmp(buf, "rssi_reject_assoc_rssi") == 0) { conf->rssi_reject_assoc_rssi = atoi(pos); } else if (os_strcmp(buf, "rssi_reject_assoc_timeout") == 0) { diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index ca1989893..727a87770 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -2578,6 +2578,10 @@ own_ip_addr=127.0.0.1 # 2 = Profile-2 Backhaul STA association disallowed #multi_ap_client_disallow=0 +# Multi-AP VLAN ID +# A valid non-zero VLAN ID will be used to update Default IEEE 802.1Q Setting +#multi_ap_vlanid=0 + # WPS UPnP interface # If set, support for external Registrars is enabled. #upnp_iface=br0 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 3254bfd8c..754d55331 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -806,6 +806,8 @@ struct hostapd_bss_config { /* Multi-AP Profile-2 clients not allowed to connect */ #define PROFILE2_CLIENT_ASSOC_DISALLOW BIT(1) unsigned int multi_ap_client_disallow; + /* Primary VLAN ID to use in Multi-AP */ + int multi_ap_vlanid; #ifdef CONFIG_AIRTIME_POLICY unsigned int airtime_weight; diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index dfc5a5c39..17f98f59d 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -110,6 +110,7 @@ static u8 * hostapd_eid_multi_ap(struct hostapd_data *hapd, u8 *eid, size_t len) MULTI_AP_PROFILE2_BACKHAUL_STA_DISALLOWED; multi_ap.profile = hapd->conf->multi_ap_profile; + multi_ap.vlanid = hapd->conf->multi_ap_vlanid; return eid + add_multi_ap_ie(eid, len, &multi_ap); } diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c index 560e48a38..7c3a21fe5 100644 --- a/src/common/ieee802_11_common.c +++ b/src/common/ieee802_11_common.c @@ -2576,6 +2576,7 @@ u16 check_multi_ap_ie(const u8 *multi_ap_ie, size_t multi_ap_len, { const struct element *elem; bool ext_present = false; + unsigned int vlan_id; os_memset(multi_ap, 0, sizeof(*multi_ap)); @@ -2613,6 +2614,27 @@ u16 check_multi_ap_ie(const u8 *multi_ap_ie, size_t multi_ap_len, return WLAN_STATUS_ASSOC_DENIED_UNSPEC; } break; + case MULTI_AP_VLAN_SUB_ELEM_TYPE: + if (multi_ap->profile < MULTI_AP_PROFILE_2) { + wpa_printf(MSG_DEBUG, + "Multi-AP IE invalid profile to read VLAN IE"); + return WLAN_STATUS_INVALID_IE; + } + if (elen < 2) { + wpa_printf(MSG_DEBUG, + "Multi-AP IE invalid Multi-AP VLAN subelement"); + return WLAN_STATUS_INVALID_IE; + } + + vlan_id = WPA_GET_LE16(pos); + if (vlan_id < 1 || vlan_id > 4094) { + wpa_printf(MSG_INFO, + "Multi-AP IE invalid Multi-AP VLAN ID %d", + vlan_id); + return WLAN_STATUS_INVALID_IE; + } + multi_ap->vlanid = vlan_id; + break; default: wpa_printf(MSG_DEBUG, "Ignore unknown subelement %u in Multi-AP IE", @@ -2670,6 +2692,19 @@ size_t add_multi_ap_ie(u8 *buf, size_t len, *pos++ = multi_ap->profile; } + /* Add Multi-AP Default 802.1Q Setting subelement only for backhaul BSS + */ + if (multi_ap->vlanid && + multi_ap->profile >= MULTI_AP_PROFILE_2 && + (multi_ap->capability & MULTI_AP_BACKHAUL_BSS)) { + if (buf + len - pos < 4) + return 0; + *pos++ = MULTI_AP_VLAN_SUB_ELEM_TYPE; + *pos++ = 2; + WPA_PUT_LE16(pos, multi_ap->vlanid); + pos += 2; + } + *len_ptr = pos - len_ptr - 1; return pos - buf; diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h index cd04666ba..4eaeed505 100644 --- a/src/common/ieee802_11_common.h +++ b/src/common/ieee802_11_common.h @@ -33,6 +33,7 @@ struct mb_ies_info { struct multi_ap_params { u8 capability; u8 profile; + u16 vlanid; }; /* Parsed Information Elements */ diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index b248a5cac..5b39a61e1 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -1448,6 +1448,7 @@ struct ieee80211_ampe_ie { #define MULTI_AP_SUB_ELEM_TYPE 0x06 #define MULTI_AP_PROFILE_SUB_ELEM_TYPE 0x07 +#define MULTI_AP_VLAN_SUB_ELEM_TYPE 0x08 #define MULTI_AP_PROFILE2_BACKHAUL_STA_DISALLOWED BIT(2) #define MULTI_AP_PROFILE1_BACKHAUL_STA_DISALLOWED BIT(3)