From 897902953cd02174e49ea796307bb0b74526e84d Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 15 Oct 2020 21:35:08 -0700 Subject: [PATCH] multiple_bssid: add support Add support for multiple bssid. In order to be able to do EMA HW offloading inside the kernel, we need to send the multiple bssid elemets inside a dedicated nl80211 arreibute. Signed-off-by: Aloka Dixit Signed-off-by: John Crispin --- hostapd/config_file.c | 4 ++-- hostapd/ctrl_iface.c | 3 +++ src/ap/ap_config.c | 2 +- src/ap/ap_config.h | 2 +- src/ap/beacon.c | 5 ++++- src/ap/ieee802_11.c | 17 ++++++++++++++--- src/ap/ieee802_11_shared.c | 4 ++-- src/common/ieee802_11_defs.h | 1 + src/drivers/driver.h | 9 +++++++-- src/drivers/driver_nl80211.c | 21 ++++++++++----------- src/drivers/nl80211_copy.h | 12 ++++-------- 11 files changed, 49 insertions(+), 31 deletions(-) --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -4560,8 +4560,8 @@ static int hostapd_config_fill(struct ho #endif /* CONFIG_MACSEC */ } else if (os_strcmp(buf, "multiple_bssid") == 0) { conf->multiple_bssid = atoi(pos); - } else if (os_strcmp(buf, "ema") == 0) { - conf->ema = atoi(pos); + } else if (os_strcmp(buf, "ema_beacon") == 0) { + conf->ema_beacon = atoi(pos); } else if (os_strcmp(buf, "rnr_beacon") == 0) { bss->rnr_beacon = atoi(pos); } else if (os_strcmp(buf, "disable_11n") == 0) { --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -2759,6 +2759,9 @@ static int hostapd_ctrl_iface_chan_switc * submitting multi-BSS CSA requests? */ return ret; } + + if (iface->bss[i]->iconf->multiple_bssid) + break; } return 0; --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -1486,7 +1486,7 @@ int hostapd_config_check(struct hostapd_ return -1; } - if (conf->ema && !conf->multiple_bssid) { + if (conf->ema_beacon && !conf->multiple_bssid) { wpa_printf(MSG_ERROR, "Cannot enable ema without enabling multiple_bssid"); return -1; --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -1017,7 +1017,7 @@ struct hostapd_config { u8 ht40_plus_minus_allowed; u8 multiple_bssid; - u8 ema; + u8 ema_beacon; /* Use driver-generated interface addresses when adding multiple BSSs */ u8 use_driver_iface_addr; --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -1808,6 +1808,9 @@ int ieee802_11_build_ap_params(struct ho params->multiple_bssid_index = hostapd_get_bss_index(hapd); params->multiple_bssid_count = hapd->iface->num_bss; + params->ema_beacon = hapd->iconf->ema_beacon; + if (hapd != hapd->iface->bss[0]) + params->multiple_bssid_parent = hapd->iface->bss[0]->conf->iface; params->multiple_bssid_ies = os_zalloc(len); if (params->multiple_bssid_ies == NULL) return -1; @@ -1817,7 +1820,7 @@ int ieee802_11_build_ap_params(struct ho 1, params->multiple_bssid_ie_offsets, ¶ms->multiple_bssid_ie_count, MULTIPLE_BSSID_IE_MAX, - hapd->iconf->ema); + hapd->iconf->ema_beacon); params->multiple_bssid_ie_len = end - params->multiple_bssid_ies; if ((params->multiple_bssid_ie_count <= 1) && (ext_cap_len >= 13) && (ext_cap_pos[12] & 0x08)) --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -7126,7 +7126,7 @@ static u8 * hostapd_eid_multiple_bssid_c for (i = *count; i < hapd->iface->num_bss; i++) { bss = hapd->iface->bss[i]; conf = bss->conf; - u8 *bss_size_offset, *index_size_offset, *pos = eid; + u8 *bss_size_offset, *index_size_offset, *pos = eid, *rsn; u16 capab_info; *eid++ = WLAN_EID_SUBELEMENT_NONTRANSMITTED_BSSID_PROFILE; @@ -7161,8 +7161,19 @@ static u8 * hostapd_eid_multiple_bssid_c } *index_size_offset = (eid - index_size_offset) - 1; - eid = hostapd_get_rsne(bss, eid, end - eid); - eid = hostapd_get_rsnxe(bss, eid, end - eid); + rsn = hostapd_get_rsne(bss, eid, end - eid); + if (rsn == eid) { + /* add RSN non-inheritance IE */ + *eid++ = WLAN_EID_EXTENSION; + *eid++ = 3; + *eid++ = WLAN_EID_EXT_NON_INHERITANCE; + *eid++ = 1; + *eid++ = WLAN_EID_RSN; + } else { + eid = rsn; + eid = hostapd_get_rsnxe(bss, eid, end - eid); + } + *bss_size_offset = (eid - bss_size_offset) - 1; if ((eid - size_offset) - 1 > 255) { --- a/src/ap/ieee802_11_shared.c +++ b/src/ap/ieee802_11_shared.c @@ -428,7 +428,7 @@ static void hostapd_ext_capab_byte(struc } #endif /* CONFIG_SAE */ /* Bit 83 - EMA AP Support */ - if (hapd->iconf->ema) + if (hapd->iconf->ema_beacon) *pos |= 0x08; if (hapd->conf->beacon_prot && (hapd->iface->drv_flags & @@ -501,7 +501,7 @@ u8 * hostapd_eid_ext_capab(struct hostap hostapd_sae_pw_id_in_use(hapd->conf)) len = 11; #endif /* CONFIG_SAE */ - if (len < 11 && (hapd->conf->beacon_prot || hapd->iconf->ema) && + if (len < 11 && (hapd->conf->beacon_prot || hapd->iconf->ema_beacon) && (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_BEACON_PROTECTION)) len = 11; #ifdef CONFIG_SAE_PK --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -482,6 +482,7 @@ #define WLAN_EID_EXT_SPATIAL_REUSE 39 #define WLAN_EID_EXT_COLOR_CHANGE_ANNOUNCEMENT 42 #define WLAN_EID_EXT_OCV_OCI 54 +#define WLAN_EID_EXT_NON_INHERITANCE 56 #define WLAN_EID_EXT_SHORT_SSID_LIST 58 #define WLAN_EID_EXT_HE_6GHZ_BAND_CAP 59 #define WLAN_EID_EXT_EDMG_CAPABILITIES 61 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1586,9 +1586,9 @@ struct wpa_driver_ap_params { size_t unsol_bcast_probe_resp_tmpl_len; /** - * multiple_bssid_non_transmitted - Is this a non transmitted BSS + * multiple_bssid_parent - The transmitting iface */ - int multiple_bssid_non_transmitted; + const char *multiple_bssid_parent; /** * multiple_bssid_index - The index of this BSS in the group @@ -1619,6 +1619,12 @@ struct wpa_driver_ap_params { * multiple_bssid_ie_count - The the number of offsets inside multiple_bssid_ie_offsets */ int multiple_bssid_ie_count; + + /** + * ema_beacon - should the multiple_bssid beacons be sent out in EMA mode + */ + int ema_beacon; + }; struct wpa_driver_mesh_bss_params { --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -4872,6 +4872,16 @@ static int wpa_driver_nl80211_set_ap(voi params->multiple_bssid_index); nla_put_u8(msg, NL80211_ATTR_MULTIPLE_BSSID_COUNT, params->multiple_bssid_count); + if (params->ema_beacon) + nla_put_flag(msg, NL80211_ATTR_MULTIPLE_BSSID_EMA); + } + + if (params->multiple_bssid_parent) { + int ifidx = if_nametoindex(params->multiple_bssid_parent); + if (ifidx <= 0) + goto fail; + nla_put_u32(msg, NL80211_ATTR_MULTIPLE_BSSID_PARENT, + ifidx); } if (params->multiple_bssid_ie_len) { @@ -5528,17 +5538,6 @@ static int nl80211_create_iface_once(str goto fail; } - if (multiple_bssid_non_transmitted) { - if (!multiple_bssid_parent) - goto fail; - ifidx = if_nametoindex(multiple_bssid_parent); - if (ifidx <= 0) - goto fail; - nla_put_flag(msg, NL80211_ATTR_MULTIPLE_BSSID_NON_TRANSMITTING); - nla_put_u32(msg, NL80211_ATTR_MULTIPLE_BSSID_PARENT, - ifidx); - } - /* * Tell cfg80211 that the interface belongs to the socket that created * it, and the interface should be deleted when the socket is closed. --- a/src/drivers/nl80211_copy.h +++ b/src/drivers/nl80211_copy.h @@ -2583,9 +2583,6 @@ enum nl80211_commands { * @NL80211_ATTR_HE_MUEDCA_PARAMS: MU-EDCA AC parameters for the NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS command. * - * @NL80211_ATTR_MULTIPLE_BSSID_NON_TRANSMITTING: Set the Non-Transmitted flag for this - * BSSIDs beacon. - * * @NL80211_ATTR_MULTIPLE_BSSID_PARENT: If this is a Non-Transmitted BSSID, define * the parent (transmitting) interface. * @@ -2595,7 +2592,9 @@ enum nl80211_commands { * @NL80211_ATTR_MULTIPLE_BSSID_COUNT: The number of BSSs inside the multi bssid element. * * @NL80211_ATTR_MULTIPLE_BSSID_IES: The Elements that describe our multiple BSS group. - * these get passed separately as the kernel might need to split them up for EMA VAP. + * these get passed separately as the kernel might need to split them up for EMA VAP. + * + * @NL80211_ATTR_MULTIPLE_BSSID_EMA: Shall the multiple BSS beacons be sent out in EMA mode. * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined @@ -3096,11 +3095,11 @@ enum nl80211_attrs { NL80211_ATTR_HE_MUEDCA_PARAMS, - NL80211_ATTR_MULTIPLE_BSSID_NON_TRANSMITTING, NL80211_ATTR_MULTIPLE_BSSID_PARENT, NL80211_ATTR_MULTIPLE_BSSID_INDEX, NL80211_ATTR_MULTIPLE_BSSID_COUNT, NL80211_ATTR_MULTIPLE_BSSID_IES, + NL80211_ATTR_MULTIPLE_BSSID_EMA, NL80211_ATTR_OBSS_COLOR_BITMAP,