mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-22 21:22:37 +01:00
station: start FT-over-DS actions after roaming
Once roamed IWD never sent out any FT Request frames. This prevented FT-over-DS from being used after an initial roam.
This commit is contained in:
parent
d68c9e69fa
commit
7e9708ddbc
149
src/station.c
149
src/station.c
@ -1729,6 +1729,77 @@ static void station_early_neighbor_report_cb(struct netdev *netdev, int err,
|
||||
&station->roam_freqs);
|
||||
}
|
||||
|
||||
static bool station_can_fast_transition(struct handshake_state *hs,
|
||||
struct scan_bss *bss)
|
||||
{
|
||||
uint16_t mdid;
|
||||
|
||||
if (!hs->mde)
|
||||
return false;
|
||||
|
||||
if (ie_parse_mobility_domain_from_data(hs->mde, hs->mde[1] + 2,
|
||||
&mdid, NULL, NULL) < 0)
|
||||
return false;
|
||||
|
||||
if (!(bss->mde_present && l_get_le16(bss->mde) == mdid))
|
||||
return false;
|
||||
|
||||
if (hs->supplicant_ie != NULL) {
|
||||
struct ie_rsn_info rsn_info;
|
||||
|
||||
if (!IE_AKM_IS_FT(hs->akm_suite))
|
||||
return false;
|
||||
|
||||
if (scan_bss_get_rsn_info(bss, &rsn_info) < 0)
|
||||
return false;
|
||||
|
||||
if (!IE_AKM_IS_FT(rsn_info.akm_suites))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void station_ft_ds_action_start(struct station *station)
|
||||
{
|
||||
struct handshake_state *hs = netdev_get_handshake(station->netdev);
|
||||
uint16_t mdid;
|
||||
const struct l_queue_entry *entry;
|
||||
struct scan_bss *bss;
|
||||
struct ie_rsn_info rsn_info;
|
||||
|
||||
if (!station_can_fast_transition(hs, station->connected_bss) ||
|
||||
!(hs->mde[4] & 1))
|
||||
return;
|
||||
|
||||
if (ie_parse_mobility_domain_from_data(hs->mde, hs->mde[1] + 2,
|
||||
&mdid, NULL, NULL) < 0)
|
||||
return;
|
||||
|
||||
for (entry = network_bss_list_get_entries(station->connected_network);
|
||||
entry; entry = entry->next) {
|
||||
bss = entry->data;
|
||||
|
||||
if (bss == station->connected_bss)
|
||||
continue;
|
||||
|
||||
if (mdid != l_get_le16(bss->mde))
|
||||
continue;
|
||||
|
||||
if (scan_bss_get_rsn_info(bss, &rsn_info) < 0)
|
||||
continue;
|
||||
|
||||
if (!IE_AKM_IS_FT(rsn_info.akm_suites))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Fire and forget. Netdev will maintain a cache of responses and
|
||||
* when the time comes these can be referenced for a roam
|
||||
*/
|
||||
netdev_fast_transition_over_ds_action(station->netdev, bss);
|
||||
}
|
||||
}
|
||||
|
||||
static void station_roamed(struct station *station)
|
||||
{
|
||||
station->roam_scan_full = false;
|
||||
@ -1754,6 +1825,8 @@ static void station_roamed(struct station *station)
|
||||
l_warn("Could not request neighbor report");
|
||||
}
|
||||
|
||||
station_ft_ds_action_start(station);
|
||||
|
||||
station_enter_state(station, STATION_STATE_CONNECTED);
|
||||
}
|
||||
|
||||
@ -1957,37 +2030,6 @@ static void station_preauthenticate_cb(struct netdev *netdev,
|
||||
station_transition_reassociate(station, bss, new_hs);
|
||||
}
|
||||
|
||||
static bool station_can_fast_transition(struct handshake_state *hs,
|
||||
struct scan_bss *bss)
|
||||
{
|
||||
uint16_t mdid;
|
||||
|
||||
if (!hs->mde)
|
||||
return false;
|
||||
|
||||
if (ie_parse_mobility_domain_from_data(hs->mde, hs->mde[1] + 2,
|
||||
&mdid, NULL, NULL) < 0)
|
||||
return false;
|
||||
|
||||
if (!(bss->mde_present && l_get_le16(bss->mde) == mdid))
|
||||
return false;
|
||||
|
||||
if (hs->supplicant_ie != NULL) {
|
||||
struct ie_rsn_info rsn_info;
|
||||
|
||||
if (!IE_AKM_IS_FT(hs->akm_suite))
|
||||
return false;
|
||||
|
||||
if (scan_bss_get_rsn_info(bss, &rsn_info) < 0)
|
||||
return false;
|
||||
|
||||
if (!IE_AKM_IS_FT(rsn_info.akm_suites))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void station_transition_start(struct station *station,
|
||||
struct scan_bss *bss)
|
||||
{
|
||||
@ -2624,36 +2666,6 @@ static bool station_retry_with_status(struct station *station,
|
||||
return station_try_next_bss(station);
|
||||
}
|
||||
|
||||
static void station_ft_ds_action_start(struct station *station, uint16_t mdid)
|
||||
{
|
||||
const struct l_queue_entry *entry;
|
||||
struct scan_bss *bss;
|
||||
struct ie_rsn_info rsn_info;
|
||||
|
||||
for (entry = network_bss_list_get_entries(station->connected_network);
|
||||
entry; entry = entry->next) {
|
||||
bss = entry->data;
|
||||
|
||||
if (bss == station->connected_bss)
|
||||
continue;
|
||||
|
||||
if (mdid != l_get_le16(bss->mde))
|
||||
continue;
|
||||
|
||||
if (scan_bss_get_rsn_info(bss, &rsn_info) < 0)
|
||||
continue;
|
||||
|
||||
if (!IE_AKM_IS_FT(rsn_info.akm_suites))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Fire and forget. Netdev will maintain a cache of responses and
|
||||
* when the time comes these can be referenced for a roam
|
||||
*/
|
||||
netdev_fast_transition_over_ds_action(station->netdev, bss);
|
||||
}
|
||||
}
|
||||
|
||||
static void station_connect_ok(struct station *station)
|
||||
{
|
||||
struct handshake_state *hs = netdev_get_handshake(station->netdev);
|
||||
@ -2677,20 +2689,7 @@ static void station_connect_ok(struct station *station)
|
||||
l_warn("Could not request neighbor report");
|
||||
}
|
||||
|
||||
/*
|
||||
* If this network supports FT-over-DS send initial action frames now
|
||||
* to prepare for future roams.
|
||||
*/
|
||||
if (station_can_fast_transition(hs, station->connected_bss) &&
|
||||
(hs->mde[4] & 1)) {
|
||||
uint16_t mdid;
|
||||
|
||||
if (ie_parse_mobility_domain_from_data(hs->mde, hs->mde[1] + 2,
|
||||
&mdid, NULL, NULL) < 0)
|
||||
return;
|
||||
|
||||
station_ft_ds_action_start(station, mdid);
|
||||
}
|
||||
station_ft_ds_action_start(station);
|
||||
|
||||
network_connected(station->connected_network);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user