Skip to content

Commit

Permalink
Merge tag '2.4'
Browse files Browse the repository at this point in the history
Release 2.4
  • Loading branch information
illiliti committed Apr 2, 2023
2 parents 6b51f09 + 53911bf commit c0d6460
Show file tree
Hide file tree
Showing 12 changed files with 166 additions and 25 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ Emmanuel VAUTRIN <[email protected]>
Jesse Lentz <[email protected]>
Pinghao Wu <[email protected]>
Neehar Vijay <[email protected]>
Jiajie Chen <[email protected]>
6 changes: 6 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
ver 2.4:
Fix issue with FT-over-Air and same channel operation.
Fix issue with AP mode and missing support for GTK.
Fix issue with AP mode and channel switch event.
Fix issue with SSID string conversion handling.

ver 2.3:
Fix issue with length calculation for WMM IE.
Fix issue with channel number allocation off-by-one.
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
AC_PREREQ([2.69])
AC_INIT([iwd],[2.3])
AC_INIT([iwd],[2.4])

AC_CONFIG_HEADERS(config.h)
AC_CONFIG_AUX_DIR(build-aux)
Expand Down
23 changes: 19 additions & 4 deletions monitor/nlmon.c
Original file line number Diff line number Diff line change
Expand Up @@ -5068,6 +5068,16 @@ static void print_probe_response(unsigned int level,
(const uint8_t *) mmpdu + len - resp->ies);
}

static void print_beacon(unsigned int level,
const struct mmpdu_header *mmpdu, size_t len)
{
const struct mmpdu_beacon *beacon = mmpdu_body(mmpdu);

print_attr(level, "Subtype: Beacon");
print_ie(level + 1, "Beacon IEs", beacon->ies,
(const uint8_t *) mmpdu + len - beacon->ies);
}

