From: Jouni Malinen Date: Sat, 12 Apr 2025 09:46:12 +0000 (+0300) Subject: Testing capability to add extra IEs to per-STA profiles in assoc req X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7108c5afbe93244fcf0787a617161abbd8d10eac;p=thirdparty%2Fhostap.git Testing capability to add extra IEs to per-STA profiles in assoc req Allow wpa_supplicant builds with CONFIG_TESTING_OPTIONS=y to be configured to add extra IEs to the per-STA profiles in Association Request frames. This can be used for testing AP MLD behavior. Signed-off-by: Jouni Malinen --- diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 3435c1db5..3892df99d 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -825,6 +825,23 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s, wpa_s->rsnxe_override_eapol = NULL; else wpa_s->rsnxe_override_eapol = wpabuf_parse_bin(value); + } else if (os_strcasecmp(cmd, "link_ies") == 0) { + int link_id = atoi(value); + char *pos; + + if (link_id < 0 || link_id >= MAX_NUM_MLD_LINKS) + return -1; + + pos = os_strchr(value, ':'); + if (!pos) + return -1; + pos++; + + wpabuf_free(wpa_s->link_ies[link_id]); + if (os_strcmp(value, "NULL") == 0) + wpa_s->link_ies[link_id] = NULL; + else + wpa_s->link_ies[link_id] = wpabuf_parse_bin(pos); } else if (os_strcasecmp(cmd, "reject_btm_req_reason") == 0) { wpa_s->reject_btm_req_reason = atoi(value); } else if (os_strcasecmp(cmd, "get_pref_freq_list_override") == 0) { @@ -9040,6 +9057,14 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s) wpabuf_free(wpa_s->rsnxe_override_eapol); wpa_s->rsnxe_override_eapol = NULL; wpas_clear_driver_signal_override(wpa_s); + { + int i; + + for (i = 0; i < MAX_NUM_MLD_LINKS; i++) { + wpabuf_free(wpa_s->link_ies[i]); + wpa_s->link_ies[i] = NULL; + } + } #ifndef CONFIG_NO_ROBUST_AV wpa_s->disable_scs_support = 0; wpa_s->disable_mscs_support = 0; diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 1696e5070..fe8e45e07 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -344,12 +344,16 @@ void wpa_supplicant_stop_countermeasures(void *eloop_ctx, void *sock_ctx) void wpas_reset_mlo_info(struct wpa_supplicant *wpa_s) { + int i; + if (!wpa_s->valid_links) return; wpa_s->valid_links = 0; wpa_s->mlo_assoc_link_id = 0; os_memset(wpa_s->ap_mld_addr, 0, ETH_ALEN); + for (i = 0; i < MAX_NUM_MLD_LINKS; i++) + wpabuf_free(wpa_s->links[i].ies); os_memset(wpa_s->links, 0, sizeof(wpa_s->links)); } diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 941d031cb..d4e9cebbc 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -538,6 +538,12 @@ static void wpas_sme_set_mlo_links(struct wpa_supplicant *wpa_s, os_memcpy(wpa_s->links[i].bssid, bssid, ETH_ALEN); wpa_s->links[i].freq = bss->mld_links[i].freq; wpa_s->links[i].disabled = bss->mld_links[i].disabled; + wpabuf_free(wpa_s->links[i].ies); + wpa_s->links[i].ies = NULL; +#ifdef CONFIG_TESTING_OPTIONS + if (wpa_s->link_ies[i]) + wpa_s->links[i].ies = wpabuf_dup(wpa_s->link_ies[i]); +#endif /* CONFIG_TESTING_OPTIONS */ if (bss->mld_link_id == i) wpa_s->links[i].bss = bss; @@ -2702,11 +2708,19 @@ mscs_fail: wpa_s->links[i].freq; params.mld_params.mld_links[i].disabled = wpa_s->links[i].disabled; + if (wpa_s->links[i].ies) { + params.mld_params.mld_links[i].ies = + wpabuf_head(wpa_s->links[i].ies); + params.mld_params.mld_links[i].ies_len = + wpabuf_len(wpa_s->links[i].ies); + } wpa_printf(MSG_DEBUG, - "MLD: id=%u, freq=%d, disabled=%u, " MACSTR, + "MLD: id=%u, freq=%d, disabled=%u, ies_len=%zu, " + MACSTR, i, wpa_s->links[i].freq, wpa_s->links[i].disabled, + params.mld_params.mld_links[i].ies_len, MAC2STR(wpa_s->links[i].bssid)); } } diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 82b9288f3..da7ff00c9 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -658,6 +658,10 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) wpabuf_free(wpa_s->rsnxe_override_eapol); wpa_s->rsnxe_override_eapol = NULL; wpas_clear_driver_signal_override(wpa_s); + for (i = 0; i < MAX_NUM_MLD_LINKS; i++) { + wpabuf_free(wpa_s->link_ies[i]); + wpa_s->link_ies[i] = NULL; + } #endif /* CONFIG_TESTING_OPTIONS */ if (wpa_s->conf != NULL) { @@ -869,6 +873,11 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) os_free(wpa_s->owe_trans_scan_freq); wpa_s->owe_trans_scan_freq = NULL; #endif /* CONFIG_OWE */ + + for (i = 0; i < MAX_NUM_MLD_LINKS; i++) { + wpabuf_free(wpa_s->links[i].ies); + wpa_s->links[i].ies = NULL; + } } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 7644ed9b5..1a7e2148e 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -740,6 +740,7 @@ struct wpa_supplicant { unsigned int freq; struct wpa_bss *bss; bool disabled; + struct wpabuf *ies; } links[MAX_NUM_MLD_LINKS]; u8 *last_con_fail_realm; size_t last_con_fail_realm_len; @@ -1371,6 +1372,7 @@ struct wpa_supplicant { unsigned int disable_eapol_g2_tx; unsigned int eapol_2_key_info_set_mask; int test_assoc_comeback_type; + struct wpabuf *link_ies[MAX_NUM_MLD_LINKS]; #endif /* CONFIG_TESTING_OPTIONS */ struct wmm_ac_assoc_data *wmm_ac_assoc_info;