3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2025-01-20 09:34:06 +01:00

station: hold reference to handshake object

To prepare for PMKSA support station needs access to the handshake
object. This is because if PMKSA fails due to an expired/missing
PMKSA on the AP station should retry using the standard association.
This poses a problem currently because netdev frees the handshake
prior to calling the connect callback.
This commit is contained in:
James Prestwood 2024-11-22 07:15:48 -08:00 committed by Denis Kenzior
parent 5b104967ce
commit 9bc71b2853

View File

@ -135,6 +135,8 @@ struct station {
unsigned int affinity_watch; unsigned int affinity_watch;
char *affinity_client; char *affinity_client;
struct handshake_state *hs;
bool preparing_roam : 1; bool preparing_roam : 1;
bool roam_scan_full : 1; bool roam_scan_full : 1;
bool signal_low : 1; bool signal_low : 1;
@ -1771,6 +1773,11 @@ static void station_enter_state(struct station *station,
station->affinity_watch = 0; station->affinity_watch = 0;
} }
if (station->hs) {
handshake_state_unref(station->hs);
station->hs = NULL;
}
break; break;
case STATION_STATE_DISCONNECTING: case STATION_STATE_DISCONNECTING:
case STATION_STATE_NETCONFIG: case STATION_STATE_NETCONFIG:
@ -2487,6 +2494,9 @@ static void station_preauthenticate_cb(struct netdev *netdev,
handshake_state_unref(new_hs); handshake_state_unref(new_hs);
station_roam_failed(station); station_roam_failed(station);
} }
handshake_state_unref(station->hs);
station->hs = handshake_state_ref(new_hs);
} }
static void station_transition_start(struct station *station); static void station_transition_start(struct station *station);
@ -2691,6 +2701,9 @@ static bool station_try_next_transition(struct station *station,
return false; return false;
} }
handshake_state_unref(station->hs);
station->hs = handshake_state_ref(new_hs);
return true; return true;
} }
@ -3721,6 +3734,15 @@ int __station_connect_network(struct station *station, struct network *network,
struct handshake_state *hs; struct handshake_state *hs;
int r; int r;
/*
* If we already have a handshake_state ref this is due to a retry,
* unref that now
*/
if (station->hs) {
handshake_state_unref(station->hs);
station->hs = NULL;
}
if (station->netconfig && !netconfig_load_settings( if (station->netconfig && !netconfig_load_settings(
station->netconfig, station->netconfig,
network_get_settings(network))) network_get_settings(network)))
@ -3747,6 +3769,7 @@ int __station_connect_network(struct station *station, struct network *network,
station->connected_bss = bss; station->connected_bss = bss;
station->connected_network = network; station->connected_network = network;
station->hs = handshake_state_ref(hs);
if (station->state != state) if (station->state != state)
station_enter_state(station, state); station_enter_state(station, state);
@ -5039,6 +5062,11 @@ static void station_free(struct station *station)
l_queue_destroy(station->owe_hidden_scan_ids, NULL); l_queue_destroy(station->owe_hidden_scan_ids, NULL);
} }
if (station->hs) {
handshake_state_unref(station->hs);
station->hs = NULL;
}
station_roam_state_clear(station); station_roam_state_clear(station);
l_queue_destroy(station->networks_sorted, NULL); l_queue_destroy(station->networks_sorted, NULL);