mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-22 21:22:37 +01:00
netdev: modify netdev_send_action_frame for ft-over-ds
To support FT-over-DS this API needed some slight modifications: - Instead of setting the DA to netdev->handshake->aa, it is just set to the same address as the 'to' parameter. The kernel actually requires and checks for these addresses to match. All occurences were passing the handshake->aa anyways so this change should have no adverse affects; and its actually required by ft-over-ds to pass in the previous BSSID, so hard coding handshake->aa will not work. - The frequency is is also passed in now, as ft-over-ds needs to use the frequency of the currently connected AP (netdev->frequency get set to the new target in netdev_fast_transition. Previous frequency is also saved now). - A new vector variant (netdev_send_action_framev) was added as well to support sending out the FT Request action frame since the FT TX authenticate function provides an iovec of the IEs. The existing function was already having to prepend the action frame header to the body, so its not any more or less copying to do the same thing with an iovec instead.
This commit is contained in:
parent
1801262f2a
commit
a432ceeee4
88
src/netdev.c
88
src/netdev.c
@ -2633,6 +2633,57 @@ int netdev_leave_adhoc(struct netdev *netdev, netdev_command_cb_t cb,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t netdev_send_action_framev(struct netdev *netdev,
|
||||
const uint8_t *to,
|
||||
struct iovec *iov, size_t iov_len,
|
||||
uint32_t freq,
|
||||
l_genl_msg_func_t callback)
|
||||
{
|
||||
struct l_genl_msg *msg;
|
||||
struct iovec iovs[iov_len + 1];
|
||||
const uint16_t frame_type = 0x00d0;
|
||||
uint8_t action_frame[24];
|
||||
uint32_t id;
|
||||
|
||||
memset(action_frame, 0, 24);
|
||||
|
||||
l_put_le16(frame_type, action_frame + 0);
|
||||
memcpy(action_frame + 4, to, 6);
|
||||
memcpy(action_frame + 10, netdev->addr, 6);
|
||||
memcpy(action_frame + 16, to, 6);
|
||||
|
||||
iovs[0].iov_base = action_frame;
|
||||
iovs[0].iov_len = sizeof(action_frame);
|
||||
memcpy(iovs + 1, iov, sizeof(*iov) * iov_len);
|
||||
|
||||
msg = l_genl_msg_new_sized(NL80211_CMD_FRAME, 128 + 512);
|
||||
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &netdev->index);
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_WIPHY_FREQ, 4, &freq);
|
||||
l_genl_msg_append_attrv(msg, NL80211_ATTR_FRAME, iovs, iov_len + 1);
|
||||
|
||||
id = l_genl_family_send(nl80211, msg, callback, netdev, NULL);
|
||||
|
||||
if (!id)
|
||||
l_genl_msg_unref(msg);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
static uint32_t netdev_send_action_frame(struct netdev *netdev,
|
||||
const uint8_t *to,
|
||||
const uint8_t *body, size_t body_len,
|
||||
uint32_t freq,
|
||||
l_genl_msg_func_t callback)
|
||||
{
|
||||
struct iovec iov[1];
|
||||
|
||||
iov[0].iov_base = (void *)body;
|
||||
iov[0].iov_len = body_len;
|
||||
|
||||
return netdev_send_action_framev(netdev, to, iov, 1, freq, callback);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build an FT Authentication Request frame according to 12.5.2 / 12.5.4:
|
||||
* RSN or non-RSN Over-the-air FT Protocol, with the IE contents
|
||||
@ -2850,40 +2901,6 @@ int netdev_preauthenticate(struct netdev *netdev, struct scan_bss *target_bss,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t netdev_send_action_frame(struct netdev *netdev,
|
||||
const uint8_t *to,
|
||||
const uint8_t *body, size_t body_len,
|
||||
l_genl_msg_func_t callback)
|
||||
{
|
||||
struct l_genl_msg *msg;
|
||||
const uint16_t frame_type = 0x00d0;
|
||||
uint8_t action_frame[24 + body_len];
|
||||
uint32_t id;
|
||||
|
||||
memset(action_frame, 0, 24);
|
||||
|
||||
l_put_le16(frame_type, action_frame + 0);
|
||||
memcpy(action_frame + 4, to, 6);
|
||||
memcpy(action_frame + 10, netdev->addr, 6);
|
||||
memcpy(action_frame + 16, netdev->handshake->aa, 6);
|
||||
memcpy(action_frame + 24, body, body_len);
|
||||
|
||||
msg = l_genl_msg_new_sized(NL80211_CMD_FRAME, 128 + body_len);
|
||||
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &netdev->index);
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_WIPHY_FREQ, 4,
|
||||
&netdev->frequency);
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_FRAME, sizeof(action_frame),
|
||||
action_frame);
|
||||
|
||||
id = l_genl_family_send(nl80211, msg, callback, netdev, NULL);
|
||||
|
||||
if (!id)
|
||||
l_genl_msg_unref(msg);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
static void netdev_neighbor_report_req_cb(struct l_genl_msg *msg,
|
||||
void *user_data)
|
||||
{
|
||||
@ -2929,6 +2946,7 @@ int netdev_neighbor_report_req(struct netdev *netdev,
|
||||
|
||||
if (!netdev_send_action_frame(netdev, netdev->handshake->aa,
|
||||
action_frame, sizeof(action_frame),
|
||||
netdev->frequency,
|
||||
netdev_neighbor_report_req_cb))
|
||||
return -EIO;
|
||||
|
||||
@ -3008,6 +3026,7 @@ static void netdev_sa_query_req_frame_event(struct netdev *netdev,
|
||||
|
||||
if (!netdev_send_action_frame(netdev, netdev->handshake->aa,
|
||||
sa_resp, sizeof(sa_resp),
|
||||
netdev->frequency,
|
||||
netdev_sa_query_resp_cb)) {
|
||||
l_error("error sending SA Query response");
|
||||
return;
|
||||
@ -3141,6 +3160,7 @@ static void netdev_unprot_disconnect_event(struct l_genl_msg *msg,
|
||||
|
||||
if (!netdev_send_action_frame(netdev, netdev->handshake->aa,
|
||||
action_frame, sizeof(action_frame),
|
||||
netdev->frequency,
|
||||
netdev_sa_query_req_cb)) {
|
||||
l_error("error sending SA Query action frame");
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user