[PATCH 20/25] hostapd: Add MBO IE to beacon/probe/association

Ilan Peer ilan.peer at intel.com
Mon Feb 15 06:53:52 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