Use default IEs in wpa_supplicant_trigger_scan()

wpa_supplicant_trigger_scan() previously wouldn't include any of the IEs
generated by wpa_supplicant_extra_ies(). Instruct it to do so in most
cases. This is necessary because MBO STAs are required to include MBO
capabilities in their Probe Request frames.

Signed-off-by: Matthew Wang <matthewmwang@chromium.org>
This commit is contained in:
Matthew Wang 2023-06-02 15:15:08 -07:00 committed by Jouni Malinen
parent ccefa6419c
commit 17bdf34c49
8 changed files with 40 additions and 10 deletions

View file

@ -209,7 +209,7 @@ fi.w1.wpa_supplicant1.CreateInterface.
<tr><th>Key</th><th>Value type</th><th>Description</th><th>Required</th> <tr><th>Key</th><th>Value type</th><th>Description</th><th>Required</th>
<tr><td>Type</td><td>s</td><td>Type of the scan. Possible values: "active", "passive"</td><td>Yes</td> <tr><td>Type</td><td>s</td><td>Type of the scan. Possible values: "active", "passive"</td><td>Yes</td>
<tr><td>SSIDs</td><td>aay</td><td>Array of SSIDs to scan for (applies only if scan type is active)</td><td>No</td> <tr><td>SSIDs</td><td>aay</td><td>Array of SSIDs to scan for (applies only if scan type is active)</td><td>No</td>
<tr><td>IEs</td><td>aay</td><td>Information elements to used in active scan (applies only if scan type is active)</td><td>No</td> <tr><td>IEs</td><td>aay</td><td>Information elements to used in active scan (applies only if scan type is active). Default IEs will be used in absence of this option.</td><td>No</td>
<tr><td>Channels</td><td>a(uu)</td><td>Array of frequencies to scan in form of (center, width) in MHz.</td><td>No</td> <tr><td>Channels</td><td>a(uu)</td><td>Array of frequencies to scan in form of (center, width) in MHz.</td><td>No</td>
<tr><td>AllowRoam</td><td>b</td><td>TRUE (or absent) to allow a roaming decision based on the results of this scan, FALSE to prevent a roaming decision.</td><td>No</td> <tr><td>AllowRoam</td><td>b</td><td>TRUE (or absent) to allow a roaming decision based on the results of this scan, FALSE to prevent a roaming decision.</td><td>No</td>
<tr><td>NonColoc6GHz</td><td>b</td><td>TRUE to force scanning of non-PSC 6 GHz channels, FALSE (or absent) to skip scanning of non-PSC 6 GHz channels.</td><td>No</td> <tr><td>NonColoc6GHz</td><td>b</td><td>TRUE to force scanning of non-PSC 6 GHz channels, FALSE (or absent) to skip scanning of non-PSC 6 GHz channels.</td><td>No</td>

View file