static void print_frame_type(unsigned int level, const char *label,
const void *data, uint16_t size)
{
Expand Down Expand Up @@ -5122,7 +5132,10 @@ static void print_frame_type(unsigned int level, const char *label,
str = "Timing Advertisement";
break;
case 0x08:
str = "Beacon";
if (mpdu)
print_beacon(level + 1, mpdu, size);
else
str = "Beacon";
break;
case 0x09:
str = "ATIM";
Expand Down Expand Up @@ -6240,9 +6253,10 @@ static const struct attr_entry attr_table[] = {
{ NL80211_ATTR_DTIM_PERIOD,
"DTIM Period", ATTR_U32 },
{ NL80211_ATTR_BEACON_HEAD,
"Beacon Head", ATTR_BINARY },
"Beacon Head", ATTR_CUSTOM, { .function = print_frame } },
{ NL80211_ATTR_BEACON_TAIL,
"Beacon Tail", ATTR_BINARY },
"Beacon Tail", ATTR_CUSTOM,
{ .function = print_management_ies } },
{ NL80211_ATTR_STA_AID,
"Station AID", ATTR_U16 },
{ NL80211_ATTR_STA_FLAGS,
Expand Down Expand Up @@ -6520,7 +6534,8 @@ static const struct attr_entry attr_table[] = {
{ NL80211_ATTR_PROBE_RESP_OFFLOAD,
"Probe Response Offload" },
{ NL80211_ATTR_PROBE_RESP,
"Probe Response" },
"Probe Response", ATTR_CUSTOM,
{ .function = print_frame} },
{ NL80211_ATTR_DFS_REGION,
"DFS Region", ATTR_U8 },
{ NL80211_ATTR_DISABLE_HT,
Expand Down
37 changes: 28 additions & 9 deletions src/ap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1499,14 +1499,19 @@ static void ap_gtk_query_cb(struct l_genl_msg *msg, void *user_data)
struct sta_state *sta = user_data;
const void *gtk_rsc;
uint8_t zero_gtk_rsc[6];
int err;

sta->gtk_query_cmd_id = 0;

if (l_genl_msg_get_error(msg) < 0)
err = l_genl_msg_get_error(msg);
if (err == -ENOTSUP)
goto zero_rsc;
else if (err < 0)
goto error;

gtk_rsc = nl80211_parse_get_key_seq(msg);
if (!gtk_rsc) {
zero_rsc:
memset(zero_gtk_rsc, 0, 6);
gtk_rsc = zero_gtk_rsc;
}
Expand Down Expand Up @@ -1643,19 +1648,22 @@ static struct l_genl_msg *ap_build_cmd_new_station(struct sta_state *sta)
{
struct l_genl_msg *msg;
uint32_t ifindex = netdev_get_ifindex(sta->ap->netdev);
/*
* This should hopefully work both with and without
* NL80211_FEATURE_FULL_AP_CLIENT_STATE.
*/
struct nl80211_sta_flag_update flags = {
.mask = (1 << NL80211_STA_FLAG_AUTHENTICATED) |
(1 << NL80211_STA_FLAG_ASSOCIATED) |
(1 << NL80211_STA_FLAG_AUTHORIZED) |
.mask = (1 << NL80211_STA_FLAG_AUTHORIZED) |
(1 << NL80211_STA_FLAG_MFP),
.set = (1 << NL80211_STA_FLAG_AUTHENTICATED) |
(1 << NL80211_STA_FLAG_ASSOCIATED),
};

/*
* Without this feature nl80211 rejects NEW_STATION if the mask contains
* auth/assoc flags
*/
if (wiphy_has_feature(netdev_get_wiphy(sta->ap->netdev),
NL80211_FEATURE_FULL_AP_CLIENT_STATE))
flags.mask |= (1 << NL80211_STA_FLAG_ASSOCIATED) |
(1 << NL80211_STA_FLAG_AUTHENTICATED);

msg = l_genl_msg_new_sized(NL80211_CMD_NEW_STATION, 300);

l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &ifindex);
Expand Down Expand Up @@ -3660,7 +3668,18 @@ static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
ap->band = BAND_FREQ_2_4_GHZ;
}

ap->supports_ht = wiphy_get_ht_capabilities(wiphy, ap->band,
if (l_settings_has_key(config, "General", "DisableHT")) {
bool boolval;

if (!l_settings_get_bool(config, "General", "DisableHT",
&boolval)) {
l_error("AP [General].DisableHT not a valid boolean");
return -EINVAL;
}

ap->supports_ht = !boolval;
} else
ap->supports_ht = wiphy_get_ht_capabilities(wiphy, ap->band,
NULL) != NULL;

if (!ap_validate_band_channel(ap)) {
Expand Down
2 changes: 2 additions & 0 deletions src/eapol.c
Original file line number Diff line number Diff line change
Expand Up @@ -2783,6 +2783,8 @@ void eapol_register(struct eapol_sm *sm)

bool eapol_start(struct eapol_sm *sm)
{
l_debug("");

if (sm->handshake->settings_8021x) {
_auto_(l_free) char *network_id = NULL;

Expand Down
57 changes: 55 additions & 2 deletions src/ft.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
#include "src/offchannel.h"
#include "src/wiphy.h"

static const unsigned int FT_ONCHANNEL_TIME = 300u; /* ms */

static ft_tx_frame_func_t tx_frame = NULL;
static ft_tx_associate_func_t tx_assoc = NULL;
static struct l_queue *info_list = NULL;
Expand All @@ -63,6 +65,7 @@ struct ft_info {
struct ie_ft_info ft_info;

bool parsed : 1;
bool onchannel : 1;
};

/*
Expand Down Expand Up @@ -1009,8 +1012,17 @@ void __ft_rx_authenticate(uint32_t ifindex, const uint8_t *frame,
info->parsed = true;

cancel:
/* Verified to be expected target, offchannel can be canceled */
offchannel_cancel(netdev_get_wdev_id(netdev), info->offchannel_id);
/*
* Verified to be expected target, offchannel or onchannel work can
* now be canceled
*/
if (info->onchannel) {
l_timeout_remove(info->timeout);
info->timeout = NULL;
wiphy_radio_work_done(netdev_get_wiphy(netdev), info->work.id);
} else
offchannel_cancel(netdev_get_wdev_id(netdev),
info->offchannel_id);
}

static void ft_send_authenticate(void *user_data)
Expand All @@ -1023,6 +1035,8 @@ static void ft_send_authenticate(void *user_data)
struct iovec iov[2];
struct mmpdu_authentication auth;

l_debug("");

/* Authentication body */
auth.algorithm = L_CPU_TO_LE16(MMPDU_AUTH_ALGO_FT);
auth.transaction_sequence = L_CPU_TO_LE16(1);
Expand Down Expand Up @@ -1079,6 +1093,45 @@ int ft_authenticate(uint32_t ifindex, const struct scan_bss *target)
return 0;
}

static void ft_onchannel_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);
}

static bool ft_send_authenticate_onchannel(struct wiphy_radio_work_item *work)
{
struct ft_info *info = l_container_of(work, struct ft_info, work);

ft_send_authenticate(info);

info->timeout = l_timeout_create_ms(FT_ONCHANNEL_TIME,
ft_onchannel_timeout,
info, NULL);
return false;
}

struct wiphy_radio_work_item_ops ft_onchannel_ops = {
.do_work = ft_send_authenticate_onchannel,
};

int ft_authenticate_onchannel(uint32_t ifindex, const struct scan_bss *target)
{
struct netdev *netdev = netdev_find(ifindex);
struct handshake_state *hs = netdev_get_handshake(netdev);
struct ft_info *info = ft_info_new(hs, target);

info->onchannel = true;

wiphy_radio_work_insert(netdev_get_wiphy(netdev), &info->work,
WIPHY_WORK_PRIORITY_FT, &ft_onchannel_ops);
l_queue_push_tail(info_list, info);

return 0;
}

int ft_associate(uint32_t ifindex, const uint8_t *addr)
{
struct netdev *netdev = netdev_find(ifindex);
Expand Down
1 change: 1 addition & 0 deletions src/ft.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ void ft_clear_authentications(uint32_t ifindex);
int ft_action(uint32_t ifindex, uint32_t freq, const struct scan_bss *target);
int ft_associate(uint32_t ifindex, const uint8_t *addr);
int ft_authenticate(uint32_t ifindex, const struct scan_bss *target);
int ft_authenticate_onchannel(uint32_t ifindex, const struct scan_bss *target);
5 changes: 5 additions & 0 deletions src/iwd.ap.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ The group ``[General]`` contains general AP configuration.
The time interval at which the AP starts a rekey for a given station. If
not provided a default value of 0 is used (rekeying is disabled).

* - DisableHT
- Boolean value

Explicitly disable HT capabilities for this AP.

Network Authentication Settings
-------------------------------

Expand Down
5 changes: 3 additions & 2 deletions src/knownnetworks.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,10 @@ static const char *known_network_get_path(const struct network_info *network)

for (i = 0; network->ssid[i] && pos < sizeof(path); i++)
pos += snprintf(path + pos, sizeof(path) - pos, "%02x",
network->ssid[i]);
(unsigned char)network->ssid[i]);

snprintf(path + pos, sizeof(path) - pos, "_%s",
if (pos < sizeof(path))
snprintf(path + pos, sizeof(path) - pos, "_%s",
security_to_str(network->type));
path[sizeof(path) - 1] = '\0';

Expand Down
33 changes: 31 additions & 2 deletions src/netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1370,6 +1370,8 @@ static void netdev_operstate_cb(int error, uint16_t type,

static void netdev_connect_ok(struct netdev *netdev)
{
l_debug("");

l_rtnl_set_linkmode_and_operstate(rtnl, netdev->index,
IF_LINK_MODE_DORMANT, IF_OPER_UP,
netdev_operstate_cb,
Expand Down Expand Up @@ -1469,7 +1471,14 @@ static void netdev_setting_keys_failed(struct netdev_handshake_state *nhs,

static void try_handshake_complete(struct netdev_handshake_state *nhs)
{
l_debug("ptk_installed: %u, gtk_installed: %u, igtk_installed: %u",
nhs->ptk_installed,
nhs->gtk_installed,
nhs->igtk_installed);

if (nhs->ptk_installed && nhs->gtk_installed && nhs->igtk_installed) {
l_debug("nhs->complete: %u", nhs->complete);

if (nhs->complete) {
handshake_event(&nhs->super,
HANDSHAKE_EVENT_REKEY_COMPLETE);
Expand All @@ -1478,6 +1487,8 @@ static void try_handshake_complete(struct netdev_handshake_state *nhs)

nhs->complete = true;

l_debug("Invoking handshake_event()");

if (handshake_event(&nhs->super, HANDSHAKE_EVENT_COMPLETE))
return;

Expand All @@ -1493,6 +1504,8 @@ static void netdev_set_station_cb(struct l_genl_msg *msg, void *user_data)
struct netdev *netdev = nhs->netdev;
int err;

l_debug("");

nhs->set_station_cmd_id = 0;
nhs->ptk_installed = true;

Expand Down Expand Up @@ -1523,6 +1536,7 @@ static void netdev_new_group_key_cb(struct l_genl_msg *msg, void *data)
struct netdev *netdev = nhs->netdev;
int err = l_genl_msg_get_error(msg);

l_debug("ifindex: %u, err: %d", netdev->index, err);
nhs->group_new_key_cmd_id = 0;

if (err < 0) {
Expand All @@ -1547,6 +1561,7 @@ static void netdev_new_group_management_key_cb(struct l_genl_msg *msg,
struct netdev *netdev = nhs->netdev;
int err = l_genl_msg_get_error(msg);

l_debug("ifindex: %u, err: %d", netdev->index, err);
nhs->group_management_new_key_cmd_id = 0;

if (err < 0) {
Expand Down Expand Up @@ -2413,6 +2428,8 @@ static int netdev_get_oci(void *user_data)
struct l_genl_msg *msg =
l_genl_msg_new_sized(NL80211_CMD_GET_INTERFACE, 64);

l_debug("");

l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &netdev->index);

netdev->get_oci_cmd_id = l_genl_family_send(nl80211, msg,
Expand All @@ -2433,6 +2450,8 @@ static void parse_request_ies(struct netdev *netdev, const uint8_t *ies,
const void *data;
const uint8_t *rsnxe = NULL;

l_debug("");

/*
* The driver may have modified the IEs we passed to CMD_CONNECT
* before sending them out, the actual IE sent is reflected in the
Expand Down Expand Up @@ -2735,6 +2754,8 @@ static void netdev_connect_event(struct l_genl_msg *msg, struct netdev *netdev)
if (netdev->ignore_connect_event)
return;

l_debug("aborting and ignore_connect_event not set, proceed");

/* Work around mwifiex which sends a Connect Event prior to the Ack */
if (netdev->connect_cmd_id)
netdev_driver_connected(netdev);
Expand Down Expand Up @@ -2794,6 +2815,8 @@ static void netdev_connect_event(struct l_genl_msg *msg, struct netdev *netdev)
goto error;
}

l_debug("expect_connect_failure not set, proceed");

if (netdev->owe_sm && status_code && *status_code ==
MMPDU_STATUS_CODE_UNSUPP_FINITE_CYCLIC_GROUP) {
if (!netdev_retry_owe(netdev))
Expand Down Expand Up @@ -2921,6 +2944,8 @@ static void netdev_connect_event(struct l_genl_msg *msg, struct netdev *netdev)
netdev_send_qos_map_set(netdev, qos_set, qos_len);
}

l_debug("Request / Response IEs parsed");

if (netdev->sm) {
if (!hs->chandef) {
if (netdev_get_oci(netdev) < 0)
Expand Down Expand Up @@ -5145,8 +5170,12 @@ static void netdev_send_sa_query_delay(struct l_timeout *timeout,
static void netdev_channel_switch_event(struct l_genl_msg *msg,
struct netdev *netdev)
{
_auto_(l_free) struct band_chandef *chandef =
l_new(struct band_chandef, 1);
_auto_(l_free) struct band_chandef *chandef = NULL;

if (netdev->type != NL80211_IFTYPE_STATION)
return;

chandef = l_new(struct band_chandef, 1);

if (nl80211_parse_chandef(msg, chandef) < 0) {
l_debug("Couldn't parse operating channel info.");
Expand Down
Loading

0 comments on commit c0d6460

Please sign in to comment.