mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-22 14:49:24 +01:00
ft: gate FT-over-DS with a wiphy work item
Queue the FT action just like we do with FT Authenticate which makes it able to be used the same way, i.e. call ft_action() then queue the ft_associate work right away. A timer was added to end the work item in case the target never responds.
This commit is contained in:
parent
59a0947c76
commit
6a616df125
58
src/ft.c
58
src/ft.c
@ -54,8 +54,12 @@ struct ft_info {
|
|||||||
uint8_t *authenticator_ie;
|
uint8_t *authenticator_ie;
|
||||||
uint8_t prev_bssid[6];
|
uint8_t prev_bssid[6];
|
||||||
uint32_t frequency;
|
uint32_t frequency;
|
||||||
|
uint32_t ds_frequency;
|
||||||
uint32_t offchannel_id;
|
uint32_t offchannel_id;
|
||||||
|
|
||||||
|
struct l_timeout *timeout;
|
||||||
|
struct wiphy_radio_work_item work;
|
||||||
|
|
||||||
struct ie_ft_info ft_info;
|
struct ie_ft_info ft_info;
|
||||||
|
|
||||||
bool parsed : 1;
|
bool parsed : 1;
|
||||||
@ -830,6 +834,11 @@ void __ft_rx_action(uint32_t ifindex, const uint8_t *frame, size_t frame_len)
|
|||||||
|
|
||||||
info->parsed = true;
|
info->parsed = true;
|
||||||
|
|
||||||
|
l_timeout_remove(info->timeout);
|
||||||
|
info->timeout = NULL;
|
||||||
|
|
||||||
|
wiphy_radio_work_done(netdev_get_wiphy(netdev), info->work.id);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ft_error:
|
ft_error:
|
||||||
@ -868,6 +877,9 @@ static void ft_info_destroy(void *data)
|
|||||||
if (info->authenticator_ie)
|
if (info->authenticator_ie)
|
||||||
l_free(info->authenticator_ie);
|
l_free(info->authenticator_ie);
|
||||||
|
|
||||||
|
if (info->timeout)
|
||||||
|
l_timeout_remove(info->timeout);
|
||||||
|
|
||||||
l_free(info);
|
l_free(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -900,19 +912,17 @@ static void ft_prepare_handshake(struct ft_info *info,
|
|||||||
handshake_state_derive_ptk(hs);
|
handshake_state_derive_ptk(hs);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ft_action(uint32_t ifindex, uint32_t freq, const struct scan_bss *target)
|
static bool ft_send_action(struct wiphy_radio_work_item *work)
|
||||||
{
|
{
|
||||||
struct netdev *netdev = netdev_find(ifindex);
|
struct ft_info *info = l_container_of(work, struct ft_info, work);
|
||||||
|
struct netdev *netdev = netdev_find(info->ifindex);
|
||||||
struct handshake_state *hs = netdev_get_handshake(netdev);
|
struct handshake_state *hs = netdev_get_handshake(netdev);
|
||||||
struct ft_info *info;
|
|
||||||
uint8_t ft_req[14];
|
uint8_t ft_req[14];
|
||||||
struct iovec iov[5];
|
struct iovec iov[5];
|
||||||
uint8_t ies[512];
|
uint8_t ies[512];
|
||||||
size_t len;
|
size_t len;
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
|
||||||
info = ft_info_new(hs, target);
|
|
||||||
|
|
||||||
ft_req[0] = 6; /* FT category */
|
ft_req[0] = 6; /* FT category */
|
||||||
ft_req[1] = 1; /* FT Request action */
|
ft_req[1] = 1; /* FT Request action */
|
||||||
memcpy(ft_req + 2, info->spa, 6);
|
memcpy(ft_req + 2, info->spa, 6);
|
||||||
@ -928,17 +938,47 @@ int ft_action(uint32_t ifindex, uint32_t freq, const struct scan_bss *target)
|
|||||||
iov[1].iov_base = ies;
|
iov[1].iov_base = ies;
|
||||||
iov[1].iov_len = len;
|
iov[1].iov_len = len;
|
||||||
|
|
||||||
ret = tx_frame(hs->ifindex, 0x00d0, freq, hs->aa, iov, 2);
|
ret = tx_frame(hs->ifindex, 0x00d0, info->ds_frequency, hs->aa, iov, 2);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
l_queue_push_tail(info_list, info);
|
l_queue_push_tail(info_list, info);
|
||||||
|
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
l_free(info);
|
l_debug("FT-over-DS action failed to "MAC, MAC_STR(hs->aa));
|
||||||
return ret;
|
|
||||||
|
ft_info_destroy(info);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wiphy_radio_work_item_ops ft_ops = {
|
||||||
|
.do_work = ft_send_action,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void ft_ds_timeout(struct l_timeout *timeout, void *user_data)
|
||||||
|
{
|
||||||
|
struct ft_info *info = user_data;
|
||||||
|
struct netdev *netdev = netdev_find(info->ifindex);
|
||||||
|
|
||||||
|
wiphy_radio_work_done(netdev_get_wiphy(netdev), info->work.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ft_action(uint32_t ifindex, uint32_t freq, const struct scan_bss *target)
|
||||||
|
{
|
||||||
|
struct netdev *netdev = netdev_find(ifindex);
|
||||||
|
struct handshake_state *hs = netdev_get_handshake(netdev);
|
||||||
|
struct ft_info *info;
|
||||||
|
|
||||||
|
info = ft_info_new(hs, target);
|
||||||
|
info->ds_frequency = freq;
|
||||||
|
info->timeout = l_timeout_create_ms(200, ft_ds_timeout, info, NULL);
|
||||||
|
|
||||||
|
wiphy_radio_work_insert(netdev_get_wiphy(netdev), &info->work,
|
||||||
|
WIPHY_WORK_PRIORITY_FT, &ft_ops);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __ft_rx_authenticate(uint32_t ifindex, const uint8_t *frame,
|
void __ft_rx_authenticate(uint32_t ifindex, const uint8_t *frame,
|
||||||
|
Loading…
Reference in New Issue
Block a user