mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-04 15:21:12 +00:00
wifi: fix enumeration of 6 GHz channels from wiphy
Command NL80211_CMD_GET_WIPHY without any flag only returns channels in the 2 GHz and 5 GHz bands, for backwards compatibility with old userspace tools. To get the full list we need to pass attribute NL80211_ATTR_SPLIT_WIPHY_DUMP (added in Linux 3.9 released in 2013), and allow the handler to be called multiple times. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/1500
This commit is contained in:
parent
8ca7433a14
commit
4cd4ab518e
1
NEWS
1
NEWS
|
@ -15,6 +15,7 @@ USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE!
|
||||||
visible in nmcli via "nmcli -f all device show $DEV".
|
visible in nmcli via "nmcli -f all device show $DEV".
|
||||||
* Deprecated 802-11-wireless and 802-11-wired property 'mac-address-blacklist'
|
* Deprecated 802-11-wireless and 802-11-wired property 'mac-address-blacklist'
|
||||||
and introduced the 'mac-address-denylist' property.
|
and introduced the 'mac-address-denylist' property.
|
||||||
|
* Fix detection of 6 GHz band capability for WiFi devices
|
||||||
|
|
||||||
=============================================
|
=============================================
|
||||||
NetworkManager-1.46
|
NetworkManager-1.46
|
||||||
|
|
|
@ -567,6 +567,7 @@ struct nl80211_device_info {
|
||||||
int phy;
|
int phy;
|
||||||
Nl80211Freq *freqs;
|
Nl80211Freq *freqs;
|
||||||
int num_freqs;
|
int num_freqs;
|
||||||
|
int num_freqs_alloc;
|
||||||
guint32 freq;
|
guint32 freq;
|
||||||
guint32 caps;
|
guint32 caps;
|
||||||
gboolean can_scan;
|
gboolean can_scan;
|
||||||
|
@ -610,7 +611,6 @@ nl80211_wiphy_info_handler(const struct nl_msg *msg, void *arg)
|
||||||
struct nlattr *nl_freq;
|
struct nlattr *nl_freq;
|
||||||
int rem_freq;
|
int rem_freq;
|
||||||
int rem_band;
|
int rem_band;
|
||||||
guint num_alloc;
|
|
||||||
|
|
||||||
#ifdef NL80211_FREQUENCY_ATTR_NO_IR
|
#ifdef NL80211_FREQUENCY_ATTR_NO_IR
|
||||||
G_STATIC_ASSERT_EXPR(NL80211_FREQUENCY_ATTR_PASSIVE_SCAN == NL80211_FREQUENCY_ATTR_NO_IR
|
G_STATIC_ASSERT_EXPR(NL80211_FREQUENCY_ATTR_PASSIVE_SCAN == NL80211_FREQUENCY_ATTR_NO_IR
|
||||||
|
@ -622,22 +622,16 @@ nl80211_wiphy_info_handler(const struct nl_msg *msg, void *arg)
|
||||||
if (nla_parse_arr(tb, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL) < 0)
|
if (nla_parse_arr(tb, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL) < 0)
|
||||||
return NL_SKIP;
|
return NL_SKIP;
|
||||||
|
|
||||||
if (tb[NL80211_ATTR_WIPHY] == NULL || tb[NL80211_ATTR_WIPHY_BANDS] == NULL)
|
if (!tb[NL80211_ATTR_WIPHY])
|
||||||
return NL_SKIP;
|
return NL_SKIP;
|
||||||
|
|
||||||
info->phy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
|
info->phy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
|
||||||
|
|
||||||
if (tb[NL80211_ATTR_WIPHY_FREQ])
|
if (tb[NL80211_ATTR_WIPHY_FREQ])
|
||||||
info->freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
|
info->freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
|
||||||
else
|
|
||||||
info->freq = 0;
|
|
||||||
|
|
||||||
if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]) {
|
if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])
|
||||||
info->can_scan_ssid = nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]) > 0;
|
info->can_scan_ssid = nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]) > 0;
|
||||||
} else {
|
|
||||||
/* old kernel that only had mac80211, so assume it can */
|
|
||||||
info->can_scan_ssid = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tb[NL80211_ATTR_SUPPORTED_COMMANDS]) {
|
if (tb[NL80211_ATTR_SUPPORTED_COMMANDS]) {
|
||||||
struct nlattr *nl_cmd;
|
struct nlattr *nl_cmd;
|
||||||
|
@ -664,15 +658,22 @@ nl80211_wiphy_info_handler(const struct nl_msg *msg, void *arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tb[NL80211_ATTR_WIPHY_BANDS]) {
|
||||||
/* Read supported frequencies */
|
/* Read supported frequencies */
|
||||||
num_alloc = 32;
|
|
||||||
|
if (!info->freqs) {
|
||||||
info->num_freqs = 0;
|
info->num_freqs = 0;
|
||||||
info->freqs = g_new(Nl80211Freq, num_alloc);
|
info->num_freqs_alloc = 32;
|
||||||
|
info->freqs = g_new(Nl80211Freq, info->num_freqs_alloc);
|
||||||
|
}
|
||||||
|
|
||||||
nla_for_each_nested (nl_band, tb[NL80211_ATTR_WIPHY_BANDS], rem_band) {
|
nla_for_each_nested (nl_band, tb[NL80211_ATTR_WIPHY_BANDS], rem_band) {
|
||||||
if (nla_parse_nested_arr(tb_band, nl_band, NULL) < 0)
|
if (nla_parse_nested_arr(tb_band, nl_band, NULL) < 0)
|
||||||
return NL_SKIP;
|
return NL_SKIP;
|
||||||
|
|
||||||
|
if (!tb_band[NL80211_BAND_ATTR_FREQS])
|
||||||
|
continue;
|
||||||
|
|
||||||
nla_for_each_nested (nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) {
|
nla_for_each_nested (nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) {
|
||||||
Nl80211Freq *f;
|
Nl80211Freq *f;
|
||||||
|
|
||||||
|
@ -682,9 +683,9 @@ nl80211_wiphy_info_handler(const struct nl_msg *msg, void *arg)
|
||||||
if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
|
if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (info->num_freqs >= num_alloc) {
|
if (info->num_freqs >= info->num_freqs_alloc) {
|
||||||
num_alloc *= 2;
|
info->num_freqs_alloc *= 2;
|
||||||
info->freqs = g_renew(Nl80211Freq, info->freqs, num_alloc);
|
info->freqs = g_renew(Nl80211Freq, info->freqs, info->num_freqs_alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
f = &info->freqs[info->num_freqs];
|
f = &info->freqs[info->num_freqs];
|
||||||
|
@ -706,8 +707,7 @@ nl80211_wiphy_info_handler(const struct nl_msg *msg, void *arg)
|
||||||
info->num_freqs++;
|
info->num_freqs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
info->freqs = g_renew(Nl80211Freq, info->freqs, info->num_freqs);
|
|
||||||
|
|
||||||
/* Read security/encryption support */
|
/* Read security/encryption support */
|
||||||
if (tb[NL80211_ATTR_CIPHER_SUITES]) {
|
if (tb[NL80211_ATTR_CIPHER_SUITES]) {
|
||||||
|
@ -874,7 +874,10 @@ nm_wifi_utils_nl80211_new(struct nl_sock *genl, guint16 genl_family_id, int ifin
|
||||||
|
|
||||||
self->phy = -1;
|
self->phy = -1;
|
||||||
|
|
||||||
msg = nl80211_alloc_msg(self, NL80211_CMD_GET_WIPHY, 0);
|
msg = nl80211_alloc_msg(self, NL80211_CMD_GET_WIPHY, NLM_F_DUMP);
|
||||||
|
NLA_PUT_FLAG(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
|
||||||
|
|
||||||
|
device_info.can_scan_ssid = TRUE;
|
||||||
|
|
||||||
device_info.self = self;
|
device_info.self = self;
|
||||||
if (nl80211_send_and_recv(self, msg, nl80211_wiphy_info_handler, &device_info) < 0) {
|
if (nl80211_send_and_recv(self, msg, nl80211_wiphy_info_handler, &device_info) < 0) {
|
||||||
|
@ -882,6 +885,10 @@ nm_wifi_utils_nl80211_new(struct nl_sock *genl, guint16 genl_family_id, int ifin
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (device_info.freqs) {
|
||||||
|
device_info.freqs = g_renew(Nl80211Freq, device_info.freqs, device_info.num_freqs);
|
||||||
|
}
|
||||||
|
|
||||||
if (!device_info.success) {
|
if (!device_info.success) {
|
||||||
_LOGD("NL80211_CMD_GET_WIPHY request indicated failure");
|
_LOGD("NL80211_CMD_GET_WIPHY request indicated failure");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -915,4 +922,7 @@ nm_wifi_utils_nl80211_new(struct nl_sock *genl, guint16 genl_family_id, int ifin
|
||||||
|
|
||||||
_LOGD("using nl80211 for Wi-Fi device control");
|
_LOGD("using nl80211 for Wi-Fi device control");
|
||||||
return (NMWifiUtils *) g_steal_pointer(&self);
|
return (NMWifiUtils *) g_steal_pointer(&self);
|
||||||
|
|
||||||
|
nla_put_failure:
|
||||||
|
g_return_val_if_reached(NULL);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue