[PATCH v3 3/3] WNM: Use standard BSS selection and enable abridged bit handling
Janusz Dziedzic
janusz.dziedzic at gmail.com
Wed Dec 17 13:53:49 PST 2025
wt., 16 gru 2025 o 13:20 Janusz Dziedzic <janusz.dziedzic at gmail.com> napisał(a):
>
> czw., 19 wrz 2024 o 12:21 Benjamin Berg <benjamin at sipsolutions.net> napisał(a):
> >
> > From: Benjamin Berg <benjamin.berg at intel.com>
> >
> > Most of the logic to reject BSSs during transition has been moved into
> > wnm_is_bss_excluded. In addition to this, since commit 67bf89f55442
> > ("WNM: Choose the best available BSS, not just the first one") we will
> > simply choose the BSS with the best throughput.
> >
> > Overall, this matches the behaviour that the supplicant will use anyway
> > in wpa_supplicant_select_bss. The only bigger difference is that using
> > this will check all known BSSs instead of only the ones in the candidate
> > list. This means that with this change the abridged bit is handled
> > according to spec.
> >
> > There are some subtle changes to the logic. Once is, that candidates
> > with a very low signal level are not explicitly dropped anymore.
> > However, that code pre-dates the logic to prefer the best BSS and should
> > not be relevant anymore.
> >
> > Another small adjustment is to change the custom logic to avoid roaming
> > when it is not needed to use wpa_supplicant_need_to_roam_within_ess.
> >
> > Signed-off-by: Benjamin Berg <benjamin.berg at intel.com>
> >
> > ---
> >
> > v3: Apply normal roaming rules, to fix the issue found by Ben Greear
> > Signed-off-by: Benjamin Berg <benjamin.berg at intel.com>
> > ---
> > wpa_supplicant/events.c | 2 +-
> > wpa_supplicant/wnm_sta.c | 137 +++++-------------------------
> > wpa_supplicant/wpa_supplicant_i.h | 5 ++
> > 3 files changed, 26 insertions(+), 118 deletions(-)
> >
> > diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
> > index 668068167f..8e43db3e41 100644
> > --- a/wpa_supplicant/events.c
> > +++ b/wpa_supplicant/events.c
> > @@ -1733,7 +1733,7 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
> > }
> >
> >
> > -static struct wpa_bss *
> > +struct wpa_bss *
> > wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s,
> > struct wpa_ssid *group,
> > struct wpa_ssid **selected_ssid,
> > diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
> > index dcef8053ee..0ee47c2b4b 100644
> > --- a/wpa_supplicant/wnm_sta.c
> > +++ b/wpa_supplicant/wnm_sta.c
> > @@ -687,117 +687,6 @@ end:
> > }
> >
> >
> > -static struct wpa_bss * find_better_target(struct wpa_bss *a,
> > - struct wpa_bss *b)
> > -{
> > - if (!a)
> > - return b;
> > - if (!b)
> > - return a;
> > -
> > - if (a->est_throughput > b->est_throughput) {
> > - wpa_printf(MSG_DEBUG, "WNM: A is better: " MACSTR
> > - " est-tput: %d B: " MACSTR " est-tput: %d",
> > - MAC2STR(a->bssid), a->est_throughput,
> > - MAC2STR(b->bssid), b->est_throughput);
> > - return a;
> > - }
> > -
> > - wpa_printf(MSG_DEBUG, "WNM: B is better, A: " MACSTR
> > - " est-tput: %d B: " MACSTR " est-tput: %d",
> > - MAC2STR(a->bssid), a->est_throughput,
> > - MAC2STR(b->bssid), b->est_throughput);
> > - return b;
> > -}
> > -
> > -static struct wpa_bss *
> > -compare_scan_neighbor_results(struct wpa_supplicant *wpa_s,
> > - enum mbo_transition_reject_reason *reason)
> > -{
> > - u8 i;
> > - struct wpa_bss *bss = wpa_s->current_bss;
> > - struct wpa_bss *target;
> > - struct wpa_bss *best_target = NULL;
> > - struct wpa_bss *bss_in_list = NULL;
> > -
> > - if (!bss)
> > - return NULL;
> > -
> > - wpa_printf(MSG_DEBUG, "WNM: Current BSS " MACSTR " RSSI %d",
> > - MAC2STR(wpa_s->bssid), bss->level);
> > -
> > - for (i = 0; i < wpa_s->wnm_num_neighbor_report; i++) {
> > - struct neighbor_report *nei;
> > -
> > - nei = &wpa_s->wnm_neighbor_report_elements[i];
> > -
> > - target = wpa_bss_get_bssid(wpa_s, nei->bssid);
> > - if (!target) {
> > - wpa_printf(MSG_DEBUG, "Candidate BSS " MACSTR
> > - " (pref %d) not found in scan results",
> > - MAC2STR(nei->bssid),
> > - nei->preference_present ? nei->preference :
> > - -1);
> > - continue;
> > - }
> > -
> > - /*
> > - * TODO: Could consider allowing transition to another ESS if
> > - * PMF was enabled for the association.
> > - */
> > - if (!wpa_scan_res_match(wpa_s, 0, target, wpa_s->current_ssid,
> > - 1, 0)) {
> > - wpa_printf(MSG_DEBUG, "Candidate BSS " MACSTR
> > - " (pref %d) does not match the current network profile",
> > - MAC2STR(nei->bssid),
> > - nei->preference_present ? nei->preference :
> > - -1);
> > - continue;
> > - }
> > -
> > - if (target->level < bss->level && target->level < -80) {
> > - wpa_printf(MSG_DEBUG, "Candidate BSS " MACSTR
> > - " (pref %d) does not have sufficient signal level (%d)",
> > - MAC2STR(nei->bssid),
> > - nei->preference_present ? nei->preference :
> > - -1,
> > - target->level);
> > - continue;
> > - }
> > -
> > - best_target = find_better_target(target, best_target);
> > - if (target == bss)
> > - bss_in_list = bss;
> > - }
> > -
> > - target = best_target;
> > -
> > - if (!target)
> > - return NULL;
> > -
> > - wpa_printf(MSG_DEBUG,
> > - "WNM: Found an acceptable preferred transition candidate BSS "
> > - MACSTR " (RSSI %d, tput: %d bss-tput: %d)",
> > - MAC2STR(target->bssid), target->level,
> > - target->est_throughput, bss->est_throughput);
> > -
> > - if (!bss_in_list)
> > - return target;
> > -
> > - if ((!target->est_throughput && !bss_in_list->est_throughput) ||
> > - (target->est_throughput > bss_in_list->est_throughput &&
> > - target->est_throughput - bss_in_list->est_throughput >
> > - bss_in_list->est_throughput >> 4)) {
> > - /* It is more than 100/16 percent better, so switch. */
> > - return target;
> > - }
> > -
> > - wpa_printf(MSG_DEBUG,
> > - "WNM: Stay with our current BSS, not enough change in estimated throughput to switch");
> > - return bss_in_list;
> > -}
> > -
> > -
> > static int wpa_bss_ies_eq(struct wpa_bss *a, struct wpa_bss *b, u8 eid)
> > {
> > const u8 *ie_a, *ie_b;
> > @@ -1115,11 +1004,12 @@ static void wnm_bss_tm_connect(struct wpa_supplicant *wpa_s,
> >
> > int wnm_scan_process(struct wpa_supplicant *wpa_s, bool pre_scan_check)
> > {
> > - struct wpa_bss *bss;
> > + struct wpa_bss *bss, *current_bss = wpa_s->current_bss;
> > struct wpa_ssid *ssid = wpa_s->current_ssid;
> > enum bss_trans_mgmt_status_code status = WNM_BSS_TM_REJECT_UNSPECIFIED;
> > enum mbo_transition_reject_reason reason =
> > MBO_TRANSITION_REJECT_REASON_UNSPECIFIED;
> > + struct wpa_ssid *selected_ssid = NULL;
> >
> > if (!wpa_s->wnm_dialog_token)
> > return 0;
> > @@ -1143,7 +1033,7 @@ int wnm_scan_process(struct wpa_supplicant *wpa_s, bool pre_scan_check)
> > fetch_drv_mbo_candidate_info(wpa_s, &reason);
> >
> > /* Compare the Neighbor Report and scan results */
> > - bss = compare_scan_neighbor_results(wpa_s, &reason);
> > + bss = wpa_supplicant_select_bss(wpa_s, ssid, &selected_ssid, 1);
> > #ifdef CONFIG_MBO
> > if (!bss && wpa_s->wnm_mbo_trans_reason_present &&
> > wpa_s->wnm_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT) {
> > @@ -1169,7 +1059,7 @@ int wnm_scan_process(struct wpa_supplicant *wpa_s, bool pre_scan_check)
> > nei->drv_mbo_reject = 0;
> > }
> >
> > - bss = compare_scan_neighbor_results(wpa_s, &reason);
> > + bss = wpa_supplicant_select_bss(wpa_s, ssid, &selected_ssid, 1);
> > }
> > #endif /* CONFIG_MBO */
> >
> > @@ -1194,20 +1084,33 @@ int wnm_scan_process(struct wpa_supplicant *wpa_s, bool pre_scan_check)
> > return 0;
> >
> > #ifndef CONFIG_NO_ROAMING
> > - if (wpa_s->current_bss && bss != wpa_s->current_bss &&
> > + if (current_bss && bss != current_bss &&
> > wpa_supplicant_need_to_roam_within_ess(wpa_s, bss,
> > - wpa_s->current_bss,
> > - false))
> > + current_bss, false))
> > return 0;
> > #endif /* CONFIG_NO_ROAMING */
> > }
> >
> > + /* Apply normal roaming rules if we can stay with the current BSS */
> > + if (current_bss && bss != current_bss &&
> > + wpa_scan_res_match(wpa_s, 0, current_bss, wpa_s->current_ssid,
> > + 1, 0) &&
> > + !wpa_supplicant_need_to_roam_within_ess(wpa_s, current_bss, bss,
> > + true))
> > + bss = current_bss;
> > +
> > if (!bss) {
> > wpa_printf(MSG_DEBUG, "WNM: No BSS transition candidate match found");
> > status = WNM_BSS_TM_REJECT_NO_SUITABLE_CANDIDATES;
> > goto send_bss_resp_fail;
> > }
> >
> > + wpa_printf(MSG_DEBUG,
> > + "WNM: Found an acceptable preferred transition candidate BSS "
> > + MACSTR " (RSSI %d, tput: %d bss-tput: %d)",
> > + MAC2STR(bss->bssid), bss->level, bss->est_throughput,
> > + current_bss ? current_bss->est_throughput : -1);
> > +
> > /* Associate to the network */
> > wnm_bss_tm_connect(wpa_s, bss, ssid, 1);
> > return 1;
> > diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
> > index 7c51cdb20e..0bd4fcdedd 100644
> > --- a/wpa_supplicant/wpa_supplicant_i.h
> > +++ b/wpa_supplicant/wpa_supplicant_i.h
> > @@ -1965,6 +1965,11 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
> > struct wpa_ssid *group,
> > int only_first_ssid, int debug_print);
> >
> > +struct wpa_bss * wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s,
> > + struct wpa_ssid *group,
> > + struct wpa_ssid **selected_ssid,
> > + int only_first_ssid);
> > +
> > int wpas_ctrl_iface_get_pref_freq_list_override(struct wpa_supplicant *wpa_s,
> > enum wpa_driver_if_type if_type,
> > unsigned int *num,
>
> Not sure you see same problem (have multiple APs with same SSID and
> testing BTM) - CONFIG_NO_ROAMING set:
>
> 1764069336.216142: WNM: BSS Transition Candidate List
> 1764069336.216153: 0: 58:00:32:c0:13:23 info=0x9af op_class=128
> chan=52 phy=9 pref=1 freq=5260
> 1764069336.216177: WNM: Candidate list valid for 102 ms
> 1764069336.217207: nl80211: Received scan results (32 BSSes)
> 1764069336.217347: nl80211: Scan results indicate BSS status with
> 58:00:32:c0:13:22 as associated
>
> 1764069336.222433: wlan2: selected BSS 7a:d4:37:e7:4e:1f ssid='testap'
> 1764069336.222461: WNM: Found an acceptable preferred transition
> candidate BSS 7a:d4:37:e7:4e:1f (RSSI -16, tput: 143402 bss-tput:
> 143402)
> 1764069336.222512: wlan2: WNM: Transition to BSS 7a:d4:37:e7:4e:1f
> based on BSS Transition Management Request (old BSSID
> 58:00:32:c0:13:22 after_new_scan=1)
> 1764069336.222539: WNM: Sending successful BSS Transition Management Response
> 1764069336.222551: WNM: Send BSS Transition Management Response to
> 58:00:32:c0:13:22 dialog_token=1 status=0 reason=0 delay=0
> 1764069336.222577: WNM: Add candidate list to BSS Transition
> Management Response frame
>
>
> Looks like find first AP from scan results and use it - just skip BTM
> prefered candidate.
> After revert works correctly and connect to bssid from candidate list.
> Testing it using latest OpenWrt (with Intel BE200 as client), so could
> be already fixed in main?
>
>
> Didn't dig in that a lot, just revert this one.
> After revert:
> 1764069110.452716: WNM: BSS Transition Candidate List
> 1764069110.452729: 0: 58:00:32:c0:13:23 info=0x9af op_class=128
> chan=52 phy=9 pref=1 freq=5260
> 1764069110.452752: WNM: Candidate list valid for 102 ms
> 1764069110.453740: nl80211: Received scan results (32 BSSes)
> 1764069110.453876: nl80211: Scan results indicate BSS status with
> 58:00:32:c0:13:22 as associated
> 1764069110.455368: wlan2: BSS: Start scan result update 2
> 1764069110.455928: wlan2: WNM: Process scan results for BSS Transition
> Management
> 1764069110.455977: WNM: Current BSS 58:00:32:c0:13:22 RSSI -35
> 1764069110.456003: Candidate BSS 58:00:32:c0:13:23 (pref 1) not found
> in scan results
> 1764069110.456021: WNM: No valid match in previous scan results - try a new scan
> 1764069110.456038: WNM: Scan 1 frequencies based on transition candidate list
> 1764069110.456051: WNM: Scan only for a specific BSSID since there is
> only a single candidate 58:00:32:c0:13:23
>
> 1764069110.603181: wlan2: WNM: Process scan results for BSS Transition
> Management
> 1764069110.603225: WNM: Current BSS 58:00:32:c0:13:22 RSSI -35
> 1764069110.603512: WNM: Found an acceptable preferred transition
> candidate BSS 58:00:32:c0:13:23 (RSSI -40, tput: 600502 bss-tput:
> 143402)
> 1764069110.603564: wlan2: WNM: Transition to BSS 58:00:32:c0:13:23
> based on BSS Transition Management Request (old BSSID
> 58:00:32:c0:13:22 after_new_scan=1)
> 1764069110.603592: WNM: Sending successful BSS Transition Management Response
> 1764069110.603604: WNM: Send BSS Transition Management Response to
> 58:00:32:c0:13:22 dialog_token=1 status=0 reason=0 delay=0
> 1764069110.603629: WNM: Add candidate list to BSS Transition
> Management Response frame
>
OK, see it. Older supplicant behave different, so new one need better
BTM request.
BR
Janusz
More information about the Hostap
mailing list