aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorVenkateswara Naralasetty <vnaralas@codeaurora.org>2018-12-05 10:23:53 (GMT)
committerJouni Malinen <j@w1.fi>2018-12-20 10:10:31 (GMT)
commit5abc7823bd01f69b8afbe1fd19f65fff86137c44 (patch)
tree2b858fa58c333dfe6068125db5d8bb1434ed38f9 /wpa_supplicant
parent9c06f0f6aed26c1628acaa74df0232dd7b345e9a (diff)
downloadhostap-5abc7823bd01f69b8afbe1fd19f65fff86137c44.zip
hostap-5abc7823bd01f69b8afbe1fd19f65fff86137c44.tar.gz
hostap-5abc7823bd01f69b8afbe1fd19f65fff86137c44.tar.bz2
wpa_supplicant: Add Multi-AP backhaul STA support
Advertise vendor specific Multi-AP IE in (Re)Association Request frames and process Multi-AP IE from (Re)Association Response frames if the user enables Multi-AP fuctionality. If the (Re)Association Response frame does not contain the Multi-AP IE, disassociate. This adds a new configuration parameter 'multi_ap_backhaul_sta' to enable/disable Multi-AP functionality. Enable 4-address mode after association (if the Association Response frame contains the Multi-AP IE). Also enable the bridge in that case. This is necessary because wpa_supplicant only enables the bridge in wpa_drv_if_add(), which only gets called when an interface is added through the control interface, not when it is configured from the command line. Signed-off-by: Venkateswara Naralasetty <vnaralas@codeaurora.org> Signed-off-by: Jouni Malinen <jouni@codeaurora.org> Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/config.c1
-rw-r--r--wpa_supplicant/config_ssid.h7
-rw-r--r--wpa_supplicant/driver_i.h8
-rw-r--r--wpa_supplicant/events.c50
-rw-r--r--wpa_supplicant/sme.c16
-rw-r--r--wpa_supplicant/wpa_supplicant.c18
-rw-r--r--wpa_supplicant/wpa_supplicant.conf7
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h1
8 files changed, 108 insertions, 0 deletions
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 78da98d..0f71e9f 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2384,6 +2384,7 @@ static const struct parse_data ssid_fields[] = {
#endif /* CONFIG_DPP */
{ INT_RANGE(owe_group, 0, 65535) },
{ INT_RANGE(owe_only, 0, 1) },
+ { INT_RANGE(multi_ap_backhaul_sta, 0, 1) },
};
#undef OFFSET
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 6427fbb..5205b07 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -948,6 +948,13 @@ struct wpa_ssid {
* the selection attempts for OWE BSS exceed the configured threshold.
*/
int owe_transition_bss_select_count;
+
+ /**
+ * multi_ap_backhaul_sta - Multi-AP backhaul STA
+ * 0 = normal (non-Multi-AP) station
+ * 1 = Multi-AP backhaul station
+ */
+ int multi_ap_backhaul_sta;
};
#endif /* CONFIG_SSID_H */
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 5581bb0..86c891a 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -1054,4 +1054,12 @@ wpa_drv_send_external_auth_status(struct wpa_supplicant *wpa_s,
params);
}
+static inline int wpa_drv_set_4addr_mode(struct wpa_supplicant *wpa_s, int val)
+{
+ if (!wpa_s->driver->set_4addr_mode)
+ return -1;
+ return wpa_s->driver->set_4addr_mode(wpa_s->drv_priv,
+ wpa_s->bridge_ifname, val);
+}
+
#endif /* DRIVER_I_H */
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 8eac4be..7f23029 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -324,6 +324,9 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
os_memset(wpa_s->last_tk, 0, sizeof(wpa_s->last_tk));
#endif /* CONFIG_TESTING_OPTIONS */
wpa_s->ieee80211ac = 0;
+
+ if (wpa_s->enabled_4addr_mode && wpa_drv_set_4addr_mode(wpa_s, 0) == 0)
+ wpa_s->enabled_4addr_mode = 0;
}
@@ -2267,6 +2270,50 @@ static void interworking_process_assoc_resp(struct wpa_supplicant *wpa_s,
#endif /* CONFIG_INTERWORKING */
+static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s,
+ const u8 *ies, size_t ies_len)
+{
+ struct ieee802_11_elems elems;
+ const u8 *map_sub_elem, *pos;
+ size_t len;
+
+ if (!wpa_s->current_ssid ||
+ !wpa_s->current_ssid->multi_ap_backhaul_sta ||
+ !ies ||
+ ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed)
+ return;
+
+ if (!elems.multi_ap || elems.multi_ap_len < 7) {
+ wpa_printf(MSG_INFO, "AP doesn't support Multi-AP protocol");
+ goto fail;
+ }
+
+ pos = elems.multi_ap + 4;
+ len = elems.multi_ap_len - 4;
+
+ map_sub_elem = get_ie(pos, len, MULTI_AP_SUB_ELEM_TYPE);
+ if (!map_sub_elem || map_sub_elem[1] < 1) {
+ wpa_printf(MSG_INFO, "invalid Multi-AP sub elem type");
+ goto fail;
+ }
+
+ if (!(map_sub_elem[2] & MULTI_AP_BACKHAUL_BSS)) {
+ wpa_printf(MSG_INFO, "AP doesn't support backhaul BSS");
+ goto fail;
+ }
+
+ if (wpa_drv_set_4addr_mode(wpa_s, 1) < 0) {
+ wpa_printf(MSG_ERROR, "Failed to set 4addr mode");
+ goto fail;
+ }
+ wpa_s->enabled_4addr_mode = 1;
+ return;
+
+fail:
+ wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
+}
+
+
#ifdef CONFIG_FST
static int wpas_fst_update_mbie(struct wpa_supplicant *wpa_s,
const u8 *ie, size_t ie_len)
@@ -2343,6 +2390,9 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
get_ie(data->assoc_info.resp_ies,
data->assoc_info.resp_ies_len, WLAN_EID_VHT_CAP))
wpa_s->ieee80211ac = 1;
+
+ multi_ap_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
+ data->assoc_info.resp_ies_len);
}
if (data->assoc_info.beacon_ies)
wpa_hexdump(MSG_DEBUG, "beacon_ies",
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 779c79b..b61e0c3 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -1554,6 +1554,22 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
}
#endif /* CONFIG_OWE */
+ if (wpa_s->current_ssid && wpa_s->current_ssid->multi_ap_backhaul_sta) {
+ size_t multi_ap_ie_len;
+
+ multi_ap_ie_len = add_multi_ap_ie(
+ wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
+ sizeof(wpa_s->sme.assoc_req_ie) -
+ wpa_s->sme.assoc_req_ie_len,
+ MULTI_AP_BACKHAUL_STA);
+ if (multi_ap_ie_len == 0) {
+ wpa_printf(MSG_ERROR,
+ "Multi-AP: Failed to build Multi-AP IE");
+ return;
+ }
+ wpa_s->sme.assoc_req_ie_len += multi_ap_ie_len;
+ }
+
params.bssid = bssid;
params.ssid = wpa_s->sme.ssid;
params.ssid_len = wpa_s->sme.ssid_len;
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index bd66d9b..1ade625 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -2816,6 +2816,21 @@ static u8 * wpas_populate_assoc_ies(
}
#endif /* CONFIG_IEEE80211R */
+ if (ssid->multi_ap_backhaul_sta) {
+ size_t multi_ap_ie_len;
+
+ multi_ap_ie_len = add_multi_ap_ie(wpa_ie + wpa_ie_len,
+ max_wpa_ie_len - wpa_ie_len,
+ MULTI_AP_BACKHAUL_STA);
+ if (multi_ap_ie_len == 0) {
+ wpa_printf(MSG_ERROR,
+ "Multi-AP: Failed to build Multi-AP IE");
+ os_free(wpa_ie);
+ return NULL;
+ }
+ wpa_ie_len += multi_ap_ie_len;
+ }
+
params->wpa_ie = wpa_ie;
params->wpa_ie_len = wpa_ie_len;
params->auth_alg = algs;
@@ -3294,6 +3309,9 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
zero_addr = 1;
}
+ if (wpa_s->enabled_4addr_mode && wpa_drv_set_4addr_mode(wpa_s, 0) == 0)
+ wpa_s->enabled_4addr_mode = 0;
+
#ifdef CONFIG_TDLS
wpa_tdls_teardown_peers(wpa_s->wpa);
#endif /* CONFIG_TDLS */
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index b939900..ffe5d2e 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -1403,6 +1403,13 @@ fast_reauth=1
# 2: MCS 0-9
# 3: not supported
+# multi_ap_backhaul_sta: Multi-AP backhaul STA functionality
+# 0 = normal STA (default)
+# 1 = backhaul STA
+# A backhaul STA sends the Multi-AP IE, fails to associate if the AP does not
+# support Multi-AP, and sets 4-address mode if it does. Thus, the netdev can be
+# added to a bridge to allow forwarding frames over this backhaul link.
+
##### Fast Session Transfer (FST) support #####################################
#
# The options in this section are only available when the build configuration
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 8b749f4..b3a7db6 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1234,6 +1234,7 @@ struct wpa_supplicant {
unsigned int disable_fils:1;
#endif /* CONFIG_FILS */
unsigned int ieee80211ac:1;
+ unsigned int enabled_4addr_mode:1;
};