[PATCH 21/26] hostapd: Add MBO IE to beacon/probe/association
Ilan Peer
ilan.peer at intel.com
Mon Feb 15 06:53:53 PST 2016
From: Avraham Stern <avraham.stern at intel.com>
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 at intel.com>
---
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
More information about the Hostap
mailing list