mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-22 14:49:24 +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;
|
const uint8_t *frame = NULL;
|
||||||
uint16_t status_code = MMPDU_STATUS_CODE_UNSPECIFIED;
|
uint16_t status_code = MMPDU_STATUS_CODE_UNSPECIFIED;
|
||||||
int ret;
|
int ret;
|
||||||
|
const struct mmpdu_header *hdr;
|
||||||
|
const struct mmpdu_association_response *assoc;
|
||||||
|
|
||||||
l_debug("");
|
l_debug("");
|
||||||
|
|
||||||
if (!netdev->connected || netdev->aborting)
|
if (!netdev->connected || netdev->aborting)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!netdev->ap) {
|
if (!netdev->ap && !netdev->in_ft) {
|
||||||
netdev->associated = true;
|
netdev->associated = true;
|
||||||
netdev->in_reassoc = false;
|
netdev->in_reassoc = false;
|
||||||
return;
|
return;
|
||||||
@ -3251,61 +3253,59 @@ static void netdev_associate_event(struct l_genl_msg *msg,
|
|||||||
if (L_WARN_ON(!frame))
|
if (L_WARN_ON(!frame))
|
||||||
goto assoc_failed;
|
goto assoc_failed;
|
||||||
|
|
||||||
if (netdev->ap) {
|
hdr = mpdu_validate(frame, frame_len);
|
||||||
const struct mmpdu_header *hdr;
|
if (L_WARN_ON(!hdr))
|
||||||
const struct mmpdu_association_response *assoc;
|
goto assoc_failed;
|
||||||
|
|
||||||
hdr = mpdu_validate(frame, frame_len);
|
assoc = mmpdu_body(hdr);
|
||||||
if (L_WARN_ON(!hdr))
|
status_code = L_CPU_TO_LE16(assoc->status_code);
|
||||||
goto assoc_failed;
|
|
||||||
|
|
||||||
assoc = mmpdu_body(hdr);
|
if (netdev->ap)
|
||||||
status_code = L_CPU_TO_LE16(assoc->status_code);
|
ret = auth_proto_rx_associate(netdev->ap, frame,
|
||||||
|
frame_len);
|
||||||
ret = auth_proto_rx_associate(netdev->ap, frame, frame_len);
|
else
|
||||||
if (ret == 0) {
|
ret = __ft_rx_associate(netdev->index, frame,
|
||||||
bool fils = !!(netdev->handshake->akm_suite &
|
frame_len);
|
||||||
(IE_RSN_AKM_SUITE_FILS_SHA256 |
|
if (ret == 0) {
|
||||||
IE_RSN_AKM_SUITE_FILS_SHA384 |
|
bool fils = !!(netdev->handshake->akm_suite &
|
||||||
IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA384 |
|
(IE_RSN_AKM_SUITE_FILS_SHA256 |
|
||||||
IE_RSN_AKM_SUITE_FT_OVER_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);
|
auth_proto_free(netdev->ap);
|
||||||
netdev->ap = NULL;
|
netdev->ap = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
netdev->sm = eapol_sm_new(netdev->handshake);
|
netdev->sm = eapol_sm_new(netdev->handshake);
|
||||||
eapol_register(netdev->sm);
|
eapol_register(netdev->sm);
|
||||||
|
|
||||||
/* Just in case this was a retry */
|
/* Just in case this was a retry */
|
||||||
netdev->ignore_connect_event = false;
|
netdev->ignore_connect_event = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If in FT and/or FILS we don't force an initial 4-way
|
* If in FT and/or FILS we don't force an initial 4-way
|
||||||
* handshake and instead just keep the EAPoL state
|
* handshake and instead just keep the EAPoL state
|
||||||
* machine for the rekeys.
|
* machine for the rekeys.
|
||||||
*/
|
*/
|
||||||
if (netdev->in_ft || fils)
|
if (netdev->in_ft || fils)
|
||||||
eapol_sm_set_require_handshake(netdev->sm,
|
eapol_sm_set_require_handshake(netdev->sm,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
netdev->in_ft = false;
|
netdev->in_ft = false;
|
||||||
netdev->in_reassoc = false;
|
netdev->in_reassoc = false;
|
||||||
netdev->associated = true;
|
netdev->associated = true;
|
||||||
return;
|
return;
|
||||||
} else if (ret == -EAGAIN) {
|
} else if (ret == -EAGAIN) {
|
||||||
/*
|
/*
|
||||||
* Here to support OWE retries. OWE will retry
|
* Here to support OWE retries. OWE will retry
|
||||||
* internally, but a connect event will still be emitted
|
* internally, but a connect event will still be emitted
|
||||||
*/
|
*/
|
||||||
netdev->ignore_connect_event = true;
|
netdev->ignore_connect_event = true;
|
||||||
return;
|
return;
|
||||||
} else if (ret > 0)
|
} else if (ret > 0)
|
||||||
status_code = (uint16_t)ret;
|
status_code = (uint16_t)ret;
|
||||||
|
|
||||||
goto assoc_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
assoc_failed:
|
assoc_failed:
|
||||||
netdev->result = NETDEV_RESULT_ASSOCIATION_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)
|
int rssi, void *user_data)
|
||||||
{
|
{
|
||||||
struct netdev *netdev = 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)
|
if (!netdev->connected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ret = ft_over_ds_parse_action_response(body, body_len, &spa, &aa,
|
__ft_rx_action(netdev->index, (const uint8_t *)hdr,
|
||||||
&ies, &ies_len);
|
mmpdu_header_len(hdr) + body_len);
|
||||||
if (ret < 0)
|
}
|
||||||
|
|
||||||
|
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;
|
return;
|
||||||
|
|
||||||
finder.spa = spa;
|
__ft_rx_authenticate(netdev->index, (const uint8_t *)hdr,
|
||||||
finder.aa = aa;
|
mmpdu_header_len(hdr) + body_len);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void netdev_qos_map_frame_event(const struct mmpdu_header *hdr,
|
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_resp_prefix[2] = { 0x08, 0x01 };
|
||||||
static const uint8_t action_sa_query_req_prefix[2] = { 0x08, 0x00 };
|
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 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 };
|
static const uint8_t action_qos_map_prefix[] = { 0x01, 0x04 };
|
||||||
uint64_t wdev = netdev->wdev_id;
|
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),
|
sizeof(action_ft_response_prefix),
|
||||||
netdev_ft_response_frame_event, netdev, NULL);
|
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))
|
if (wiphy_supports_qos_set_map(netdev->wiphy))
|
||||||
frame_watch_add(wdev, 0, 0x00d0, action_qos_map_prefix,
|
frame_watch_add(wdev, 0, 0x00d0, action_qos_map_prefix,
|
||||||
sizeof(action_qos_map_prefix),
|
sizeof(action_qos_map_prefix),
|
||||||
|
Loading…
Reference in New Issue
Block a user