mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-22 14:49:24 +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);
|
&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)
|
static void station_roamed(struct station *station)
|
||||||
{
|
{
|
||||||
station->roam_scan_full = false;
|
station->roam_scan_full = false;
|
||||||
@ -1754,6 +1825,8 @@ static void station_roamed(struct station *station)
|
|||||||
l_warn("Could not request neighbor report");
|
l_warn("Could not request neighbor report");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
station_ft_ds_action_start(station);
|
||||||
|
|
||||||
station_enter_state(station, STATION_STATE_CONNECTED);
|
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);
|
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,
|
static void station_transition_start(struct station *station,
|
||||||
struct scan_bss *bss)
|
struct scan_bss *bss)
|
||||||
{
|
{
|
||||||
@ -2624,36 +2666,6 @@ static bool station_retry_with_status(struct station *station,
|
|||||||
return station_try_next_bss(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)
|
static void station_connect_ok(struct station *station)
|
||||||
{
|
{
|
||||||
struct handshake_state *hs = netdev_get_handshake(station->netdev);
|
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");
|
l_warn("Could not request neighbor report");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
station_ft_ds_action_start(station);
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
network_connected(station->connected_network);
|
network_connected(station->connected_network);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user