From: John Crispin <john@xxxxxxxxxxx> Add helper functions to retrieve the context for the transmitting interfaces of the MBSSID set and the index of a given BSS. Set device parameters - BSS index and the transmitting BSS. Include multiple BSSID elements in beacon and probe response frames. Signed-off-by: John Crispin <john@xxxxxxxxxxx> Co-developed-by: Aloka Dixit <quic_alokad@xxxxxxxxxxx> Signed-off-by: Aloka Dixit <quic_alokad@xxxxxxxxxxx> --- v2: Checks for error conditions before setting any driver parameters. src/ap/beacon.c | 80 ++++++++++++++++++++++++++++++++++++++++++-- src/ap/hostapd.c | 23 +++++++++++++ src/ap/hostapd.h | 2 ++ src/drivers/driver.h | 36 ++++++++++++++++++++ 4 files changed, 138 insertions(+), 3 deletions(-) diff --git a/src/ap/beacon.c b/src/ap/beacon.c index 58872bfdab71..b2619bf40fe8 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -462,6 +462,55 @@ static u8 * hostapd_eid_supported_op_classes(struct hostapd_data *hapd, u8 *eid) } +static int ieee802_11_build_ap_params_mbssid(struct hostapd_data *hapd, + struct wpa_driver_ap_params *params) +{ + struct hostapd_iface *iface = hapd->iface; + struct hostapd_data *tx_bss; + size_t len; + u8 elem_count = 0, *elem = NULL, **elem_offset = NULL, *end; + + if (!iface->mbssid_max_interfaces || + iface->num_bss > iface->mbssid_max_interfaces || + (iface->conf->mbssid == ENHANCED_MBSSID_ENABLED && + !iface->ema_max_periodicity)) + goto fail; + + tx_bss = hostapd_mbssid_get_tx_bss(hapd); + len = hostapd_eid_mbssid_len(tx_bss, WLAN_FC_STYPE_BEACON, &elem_count); + if (!len || (iface->conf->mbssid == ENHANCED_MBSSID_ENABLED && + elem_count > iface->ema_max_periodicity)) + goto fail; + + elem = os_zalloc(len); + if (!elem) + goto fail; + + elem_offset = os_zalloc(elem_count * sizeof(u8 *)); + if (!elem_offset) + goto fail; + + end = hostapd_eid_mbssid(tx_bss, elem, elem + len, WLAN_FC_STYPE_BEACON, + elem_count, elem_offset); + + params->mbssid_tx_iface = tx_bss->conf->iface; + params->mbssid_index = hostapd_mbssid_get_bss_index(hapd); + params->mbssid_elem = elem; + params->mbssid_elem_len = end - elem; + params->mbssid_elem_count = elem_count; + params->mbssid_elem_offset = elem_offset; + if (iface->conf->mbssid == ENHANCED_MBSSID_ENABLED) + params->ema = true; + + return 0; + +fail: + os_free(elem); + wpa_printf(MSG_ERROR, "MBSSID: Configuration failed"); + return -1; +} + + static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, const struct ieee80211_mgmt *req, int is_p2p, size_t *resp_len, @@ -471,6 +520,8 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, u8 *pos, *epos, *csa_pos; size_t buflen; + hapd = hostapd_mbssid_get_tx_bss(hapd); + #define MAX_PROBERESP_LEN 768 buflen = MAX_PROBERESP_LEN; #ifdef CONFIG_WPS @@ -517,6 +568,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, } #endif /* CONFIG_IEEE80211BE */ + buflen += hostapd_eid_mbssid_len(hapd, WLAN_FC_STYPE_PROBE_RESP, NULL); buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP); buflen += hostapd_mbo_ie_len(hapd); buflen += hostapd_eid_owe_trans_len(hapd); @@ -588,6 +640,8 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, pos = hostapd_eid_supported_op_classes(hapd, pos); pos = hostapd_eid_ht_capabilities(hapd, pos); pos = hostapd_eid_ht_operation(hapd, pos); + pos = hostapd_eid_mbssid(hapd, pos, epos, WLAN_FC_STYPE_PROBE_RESP, 0, + NULL); pos = hostapd_eid_ext_capab(hapd, pos); @@ -1141,6 +1195,11 @@ void handle_probe_req(struct hostapd_data *hapd, } #endif /* CONFIG_TESTING_OPTIONS */ + /* Do not send probe response from a non-transmitting multiple BSSID + * profile unless the probe request is directed at that paticular BSS */ + if (hapd != hostapd_mbssid_get_tx_bss(hapd) && res != EXACT_SSID_MATCH) + return; + wpa_msg_ctrl(hapd->msg_ctx, MSG_INFO, RX_PROBE_REQUEST "sa=" MACSTR " signal=%d", MAC2STR(mgmt->sa), ssi_signal); @@ -1167,7 +1226,8 @@ void handle_probe_req(struct hostapd_data *hapd, hapd->cs_c_off_ecsa_proberesp; } - ret = hostapd_drv_send_mlme(hapd, resp, resp_len, noack, + ret = hostapd_drv_send_mlme(hostapd_mbssid_get_tx_bss(hapd), resp, + resp_len, noack, csa_offs_len ? csa_offs : NULL, csa_offs_len, 0); @@ -1512,7 +1572,11 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, #ifdef NEED_AP_MLME u16 capab_info; u8 *pos, *tailpos, *tailend, *csa_pos; +#endif /* NEED_AP_MLME */ + + os_memset(params, 0, sizeof(*params)); +#ifdef NEED_AP_MLME #define BEACON_HEAD_BUF_SIZE 256 #define BEACON_TAIL_BUF_SIZE 512 head = os_zalloc(BEACON_HEAD_BUF_SIZE); @@ -1649,9 +1713,16 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, tailpos = hostapd_eid_supported_op_classes(hapd, tailpos); tailpos = hostapd_eid_ht_capabilities(hapd, tailpos); tailpos = hostapd_eid_ht_operation(hapd, tailpos); - tailpos = hostapd_eid_ext_capab(hapd, tailpos); + if (hapd->iconf->mbssid && hapd->iconf->num_bss > 1 && + ieee802_11_build_ap_params_mbssid(hapd, params)) { + os_free(head); + os_free(tail); + wpa_printf(MSG_ERROR, "Failed to set beacon data"); + return -1; + } + /* * TODO: Time Advertisement element should only be included in some * DTIM Beacon frames. @@ -1772,7 +1843,6 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, resp = hostapd_probe_resp_offloads(hapd, &resp_len); #endif /* NEED_AP_MLME */ - os_memset(params, 0, sizeof(*params)); params->head = (u8 *) head; params->head_len = head_len; params->tail = tail; @@ -1875,6 +1945,10 @@ void ieee802_11_free_ap_params(struct wpa_driver_ap_params *params) params->head = NULL; os_free(params->proberesp); params->proberesp = NULL; + os_free(params->mbssid_elem); + params->mbssid_elem = NULL; + os_free(params->mbssid_elem_offset); + params->mbssid_elem_offset = NULL; #ifdef CONFIG_FILS os_free(params->fd_frame_tmpl); params->fd_frame_tmpl = NULL; diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 39340864edc4..eb059c508fbc 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -91,6 +91,29 @@ int hostapd_for_each_interface(struct hapd_interfaces *interfaces, } +struct hostapd_data * hostapd_mbssid_get_tx_bss(struct hostapd_data *hapd) +{ + if (hapd->iconf->mbssid) + return hapd->iface->bss[0]; + + return hapd; +} + + +int hostapd_mbssid_get_bss_index(struct hostapd_data *hapd) +{ + if (hapd->iconf->mbssid) { + size_t i; + + for (i = 1; i < hapd->iface->num_bss; i++) + if (hapd->iface->bss[i] == hapd) + return i; + } + + return 0; +} + + void hostapd_reconfig_encryption(struct hostapd_data *hapd) { if (hapd->wpa_auth) diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 36c6a8b21d08..a210a5f68da1 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -723,6 +723,8 @@ struct hostapd_data * hostapd_get_iface(struct hapd_interfaces *interfaces, void hostapd_event_sta_opmode_changed(struct hostapd_data *hapd, const u8 *addr, enum smps_mode smps_mode, enum chan_width chan_width, u8 rx_nss); +struct hostapd_data * hostapd_mbssid_get_tx_bss(struct hostapd_data *hapd); +int hostapd_mbssid_get_bss_index(struct hostapd_data *hapd); #ifdef CONFIG_FST void fst_hostapd_fill_iface_obj(struct hostapd_data *hapd, diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 39a2e6387d8a..d7511130ee18 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1618,6 +1618,42 @@ struct wpa_driver_ap_params { * Unsolicited broadcast Probe Response template length */ size_t unsol_bcast_probe_resp_tmpl_len; + + /** + * mbssid_tx_iface - Transmitting interface of the MBSSID set + */ + const char *mbssid_tx_iface; + + /** + * mbssid_index - The index of this BSS in the MBSSID set + */ + unsigned int mbssid_index; + + /** + * mbssid_elem - Buffer containing all MBSSID elements + */ + u8 *mbssid_elem; + + /** + * mbssid_elem_len - Total length of all MBSSID elements + */ + size_t mbssid_elem_len; + + /** + * mbssid_elem_count - The number of MBSSID elements + */ + u8 mbssid_elem_count; + + /** + * mbssid_elem_offset - Offsets to elements in mbssid_elem. + * Kernel will use these offsets to generate multiple BSSID beacons. + */ + u8 **mbssid_elem_offset; + + /** + * ema - Enhanced MBSSID advertisements support. + */ + bool ema; }; struct wpa_driver_mesh_bss_params { -- 2.31.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap