Cumulative patch from commit 077dcfb8c48d2509a6e116c0de3ad57d2fbfe4fe

077dcfb AP: Debug print management frame TX result
ca911d6 MBO: Parse non-preferred channel list on the AP
3f48274 WNM: Fix a memory leak on AP error path
f5ca176 VLAN: Fix vlan_compare() for tagged VLANs
1260564 hostapd_cli: Add support for RAW command
940491c MBO: Mandate use of PMF for WPA2+MBO association (STA)
4c57228 MBO: Mandate use of PMF for WPA2+MBO association (AP)
8dd49f0 MBO: Update STA cellular data capability based on WNM Notification
6332aaf MBO: Track STA cellular data capability from association request
f3cb7a6 WNM: Minimal processing for WNM Notification Request frames on AP
e578343 MBO: Indicate WNM-Notification support on AP when MBO is enabled
990b7b6 Simplify hostapd_build_ap_extra_ies() with helper functions
d010048 MBO: Expire non-matching bss_tmp_disallowed entries as part of check
f4c74e1 MBO: Parse MBO IE in ieee802_11_parse_elems()
016082e MBO: Send WNM-Notification when cellular capabilities change
c0e2a17 hostapd: Add MBO IE to BSS Transition Management Request frame
fb9a1c3 hostapd: Add MBO IE to Beacon, Probe Response, Association Response
c484b19 Move Hotspot 2.0 element in (Re)Association Request frames
a0c38e5 Re-order elements in (Re)Association Request frames
9a493fa WNM: Add candidate list to BSS transition query
84d1c0f WNM: Add candidate list to BSS transition response
cf11ab7 utils: Derive phy type by frequency and bandwidth
c8082d2 MBO: Add MBO IE to BSS Transition Management Response frame
dd59990 MBO: Parse MBO IE in BSS Transition Management Request frames
5e57ba2 MBO: Add Supported Operating Classes element to Association Request
7d46f58 MBO: Add global operating class definitions
cb06cf3 MBO: Prevent association to APs that explicitly disallow this
c5d193d MBO: Add cellular capability to MBO IE
2d5b861 MBO: Send MBO WNM-Notification Request frames to notify changes
92c6e2e MBO: Implement MBO non-preferred channel report in Association Request
facf2c7 MBO: Add non-preferred channel configuration in wpa_supplicant
425dd78 MBO: Add Multi Band Operation definitions
a159958 ndis: Use the new get_ie() helper to avoid duplicated code
231b04b utils: Share a single helper function to get IE by ID
ea69d97 wpa_supplicant: Share a single get_mode() implementation
75cc211 VLAN: Check vlan_desc validity in a failure debug print
43022ab Use 64-bit TX/RX byte counters for statistics
3f81ac0 AP: Set STA assoc flag in the driver before sending Assoc Resp frame
bb598c3 AP: Add support for full station state
dc55b6b nl80211: Add support for full station state operations
5558b99 EAP-FAST peer: Remove fixed return value from eap_fast_parse_phase1()
4b16c15 EAP-pwd server: Use os_get_random() for unpredictable token
239952b DFS: Remove the os_random() fallback
98a516e WPS: Use only os_get_random() for PIN generation
f441e5a Use os_get_random() for Shared Key authentication challenge
8c676b5 Add RADIUS Service-Type attribute with a value of Framed
09d96de mesh: Drop Authentication frames from BLOCKED STA
70c9396 SAE: Fix PMKID calculation for PMKSA cache
1492fbb Print Acct-Session-Id and Acct-Multi-Session-Id 64-bit values
e21ceca kqueue: Use 0 instead of NULL for udata
640b0b9 ctype functions require an unsigned char
a5a3efc Fix compile on NetBSD for vlan
a084c24 wired: Fix compile on NetBSD for wired driver
634e2e2 Add CONFIG_ELOOP_KQUEUE to defconfig
99a94f5 nl80211: Avoid wpa_printf %s call with NULL pointer in set_param()
ba91e92 wpa_supplicant: Parse ifname argument from DATA_TEST_CONFIG
8be640b VLAN: Add per-STA vif option
d0bdc96 VLAN: Actually add tagged VLANs to AP_VLAN
f9c0018 VLAN: Factor out per-vid code in newlink/dellink
8e44c19 radius: Add tagged VLAN parsing
1889af2 VLAN: Separate station grouping and uplink configuration
3a583e0 OpenSSL: Fix PKCS#12 parsing of extra certificates with OpenSSL 1.0.1
ddd0032 wpa_cli: Clean up logical operation
24c382a TDLS: Clean up os_memcmp use
6136d43 trace: Free symbols on program exit
8bcf8de OpenSSL: Fix memory leak in PKCS12 additional certificate parsing
03e3ddf OpenSSL: Fix memory leak in HMAC_CTX compatibility wrapper function
d9a0f69 OpenSSL: Fix memory leak in OCSP parsing
29bc76e OpenSSL: Do not use library init/deinit functions with 1.1.0
0f09637 OpenSSL: Fix memory leak in subjectAltName parsing
e60913b curl: Fix memory leak in subjectAltName parsing
6014890 OpenSSL: Fix memory leak with EVP_CIPHER_CTX_new()
99a1735 rfkill: Fix a memory leak
1f1e599 OpenSSL: Fix memory leak on error path
b907491 wpa_supplicant: Basic support for PBSS/PCP
86b5c40 nl80211: Basic support for PBSS/PCP
afa453a Sync with mac80211-next.git include/uapi/linux/nl80211.h
d1d8a2b EAP peer: Simplify buildNotify return
1314bc1 Clean up EAP peer PCSC identity functions

Change-Id: I9db475a2a4ebc88d2ee024319ed59a850636bb16
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index cb6fb17..c0008fd 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -884,6 +884,8 @@
 	int ret;
 	u8 nei_rep[1000];
 	u8 *nei_pos = nei_rep;
+	u8 mbo[10];
+	size_t mbo_len = 0;
 
 	if (hwaddr_aton(cmd, addr)) {
 		wpa_printf(MSG_DEBUG, "Invalid STA MAC address");
@@ -1049,10 +1051,66 @@
 	if (os_strstr(cmd, " disassoc_imminent=1"))
 		req_mode |= WNM_BSS_TM_REQ_DISASSOC_IMMINENT;
 
+#ifdef CONFIG_MBO
+	pos = os_strstr(cmd, "mbo=");
+	if (pos) {
+		unsigned int mbo_reason, cell_pref, reassoc_delay;
+		u8 *mbo_pos = mbo;
+
+		ret = sscanf(pos, "mbo=%u:%u:%u", &mbo_reason,
+			     &reassoc_delay, &cell_pref);
+		if (ret != 3) {
+			wpa_printf(MSG_DEBUG,
+				   "MBO requires three arguments: mbo=<reason>:<reassoc_delay>:<cell_pref>");
+			return -1;
+		}
+
+		if (mbo_reason > MBO_TRANSITION_REASON_PREMIUM_AP) {
+			wpa_printf(MSG_DEBUG,
+				   "Invalid MBO transition reason code %u",
+				   mbo_reason);
+			return -1;
+		}
+
+		/* Valid values for Cellular preference are: 0, 1, 255 */
+		if (cell_pref != 0 && cell_pref != 1 && cell_pref != 255) {
+			wpa_printf(MSG_DEBUG,
+				   "Invalid MBO cellular capability %u",
+				   cell_pref);
+			return -1;
+		}
+
+		if (reassoc_delay > 65535 ||
+		    (reassoc_delay &&
+		     !(req_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT))) {
+			wpa_printf(MSG_DEBUG,
+				   "MBO: Assoc retry delay is only valid in disassoc imminent mode");
+			return -1;
+		}
+
+		*mbo_pos++ = MBO_ATTR_ID_TRANSITION_REASON;
+		*mbo_pos++ = 1;
+		*mbo_pos++ = mbo_reason;
+		*mbo_pos++ = MBO_ATTR_ID_CELL_DATA_PREF;
+		*mbo_pos++ = 1;
+		*mbo_pos++ = cell_pref;
+
+		if (reassoc_delay) {
+			*mbo_pos++ = MBO_ATTR_ID_ASSOC_RETRY_DELAY;
+			*mbo_pos++ = 2;
+			WPA_PUT_LE16(mbo_pos, reassoc_delay);
+			mbo_pos += 2;
+		}
+
+		mbo_len = mbo_pos - mbo;
+	}
+#endif /* CONFIG_MBO */
+
 	ret = wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer,
 				  valid_int, bss_term_dur, url,
 				  nei_pos > nei_rep ? nei_rep : NULL,
-				  nei_pos - nei_rep);
+				  nei_pos - nei_rep, mbo_len ? mbo : NULL,
+				  mbo_len);
 	os_free(url);
 	return ret;
 }
@@ -1320,9 +1378,28 @@
 	} 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) {
+		int val;
+
+		if (!hapd->conf->mbo_enabled)
+			return -1;
+
+		val = atoi(value);
+		if (val < 0 || val > 1)
+			return -1;
+
+		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 /* CONFIG_MBO */
 	} else {
 		struct sta_info *sta;
-		int vlan_id;
+		struct vlan_description vlan_id;
 
 		ret = hostapd_set_iface(hapd->iconf, hapd->conf, cmd, value);
 		if (ret)
@@ -1334,7 +1411,8 @@
 					    hapd->conf->deny_mac,
 					    hapd->conf->num_deny_mac, sta->addr,
 					    &vlan_id) &&
-				    (!vlan_id || vlan_id == sta->vlan_id))
+				    (!vlan_id.notempty ||
+				     !vlan_compare(&vlan_id, sta->vlan_desc)))
 					ap_sta_disconnect(
 						hapd, sta, sta->addr,
 						WLAN_REASON_UNSPECIFIED);
@@ -1346,7 +1424,8 @@
 					    hapd->conf->accept_mac,
 					    hapd->conf->num_accept_mac,
 					    sta->addr, &vlan_id) ||
-				    (vlan_id && vlan_id != sta->vlan_id))
+				    (vlan_id.notempty &&
+				     vlan_compare(&vlan_id, sta->vlan_desc)))
 					ap_sta_disconnect(
 						hapd, sta, sta->addr,
 						WLAN_REASON_UNSPECIFIED);
@@ -1875,13 +1954,13 @@
 
 	/* cmd: <vendor id> <subcommand id> [<hex formatted data>] */
 	vendor_id = strtoul(cmd, &pos, 16);
-	if (!isblank(*pos))
+	if (!isblank((unsigned char) *pos))
 		return -EINVAL;
 
 	subcmd = strtoul(pos, &pos, 10);
 
 	if (*pos != '\0') {
-		if (!isblank(*pos++))
+		if (!isblank((unsigned char) *pos++))
 			return -EINVAL;
 		data_len = os_strlen(pos);
 	}