diff options
-rw-r--r-- | src/drivers/driver_nl80211_event.c | 7 | ||||
-rw-r--r-- | src/p2p/p2p_pd.c | 12 | ||||
-rw-r--r-- | wpa_supplicant/config.c | 3 | ||||
-rw-r--r-- | wpa_supplicant/config.h | 19 | ||||
-rw-r--r-- | wpa_supplicant/config_file.c | 3 | ||||
-rw-r--r-- | wpa_supplicant/ctrl_iface.h | 7 | ||||
-rw-r--r-- | wpa_supplicant/ctrl_iface_named_pipe.c | 5 | ||||
-rw-r--r-- | wpa_supplicant/ctrl_iface_udp.c | 6 | ||||
-rw-r--r-- | wpa_supplicant/ctrl_iface_unix.c | 43 | ||||
-rw-r--r-- | wpa_supplicant/eapol_test.c | 6 | ||||
-rw-r--r-- | wpa_supplicant/events.c | 5 | ||||
-rw-r--r-- | wpa_supplicant/preauth_test.c | 6 | ||||
-rw-r--r-- | wpa_supplicant/wnm_sta.c | 22 | ||||
-rw-r--r-- | wpa_supplicant/wpa_supplicant.c | 18 | ||||
-rw-r--r-- | wpa_supplicant/wpa_supplicant.conf | 6 | ||||
-rw-r--r-- | wpa_supplicant/wpa_supplicant_template.conf | 1 |
16 files changed, 135 insertions, 34 deletions
diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c index 6a2de1f3..1a5f8998 100644 --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -464,6 +464,13 @@ static void mlme_event_connect(struct wpa_driver_nl80211_data *drv, event.assoc_info.fils_pmkid = nla_data(fils_pmkid); wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event); + + /* Avoid a race condition by stopping to ignore any following + * disconnection events now that the driver has indicated it is + * connected since that connection could have been triggered by a roam + * operation that happened in parallel with the disconnection request. + */ + drv->ignore_next_local_disconnect = 0; } diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c index 3994ec03..05fd5934 100644 --- a/src/p2p/p2p_pd.c +++ b/src/p2p/p2p_pd.c @@ -595,14 +595,12 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, goto out; } + dev = p2p_get_device(p2p, sa); if (!dev) { - dev = p2p_get_device(p2p, sa); - if (!dev) { - p2p_dbg(p2p, - "Provision Discovery device not found " - MACSTR, MAC2STR(sa)); - goto out; - } + p2p_dbg(p2p, + "Provision Discovery device not found " + MACSTR, MAC2STR(sa)); + goto out; } } else if (msg.wfd_subelems) { wpabuf_free(dev->info.wfd_subelems); diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index e1d98249..173be096 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -4305,6 +4305,7 @@ struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface, config->disassoc_imminent_rssi_threshold = DEFAULT_DISASSOC_IMMINENT_RSSI_THRESHOLD; config->oce = DEFAULT_OCE_SUPPORT; + config->btm_offload = DEFAULT_BTM_OFFLOAD; #endif /* CONFIG_MBO */ if (ctrl_interface) @@ -5048,6 +5049,7 @@ static const struct global_parse_data global_fields[] = { MBO_CELL_CAPA_NOT_SUPPORTED), 0 }, { INT_RANGE(disassoc_imminent_rssi_threshold, -120, 0), 0 }, { INT_RANGE(oce, 0, 3), 0 }, + { INT_RANGE(btm_offload, 0, 1), CFG_CHANGED_DISABLE_BTM_NOTIFY }, #endif /* CONFIG_MBO */ { INT(gas_address3), 0 }, { INT_RANGE(ftm_responder, 0, 1), 0 }, @@ -5065,6 +5067,7 @@ static const struct global_parse_data global_fields[] = { { INT_RANGE(disable_btm, 0, 1), CFG_CHANGED_DISABLE_BTM }, { INT_RANGE(extended_key_id, 0, 1), 0 }, #endif /* CONFIG_WNM */ + { INT_RANGE(wowlan_disconnect_on_deinit, 0, 1), 0}, }; #undef FUNC diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 0ca27cb3..712e8717 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -45,6 +45,7 @@ #define DEFAULT_DISASSOC_IMMINENT_RSSI_THRESHOLD -75 #define DEFAULT_OCE_SUPPORT OCE_STA #define DEFAULT_EXTENDED_KEY_ID 0 +#define DEFAULT_BTM_OFFLOAD 0 #include "config_ssid.h" #include "wps/wps.h" @@ -376,6 +377,7 @@ struct wpa_cred { #define CFG_CHANGED_SCHED_SCAN_PLANS BIT(17) #define CFG_CHANGED_WOWLAN_TRIGGERS BIT(18) #define CFG_CHANGED_DISABLE_BTM BIT(19) +#define CFG_CHANGED_DISABLE_BTM_NOTIFY BIT(20) /** * struct wpa_config - wpa_supplicant configuration data @@ -1447,6 +1449,14 @@ struct wpa_config { * - Set BIT(1) to enable OCE in STA-CFON mode */ unsigned int oce; + + /** + * btm_offload - Set where to perform roaming logic + * - Set to 0 to handle fully roaming logic in supplicant + * - Set to 1 to skip roaming logic in supplicant for firmware roaming + * just parse BTM frame and notify framework + */ + int btm_offload; #endif /* CONFIG_MBO */ /** @@ -1590,6 +1600,15 @@ struct wpa_config { * 1 = use Extended Key ID when possible */ int extended_key_id; + + /** + * wowlan_disconnect_on_deinit - Trigger disconnect on wpa_supplicant + * interface deinit even if the driver has enabled WoWLAN. + * + * 0 = Do not disconnect + * 1 = Trigger disconnection + */ + int wowlan_disconnect_on_deinit; }; diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 52e1372e..5faed4ee 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -1607,6 +1607,9 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) if (config->extended_key_id != DEFAULT_EXTENDED_KEY_ID) fprintf(f, "extended_key_id=%d\n", config->extended_key_id); + if (config->wowlan_disconnect_on_deinit) + fprintf(f, "wowlan_disconnect_on_deinit=%d\n", + config->wowlan_disconnect_on_deinit); } #endif /* CONFIG_NO_CONFIG_WRITE */ diff --git a/wpa_supplicant/ctrl_iface.h b/wpa_supplicant/ctrl_iface.h index 510668d4..a408288c 100644 --- a/wpa_supplicant/ctrl_iface.h +++ b/wpa_supplicant/ctrl_iface.h @@ -70,14 +70,17 @@ wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s); /** * wpa_supplicant_ctrl_iface_deinit - Deinitialize control interface + * @wpa_s: Pointer to wpa_supplicant data * @priv: Pointer to private data from wpa_supplicant_ctrl_iface_init() * * Deinitialize the control interface that was initialized with - * wpa_supplicant_ctrl_iface_init(). + * wpa_supplicant_ctrl_iface_init() and any data related to the wpa_s instance. + * @priv may be %NULL if the control interface has not yet been initialized. * * Required to be implemented in each control interface backend. */ -void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv); +void wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant *wpa_s, + struct ctrl_iface_priv *priv); /** * wpa_supplicant_ctrl_iface_wait - Wait for ctrl_iface monitor diff --git a/wpa_supplicant/ctrl_iface_named_pipe.c b/wpa_supplicant/ctrl_iface_named_pipe.c index 79ff7871..bddc0414 100644 --- a/wpa_supplicant/ctrl_iface_named_pipe.c +++ b/wpa_supplicant/ctrl_iface_named_pipe.c @@ -462,8 +462,11 @@ wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s) } -void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv) +void wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant *wpa_s, + struct ctrl_iface_priv *priv) { + if (!priv) + return; while (priv->ctrl_dst) ctrl_close_pipe(priv->ctrl_dst); if (priv->sec_attr_set) diff --git a/wpa_supplicant/ctrl_iface_udp.c b/wpa_supplicant/ctrl_iface_udp.c index 1512080d..1cbf7fa2 100644 --- a/wpa_supplicant/ctrl_iface_udp.c +++ b/wpa_supplicant/ctrl_iface_udp.c @@ -490,8 +490,12 @@ fail: } -void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv) +void wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant *wpa_s, + struct ctrl_iface_priv *priv) { + if (!priv) + return; + if (priv->sock > -1) { eloop_unregister_read_sock(priv->sock); if (priv->ctrl_dst) { diff --git a/wpa_supplicant/ctrl_iface_unix.c b/wpa_supplicant/ctrl_iface_unix.c index 953fd2cc..639573da 100644 --- a/wpa_supplicant/ctrl_iface_unix.c +++ b/wpa_supplicant/ctrl_iface_unix.c @@ -800,12 +800,52 @@ static int wpas_ctrl_iface_reinit(struct wpa_supplicant *wpa_s, } -void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv) +static void +wpas_global_ctrl_iface_flush_queued_msg(struct wpa_global *global, + struct wpa_supplicant *wpa_s) +{ + struct ctrl_iface_global_priv *gpriv; + struct ctrl_iface_msg *msg, *prev_msg; + unsigned int count = 0; + + if (!global || !global->ctrl_iface) + return; + + gpriv = global->ctrl_iface; + dl_list_for_each_safe(msg, prev_msg, &gpriv->msg_queue, + struct ctrl_iface_msg, list) { + if (msg->wpa_s == wpa_s) { + count++; + dl_list_del(&msg->list); + os_free(msg); + } + } + + if (count) { + wpa_printf(MSG_DEBUG, + "CTRL: Dropped %u pending message(s) for interface that is being removed", + count); + } +} + + +void wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant *wpa_s, + struct ctrl_iface_priv *priv) { struct wpa_ctrl_dst *dst, *prev; struct ctrl_iface_msg *msg, *prev_msg; struct ctrl_iface_global_priv *gpriv; + if (!priv) { + /* Control interface has not yet been initialized, so there is + * nothing to deinitialize here. However, there might be a + * pending message for this interface, so get rid of any such + * entry before completing interface removal. */ + wpas_global_ctrl_iface_flush_queued_msg(wpa_s->global, wpa_s); + eloop_cancel_timeout(wpas_ctrl_msg_queue_timeout, wpa_s, NULL); + return; + } + if (priv->sock > -1) { char *fname; char *buf, *dir = NULL; @@ -877,6 +917,7 @@ free_dst: } } } + wpas_global_ctrl_iface_flush_queued_msg(wpa_s->global, wpa_s); eloop_cancel_timeout(wpas_ctrl_msg_queue_timeout, priv->wpa_s, NULL); os_free(priv); } diff --git a/wpa_supplicant/eapol_test.c b/wpa_supplicant/eapol_test.c index 9f69736b..11eee98a 100644 --- a/wpa_supplicant/eapol_test.c +++ b/wpa_supplicant/eapol_test.c @@ -674,10 +674,8 @@ static void test_eapol_clean(struct eapol_test_data *e, os_free(e->radius_conf); e->radius_conf = NULL; scard_deinit(wpa_s->scard); - if (wpa_s->ctrl_iface) { - wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface); - wpa_s->ctrl_iface = NULL; - } + wpa_supplicant_ctrl_iface_deinit(wpa_s, wpa_s->ctrl_iface); + wpa_s->ctrl_iface = NULL; ext_password_deinit(wpa_s->ext_pw); wpa_s->ext_pw = NULL; diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 7b68ebee..096fd02c 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -4586,6 +4586,11 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, break; } #endif /* CONFIG_TESTING_OPTIONS */ + if (wpa_s->disconnected) { + wpa_printf(MSG_INFO, + "Ignore unexpected EVENT_ASSOC in disconnected state"); + break; + } wpa_supplicant_event_assoc(wpa_s, data); wpa_s->assoc_status_code = WLAN_STATUS_SUCCESS; if (data && diff --git a/wpa_supplicant/preauth_test.c b/wpa_supplicant/preauth_test.c index 4a8f4ff8..dc955b8f 100644 --- a/wpa_supplicant/preauth_test.c +++ b/wpa_supplicant/preauth_test.c @@ -192,10 +192,8 @@ static void test_eapol_clean(struct wpa_supplicant *wpa_s) pmksa_candidate_free(wpa_s->wpa); wpa_sm_deinit(wpa_s->wpa); scard_deinit(wpa_s->scard); - if (wpa_s->ctrl_iface) { - wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface); - wpa_s->ctrl_iface = NULL; - } + wpa_supplicant_ctrl_iface_deinit(wpa_s, wpa_s->ctrl_iface); + wpa_s->ctrl_iface = NULL; wpa_config_free(wpa_s->conf); } diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c index 2e09102d..ac04383d 100644 --- a/wpa_supplicant/wnm_sta.c +++ b/wpa_supplicant/wnm_sta.c @@ -1451,6 +1451,22 @@ static void ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s, wpa_s->wnm_dissoc_timer * beacon_int * 128 / 125, url); } +#ifdef CONFIG_MBO + vendor = get_ie(pos, end - pos, WLAN_EID_VENDOR_SPECIFIC); + if (vendor) { + wpas_mbo_ie_trans_req(wpa_s, vendor + 2, vendor[1]); + if (wpa_s->conf->btm_offload) { + wpa_msg(wpa_s, MSG_INFO, + "WNM: Notify BSS Transition Management Request frame status"); + wpa_s->bss_tm_status = WNM_BSS_TM_ACCEPT; + wpas_notify_bss_tm_status(wpa_s); + /* since it could be referenced in the scan result logic, initialize it */ + wpa_s->wnm_mbo_trans_reason_present = 0; + return; + } + } +#endif /* CONFIG_MBO */ + if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT) { wpa_msg(wpa_s, MSG_INFO, "WNM: Disassociation Imminent - " "Disassociation Timer %u", wpa_s->wnm_dissoc_timer); @@ -1462,12 +1478,6 @@ static void ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s, } } -#ifdef CONFIG_MBO - vendor = get_ie(pos, end - pos, WLAN_EID_VENDOR_SPECIFIC); - if (vendor) - wpas_mbo_ie_trans_req(wpa_s, vendor + 2, vendor[1]); -#endif /* CONFIG_MBO */ - if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED) { unsigned int valid_ms; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index a01a4e53..f928fdb8 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1137,8 +1137,8 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s) os_strcmp(conf->ctrl_interface, wpa_s->conf->ctrl_interface) != 0); - if (reconf_ctrl && wpa_s->ctrl_iface) { - wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface); + if (reconf_ctrl) { + wpa_supplicant_ctrl_iface_deinit(wpa_s, wpa_s->ctrl_iface); wpa_s->ctrl_iface = NULL; } @@ -6493,8 +6493,12 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s, wpa_s->disconnected = 1; if (wpa_s->drv_priv) { - /* Don't deauthenticate if WoWLAN is enabled */ - if (!wpa_drv_get_wowlan(wpa_s)) { + /* + * Don't deauthenticate if WoWLAN is enabled and not explicitly + * been configured to disconnect. + */ + if (!wpa_drv_get_wowlan(wpa_s) || + wpa_s->conf->wowlan_disconnect_on_deinit) { wpa_supplicant_deauthenticate( wpa_s, WLAN_REASON_DEAUTH_LEAVING); @@ -6532,10 +6536,8 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s, if (terminate) wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING); - if (wpa_s->ctrl_iface) { - wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface); - wpa_s->ctrl_iface = NULL; - } + wpa_supplicant_ctrl_iface_deinit(wpa_s, wpa_s->ctrl_iface); + wpa_s->ctrl_iface = NULL; #ifdef CONFIG_MESH if (wpa_s->ifmsh) { diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index 3b905677..f5194bec 100644 --- a/wpa_supplicant/wpa_supplicant.conf +++ b/wpa_supplicant/wpa_supplicant.conf @@ -1584,6 +1584,12 @@ fast_reauth=1 # Set to 1 to disable BSS transition management #disable_btm=0 +# This value is used to set where to perform roaming logic +# Set to 0 to handle roaming logic fully in supplicant +# Set to 1 to skip roaming logic in supplicant and handle it in firmware +# In supplicant, just parse BTM frame and notify framework +#btm_offload=0 + # Enable EDMG capability in STA/AP mode, default value is false #enable_edmg=1 diff --git a/wpa_supplicant/wpa_supplicant_template.conf b/wpa_supplicant/wpa_supplicant_template.conf index fce7e5e4..552477db 100644 --- a/wpa_supplicant/wpa_supplicant_template.conf +++ b/wpa_supplicant/wpa_supplicant_template.conf @@ -6,3 +6,4 @@ fast_reauth=1 pmf=1 p2p_add_cli_chan=1 oce=1 +wowlan_disconnect_on_deinit=1 |