Hi, On Fri, 2024-02-09 at 16:18 +0100, benjamin@xxxxxxxxxxxxxxxx wrote: > From: Benjamin Berg <benjamin.berg@xxxxxxxxx> > > 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@xxxxxxxxx> > --- > 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; _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap