mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-25 17:59:25 +01:00
netdev: hook in RX for FT-Action/Authentication/Association
This forwards Action, Authentication and Association frames to ft.c via their new hooks in netdev. Note that this will break FT-over-Air temporarily since the auth-proto still is in use.
This commit is contained in:
parent
e12f198255
commit
8833a7377e
149
src/netdev.c
149
src/netdev.c
@ -3205,13 +3205,15 @@ static void netdev_associate_event(struct l_genl_msg *msg,
|
||||
const uint8_t *frame = NULL;
|
||||
uint16_t status_code = MMPDU_STATUS_CODE_UNSPECIFIED;
|
||||
int ret;
|
||||
const struct mmpdu_header *hdr;
|
||||
const struct mmpdu_association_response *assoc;
|
||||
|
||||
l_debug("");
|
||||
|
||||
if (!netdev->connected || netdev->aborting)
|
||||
return;
|
||||
|
||||
if (!netdev->ap) {
|
||||
if (!netdev->ap && !netdev->in_ft) {
|
||||
netdev->associated = true;
|
||||
netdev->in_reassoc = false;
|
||||
return;
|
||||
@ -3251,61 +3253,59 @@ static void netdev_associate_event(struct l_genl_msg *msg,
|
||||
if (L_WARN_ON(!frame))
|
||||
goto assoc_failed;
|
||||
|
||||
if (netdev->ap) {
|
||||
const struct mmpdu_header *hdr;
|
||||
const struct mmpdu_association_response *assoc;
|
||||
hdr = mpdu_validate(frame, frame_len);
|
||||
if (L_WARN_ON(!hdr))
|
||||
goto assoc_failed;
|
||||
|
||||
hdr = mpdu_validate(frame, frame_len);
|
||||
if (L_WARN_ON(!hdr))
|
||||
goto assoc_failed;
|
||||
assoc = mmpdu_body(hdr);
|
||||
status_code = L_CPU_TO_LE16(assoc->status_code);
|
||||
|
||||
assoc = mmpdu_body(hdr);
|
||||
status_code = L_CPU_TO_LE16(assoc->status_code);
|
||||
|
||||
ret = auth_proto_rx_associate(netdev->ap, frame, frame_len);
|
||||
if (ret == 0) {
|
||||
bool fils = !!(netdev->handshake->akm_suite &
|
||||
(IE_RSN_AKM_SUITE_FILS_SHA256 |
|
||||
IE_RSN_AKM_SUITE_FILS_SHA384 |
|
||||
IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA384 |
|
||||
IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA256));
|
||||
if (netdev->ap)
|
||||
ret = auth_proto_rx_associate(netdev->ap, frame,
|
||||
frame_len);
|
||||
else
|
||||
ret = __ft_rx_associate(netdev->index, frame,
|
||||
frame_len);
|
||||
if (ret == 0) {
|
||||
bool fils = !!(netdev->handshake->akm_suite &
|
||||
(IE_RSN_AKM_SUITE_FILS_SHA256 |
|
||||
IE_RSN_AKM_SUITE_FILS_SHA384 |
|
||||
IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA384 |
|
||||
IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA256));
|
||||
|
||||
if (netdev->ap) {
|
||||
auth_proto_free(netdev->ap);
|
||||
netdev->ap = NULL;
|
||||
}
|
||||
|
||||
netdev->sm = eapol_sm_new(netdev->handshake);
|
||||
eapol_register(netdev->sm);
|
||||
netdev->sm = eapol_sm_new(netdev->handshake);
|
||||
eapol_register(netdev->sm);
|
||||
|
||||
/* Just in case this was a retry */
|
||||
netdev->ignore_connect_event = false;
|
||||
/* Just in case this was a retry */
|
||||
netdev->ignore_connect_event = false;
|
||||
|
||||
/*
|
||||
* If in FT and/or FILS we don't force an initial 4-way
|
||||
* handshake and instead just keep the EAPoL state
|
||||
* machine for the rekeys.
|
||||
*/
|
||||
if (netdev->in_ft || fils)
|
||||
eapol_sm_set_require_handshake(netdev->sm,
|
||||
false);
|
||||
/*
|
||||
* If in FT and/or FILS we don't force an initial 4-way
|
||||
* handshake and instead just keep the EAPoL state
|
||||
* machine for the rekeys.
|
||||
*/
|
||||
if (netdev->in_ft || fils)
|
||||
eapol_sm_set_require_handshake(netdev->sm,
|
||||
false);
|
||||
|
||||
netdev->in_ft = false;
|
||||
netdev->in_reassoc = false;
|
||||
netdev->associated = true;
|
||||
return;
|
||||
} else if (ret == -EAGAIN) {
|
||||
/*
|
||||
* Here to support OWE retries. OWE will retry
|
||||
* internally, but a connect event will still be emitted
|
||||
*/
|
||||
netdev->ignore_connect_event = true;
|
||||
return;
|
||||
} else if (ret > 0)
|
||||
status_code = (uint16_t)ret;
|
||||
|
||||
goto assoc_failed;
|
||||
}
|
||||
|
||||
return;
|
||||
netdev->in_ft = false;
|
||||
netdev->in_reassoc = false;
|
||||
netdev->associated = true;
|
||||
return;
|
||||
} else if (ret == -EAGAIN) {
|
||||
/*
|
||||
* Here to support OWE retries. OWE will retry
|
||||
* internally, but a connect event will still be emitted
|
||||
*/
|
||||
netdev->ignore_connect_event = true;
|
||||
return;
|
||||
} else if (ret > 0)
|
||||
status_code = (uint16_t)ret;
|
||||
|
||||
assoc_failed:
|
||||
netdev->result = NETDEV_RESULT_ASSOCIATION_FAILED;
|
||||
@ -4591,49 +4591,25 @@ static void netdev_ft_response_frame_event(const struct mmpdu_header *hdr,
|
||||
int rssi, void *user_data)
|
||||
{
|
||||
struct netdev *netdev = user_data;
|
||||
struct netdev_ft_over_ds_info *info;
|
||||
int ret;
|
||||
uint16_t status_code = MMPDU_STATUS_CODE_UNSPECIFIED;
|
||||
const uint8_t *aa;
|
||||
const uint8_t *spa;
|
||||
const uint8_t *ies;
|
||||
size_t ies_len;
|
||||
struct ft_ds_finder finder;
|
||||
|
||||
if (!netdev->connected)
|
||||
return;
|
||||
|
||||
ret = ft_over_ds_parse_action_response(body, body_len, &spa, &aa,
|
||||
&ies, &ies_len);
|
||||
if (ret < 0)
|
||||
__ft_rx_action(netdev->index, (const uint8_t *)hdr,
|
||||
mmpdu_header_len(hdr) + body_len);
|
||||
}
|
||||
|
||||
static void netdev_ft_auth_response_frame_event(const struct mmpdu_header *hdr,
|
||||
const void *body, size_t body_len,
|
||||
int rssi, void *user_data)
|
||||
{
|
||||
struct netdev *netdev = user_data;
|
||||
|
||||
if (!netdev->connected)
|
||||
return;
|
||||
|
||||
finder.spa = spa;
|
||||
finder.aa = aa;
|
||||
|
||||
info = l_queue_find(netdev->ft_ds_list, match_ft_ds_info, &finder);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
/* Lookup successful, now check the status code */
|
||||
if (ret > 0) {
|
||||
status_code = (uint16_t)ret;
|
||||
goto ft_error;
|
||||
}
|
||||
|
||||
if (!ft_over_ds_parse_action_ies(&info->super, netdev->handshake,
|
||||
ies, ies_len))
|
||||
goto ft_error;
|
||||
|
||||
info->parsed = true;
|
||||
|
||||
return;
|
||||
|
||||
ft_error:
|
||||
l_debug("FT-over-DS to "MAC" failed (%d)", MAC_STR(info->super.aa),
|
||||
status_code);
|
||||
|
||||
netdev_ft_over_ds_auth_failed(info, status_code);
|
||||
__ft_rx_authenticate(netdev->index, (const uint8_t *)hdr,
|
||||
mmpdu_header_len(hdr) + body_len);
|
||||
}
|
||||
|
||||
static void netdev_qos_map_frame_event(const struct mmpdu_header *hdr,
|
||||
@ -5859,6 +5835,7 @@ static void netdev_add_station_frame_watches(struct netdev *netdev)
|
||||
static const uint8_t action_sa_query_resp_prefix[2] = { 0x08, 0x01 };
|
||||
static const uint8_t action_sa_query_req_prefix[2] = { 0x08, 0x00 };
|
||||
static const uint8_t action_ft_response_prefix[] = { 0x06, 0x02 };
|
||||
static const uint8_t auth_ft_response_prefix[] = { 0x02, 0x00 };
|
||||
static const uint8_t action_qos_map_prefix[] = { 0x01, 0x04 };
|
||||
uint64_t wdev = netdev->wdev_id;
|
||||
|
||||
@ -5879,6 +5856,10 @@ static void netdev_add_station_frame_watches(struct netdev *netdev)
|
||||
sizeof(action_ft_response_prefix),
|
||||
netdev_ft_response_frame_event, netdev, NULL);
|
||||
|
||||
frame_watch_add(wdev, 0, 0x00b0, auth_ft_response_prefix,
|
||||
sizeof(auth_ft_response_prefix),
|
||||
netdev_ft_auth_response_frame_event, netdev, NULL);
|
||||
|
||||
if (wiphy_supports_qos_set_map(netdev->wiphy))
|
||||
frame_watch_add(wdev, 0, 0x00d0, action_qos_map_prefix,
|
||||
sizeof(action_qos_map_prefix),
|
||||
|
Loading…
Reference in New Issue
Block a user