* [PATCH 1/5] nl80211util: populate no-IR list parsing frequencies
@ 2022-12-08 23:48 James Prestwood
2022-12-08 23:48 ` [PATCH 2/5] wiphy: track no-IR frequencies James Prestwood
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: James Prestwood @ 2022-12-08 23:48 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
In AP mode no-IR channels need to be known since they are effectively
disabled with respect to AP operation. Parse these channels into a
separate list.
---
src/nl80211util.c | 11 ++++++++++-
src/nl80211util.h | 3 ++-
src/wiphy.c | 6 ++++--
3 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/src/nl80211util.c b/src/nl80211util.c
index da36d936..396c82c2 100644
--- a/src/nl80211util.c
+++ b/src/nl80211util.c
@@ -502,7 +502,8 @@ int nl80211_parse_chandef(struct l_genl_msg *msg, struct band_chandef *out)
int nl80211_parse_supported_frequencies(struct l_genl_attr *band_freqs,
struct scan_freq_set *supported_list,
- struct scan_freq_set *disabled_list)
+ struct scan_freq_set *disabled_list,
+ struct scan_freq_set *no_ir_list)
{
uint16_t type, len;
const void *data;
@@ -515,6 +516,7 @@ int nl80211_parse_supported_frequencies(struct l_genl_attr *band_freqs,
while (l_genl_attr_next(&nested, NULL, NULL, NULL)) {
uint32_t freq = 0;
bool disabled = false;
+ bool no_ir = false;
if (!l_genl_attr_recurse(&nested, &attr))
continue;
@@ -527,6 +529,9 @@ int nl80211_parse_supported_frequencies(struct l_genl_attr *band_freqs,
case NL80211_FREQUENCY_ATTR_DISABLED:
disabled = true;
break;
+ case NL80211_FREQUENCY_ATTR_NO_IR:
+ no_ir = true;
+ break;
}
}
@@ -538,6 +543,10 @@ int nl80211_parse_supported_frequencies(struct l_genl_attr *band_freqs,
if (disabled && disabled_list)
scan_freq_set_add(disabled_list, freq);
+
+ if (no_ir && no_ir_list)
+ scan_freq_set_add(no_ir_list, freq);
+
}
return 0;
diff --git a/src/nl80211util.h b/src/nl80211util.h
index 44555a25..ce1df2cd 100644
--- a/src/nl80211util.h
+++ b/src/nl80211util.h
@@ -59,4 +59,5 @@ struct l_genl_msg *nl80211_build_cmd_frame(uint32_t ifindex,
int nl80211_parse_chandef(struct l_genl_msg *msg, struct band_chandef *out);
int nl80211_parse_supported_frequencies(struct l_genl_attr *band_freqs,
struct scan_freq_set *supported,
- struct scan_freq_set *disabled);
+ struct scan_freq_set *disabled,
+ struct scan_freq_set *no_ir);
diff --git a/src/wiphy.c b/src/wiphy.c
index 10514572..4744e7f4 100644
--- a/src/wiphy.c
+++ b/src/wiphy.c
@@ -1514,7 +1514,8 @@ static void parse_supported_bands(struct wiphy *wiphy,
case NL80211_BAND_ATTR_FREQS:
nl80211_parse_supported_frequencies(&attr,
wiphy->supported_freqs,
- wiphy->disabled_freqs);
+ wiphy->disabled_freqs,
+ NULL);
break;
case NL80211_BAND_ATTR_RATES:
@@ -1988,7 +1989,8 @@ static void wiphy_dump_callback(struct l_genl_msg *msg,
continue;
nl80211_parse_supported_frequencies(&attr, NULL,
- wiphy->pending_freqs);
+ wiphy->pending_freqs,
+ NULL);
}
}
}
--
2.34.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/5] wiphy: track no-IR frequencies
2022-12-08 23:48 [PATCH 1/5] nl80211util: populate no-IR list parsing frequencies James Prestwood
@ 2022-12-08 23:48 ` James Prestwood
2022-12-08 23:48 ` [PATCH 3/5] wiphy: add wiphy_get_no_ir_freqs James Prestwood
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: James Prestwood @ 2022-12-08 23:48 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
Track these frequencies as is done with disabled frequencies, and
update on regulatory changes. AP mode needs to know if any
frequencies are marked no-IR since it cannot start on these.
---
src/wiphy.c | 59 ++++++++++++++++++++++++++++++++++-------------------
1 file changed, 38 insertions(+), 21 deletions(-)
diff --git a/src/wiphy.c b/src/wiphy.c
index 4744e7f4..af0443bc 100644
--- a/src/wiphy.c
+++ b/src/wiphy.c
@@ -106,7 +106,9 @@ struct wiphy {
uint16_t supported_ciphers;
struct scan_freq_set *supported_freqs;
struct scan_freq_set *disabled_freqs;
- struct scan_freq_set *pending_freqs;
+ struct scan_freq_set *no_ir_freqs;
+ struct scan_freq_set *pending_disabled_freqs;
+ struct scan_freq_set *pending_no_ir_freqs;
struct band *band_2g;
struct band *band_5g;
struct band *band_6g;
@@ -346,6 +348,7 @@ static struct wiphy *wiphy_new(uint32_t id)
wiphy->id = id;
wiphy->supported_freqs = scan_freq_set_new();
wiphy->disabled_freqs = scan_freq_set_new();
+ wiphy->no_ir_freqs = scan_freq_set_new();
watchlist_init(&wiphy->state_watches, NULL);
wiphy->extended_capabilities[0] = IE_TYPE_EXTENDED_CAPABILITIES;
wiphy->extended_capabilities[1] = EXT_CAP_LEN;
@@ -951,7 +954,7 @@ int wiphy_estimate_data_rate(struct wiphy *wiphy,
bool wiphy_regdom_is_updating(struct wiphy *wiphy)
{
- return wiphy->pending_freqs != NULL;
+ return wiphy->pending_disabled_freqs != NULL;
}
uint32_t wiphy_state_watch_add(struct wiphy *wiphy,
@@ -1515,7 +1518,7 @@ static void parse_supported_bands(struct wiphy *wiphy,
nl80211_parse_supported_frequencies(&attr,
wiphy->supported_freqs,
wiphy->disabled_freqs,
- NULL);
+ wiphy->no_ir_freqs);
break;
case NL80211_BAND_ATTR_RATES:
@@ -1921,6 +1924,16 @@ static void wiphy_setup_rm_enabled_capabilities(struct wiphy *wiphy)
*/
}
+static void wiphy_set_pending_freqs(struct wiphy *wiphy)
+{
+ scan_freq_set_free(wiphy->disabled_freqs);
+ scan_freq_set_free(wiphy->no_ir_freqs);
+ wiphy->disabled_freqs = wiphy->pending_disabled_freqs;
+ wiphy->no_ir_freqs = wiphy->pending_no_ir_freqs;
+ wiphy->pending_disabled_freqs = NULL;
+ wiphy->pending_no_ir_freqs = NULL;
+}
+
static void wiphy_dump_done(void *user_data)
{
struct wiphy *wiphy = user_data;
@@ -1932,9 +1945,8 @@ static void wiphy_dump_done(void *user_data)
if (wiphy) {
wiphy->dump_id = 0;
- scan_freq_set_free(wiphy->disabled_freqs);
- wiphy->disabled_freqs = wiphy->pending_freqs;
- wiphy->pending_freqs = NULL;
+
+ wiphy_set_pending_freqs(wiphy);
WATCHLIST_NOTIFY(&wiphy->state_watches,
wiphy_state_watch_func_t, wiphy,
@@ -1948,12 +1960,10 @@ static void wiphy_dump_done(void *user_data)
for (e = l_queue_get_entries(wiphy_list); e; e = e->next) {
wiphy = e->data;
- if (!wiphy->pending_freqs || wiphy->self_managed)
+ if (!wiphy->pending_disabled_freqs || wiphy->self_managed)
continue;
- scan_freq_set_free(wiphy->disabled_freqs);
- wiphy->disabled_freqs = wiphy->pending_freqs;
- wiphy->pending_freqs = NULL;
+ wiphy_set_pending_freqs(wiphy);
WATCHLIST_NOTIFY(&wiphy->state_watches,
wiphy_state_watch_func_t, wiphy,
@@ -1989,8 +1999,8 @@ static void wiphy_dump_callback(struct l_genl_msg *msg,
continue;
nl80211_parse_supported_frequencies(&attr, NULL,
- wiphy->pending_freqs,
- NULL);
+ wiphy->pending_disabled_freqs,
+ wiphy->pending_no_ir_freqs);
}
}
}
@@ -2002,15 +2012,18 @@ static bool wiphy_cancel_last_dump(struct wiphy *wiphy)
/*
* Zero command ID to signal that wiphy_dump_done doesn't need to do
- * anything. For a self-managed wiphy just free/NULL pending_freqs. For
- * a global dump each wiphy needs to be checked and dealt with.
+ * anything. For a self-managed wiphy just free/NULL
+ * pending_disabled_freqs. For a global dump each wiphy needs to be
+ * checked and dealt with.
*/
if (wiphy && wiphy->dump_id) {
id = wiphy->dump_id;
wiphy->dump_id = 0;
- scan_freq_set_free(wiphy->pending_freqs);
- wiphy->pending_freqs = NULL;
+ scan_freq_set_free(wiphy->pending_disabled_freqs);
+ scan_freq_set_free(wiphy->pending_no_ir_freqs);
+ wiphy->pending_disabled_freqs = NULL;
+ wiphy->pending_no_ir_freqs = NULL;
} else if (!wiphy && wiphy_dump_id) {
id = wiphy_dump_id;
wiphy_dump_id = 0;
@@ -2018,11 +2031,13 @@ static bool wiphy_cancel_last_dump(struct wiphy *wiphy)
for (e = l_queue_get_entries(wiphy_list); e; e = e->next) {
struct wiphy *w = e->data;
- if (!w->pending_freqs || w->self_managed)
+ if (!w->pending_disabled_freqs || w->self_managed)
continue;
- scan_freq_set_free(w->pending_freqs);
- w->pending_freqs = NULL;
+ scan_freq_set_free(w->pending_disabled_freqs);
+ scan_freq_set_free(w->pending_no_ir_freqs);
+ w->pending_disabled_freqs = NULL;
+ w->pending_no_ir_freqs = NULL;
}
}
@@ -2068,7 +2083,8 @@ static void wiphy_dump_after_regdom(struct wiphy *wiphy)
/* Limited dump so just emit the event for this wiphy */
if (wiphy) {
wiphy->dump_id = id;
- wiphy->pending_freqs = scan_freq_set_new();
+ wiphy->pending_disabled_freqs = scan_freq_set_new();
+ wiphy->pending_no_ir_freqs = scan_freq_set_new();
if (no_start_event)
return;
@@ -2088,7 +2104,8 @@ static void wiphy_dump_after_regdom(struct wiphy *wiphy)
if (w->self_managed)
continue;
- w->pending_freqs = scan_freq_set_new();
+ w->pending_disabled_freqs = scan_freq_set_new();
+ w->pending_no_ir_freqs = scan_freq_set_new();
if (no_start_event)
continue;
--
2.34.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/5] wiphy: add wiphy_get_no_ir_freqs
2022-12-08 23:48 [PATCH 1/5] nl80211util: populate no-IR list parsing frequencies James Prestwood
2022-12-08 23:48 ` [PATCH 2/5] wiphy: track no-IR frequencies James Prestwood
@ 2022-12-08 23:48 ` James Prestwood
2022-12-08 23:48 ` [PATCH 4/5] ap: add support for 5GHz frequencies in AP mode James Prestwood
2022-12-08 23:48 ` [PATCH 5/5] doc: document new AP profile key: [General].Band James Prestwood
3 siblings, 0 replies; 5+ messages in thread
From: James Prestwood @ 2022-12-08 23:48 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
Similar to supported/disabled, returns a list of frequencies which
were flagged as no-IR.
---
src/wiphy.c | 5 +++++
src/wiphy.h | 1 +
2 files changed, 6 insertions(+)
diff --git a/src/wiphy.c b/src/wiphy.c
index af0443bc..593679df 100644
--- a/src/wiphy.c
+++ b/src/wiphy.c
@@ -499,6 +499,11 @@ const struct scan_freq_set *wiphy_get_disabled_freqs(const struct wiphy *wiphy)
return wiphy->disabled_freqs;
}
+const struct scan_freq_set *wiphy_get_no_ir_freqs(const struct wiphy *wiphy)
+{
+ return wiphy->no_ir_freqs;
+}
+
bool wiphy_supports_probe_resp_offload(struct wiphy *wiphy)
{
return wiphy->ap_probe_resp_offload;
diff --git a/src/wiphy.h b/src/wiphy.h
index f8de7e0e..40aa75fa 100644
--- a/src/wiphy.h
+++ b/src/wiphy.h
@@ -99,6 +99,7 @@ uint32_t wiphy_get_supported_bands(struct wiphy *wiphy);
const struct scan_freq_set *wiphy_get_supported_freqs(
const struct wiphy *wiphy);
const struct scan_freq_set *wiphy_get_disabled_freqs(const struct wiphy *wiphy);
+const struct scan_freq_set *wiphy_get_no_ir_freqs(const struct wiphy *wiphy);
bool wiphy_supports_probe_resp_offload(struct wiphy *wiphy);
bool wiphy_can_transition_disable(struct wiphy *wiphy);
bool wiphy_can_offload(struct wiphy *wiphy);
--
2.34.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 4/5] ap: add support for 5GHz frequencies in AP mode
2022-12-08 23:48 [PATCH 1/5] nl80211util: populate no-IR list parsing frequencies James Prestwood
2022-12-08 23:48 ` [PATCH 2/5] wiphy: track no-IR frequencies James Prestwood
2022-12-08 23:48 ` [PATCH 3/5] wiphy: add wiphy_get_no_ir_freqs James Prestwood
@ 2022-12-08 23:48 ` James Prestwood
2022-12-08 23:48 ` [PATCH 5/5] doc: document new AP profile key: [General].Band James Prestwood
3 siblings, 0 replies; 5+ messages in thread
From: James Prestwood @ 2022-12-08 23:48 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
This enables IWD to use 5GHz frequencies in AP mode. Only profile
based AP's can use this feature since additional information is
needed. A new profile key [General].Band was added which is optional
and expects a string, either "2.4GHz" or "5GHz". The existing
Channel key can then be used to specify any 5GHz channel.
It should be noted that the system will probably need a regulatory
domain set in order for 5GHz to be allowed in AP mode. This is due
to world roaming (00) restricting any/all 5GHz frequencies. This
can be accomplished by setting main.conf [General].Country=CC to
the country this AP will operate in.
---
src/ap.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 83 insertions(+), 8 deletions(-)
diff --git a/src/ap.c b/src/ap.c
index 69412174..7608ab23 100644
--- a/src/ap.c
+++ b/src/ap.c
@@ -70,6 +70,7 @@ struct ap_state {
char ssid[33];
char passphrase[64];
uint8_t psk[32];
+ enum band_freq band;
uint8_t channel;
uint8_t *authorized_macs;
unsigned int authorized_macs_num;
@@ -985,7 +986,7 @@ static uint32_t ap_send_mgmt_frame(struct ap_state *ap,
frame_xchg_cb_t callback,
void *user_data)
{
- uint32_t ch_freq = band_channel_to_freq(ap->channel, BAND_FREQ_2_4_GHZ);
+ uint32_t ch_freq = band_channel_to_freq(ap->channel, ap->band);
uint64_t wdev_id = netdev_get_wdev_id(ap->netdev);
struct iovec iov[2];
@@ -2408,7 +2409,7 @@ static struct l_genl_msg *ap_build_cmd_start_ap(struct ap_state *ap)
uint32_t nl_akm = CRYPTO_AKM_PSK;
uint32_t wpa_version = NL80211_WPA_VERSION_2;
uint32_t auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
- uint32_t ch_freq = band_channel_to_freq(ap->channel, BAND_FREQ_2_4_GHZ);
+ uint32_t ch_freq = band_channel_to_freq(ap->channel, ap->band);
uint32_t ch_width = NL80211_CHAN_WIDTH_20;
unsigned int i;
@@ -3170,6 +3171,45 @@ static char **ap_ciphers_to_strv(uint16_t ciphers)
return list;
}
+static bool ap_validate_band_channel(struct ap_state *ap)
+{
+ struct wiphy *wiphy = netdev_get_wiphy(ap->netdev);
+ const struct scan_freq_set *supported;
+ const struct scan_freq_set *disabled;
+ const struct scan_freq_set *no_ir;
+ uint32_t freq;
+
+ if (!(wiphy_get_supported_bands(wiphy) & ap->band)) {
+ l_error("AP hardware does not support band");
+ return -EINVAL;
+ }
+
+ freq = band_channel_to_freq(ap->channel, ap->band);
+ if (!freq) {
+ l_error("AP invalid band (%s) and channel (%u) combination",
+ (ap->band & BAND_FREQ_5_GHZ) ? "5Ghz" : "2.4GHz",
+ ap->channel);
+ return false;
+ }
+
+ supported = wiphy_get_supported_freqs(wiphy);
+ disabled = wiphy_get_disabled_freqs(wiphy);
+ no_ir = wiphy_get_no_ir_freqs(wiphy);
+
+ if (!scan_freq_set_contains(supported, freq)) {
+ l_error("AP hardware does not support frequency %u", freq);
+ return false;
+ }
+
+ if (scan_freq_set_contains(disabled, freq) ||
+ scan_freq_set_contains(no_ir, freq)) {
+ l_error("AP hardware has frequency %u disabled or no-IR", freq);
+ return false;
+ }
+
+ return true;
+}
+
static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
bool *out_cck_rates)
{
@@ -3210,13 +3250,26 @@ static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
if (err)
return err;
+ strval = l_settings_get_string(config, "General", "Band");
+ if (strval) {
+ if (!strcmp(strval, "2.4GHz"))
+ ap->band = BAND_FREQ_2_4_GHZ;
+ else if (!strcmp(strval, "5GHz"))
+ ap->band = BAND_FREQ_5_GHZ;
+ else {
+ l_error("AP Band value unsupported: %s", strval);
+ return -EINVAL;
+ }
+
+ l_free(l_steal_ptr(strval));
+ } else
+ ap->band = BAND_FREQ_2_4_GHZ;
+
if (l_settings_has_key(config, "General", "Channel")) {
unsigned int uintval;
if (!l_settings_get_uint(config, "General", "Channel",
- &uintval) ||
- !band_channel_to_freq(uintval,
- BAND_FREQ_2_4_GHZ)) {
+ &uintval)) {
l_error("AP Channel value unsupported");
return -EINVAL;
}
@@ -3224,7 +3277,12 @@ static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
ap->channel = uintval;
} else
/* TODO: Start a Get Survey to decide the channel */
- ap->channel = 6;
+ ap->channel = (ap->band & BAND_FREQ_2_4_GHZ) ? 6 : 36;
+
+ if (!ap_validate_band_channel(ap)) {
+ l_error("AP Band and Channel combination invalid");
+ return -EINVAL;
+ }
strval = l_settings_get_string(config, "WSC", "DeviceName");
if (strval) {
@@ -3300,9 +3358,26 @@ static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
return -EINVAL;
}
+ /*
+ * If CCK Rates are used with 5GHz the AP will start but any
+ * linux-based (maybe others?) station will reject
+ * authentications and log:
+ *
+ * "No legacy rates in association response"
+ *
+ * This isn't outlined in 802.11, and a proper fix is to use
+ * the rates the hardware supports as noted by the TODO in
+ * ap_start(). For now don't allow CCK rates with 5GHz.
+ */
+ if (!boolval && (ap->band & BAND_FREQ_5_GHZ)) {
+ l_error("AP [General].NoCCKRates must be true for 5GHz "
+ " band");
+ return -EINVAL;
+ }
+
*out_cck_rates = !boolval;
} else
- *out_cck_rates = true;
+ *out_cck_rates = (ap->band & BAND_FREQ_2_4_GHZ);
cipher_mask = wiphy_get_supported_ciphers(wiphy, IE_GROUP_CIPHERS);
@@ -4080,7 +4155,7 @@ static bool ap_dbus_property_get_freq(struct l_dbus *dbus,
if (!ap_if->ap || !ap_if->ap->started)
return false;
- freq = band_channel_to_freq(ap_if->ap->channel, BAND_FREQ_2_4_GHZ);
+ freq = band_channel_to_freq(ap_if->ap->channel, ap_if->ap->band);
l_dbus_message_builder_append_basic(builder, 'u', &freq);
--
2.34.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 5/5] doc: document new AP profile key: [General].Band
2022-12-08 23:48 [PATCH 1/5] nl80211util: populate no-IR list parsing frequencies James Prestwood
` (2 preceding siblings ...)
2022-12-08 23:48 ` [PATCH 4/5] ap: add support for 5GHz frequencies in AP mode James Prestwood
@ 2022-12-08 23:48 ` James Prestwood
3 siblings, 0 replies; 5+ messages in thread
From: James Prestwood @ 2022-12-08 23:48 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
---
src/iwd.ap.rst | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/iwd.ap.rst b/src/iwd.ap.rst
index 7b8844e7..22d307e1 100644
--- a/src/iwd.ap.rst
+++ b/src/iwd.ap.rst
@@ -52,11 +52,23 @@ The group ``[General]`` contains general AP configuration.
:widths: 20 80
:align: left
+ * - Band
+ - Frequency band
+
+ Band the access point will operate on. This is optional and if omitted
+ the 2.4GHz band will be used. Value should be "2.4GHz" or "5GHz".
+
+ Note: Due to regulatory requirements the linux kernel does not allow or
+ strictly limits 5GHz use in AP mode while in world roaming. These
+ frequencies become available once the country is set, either via IWD's
+ main.conf option ``[General].Country`` (see ``man iwd.config``) or
+ externally (e.g. iw reg set <CC>).
+
* - Channel
- Channel number
- Optional channel number for the access point to operate on. Only the
- 2.4GHz-band channels are currently allowed.
+ Optional channel number for the access point to operate on. If omitted
+ the channel will be chosen automatically.
Network Authentication Settings
-------------------------------
--
2.34.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2022-12-08 23:48 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-08 23:48 [PATCH 1/5] nl80211util: populate no-IR list parsing frequencies James Prestwood
2022-12-08 23:48 ` [PATCH 2/5] wiphy: track no-IR frequencies James Prestwood
2022-12-08 23:48 ` [PATCH 3/5] wiphy: add wiphy_get_no_ir_freqs James Prestwood
2022-12-08 23:48 ` [PATCH 4/5] ap: add support for 5GHz frequencies in AP mode James Prestwood
2022-12-08 23:48 ` [PATCH 5/5] doc: document new AP profile key: [General].Band James Prestwood
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).