@ -305,7 +305,7 @@ static void bgscan_learn_timeout(void *eloop_ctx, void *timeout_ctx)
} }
wpa_printf(MSG_DEBUG, "bgscan learn: Request a background scan"); wpa_printf(MSG_DEBUG, "bgscan learn: Request a background scan");
if (wpa_supplicant_trigger_scan(wpa_s, &params)) { if (wpa_supplicant_trigger_scan(wpa_s, &params, true)) {
wpa_printf(MSG_DEBUG, "bgscan learn: Failed to trigger scan"); wpa_printf(MSG_DEBUG, "bgscan learn: Failed to trigger scan");
eloop_register_timeout(data->scan_interval, 0, eloop_register_timeout(data->scan_interval, 0,
bgscan_learn_timeout, data, NULL); bgscan_learn_timeout, data, NULL);

View file

@ -49,7 +49,7 @@ static void bgscan_simple_timeout(void *eloop_ctx, void *timeout_ctx)
*/ */
wpa_printf(MSG_DEBUG, "bgscan simple: Request a background scan"); wpa_printf(MSG_DEBUG, "bgscan simple: Request a background scan");
if (wpa_supplicant_trigger_scan(wpa_s, &params)) { if (wpa_supplicant_trigger_scan(wpa_s, &params, true)) {
wpa_printf(MSG_DEBUG, "bgscan simple: Failed to trigger scan"); wpa_printf(MSG_DEBUG, "bgscan simple: Failed to trigger scan");
eloop_register_timeout(data->scan_interval, 0, eloop_register_timeout(data->scan_interval, 0,
bgscan_simple_timeout, data, NULL); bgscan_simple_timeout, data, NULL);

View file

@ -1632,6 +1632,7 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
dbus_bool_t allow_roam = TRUE; dbus_bool_t allow_roam = TRUE;
dbus_bool_t non_coloc_6ghz = FALSE; dbus_bool_t non_coloc_6ghz = FALSE;
dbus_bool_t scan_6ghz_only = FALSE; dbus_bool_t scan_6ghz_only = FALSE;
bool custom_ies = false;
os_memset(&params, 0, sizeof(params)); os_memset(&params, 0, sizeof(params));
@ -1658,6 +1659,7 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
if (wpas_dbus_get_scan_ies(message, &variant_iter, if (wpas_dbus_get_scan_ies(message, &variant_iter,
&params, &reply) < 0) &params, &reply) < 0)
goto out; goto out;
custom_ies = true;
} else if (os_strcmp(key, "Channels") == 0) { } else if (os_strcmp(key, "Channels") == 0) {
if (wpas_dbus_get_scan_channels(message, &variant_iter, if (wpas_dbus_get_scan_channels(message, &variant_iter,
&params, &reply) < 0) &params, &reply) < 0)
@ -1724,7 +1726,8 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
if (params.freqs && params.freqs[0]) { if (params.freqs && params.freqs[0]) {
wpa_s->last_scan_req = MANUAL_SCAN_REQ; wpa_s->last_scan_req = MANUAL_SCAN_REQ;
if (wpa_supplicant_trigger_scan(wpa_s, if (wpa_supplicant_trigger_scan(wpa_s,
&params)) { &params,
false)) {
reply = wpas_dbus_error_scan_error( reply = wpas_dbus_error_scan_error(
message, message,
"Scan request rejected"); "Scan request rejected");
@ -1750,7 +1753,7 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
} }
wpa_s->last_scan_req = MANUAL_SCAN_REQ; wpa_s->last_scan_req = MANUAL_SCAN_REQ;
if (wpa_supplicant_trigger_scan(wpa_s, &params)) { if (wpa_supplicant_trigger_scan(wpa_s, &params, !custom_ies)) {
reply = wpas_dbus_error_scan_error( reply = wpas_dbus_error_scan_error(
message, "Scan request rejected"); message, "Scan request rejected");
} }

View file

@ -1033,7 +1033,7 @@ static void wpas_rrm_scan_timeout(void *eloop_ctx, void *timeout_ctx)
} }
os_get_reltime(&wpa_s->beacon_rep_scan); os_get_reltime(&wpa_s->beacon_rep_scan);
if (wpa_s->scanning || wpas_p2p_in_progress(wpa_s) || if (wpa_s->scanning || wpas_p2p_in_progress(wpa_s) ||
wpa_supplicant_trigger_scan(wpa_s, params)) wpa_supplicant_trigger_scan(wpa_s, params, true))
wpas_rrm_refuse_request(wpa_s); wpas_rrm_refuse_request(wpa_s);
params->duration = prev_duration; params->duration = prev_duration;
} }

View file

@ -24,6 +24,8 @@
#include "scan.h" #include "scan.h"
#include "mesh.h" #include "mesh.h"
static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s);
static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s) static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s)
{ {
@ -278,19 +280,43 @@ static void wpas_trigger_scan_cb(struct wpa_radio_work *work, int deinit)
* wpa_supplicant_trigger_scan - Request driver to start a scan * wpa_supplicant_trigger_scan - Request driver to start a scan
* @wpa_s: Pointer to wpa_supplicant data * @wpa_s: Pointer to wpa_supplicant data
* @params: Scan parameters * @params: Scan parameters
* @default_ies: Whether or not to use the default IEs in the Probe Request
* frames. Note that this will free any existing IEs set in @params, so this
* shouldn't be set if the IEs have already been set with
* wpa_supplicant_extra_ies(). Otherwise, wpabuf_free() will lead to a
* double-free.
* Returns: 0 on success, -1 on failure * Returns: 0 on success, -1 on failure
*/ */
int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s, int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
struct wpa_driver_scan_params *params) struct wpa_driver_scan_params *params,
bool default_ies)
{ {
struct wpa_driver_scan_params *ctx; struct wpa_driver_scan_params *ctx;
struct wpabuf *ies = NULL;
if (wpa_s->scan_work) { if (wpa_s->scan_work) {
wpa_dbg(wpa_s, MSG_INFO, "Reject scan trigger since one is already pending"); wpa_dbg(wpa_s, MSG_INFO, "Reject scan trigger since one is already pending");
return -1; return -1;
} }
if (default_ies) {
if (params->extra_ies_len) {
os_free((u8 *) params->extra_ies);
params->extra_ies = NULL;
params->extra_ies_len = 0;
}
ies = wpa_supplicant_extra_ies(wpa_s);
if (ies) {
params->extra_ies = wpabuf_head(ies);
params->extra_ies_len = wpabuf_len(ies);
}
}
ctx = wpa_scan_clone_params(params); ctx = wpa_scan_clone_params(params);
if (ies) {
wpabuf_free(ies);
params->extra_ies = NULL;
params->extra_ies_len = 0;
}
if (!ctx || if (!ctx ||
radio_add_work(wpa_s, 0, "scan", 0, wpas_trigger_scan_cb, ctx) < 0) radio_add_work(wpa_s, 0, "scan", 0, wpas_trigger_scan_cb, ctx) < 0)
{ {
@ -1534,7 +1560,7 @@ scan:
wpas_p2p_scan_freqs(wpa_s, &params, true); wpas_p2p_scan_freqs(wpa_s, &params, true);
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
ret = wpa_supplicant_trigger_scan(wpa_s, scan_params); ret = wpa_supplicant_trigger_scan(wpa_s, scan_params, false);
if (ret && wpa_s->last_scan_req == MANUAL_SCAN_REQ && params.freqs && if (ret && wpa_s->last_scan_req == MANUAL_SCAN_REQ && params.freqs &&
!wpa_s->manual_scan_freqs) { !wpa_s->manual_scan_freqs) {

View file

@ -45,7 +45,8 @@ void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s,
int scanning); int scanning);
struct wpa_driver_scan_params; struct wpa_driver_scan_params;
int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s, int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
struct wpa_driver_scan_params *params); struct wpa_driver_scan_params *params,
bool default_ies);
struct wpa_scan_results * struct wpa_scan_results *
wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s, wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
struct scan_info *info, int new_scan); struct scan_info *info, int new_scan);

View file

@ -3093,7 +3093,7 @@ static void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx)
params.low_priority = 1; params.low_priority = 1;
wpa_printf(MSG_DEBUG, "SME OBSS: Request an OBSS scan"); wpa_printf(MSG_DEBUG, "SME OBSS: Request an OBSS scan");
if (wpa_supplicant_trigger_scan(wpa_s, &params)) if (wpa_supplicant_trigger_scan(wpa_s, &params, true))
wpa_printf(MSG_DEBUG, "SME OBSS: Failed to trigger scan"); wpa_printf(MSG_DEBUG, "SME OBSS: Failed to trigger scan");
else else
wpa_s->sme.sched_obss_scan = 1; wpa_s->sme.sched_obss_scan = 1;