From: Avraham Stern <avraham.stern@xxxxxxxxx> Add MBO IE with AP capability attribute to beacon/probe/association to indicate the AP supports MBO. Add option to add Association Disallowed attribute to beacon, probe response and association response. Usage: set mbo_assoc_disallow <reason code> Valid reason code values are between 1-5. Setting the reason code to 0 will remove the Association Disallowed attribute from the MBO IE and will allow new associations. MBO functionality is enabled by setting "mbo=1" in the config file. Signed-off-by: Avraham Stern <avraham.stern@xxxxxxxxx> --- hostapd/Makefile | 4 ++++ hostapd/config_file.c | 4 ++++ hostapd/ctrl_iface.c | 21 +++++++++++++++++++++ hostapd/defconfig | 5 +++++ src/ap/ap_config.h | 4 ++++ src/ap/ap_drv_ops.c | 20 ++++++++++++++++++++ src/ap/beacon.c | 9 +++++++++ src/ap/hostapd.h | 4 ++++ src/ap/ieee802_11.c | 9 +++++++++ src/ap/ieee802_11.h | 17 +++++++++++++++++ src/ap/ieee802_11_shared.c | 40 ++++++++++++++++++++++++++++++++++++++++ 11 files changed, 137 insertions(+) diff --git a/hostapd/Makefile b/hostapd/Makefile index fd3105e..e2cf06a 100644 --- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -976,6 +976,10 @@ OBJS += ../src/fst/fst_ctrl_iface.o endif endif +ifdef CONFIG_MBO +CFLAGS += -DCONFIG_MBO +endif + ALL=hostapd hostapd_cli all: verify_config $(ALL) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 503d479..f682e69 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -3293,6 +3293,10 @@ static int hostapd_config_fill(struct hostapd_config *conf, } else if (os_strcmp(buf, "subscr_remediation_method") == 0) { bss->subscr_remediation_method = atoi(pos); #endif /* CONFIG_HS20 */ +#ifdef CONFIG_MBO + } else if (os_strcmp(buf, "mbo") == 0) { + bss->mbo_enabled = atoi(pos); +#endif /* CONFIG_MBO */ #ifdef CONFIG_TESTING_OPTIONS #define PARSE_TEST_PROBABILITY(_val) \ } else if (os_strcmp(buf, #_val) == 0) { \ diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index a45ccf2..f931a89 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -1376,6 +1376,27 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd) } else if (os_strcasecmp(cmd, "ext_eapol_frame_io") == 0) { hapd->ext_eapol_frame_io = atoi(value); #endif /* CONFIG_TESTING_OPTIONS */ +#ifdef CONFIG_MBO + } else if (os_strcasecmp(cmd, "mbo_assoc_disallow") == 0) { + if (!hapd->conf->mbo_enabled) { + ret = -1; + } else { + int val = atoi(value); + + if (val > 1) { + ret = -1; + } else { + hapd->mbo_assoc_disallow = val; + ieee802_11_update_beacons(hapd->iface); + + /* + * TODO: Need to configure drivers that do + * AP MLME offload with disallowing station + * logic. + */ + } + } +#endif } else { struct sta_info *sta; int vlan_id; diff --git a/hostapd/defconfig b/hostapd/defconfig index 2a749dd..1668ba6 100644 --- a/hostapd/defconfig +++ b/hostapd/defconfig @@ -329,3 +329,8 @@ CONFIG_IPV6=y # http://wireless.kernel.org/en/users/Documentation/acs # #CONFIG_ACS=y +# +# Multiband Operation Support +# These extentions facilitate efficient use of multiple frequency bands +# available to the AP and the devices that may associate with it. +#CONFIG_MBO=y diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index e68ec28..168f41d 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -572,6 +572,10 @@ struct hostapd_bss_config { char *no_auth_if_seen_on; int pbss; + +#ifdef CONFIG_MBO + int mbo_enabled; +#endif /* CONFIG_MBO */ }; diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c index b390450..db7df46 100644 --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -200,6 +200,26 @@ int hostapd_build_ap_extra_ies(struct hostapd_data *hapd, } #endif /* CONFIG_HS20 */ +#ifdef CONFIG_MBO + if (hapd->conf->mbo_enabled) { + pos = buf; + pos = hostapd_eid_mbo(hapd, buf, sizeof(buf)); + if (pos != buf) { + if (wpabuf_resize(&beacon, pos - buf) != 0) + goto fail; + wpabuf_put_data(beacon, buf, pos - buf); + + if (wpabuf_resize(&proberesp, pos - buf) != 0) + goto fail; + wpabuf_put_data(proberesp, buf, pos - buf); + + if (wpabuf_resize(&assocresp, pos - buf) != 0) + goto fail; + wpabuf_put_data(assocresp, buf, pos - buf); + } + } +#endif /* CONFIG_MBO */ + if (hapd->conf->vendor_elements) { size_t add = wpabuf_len(hapd->conf->vendor_elements); if (wpabuf_resize(&beacon, add) == 0) diff --git a/src/ap/beacon.c b/src/ap/beacon.c index 560b19c..0ddd0e2 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -387,6 +387,9 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, buflen += 5 + 2 + sizeof(struct ieee80211_vht_capabilities) + 2 + sizeof(struct ieee80211_vht_operation); } + + buflen += hostapd_mbo_ie_len(hapd); + resp = os_zalloc(buflen); if (resp == NULL) return NULL; @@ -518,6 +521,8 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, pos = hostapd_eid_osen(hapd, pos); #endif /* CONFIG_HS20 */ + pos = hostapd_eid_mbo(hapd, pos, (u8 *)resp + buflen - pos); + if (hapd->conf->vendor_elements) { os_memcpy(pos, wpabuf_head(hapd->conf->vendor_elements), wpabuf_len(hapd->conf->vendor_elements)); @@ -980,6 +985,8 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, } #endif /* CONFIG_IEEE80211AC */ + tail_len += hostapd_mbo_ie_len(hapd); + tailpos = tail = os_malloc(tail_len); if (head == NULL || tail == NULL) { wpa_printf(MSG_ERROR, "Failed to set beacon data"); @@ -1133,6 +1140,8 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, tailpos = hostapd_eid_osen(hapd, tailpos); #endif /* CONFIG_HS20 */ + tailpos = hostapd_eid_mbo(hapd, tailpos, tail + tail_len - tailpos); + if (hapd->conf->vendor_elements) { os_memcpy(tailpos, wpabuf_head(hapd->conf->vendor_elements), wpabuf_len(hapd->conf->vendor_elements)); diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 0f31dd4..d6d96db 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -281,6 +281,10 @@ struct hostapd_data { struct l2_packet_data *l2_test; #endif /* CONFIG_TESTING_OPTIONS */ + +#ifdef CONFIG_MBO + unsigned int mbo_assoc_disallow; +#endif /* CONFIG_MBO */ }; diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index ec6f8a7..e7c6233 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -1766,6 +1766,8 @@ static void send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta, p = hostapd_eid_p2p_manage(hapd, p); #endif /* CONFIG_P2P_MANAGER */ + p = hostapd_eid_mbo(hapd, p, buf + sizeof(buf) - p); + send_len += p - reply->u.assoc_resp.variable; if (hostapd_drv_send_mlme(hapd, reply, send_len, 0) < 0) @@ -1889,6 +1891,13 @@ static void handle_assoc(struct hostapd_data *hapd, goto fail; } +#ifdef CONFIG_MBO + if (hapd->conf->mbo_enabled && hapd->mbo_assoc_disallow) { + resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; + goto fail; + } +#endif /* CONFIG_MBO */ + /* followed by SSID and Supported rates; and HT capabilities if 802.11n * is used */ resp = check_assoc_ies(hapd, sta, pos, left, reassoc); diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h index 0020ff5..dd1d6bc 100644 --- a/src/ap/ieee802_11.h +++ b/src/ap/ieee802_11.h @@ -109,4 +109,21 @@ static inline void sae_clear_retransmit_timer(struct hostapd_data *hapd, } #endif /* CONFIG_SAE */ +#ifdef CONFIG_MBO +u8 *hostapd_eid_mbo(struct hostapd_data *hapd, u8 *eid, size_t len); + +u8 hostapd_mbo_ie_len(struct hostapd_data *hapd); +#else /* CONFIG_MBO */ +static inline u8 *hostapd_eid_mbo(struct hostapd_data *hapd, u8 *eid, + size_t len) +{ + return eid; +} + +static inline u8 hostapd_mbo_ie_len(struct hostapd_data *hapd) +{ + return 0; +} +#endif /* CONFIG_MBO */ + #endif /* IEEE802_11_H */ diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c index 9e3363e..4bf3416 100644 --- a/src/ap/ieee802_11_shared.c +++ b/src/ap/ieee802_11_shared.c @@ -508,3 +508,43 @@ u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid) return pos; } + + +#ifdef CONFIG_MBO +u8 *hostapd_eid_mbo(struct hostapd_data *hapd, u8 *eid, size_t len) +{ + u8 mbo[6]; + u8 *pos = eid; + size_t mbo_len = 3; + + if (hapd->conf->mbo_enabled) { + mbo[0] = MBO_ATTR_ID_CAPA_IND; + mbo[1] = 1; + /* Not Cellular aware */ + mbo[2] = 0; + + if (hapd->mbo_assoc_disallow) { + mbo[3] = MBO_ATTR_ID_ASSOC_DISALLOW; + mbo[4] = 1; + mbo[5] = hapd->mbo_assoc_disallow; + mbo_len = 6; + } + + pos += mbo_add_ie(pos, len, mbo, mbo_len); + } + + return pos; +} + + +u8 hostapd_mbo_ie_len(struct hostapd_data *hapd) +{ + if (!hapd->conf->mbo_enabled) + return 0; + + /* MBO IE header (6) + Capability Indication attribute (3) + + * Association Disallowed attribute (3) = 12 + */ + return hapd->mbo_assoc_disallow ? 12 : 9; +} +#endif /* CONFIG_MBO */ -- 1.9.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap