mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-30 14:22:37 +01:00
netdev: Move eapol_read to eapol.c
This commit is contained in:
parent
746b0e5cb1
commit
efe5bed7c5
58
src/eapol.c
58
src/eapol.c
@ -603,6 +603,7 @@ struct eapol_sm {
|
||||
void *user_data;
|
||||
void *tx_user_data;
|
||||
struct l_timeout *timeout;
|
||||
struct l_io *io;
|
||||
bool have_snonce:1;
|
||||
bool have_replay:1;
|
||||
bool ptk_complete:1;
|
||||
@ -619,6 +620,7 @@ static void eapol_sm_destroy(void *value)
|
||||
l_free(sm->own_ie);
|
||||
|
||||
l_timeout_remove(sm->timeout);
|
||||
l_io_destroy(sm->io);
|
||||
|
||||
if (sm->eap)
|
||||
eap_free(sm->eap);
|
||||
@ -1462,14 +1464,12 @@ void eapol_sm_set_8021x_config(struct eapol_sm *sm, struct l_settings *settings)
|
||||
eap_load_settings(sm->eap, settings, "EAP-");
|
||||
}
|
||||
|
||||
void __eapol_rx_packet(uint32_t ifindex, const uint8_t *spa, const uint8_t *aa,
|
||||
const uint8_t *frame, size_t len)
|
||||
static void eapol_rx_packet(struct eapol_sm *sm,
|
||||
const uint8_t *frame, size_t len)
|
||||
{
|
||||
const struct eapol_header *eh;
|
||||
struct eapol_sm *sm;
|
||||
|
||||
/* Validate Header */
|
||||
|
||||
if (len < sizeof(struct eapol_header))
|
||||
return;
|
||||
|
||||
@ -1482,10 +1482,6 @@ void __eapol_rx_packet(uint32_t ifindex, const uint8_t *spa, const uint8_t *aa,
|
||||
if (len < (size_t) 4 + L_BE16_TO_CPU(eh->packet_len))
|
||||
return;
|
||||
|
||||
sm = eapol_find_sm(ifindex, spa, aa);
|
||||
if (!sm)
|
||||
return;
|
||||
|
||||
switch (eh->packet_type) {
|
||||
case 0: /* EAPOL-EAP */
|
||||
if (!sm->eap) {
|
||||
@ -1512,7 +1508,7 @@ void __eapol_rx_packet(uint32_t ifindex, const uint8_t *spa, const uint8_t *aa,
|
||||
if (!sm->have_pmk)
|
||||
return;
|
||||
|
||||
eapol_key_handle(sm, ifindex, frame, len);
|
||||
eapol_key_handle(sm, sm->ifindex, frame, len);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1520,6 +1516,17 @@ void __eapol_rx_packet(uint32_t ifindex, const uint8_t *spa, const uint8_t *aa,
|
||||
}
|
||||
}
|
||||
|
||||
void __eapol_rx_packet(uint32_t ifindex, const uint8_t *spa, const uint8_t *aa,
|
||||
const uint8_t *frame, size_t len)
|
||||
{
|
||||
struct eapol_sm *sm = eapol_find_sm(ifindex, spa, aa);
|
||||
|
||||
if (!sm)
|
||||
return;
|
||||
|
||||
eapol_rx_packet(sm, frame, len);
|
||||
}
|
||||
|
||||
void __eapol_update_replay_counter(uint32_t ifindex, const uint8_t *spa,
|
||||
const uint8_t *aa, uint64_t replay_counter)
|
||||
{
|
||||
@ -1608,6 +1615,33 @@ struct l_io *eapol_open_pae(uint32_t index)
|
||||
return io;
|
||||
}
|
||||
|
||||
static bool eapol_read(struct l_io *io, void *user_data)
|
||||
{
|
||||
struct eapol_sm *sm = user_data;
|
||||
int fd = l_io_get_fd(io);
|
||||
struct sockaddr_ll sll;
|
||||
socklen_t sll_len;
|
||||
ssize_t bytes;
|
||||
uint8_t frame[2304]; /* IEEE Std 802.11 ch. 8.2.3 */
|
||||
|
||||
memset(&sll, 0, sizeof(sll));
|
||||
sll_len = sizeof(sll);
|
||||
|
||||
bytes = recvfrom(fd, frame, sizeof(frame), 0,
|
||||
(struct sockaddr *) &sll, &sll_len);
|
||||
if (bytes <= 0) {
|
||||
l_error("EAPoL read socket: %s", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (memcmp(sm->aa, sll.sll_addr, 6))
|
||||
return true;
|
||||
|
||||
eapol_rx_packet(sm, frame, bytes);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Default implementation of the frame transmission function.
|
||||
* This function expects an fd to be passed as user_data
|
||||
@ -1649,6 +1683,12 @@ void eapol_start(uint32_t ifindex, struct l_io *io, struct eapol_sm *sm)
|
||||
{
|
||||
sm->ifindex = ifindex;
|
||||
sm->timeout = l_timeout_create(2, eapol_timeout, sm, NULL);
|
||||
|
||||
if (io) {
|
||||
sm->io = io;
|
||||
l_io_set_read_handler(io, eapol_read, sm, NULL);
|
||||
}
|
||||
|
||||
l_queue_push_head(state_machines, sm);
|
||||
}
|
||||
|
||||
|
@ -202,7 +202,7 @@ const uint8_t *eapol_sm_get_own_ie(struct eapol_sm *sm, size_t *out_ie_len);
|
||||
|
||||
struct l_io *eapol_open_pae(uint32_t index);
|
||||
|
||||
void eapol_start(uint32_t ifindex, struct eapol_sm *sm);
|
||||
void eapol_start(uint32_t ifindex, struct l_io *io, struct eapol_sm *sm);
|
||||
void eapol_cancel(uint32_t ifindex);
|
||||
|
||||
bool eapol_init();
|
||||
|
88
src/netdev.c
88
src/netdev.c
@ -53,7 +53,6 @@ struct netdev {
|
||||
char name[IFNAMSIZ];
|
||||
uint32_t type;
|
||||
uint8_t addr[ETH_ALEN];
|
||||
struct l_io *eapol_io;
|
||||
struct device *device;
|
||||
|
||||
netdev_event_func_t event_filter;
|
||||
@ -62,6 +61,7 @@ struct netdev {
|
||||
void *user_data;
|
||||
struct l_genl_msg *associate_msg;
|
||||
struct eapol_sm *sm;
|
||||
struct l_io *eapol_io;
|
||||
uint8_t remote_addr[ETH_ALEN];
|
||||
uint32_t pairwise_new_key_cmd_id;
|
||||
uint32_t pairwise_set_key_cmd_id;
|
||||
@ -93,31 +93,6 @@ static void do_debug(const char *str, void *user_data)
|
||||
l_info("%s%s", prefix, str);
|
||||
}
|
||||
|
||||
static bool eapol_read(struct l_io *io, void *user_data)
|
||||
{
|
||||
struct netdev *netdev = user_data;
|
||||
int fd = l_io_get_fd(io);
|
||||
struct sockaddr_ll sll;
|
||||
socklen_t sll_len;
|
||||
ssize_t bytes;
|
||||
uint8_t frame[2304]; /* IEEE Std 802.11 ch. 8.2.3 */
|
||||
|
||||
memset(&sll, 0, sizeof(sll));
|
||||
sll_len = sizeof(sll);
|
||||
|
||||
bytes = recvfrom(fd, frame, sizeof(frame), 0,
|
||||
(struct sockaddr *) &sll, &sll_len);
|
||||
if (bytes <= 0) {
|
||||
l_error("EAPoL read socket: %s", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
__eapol_rx_packet(netdev->index, netdev->addr, sll.sll_addr,
|
||||
frame, bytes);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct cb_data {
|
||||
netdev_command_func_t callback;
|
||||
void *user_data;
|
||||
@ -233,6 +208,9 @@ static void netdev_free(void *data)
|
||||
if (netdev->sm) {
|
||||
eapol_sm_free(netdev->sm);
|
||||
netdev->sm = NULL;
|
||||
|
||||
l_io_destroy(netdev->eapol_io);
|
||||
netdev->eapol_io = NULL;
|
||||
}
|
||||
|
||||
if (netdev->associate_msg) {
|
||||
@ -240,9 +218,6 @@ static void netdev_free(void *data)
|
||||
netdev->associate_msg = NULL;
|
||||
}
|
||||
|
||||
l_io_destroy(netdev->eapol_io);
|
||||
netdev->eapol_io = NULL;
|
||||
|
||||
netdev_set_linkmode_and_operstate(netdev->index, 0, IF_OPER_DOWN,
|
||||
netdev_operstate_down_cb,
|
||||
L_UINT_TO_PTR(netdev->index));
|
||||
@ -838,6 +813,21 @@ static void netdev_set_rekey_offload(uint32_t ifindex,
|
||||
|
||||
}
|
||||
|
||||
static void netdev_connect_failed(struct netdev *netdev,
|
||||
enum netdev_result result)
|
||||
{
|
||||
if (netdev->sm) {
|
||||
eapol_sm_free(netdev->sm);
|
||||
netdev->sm = NULL;
|
||||
|
||||
l_io_destroy(netdev->eapol_io);
|
||||
netdev->eapol_io = NULL;
|
||||
}
|
||||
|
||||
if (netdev->connect_cb)
|
||||
netdev->connect_cb(netdev, result, netdev->user_data);
|
||||
}
|
||||
|
||||
static void netdev_connect_event(struct l_genl_msg *msg,
|
||||
struct netdev *netdev)
|
||||
{
|
||||
@ -873,9 +863,10 @@ static void netdev_connect_event(struct l_genl_msg *msg,
|
||||
if (netdev->sm) {
|
||||
eapol_sm_set_tx_user_data(netdev->sm,
|
||||
L_INT_TO_PTR(l_io_get_fd(netdev->eapol_io)));
|
||||
eapol_start(netdev->index, netdev->sm);
|
||||
eapol_start(netdev->index, netdev->eapol_io, netdev->sm);
|
||||
|
||||
netdev->sm = NULL;
|
||||
netdev->eapol_io = NULL;
|
||||
|
||||
if (netdev->event_filter)
|
||||
netdev->event_filter(netdev,
|
||||
@ -888,13 +879,7 @@ static void netdev_connect_event(struct l_genl_msg *msg,
|
||||
return;
|
||||
|
||||
error:
|
||||
if (netdev->sm) {
|
||||
eapol_sm_free(netdev->sm);
|
||||
netdev->sm = NULL;
|
||||
|
||||
if (netdev->connect_cb)
|
||||
netdev->connect_cb(netdev, NETDEV_RESULT_ASSOCIATION_FAILED,
|
||||
netdev->user_data);
|
||||
netdev_connect_failed(netdev, NETDEV_RESULT_ASSOCIATION_FAILED);
|
||||
}
|
||||
|
||||
static void netdev_authenticate_event(struct l_genl_msg *msg,
|
||||
@ -923,9 +908,7 @@ static void netdev_cmd_connect_cb(struct l_genl_msg *msg, void *user_data)
|
||||
return;
|
||||
}
|
||||
|
||||
if (netdev->connect_cb)
|
||||
netdev->connect_cb(netdev, NETDEV_RESULT_ASSOCIATION_FAILED,
|
||||
netdev->user_data);
|
||||
netdev_connect_failed(netdev, NETDEV_RESULT_ASSOCIATION_FAILED);
|
||||
}
|
||||
|
||||
static struct l_genl_msg *netdev_build_cmd_connect(struct netdev *netdev,
|
||||
@ -1003,9 +986,25 @@ int netdev_connect(struct netdev *netdev, struct scan_bss *bss,
|
||||
netdev->event_filter = event_filter;
|
||||
netdev->connect_cb = cb;
|
||||
netdev->user_data = user_data;
|
||||
netdev->sm = sm;
|
||||
memcpy(netdev->remote_addr, bss->addr, ETH_ALEN);
|
||||
|
||||
netdev->sm = sm;
|
||||
if (netdev->sm) {
|
||||
/*
|
||||
* Due to timing / race conditions, it is possible for
|
||||
* EAPoL packets to arrive before the netdev events
|
||||
* are received. Here we 'prime' the socket, so that
|
||||
* the data is available as soon as we call eapol_start
|
||||
*
|
||||
* If this isn't done, then we might 'miss' the first EAPoL
|
||||
* packet from the AP, and have to wait for the AP to
|
||||
* retransmit. This delays our handshake by 1-2 seconds
|
||||
*/
|
||||
netdev->eapol_io = eapol_open_pae(netdev->index);
|
||||
if (!netdev->eapol_io)
|
||||
l_error("Failed to open PAE socket");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1259,13 +1258,6 @@ static void netdev_get_interface_callback(struct l_genl_msg *msg,
|
||||
memcpy(netdev->addr, ifaddr, sizeof(netdev->addr));
|
||||
memcpy(netdev->name, ifname, ifname_len);
|
||||
|
||||
netdev->eapol_io = eapol_open_pae(netdev->index);
|
||||
if (netdev->eapol_io)
|
||||
l_io_set_read_handler(netdev->eapol_io, eapol_read,
|
||||
netdev, NULL);
|
||||
else
|
||||
l_error("Failed to open PAE socket");
|
||||
|
||||
l_queue_push_tail(netdev_list, netdev);
|
||||
|
||||
netdev_set_linkmode_and_operstate(netdev->index, 1,
|
||||
|
Loading…
Reference in New Issue
Block a user