[PATCH 9/9] WNM: Keep BTM information until connection completes
Benjamin Berg
benjamin at sipsolutions.net
Fri Feb 9 08:49:14 PST 2024
Hi,
On Fri, 2024-02-09 at 16:18 +0100, benjamin at sipsolutions.net wrote:
> From: Benjamin Berg <benjamin.berg at intel.com>
>
> In the MLD case, the information from the transition management request
> is relevant during the association process in order to filter out links
> that were disallowed by the BTM request. Also, the information remains
> useful should a connection attempt fail.
>
> To enable these scenarios, keep the information around until the
> connection has completed. As this might make it impossible to establish
> a connection, also clear this information at the same time that a normal
> BSS ignore is cleared to avoid getting stuck in case the transition
> fails unexpectedly.
I am now realizing that the state is not self-contained enough right
now as wnm_is_bss_excluded is using current_bss. So other changes will
be needed before making such a switch.
That said, I do think that the patch is reasonable in principle.
Benjamin
>
> Signed-off-by: Benjamin Berg <benjamin.berg at intel.com>
> ---
> wpa_supplicant/ctrl_iface.c | 2 ++
> wpa_supplicant/events.c | 4 ++-
> wpa_supplicant/wnm_sta.c | 42 +++++++++++++++--------------
> --
> wpa_supplicant/wnm_sta.h | 16 +++++++++++-
> wpa_supplicant/wpa_supplicant.c | 8 +++---
> wpa_supplicant/wpa_supplicant_i.h | 1 -
> 6 files changed, 45 insertions(+), 28 deletions(-)
>
> diff --git a/wpa_supplicant/ctrl_iface.c
> b/wpa_supplicant/ctrl_iface.c
> index bfc9a6631..4df7e77b4 100644
> --- a/wpa_supplicant/ctrl_iface.c
> +++ b/wpa_supplicant/ctrl_iface.c
> @@ -8839,6 +8839,8 @@ static void
> wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
>
> wpa_s->next_ssid = NULL;
>
> + wnm_btm_reset(wpa_s);
> +
> #ifdef CONFIG_INTERWORKING
> #ifdef CONFIG_HS20
> hs20_cancel_fetch_osu(wpa_s);
> diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
> index a938bce99..d4f2609d8 100644
> --- a/wpa_supplicant/events.c
> +++ b/wpa_supplicant/events.c
> @@ -1802,10 +1802,12 @@ struct wpa_bss *
> wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
> break;
> }
>
> - if (selected == NULL && wpa_s->bssid_ignore &&
> + if (selected == NULL &&
> + (wpa_s->bssid_ignore ||
> wnm_active_bss_trans_mgmt(wpa_s)) &&
> !wpa_s->countermeasures) {
> wpa_dbg(wpa_s, MSG_DEBUG,
> "No APs found - clear BSSID ignore
> list and try again");
> + wnm_btm_reset(wpa_s);
> wpa_bssid_ignore_clear(wpa_s);
> wpa_s->bssid_ignore_cleared = true;
> } else if (selected == NULL)
> diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
> index 939c3b7c0..c0ed37292 100644
> --- a/wpa_supplicant/wnm_sta.c
> +++ b/wpa_supplicant/wnm_sta.c
> @@ -418,7 +418,7 @@ static void ieee802_11_rx_wnmsleep_resp(struct
> wpa_supplicant *wpa_s,
> }
>
>
> -void wnm_deallocate_memory(struct wpa_supplicant *wpa_s)
> +void wnm_btm_reset(struct wpa_supplicant *wpa_s)
> {
> int i;
>
> @@ -430,6 +430,18 @@ void wnm_deallocate_memory(struct wpa_supplicant
> *wpa_s)
> wpa_s->wnm_num_neighbor_report = 0;
> os_free(wpa_s->wnm_neighbor_report_elements);
> wpa_s->wnm_neighbor_report_elements = NULL;
> +
> + wpa_s->wnm_cand_valid_until.sec = 0;
> + wpa_s->wnm_cand_valid_until.usec = 0;
> +
> + wpa_s->wnm_mode = 0;
> + wpa_s->wnm_dialog_token = 0;
> + wpa_s->wnm_reply = 0;
> +
> +#ifdef CONFIG_MBO
> + wpa_s->wnm_mbo_trans_reason_present = 0;
> + wpa_s->wnm_mbo_transition_reason = 0;
> +#endif /* CONFIG_MBO */
> }
>
>
> @@ -1137,7 +1149,6 @@ static void wnm_bss_tm_connect(struct
> wpa_supplicant *wpa_s,
> if (bss == wpa_s->current_bss) {
> wpa_printf(MSG_DEBUG,
> "WNM: Already associated with the
> preferred candidate");
> - wnm_deallocate_memory(wpa_s);
> return;
> }
>
> @@ -1153,7 +1164,6 @@ static void wnm_bss_tm_connect(struct
> wpa_supplicant *wpa_s,
> */
> if (!already_connecting && radio_work_pending(wpa_s, "sme-
> connect"))
> wpa_s->bss_trans_mgmt_in_progress = true;
> - wnm_deallocate_memory(wpa_s);
> }
>
>
> @@ -1165,23 +1175,16 @@ int wnm_scan_process(struct wpa_supplicant
> *wpa_s, int reply_on_fail)
> enum mbo_transition_reject_reason reason =
> MBO_TRANSITION_REJECT_REASON_UNSPECIFIED;
>
> - if (!wpa_s->wnm_neighbor_report_elements)
> + if (!wpa_s->wnm_dialog_token)
> return 0;
>
> wpa_dbg(wpa_s, MSG_DEBUG,
> "WNM: Process scan results for BSS Transition
> Management");
> - if (os_reltime_before(&wpa_s->wnm_cand_valid_until,
> + if (os_reltime_initialized(&wpa_s->wnm_cand_valid_until) &&
> + os_reltime_before(&wpa_s->wnm_cand_valid_until,
> &wpa_s->scan_trigger_time)) {
> wpa_printf(MSG_DEBUG, "WNM: Previously stored BSS
> transition candidate list is not valid anymore - drop it");
> - wnm_deallocate_memory(wpa_s);
> - return 0;
> - }
> -
> - if (!wpa_s->current_bss ||
> - !ether_addr_equal(wpa_s->wnm_cand_from_bss,
> - wpa_s->current_bss->bssid)) {
> - wpa_printf(MSG_DEBUG, "WNM: Stored BSS transition
> candidate list not from the current BSS - ignore it");
> - return 0;
> + goto send_bss_resp_fail;
> }
>
> /* Compare the Neighbor Report and scan results */
> @@ -1208,7 +1211,7 @@ send_bss_resp_fail:
> wpa_s-
> > wnm_dialog_token,
> status, reason, 0,
> NULL);
> }
> - wnm_deallocate_memory(wpa_s);
> + wnm_btm_reset(wpa_s);
>
> return 0;
> }
> @@ -1429,16 +1432,13 @@ static void
> ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s,
> if (end - pos < 5)
> return;
>
> -#ifdef CONFIG_MBO
> - wpa_s->wnm_mbo_trans_reason_present = 0;
> - wpa_s->wnm_mbo_transition_reason = 0;
> -#endif /* CONFIG_MBO */
> -
> if (wpa_s->current_bss)
> beacon_int = wpa_s->current_bss->beacon_int;
> else
> beacon_int = 100; /* best guess */
>
> + wnm_btm_reset(wpa_s);
> +
> wpa_s->wnm_dialog_token = pos[0];
> wpa_s->wnm_mode = pos[1];
> wpa_s->wnm_dissoc_timer = WPA_GET_LE16(pos + 2);
> @@ -1539,7 +1539,6 @@ static void
> ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s,
> unsigned int valid_ms;
>
> wpa_msg(wpa_s, MSG_INFO, "WNM: Preferred List
> Available");
> - wnm_deallocate_memory(wpa_s);
> wpa_s->wnm_neighbor_report_elements = os_calloc(
> WNM_MAX_NEIGHBOR_REPORT,
> sizeof(struct neighbor_report));
> @@ -1616,7 +1615,6 @@ static void
> ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s,
> wpa_s->wnm_cand_valid_until.sec +=
> wpa_s->wnm_cand_valid_until.usec / 1000000;
> wpa_s->wnm_cand_valid_until.usec %= 1000000;
> - os_memcpy(wpa_s->wnm_cand_from_bss, wpa_s->bssid,
> ETH_ALEN);
>
> /*
> * Fetch the latest scan results from the kernel and
> check for
> diff --git a/wpa_supplicant/wnm_sta.h b/wpa_supplicant/wnm_sta.h
> index 514a92d70..ba1ae1731 100644
> --- a/wpa_supplicant/wnm_sta.h
> +++ b/wpa_supplicant/wnm_sta.h
> @@ -65,7 +65,7 @@ int wnm_send_bss_transition_mgmt_query(struct
> wpa_supplicant *wpa_s,
> const char *btm_candidates,
> int cand_list);
>
> -void wnm_deallocate_memory(struct wpa_supplicant *wpa_s);
> +void wnm_btm_reset(struct wpa_supplicant *wpa_s);
> int wnm_send_coloc_intf_report(struct wpa_supplicant *wpa_s, u8
> dialog_token,
> const struct wpabuf *elems);
> void wnm_set_coloc_intf_elems(struct wpa_supplicant *wpa_s,
> @@ -81,6 +81,11 @@ void wnm_clear_coloc_intf_reporting(struct
> wpa_supplicant *wpa_s);
>
> bool wnm_is_bss_excluded(struct wpa_supplicant *wpa_s, struct
> wpa_bss *bss);
>
> +static inline bool wnm_active_bss_trans_mgmt(struct wpa_supplicant
> *wpa_s)
> +{
> + return !!wpa_s->wnm_dialog_token;
> +}
> +
> #else /* CONFIG_WNM */
>
> static inline int wnm_scan_process(struct wpa_supplicant *wpa_s,
> @@ -99,6 +104,15 @@ wnm_is_bss_excluded(struct wpa_supplicant *wpa_s,
> struct wpa_bss *bss)
> return false;
> }
>
> +static inline wnm_btm_reset(struct wpa_supplicant *wpa_s)
> +{
> +}
> +
> +static inline bool wnm_active_bss_trans_mgmt(struct wpa_supplicant
> *wpa_s)
> +{
> + return false;
> +}
> +
> #endif /* CONFIG_WNM */
>
> #endif /* WNM_STA_H */
> diff --git a/wpa_supplicant/wpa_supplicant.c
> b/wpa_supplicant/wpa_supplicant.c
> index afe827e01..0bd19e1bb 100644
> --- a/wpa_supplicant/wpa_supplicant.c
> +++ b/wpa_supplicant/wpa_supplicant.c
> @@ -675,9 +675,7 @@ static void wpa_supplicant_cleanup(struct
> wpa_supplicant *wpa_s)
> wpa_s->disallow_aps_ssid = NULL;
>
> wnm_bss_keep_alive_deinit(wpa_s);
> -#ifdef CONFIG_WNM
> - wnm_deallocate_memory(wpa_s);
> -#endif /* CONFIG_WNM */
> + wnm_btm_reset(wpa_s);
>
> ext_password_deinit(wpa_s->ext_pw);
> wpa_s->ext_pw = NULL;
> @@ -1071,6 +1069,10 @@ void wpa_supplicant_set_state(struct
> wpa_supplicant *wpa_s,
> if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
> wpa_supplicant_start_autoscan(wpa_s);
>
> + if (state == WPA_COMPLETED || state ==
> WPA_INTERFACE_DISABLED ||
> + state == WPA_INACTIVE)
> + wnm_btm_reset(wpa_s);
> +
> #ifndef CONFIG_NO_WMM_AC
> if (old_state >= WPA_ASSOCIATED && wpa_s->wpa_state <
> WPA_ASSOCIATED)
> wmm_ac_notify_disassoc(wpa_s);
> diff --git a/wpa_supplicant/wpa_supplicant_i.h
> b/wpa_supplicant/wpa_supplicant_i.h
> index 7d72b56ff..77df97842 100644
> --- a/wpa_supplicant/wpa_supplicant_i.h
> +++ b/wpa_supplicant/wpa_supplicant_i.h
> @@ -1308,7 +1308,6 @@ struct wpa_supplicant {
> u8 wnm_bss_termination_duration[12];
> struct neighbor_report *wnm_neighbor_report_elements;
> struct os_reltime wnm_cand_valid_until;
> - u8 wnm_cand_from_bss[ETH_ALEN];
> struct wpa_bss *wnm_target_bss;
> enum bss_trans_mgmt_status_code bss_tm_status;
> bool bss_trans_mgmt_in_progress;
More information about the Hostap
mailing list