mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-22 13:02:44 +01:00
netdev: ft: complete FT refactor
This finalizes the refactor by moving all the handshake prep into FT itself (most was already in there). The netdev-specific flags and state were added into netdev_ft_tx_associate which now avoids any need for a netdev API related to FT. The NETDEV_EVENT_FT_ROAMED event is now emitted once FT completes (netdev_connect_ok). This did require moving the 'in_ft' flag setting until after the keys are set into the kernel otherwise netdev_connect_ok has no context as to if this was FT or some other connection attempt. In addition the prev_snonce was removed from netdev. Restoring the snonce has no value once association begins. If association fails it will result in a disconnect regardless which requires a new snonce to be generated
This commit is contained in:
parent
0e6aaea2a9
commit
ad59fb6249
10
src/ft.c
10
src/ft.c
@ -1123,9 +1123,19 @@ static void ft_info_destroy(void *data)
|
||||
static void ft_prepare_handshake(struct ft_info *info,
|
||||
struct handshake_state *hs)
|
||||
{
|
||||
handshake_state_set_authenticator_address(hs, info->aa);
|
||||
|
||||
memcpy(hs->mde + 2, info->mde, 3);
|
||||
|
||||
handshake_state_set_chandef(hs, NULL);
|
||||
|
||||
if (!hs->supplicant_ie)
|
||||
return;
|
||||
|
||||
if (info->authenticator_ie)
|
||||
handshake_state_set_authenticator_ie(hs,
|
||||
info->authenticator_ie);
|
||||
|
||||
memcpy(hs->snonce, info->snonce, sizeof(hs->snonce));
|
||||
|
||||
handshake_state_set_fte(hs, info->fte);
|
||||
|
65
src/netdev.c
65
src/netdev.c
@ -1413,6 +1413,15 @@ static void netdev_connect_ok(struct netdev *netdev)
|
||||
scan_bss_free(netdev->fw_roam_bss);
|
||||
|
||||
netdev->fw_roam_bss = NULL;
|
||||
} else if (netdev->in_ft) {
|
||||
if (netdev->event_filter)
|
||||
netdev->event_filter(netdev, NETDEV_EVENT_FT_ROAMED,
|
||||
NULL, netdev->user_data);
|
||||
netdev->in_ft = false;
|
||||
} else if (netdev->connect_cb) {
|
||||
netdev->connect_cb(netdev, NETDEV_RESULT_OK, NULL,
|
||||
netdev->user_data);
|
||||
netdev->connect_cb = NULL;
|
||||
}
|
||||
|
||||
if (netdev->ft_ds_list) {
|
||||
@ -1420,12 +1429,6 @@ static void netdev_connect_ok(struct netdev *netdev)
|
||||
netdev->ft_ds_list = NULL;
|
||||
}
|
||||
|
||||
if (netdev->connect_cb) {
|
||||
netdev->connect_cb(netdev, NETDEV_RESULT_OK, NULL,
|
||||
netdev->user_data);
|
||||
netdev->connect_cb = NULL;
|
||||
}
|
||||
|
||||
netdev_rssi_polling_update(netdev);
|
||||
|
||||
if (netdev->work.id)
|
||||
@ -3293,7 +3296,6 @@ static void netdev_associate_event(struct l_genl_msg *msg,
|
||||
eapol_sm_set_require_handshake(netdev->sm,
|
||||
false);
|
||||
|
||||
netdev->in_ft = false;
|
||||
netdev->in_reassoc = false;
|
||||
netdev->associated = true;
|
||||
return;
|
||||
@ -4459,6 +4461,7 @@ static int netdev_ft_tx_associate(uint32_t ifindex, uint32_t freq,
|
||||
struct iovec *ft_iov, size_t n_ft_iov)
|
||||
{
|
||||
struct netdev *netdev = netdev_find(ifindex);
|
||||
struct netdev_handshake_state *nhs;
|
||||
struct handshake_state *hs = netdev->handshake;
|
||||
struct l_genl_msg *msg;
|
||||
struct iovec iov[64];
|
||||
@ -4467,6 +4470,54 @@ static int netdev_ft_tx_associate(uint32_t ifindex, uint32_t freq,
|
||||
enum mpdu_management_subtype subtype =
|
||||
MPDU_MANAGEMENT_SUBTYPE_REASSOCIATION_REQUEST;
|
||||
|
||||
/*
|
||||
* At this point there is no going back with FT so reset all the flags
|
||||
* needed to associate with a new BSS.
|
||||
*/
|
||||
netdev->frequency = freq;
|
||||
netdev->handshake->active_tk_index = 0;
|
||||
netdev->associated = false;
|
||||
netdev->operational = false;
|
||||
netdev->in_ft = true;
|
||||
|
||||
/*
|
||||
* Cancel commands that could be running because of EAPoL activity
|
||||
* like re-keying, this way the callbacks for those commands don't
|
||||
* have to check if failures resulted from the transition.
|
||||
*/
|
||||
nhs = l_container_of(netdev->handshake,
|
||||
struct netdev_handshake_state, super);
|
||||
|
||||
/* reset key states just as we do in initialization */
|
||||
nhs->complete = false;
|
||||
nhs->ptk_installed = false;
|
||||
nhs->gtk_installed = true;
|
||||
nhs->igtk_installed = true;
|
||||
|
||||
if (nhs->group_new_key_cmd_id) {
|
||||
l_genl_family_cancel(nl80211, nhs->group_new_key_cmd_id);
|
||||
nhs->group_new_key_cmd_id = 0;
|
||||
}
|
||||
|
||||
if (nhs->group_management_new_key_cmd_id) {
|
||||
l_genl_family_cancel(nl80211,
|
||||
nhs->group_management_new_key_cmd_id);
|
||||
nhs->group_management_new_key_cmd_id = 0;
|
||||
}
|
||||
|
||||
if (netdev->rekey_offload_cmd_id) {
|
||||
l_genl_family_cancel(nl80211, netdev->rekey_offload_cmd_id);
|
||||
netdev->rekey_offload_cmd_id = 0;
|
||||
}
|
||||
|
||||
netdev_rssi_polling_update(netdev);
|
||||
netdev_cqm_rssi_update(netdev);
|
||||
|
||||
if (netdev->sm) {
|
||||
eapol_sm_free(netdev->sm);
|
||||
netdev->sm = NULL;
|
||||
}
|
||||
|
||||
msg = netdev_build_cmd_associate_common(netdev);
|
||||
|
||||
c_iov = netdev_populate_common_ies(netdev, hs, msg, iov, n_iov, c_iov);
|
||||
|
Loading…
Reference in New Issue
Block a user