diff options
| author | Michael Biebl <biebl@debian.org> | 2019-09-30 13:49:20 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2019-09-30 13:49:20 +0200 |
| commit | d0425f68f7ee83a1dc5a6ad3688627c1b472a58b (patch) | |
| tree | 978af126d9871da5f3bb07ad4180b30cefa5feb6 /src | |
| parent | 555dfa331e295a3a687a7cc6870e1349ffed8f26 (diff) | |
New upstream version 1.20.4 upstream/1.20.4
Diffstat (limited to 'src')
| -rw-r--r-- | src/devices/nm-device.c | 32 | ||||
| -rw-r--r-- | src/devices/wifi/nm-device-iwd.c | 1 | ||||
| -rw-r--r-- | src/devices/wifi/nm-device-olpc-mesh.c | 53 | ||||
| -rw-r--r-- | src/devices/wifi/nm-device-wifi-p2p.c | 1 | ||||
| -rw-r--r-- | src/devices/wifi/nm-device-wifi.c | 1 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-nettools.c | 49 | ||||
| -rw-r--r-- | src/initrd/nm-initrd-generator.c | 4 | ||||
| -rw-r--r-- | src/initrd/nm-initrd-generator.h | 2 | ||||
| -rw-r--r-- | src/initrd/nmi-cmdline-reader.c | 62 | ||||
| -rw-r--r-- | src/initrd/tests/test-cmdline-reader.c | 153 | ||||
| -rw-r--r-- | src/platform/nm-linux-platform.c | 10 | ||||
| -rw-r--r-- | src/platform/wifi/nm-wifi-utils-nl80211.c | 67 | ||||
| -rw-r--r-- | src/settings/nm-settings.c | 40 | ||||
| -rw-r--r-- | src/supplicant/nm-supplicant-settings-verify.c | 2 |
14 files changed, 338 insertions, 139 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 823cf48a..67e23b8f 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -3933,12 +3933,18 @@ device_link_changed (NMDevice *self) if (priv->up && (!was_up || seen_down)) { /* the link was down and just came up. That happens for example, while changing MTU. * We must restore IP configuration. */ - if (!ip_config_merge_and_apply (self, AF_INET, TRUE)) - _LOGW (LOGD_IP4, "failed applying IP4 config after link comes up again"); + if (NM_IN_SET (priv->ip_state_4, NM_DEVICE_IP_STATE_CONF, + NM_DEVICE_IP_STATE_DONE)) { + if (!ip_config_merge_and_apply (self, AF_INET, TRUE)) + _LOGW (LOGD_IP4, "failed applying IP4 config after link comes up again"); + } priv->linklocal6_dad_counter = 0; - if (!ip_config_merge_and_apply (self, AF_INET6, TRUE)) - _LOGW (LOGD_IP6, "failed applying IP6 config after link comes up again"); + if (NM_IN_SET (priv->ip_state_6, NM_DEVICE_IP_STATE_CONF, + NM_DEVICE_IP_STATE_DONE)) { + if (!ip_config_merge_and_apply (self, AF_INET6, TRUE)) + _LOGW (LOGD_IP6, "failed applying IP6 config after link comes up again"); + } } if (update_unmanaged_specs) @@ -7733,8 +7739,8 @@ dhcp4_dad_cb (NMDevice *self, NMIP4Config **configs, gboolean success) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (success) { - nm_dhcp_client_accept (priv->dhcp4.client, NULL); - nm_device_activate_schedule_ip_config_result (self, AF_INET, NM_IP_CONFIG_CAST (configs[1])); + nm_device_activate_schedule_ip_config_result (self, AF_INET, + NM_IP_CONFIG_CAST (configs[1])); } else { nm_dhcp_client_decline (priv->dhcp4.client, "Address conflict detected", NULL); nm_device_ip_method_failed (self, AF_INET, @@ -9365,7 +9371,7 @@ _commit_mtu (NMDevice *self, const NMIP4Config *config) s_ip6 = nm_device_get_applied_setting (self, NM_TYPE_SETTING_IP6_CONFIG); if ( s_ip6 && !NM_IN_STRSET (nm_setting_ip_config_get_method (s_ip6), - NM_SETTING_IP6_CONFIG_METHOD_IGNORE + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) { /* the interface has IPv6 enabled. The MTU with IPv6 cannot be smaller * then 1280. @@ -10722,6 +10728,18 @@ activate_stage5_ip_config_result_4 (NMDevice *self) } } + if (priv->dhcp4.client) { + gs_free_error GError *error = NULL; + + if (!nm_dhcp_client_accept (priv->dhcp4.client, &error)) { + _LOGW (LOGD_DHCP4, + "Activation: Stage 5 of 5 (IPv4 Commit) error accepting lease: %s", + error->message); + nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_DHCP_ERROR); + return; + } + } + /* If IPv4 wasn't the first to complete, and DHCP was used, then ensure * dispatcher scripts get the DHCP lease information. */ diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c index 9cfe5f70..6ef9ef94 100644 --- a/src/devices/wifi/nm-device-iwd.c +++ b/src/devices/wifi/nm-device-iwd.c @@ -2061,6 +2061,7 @@ can_reapply_change (NMDevice *device, return nm_device_hash_check_invalid_keys (diffs, NM_SETTING_WIRELESS_SETTING_NAME, error, + NM_SETTING_WIRELESS_SEEN_BSSIDS, /* ignored */ NM_SETTING_WIRELESS_MTU); /* reapplied with IP config */ } diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c index 3c865c55..aa50c420 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.c +++ b/src/devices/wifi/nm-device-olpc-mesh.c @@ -82,9 +82,9 @@ get_autoconnect_allowed (NMDevice *device) NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device); NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); - /* We shall always have a companion if we're >= DISCONENCTED, and this - * ought not be called until then. */ - g_return_val_if_fail (priv->companion, FALSE); + /* We can't even connect if we don't have a companion yet. */ + if (!priv->companion) + return FALSE; /* We must not attempt to autoconnect when the companion is connected or * connecting, * because we'd tear down its connection. */ @@ -174,17 +174,28 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) return NM_ACT_STAGE_RETURN_SUCCESS; } -static void +static gboolean _mesh_set_channel (NMDeviceOlpcMesh *self, guint32 channel) { NMPlatform *platform; int ifindex = nm_device_get_ifindex (NM_DEVICE (self)); + guint32 old_channel; platform = nm_device_get_platform (NM_DEVICE (self)); - if (nm_platform_mesh_get_channel (platform, ifindex) != channel) { - if (nm_platform_mesh_set_channel (platform, ifindex, channel)) - _notify (self, PROP_ACTIVE_CHANNEL); - } + old_channel = nm_platform_mesh_get_channel (platform, ifindex); + + if (channel == 0) + channel = old_channel; + + /* We want to call this even if the channel number is the same, + * because that actually starts the mesh with the configured mesh ID. */ + if (!nm_platform_mesh_set_channel (platform, ifindex, channel)) + return FALSE; + + if (old_channel != channel) + _notify (self, PROP_ACTIVE_CHANNEL); + + return TRUE; } static NMActStageReturn @@ -192,27 +203,35 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) { NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device); NMSettingOlpcMesh *s_mesh; - guint32 channel; GBytes *ssid; const char *anycast_addr; + gboolean success; s_mesh = nm_device_get_applied_setting (device, NM_TYPE_SETTING_OLPC_MESH); g_return_val_if_fail (s_mesh, NM_ACT_STAGE_RETURN_FAILURE); - channel = nm_setting_olpc_mesh_get_channel (s_mesh); - if (channel != 0) - _mesh_set_channel (self, channel); - ssid = nm_setting_olpc_mesh_get_ssid (s_mesh); - nm_platform_mesh_set_ssid (nm_device_get_platform (device), - nm_device_get_ifindex (device), - g_bytes_get_data (ssid, NULL), - g_bytes_get_size (ssid)); + nm_device_take_down (NM_DEVICE (self), TRUE); + success = nm_platform_mesh_set_ssid (nm_device_get_platform (device), + nm_device_get_ifindex (device), + g_bytes_get_data (ssid, NULL), + g_bytes_get_size (ssid)); + nm_device_bring_up (NM_DEVICE (self), TRUE, NULL); + if (!success) { + _LOGW (LOGD_WIFI, "Unable to set the mesh ID"); + return NM_ACT_STAGE_RETURN_FAILURE; + } anycast_addr = nm_setting_olpc_mesh_get_dhcp_anycast_address (s_mesh); nm_device_set_dhcp_anycast_address (device, anycast_addr); + if (!_mesh_set_channel (self, nm_setting_olpc_mesh_get_channel (s_mesh))) { + _LOGW (LOGD_WIFI, "Unable to set the mesh channel"); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + return NM_ACT_STAGE_RETURN_SUCCESS; } diff --git a/src/devices/wifi/nm-device-wifi-p2p.c b/src/devices/wifi/nm-device-wifi-p2p.c index c5826e24..c9e6189b 100644 --- a/src/devices/wifi/nm-device-wifi-p2p.c +++ b/src/devices/wifi/nm-device-wifi-p2p.c @@ -828,6 +828,7 @@ supplicant_group_iface_state_cb (NMSupplicantInterface *iface, static void supplicant_group_iface_group_finished_cb (NMSupplicantInterface *iface, + const char *iface_path, void *user_data) { NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (user_data); diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 2ffba47a..8c80b0aa 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -3254,6 +3254,7 @@ can_reapply_change (NMDevice *device, return nm_device_hash_check_invalid_keys (diffs, NM_SETTING_WIRELESS_SETTING_NAME, error, + NM_SETTING_WIRELESS_SEEN_BSSIDS, /* ignored */ NM_SETTING_WIRELESS_MTU, /* reapplied with IP config */ NM_SETTING_WIRELESS_WAKE_ON_WLAN); } diff --git a/src/dhcp/nm-dhcp-nettools.c b/src/dhcp/nm-dhcp-nettools.c index 9a0c6906..6140a916 100644 --- a/src/dhcp/nm-dhcp-nettools.c +++ b/src/dhcp/nm-dhcp-nettools.c @@ -368,10 +368,13 @@ lease_parse_address (NDhcp4ClientLease *lease, { char addr_str[NM_UTILS_INET_ADDRSTRLEN]; const gint64 ts = nm_utils_get_monotonic_timestamp_ns (); + const gint64 ts_clock_boottime = nm_utils_monotonic_timestamp_as_boottime (ts, 1); struct in_addr a_address; struct in_addr a_netmask; guint32 a_plen; - guint64 a_lifetime; + guint64 nettools_lifetime; + gint64 a_lifetime; + gint64 a_expiry; n_dhcp4_client_lease_get_yiaddr (lease, &a_address); if (a_address.s_addr == INADDR_ANY) { @@ -380,7 +383,29 @@ lease_parse_address (NDhcp4ClientLease *lease, } /* n_dhcp4_client_lease_get_lifetime() never fails */ - n_dhcp4_client_lease_get_lifetime (lease, &a_lifetime); + n_dhcp4_client_lease_get_lifetime (lease, &nettools_lifetime); + /* FIXME: n_dhcp4_client_lease_get_lifetime() returns the time in nsec of CLOCK_BOOTTIME. + * We want to retrieve the original lifetime value in seconds, so we approximate it in a_lifetime. + * Use a nettools API to retrieve the original value as passed by the server. + */ + if (nettools_lifetime == G_MAXUINT64) { + a_lifetime = NM_PLATFORM_LIFETIME_PERMANENT; + a_expiry = NM_PLATFORM_LIFETIME_PERMANENT; + } else { + gint64 ts_time = time (NULL); + + a_lifetime = ((gint64) nettools_lifetime - ts_clock_boottime) / NM_UTILS_NS_PER_SECOND; + /* A lease time of 0 is allowed on some dhcp servers, so, let's accept it. */ + if (a_lifetime < 0) + a_lifetime = 0; + else if (a_lifetime > NM_PLATFORM_LIFETIME_PERMANENT) + a_lifetime = NM_PLATFORM_LIFETIME_PERMANENT - 1; + + if (ts_time > NM_PLATFORM_LIFETIME_PERMANENT - a_lifetime) + a_expiry = NM_PLATFORM_LIFETIME_PERMANENT - 1; + else + a_expiry = ts_time + a_lifetime; + } if (!lease_get_in_addr (lease, NM_DHCP_OPTION_DHCP4_SUBNET_MASK, &a_netmask)) { nm_utils_error_set_literal (error, NM_UTILS_ERROR_UNKNOWN, "could not get netmask from lease"); @@ -400,12 +425,20 @@ lease_parse_address (NDhcp4ClientLease *lease, NM_DHCP_OPTION_DHCP4_SUBNET_MASK, nm_utils_inet4_ntop (a_netmask.s_addr, addr_str)); - LOG_LEASE (LOGD_DHCP4, "expires in %u seconds", - (guint) ((a_lifetime - ts)/1000000000)); + LOG_LEASE (LOGD_DHCP4, "%s '%u' seconds (at %lld)", + nm_dhcp_option_request_string (_nm_dhcp_option_dhcp4_options, + NM_DHCP_OPTION_DHCP4_IP_ADDRESS_LEASE_TIME), + (guint) a_lifetime, + (long long) a_expiry); nm_dhcp_option_add_option_u64 (options, _nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_IP_ADDRESS_LEASE_TIME, - (guint64) (a_lifetime / 1000000000)); + (guint64) a_lifetime); + + nm_dhcp_option_add_option_u64 (options, + _nm_dhcp_option_dhcp4_options, + NM_DHCP_OPTION_DHCP4_NM_EXPIRY, + (guint64) a_expiry); nm_ip4_config_add_address (ip4_config, &((const NMPlatformIP4Address) { @@ -413,9 +446,9 @@ lease_parse_address (NDhcp4ClientLease *lease, .peer_address = a_address.s_addr, .plen = a_plen, .addr_source = NM_IP_CONFIG_SOURCE_DHCP, - .timestamp = ts / 1000000000, - .lifetime = (a_lifetime - ts) / 1000000000, - .preferred = (a_lifetime - ts) / 1000000000, + .timestamp = ts / NM_UTILS_NS_PER_SECOND, + .lifetime = a_lifetime, + .preferred = a_lifetime, })); return TRUE; diff --git a/src/initrd/nm-initrd-generator.c b/src/initrd/nm-initrd-generator.c index c916459d..0ff3428e 100644 --- a/src/initrd/nm-initrd-generator.c +++ b/src/initrd/nm-initrd-generator.c @@ -95,7 +95,7 @@ main (int argc, char *argv[]) int errsv; option_context = g_option_context_new ("-- [ip=...] [rd.route=...] [bridge=...] [bond=...] [team=...] [vlan=...] " - "[bootdev=...] [nameserver=...] [rd.peerdns=...] [rd.bootif=...] [BOOTIF=...] ... "); + "[bootdev=...] [nameserver=...] [rd.peerdns=...] [rd.bootif=...] [BOOTIF=...] [rd.znet=...] ... "); g_option_context_set_summary (option_context, "Generate early NetworkManager configuration."); g_option_context_set_description (option_context, @@ -127,7 +127,7 @@ main (int argc, char *argv[]) return 1; } - connections = nmi_cmdline_reader_parse (sysfs_dir, remaining); + connections = nmi_cmdline_reader_parse (sysfs_dir, (const char *const*) remaining); g_hash_table_foreach (connections, output_conn, connections_dir); g_hash_table_destroy (connections); diff --git a/src/initrd/nm-initrd-generator.h b/src/initrd/nm-initrd-generator.h index dab6fb64..7ff9a92e 100644 --- a/src/initrd/nm-initrd-generator.h +++ b/src/initrd/nm-initrd-generator.h @@ -41,6 +41,6 @@ GHashTable *nmi_ibft_read (const char *sysfs_dir); gboolean nmi_ibft_update_connection_from_nic (NMConnection *connection, GHashTable *nic, GError **error); -GHashTable *nmi_cmdline_reader_parse (const char *sysfs_dir, char **argv); +GHashTable *nmi_cmdline_reader_parse (const char *sysfs_dir, const char *const*argv); #endif /* __NM_INITRD_GENERATOR_H__ */ diff --git a/src/initrd/nmi-cmdline-reader.c b/src/initrd/nmi-cmdline-reader.c index 7a3af8d6..8ae6aa36 100644 --- a/src/initrd/nmi-cmdline-reader.c +++ b/src/initrd/nmi-cmdline-reader.c @@ -690,6 +690,43 @@ parse_rd_peerdns (GHashTable *connections, char *argument) } static void +parse_rd_znet (GHashTable *connections, char *argument) +{ + const char *nettype; + const char *subchannels[4] = { 0, 0, 0, 0 }; + const char *tmp; + NMConnection *connection; + NMSettingWired *s_wired; + + nettype = get_word (&argument, ','); + subchannels[0] = get_word (&argument, ','); + subchannels[1] = get_word (&argument, ','); + if (!nm_streq0 (nettype, "ctc")) + subchannels[2] = get_word (&argument, ','); + + connection = get_conn (connections, NULL, NM_SETTING_WIRED_SETTING_NAME); + s_wired = nm_connection_get_setting_wired (connection); + g_object_set (s_wired, + NM_SETTING_WIRED_S390_NETTYPE, nettype, + NM_SETTING_WIRED_S390_SUBCHANNELS, &subchannels, + NULL); + + while ((tmp = get_word (&argument, ',')) != NULL) { + char *val; + + val = strchr (tmp, '='); + if (val) { + gs_free char *key = NULL; + + key = g_strndup (tmp, val - tmp); + val[0] = '\0'; + val++; + nm_setting_wired_add_s390_option (s_wired, key, val); + } + } +} + +static void _normalize_conn (gpointer key, gpointer value, gpointer user_data) { NMConnection *connection = value; @@ -698,20 +735,24 @@ _normalize_conn (gpointer key, gpointer value, gpointer user_data) } GHashTable * -nmi_cmdline_reader_parse (const char *sysfs_dir, char **argv) +nmi_cmdline_reader_parse (const char *sysfs_dir, const char *const*argv) { GHashTable *connections; const char *tag; - char *argument; gboolean ignore_bootif = FALSE; gboolean neednet = FALSE; - char *bootif = NULL; + gs_free char *bootif_val = NULL; int i; connections = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_object_unref); for (i = 0; argv[i]; i++) { - argument = argv[i]; + gs_free char *argument_clone = NULL; + char *argument; + + argument_clone = g_strdup (argv[i]); + argument = argument_clone; + tag = get_word (&argument, '='); if (strcmp (tag, "ip") == 0) parse_ip (connections, sysfs_dir, argument); @@ -735,15 +776,20 @@ nmi_cmdline_reader_parse (const char *sysfs_dir, char **argv) ignore_bootif = !_nm_utils_ascii_str_to_bool (argument, TRUE); else if (strcmp (tag, "rd.neednet") == 0) neednet = _nm_utils_ascii_str_to_bool (argument, TRUE); - else if (strcasecmp (tag, "BOOTIF") == 0) - bootif = argument; + else if (strcmp (tag, "rd.znet") == 0) + parse_rd_znet (connections, argument); + else if (strcasecmp (tag, "BOOTIF") == 0) { + nm_clear_g_free (&bootif_val); + bootif_val = g_strdup (argument); + } } if (ignore_bootif) - bootif = NULL; - if (bootif) { + nm_clear_g_free (&bootif_val); + if (bootif_val) { NMConnection *connection; NMSettingWired *s_wired; + const char *bootif = bootif_val; if ( !nm_utils_hwaddr_valid (bootif, ETH_ALEN) && g_str_has_prefix (bootif, "01-") diff --git a/src/initrd/tests/test-cmdline-reader.c b/src/initrd/tests/test-cmdline-reader.c index 9bae73a2..a8a6e825 100644 --- a/src/initrd/tests/test-cmdline-reader.c +++ b/src/initrd/tests/test-cmdline-reader.c @@ -39,14 +39,14 @@ static void test_auto (void) { gs_unref_hashtable GHashTable *connections = NULL; - gs_strfreev char **argv = g_strdupv ((char *[]){ "ip=auto", NULL }); + const char *const*ARGV = NM_MAKE_STRV ("ip=auto"); NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; - connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", argv); + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); g_assert (connections); g_assert_cmpint (g_hash_table_size (connections), ==, 1); @@ -91,13 +91,13 @@ static void test_if_auto_with_mtu (void) { gs_unref_hashtable GHashTable *connections = NULL; - gs_strfreev char **argv = g_strdupv ((char *[]){ "ip=eth0:auto:1666", NULL }); + const char *const*ARGV = NM_MAKE_STRV ("ip=eth0:auto:1666"); NMConnection *connection; NMSettingWired *s_wired; NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; - connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", argv); + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); g_assert (connections); g_assert_cmpint (g_hash_table_size (connections), ==, 1); @@ -126,12 +126,12 @@ static void test_if_dhcp6 (void) { gs_unref_hashtable GHashTable *connections = NULL; - gs_strfreev char **argv = g_strdupv ((char *[]){ "ip=eth1:dhcp6", NULL }); + const char *const*ARGV = NM_MAKE_STRV ("ip=eth1:dhcp6"); NMConnection *connection; NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; - connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", argv); + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); g_assert (connections); g_assert_cmpint (g_hash_table_size (connections), ==, 1); connection = g_hash_table_lookup (connections, "eth1"); @@ -155,13 +155,13 @@ static void test_if_auto_with_mtu_and_mac (void) { gs_unref_hashtable GHashTable *connections = NULL; - gs_strfreev char **argv = g_strdupv ((char *[]){ "ip=eth2:auto6:2048:00:53:ef:12:34:56", NULL }); + const char *const*ARGV = NM_MAKE_STRV ("ip=eth2:auto6:2048:00:53:ef:12:34:56"); NMConnection *connection; NMSettingWired *s_wired; NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; - connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", argv); + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); g_assert (connections); g_assert_cmpint (g_hash_table_size (connections), ==, 1); @@ -191,16 +191,15 @@ static void test_if_ip4_manual (void) { gs_unref_hashtable GHashTable *connections = NULL; - gs_strfreev char **argv = g_strdupv ((char *[]){ - "ip=192.0.2.2::192.0.2.1:255.255.255.0:" - "hostname0.example.com:eth3::192.0.2.53", - "ip=203.0.113.2::203.0.113.1:26:" - "hostname1.example.com:eth4", NULL }); + const char *const*ARGV = NM_MAKE_STRV ("ip=192.0.2.2::192.0.2.1:255.255.255.0:" + "hostname0.example.com:eth3::192.0.2.53", + "ip=203.0.113.2::203.0.113.1:26:" + "hostname1.example.com:eth4"); NMConnection *connection; NMSettingIPConfig *s_ip4; NMIPAddress *ip_addr; - connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", argv); + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); g_assert (connections); g_assert_cmpint (g_hash_table_size (connections), ==, 2); @@ -248,16 +247,13 @@ static void test_if_ip6_manual (void) { gs_unref_hashtable GHashTable *connections = NULL; - gs_strfreev char **argv = g_strdupv ((char *[]){ - "ip=[2001:0db8::02]/64::[2001:0db8::01]::" - "hostname0.example.com:eth4::[2001:0db8::53]", - NULL - }); + const char *const*ARGV = NM_MAKE_STRV ("ip=[2001:0db8::02]/64::[2001:0db8::01]::" + "hostname0.example.com:eth4::[2001:0db8::53]"); NMConnection *connection; NMSettingIPConfig *s_ip6; NMIPAddress *ip_addr; - connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", argv); + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); g_assert (connections); g_assert_cmpint (g_hash_table_size (connections), ==, 1); @@ -286,17 +282,16 @@ static void test_multiple (void) { gs_unref_hashtable GHashTable *connections = NULL; - gs_strfreev char **argv = g_strdupv ((char *[]){ "ip=192.0.2.2:::::eth0", - "ip=[2001:db8::2]:::::eth0", - "BOOTIF=00:53:AB:cd:02:03", - NULL }); + const char *const*ARGV = NM_MAKE_STRV ("ip=192.0.2.2:::::eth0", + "ip=[2001:db8::2]:::::eth0", + "BOOTIF=00:53:AB:cd:02:03"); NMConnection *connection; NMSettingWired *s_wired; NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; NMIPAddress *ip_addr; - connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", argv); + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); g_assert (connections); g_assert_cmpint (g_hash_table_size (connections), ==, 1); @@ -332,11 +327,10 @@ static void test_some_more (void) { gs_unref_hashtable GHashTable *connections = NULL; - gs_strfreev char **argv = g_strdupv ((char *[]){ "bootdev=eth1", "hail", "nameserver=[2001:DB8:3::53]", - "satan", "nameserver=192.0.2.53", "worship", - "BOOTIF=01-00-53-AB-cd-02-03", "doom", "rd.peerdns=0", - "rd.route=[2001:DB8:3::/48]:[2001:DB8:2::1]:ens10", - NULL }); + const char *const*ARGV = NM_MAKE_STRV ("bootdev=eth1", "hail", "nameserver=[2001:DB8:3::53]", + "satan", "nameserver=192.0.2.53", "worship", + "BOOTIF=01-00-53-AB-cd-02-03", "doom", "rd.peerdns=0", + "rd.route=[2001:DB8:3::/48]:[2001:DB8:2::1]:ens10"); NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; @@ -344,7 +338,7 @@ test_some_more (void) NMSettingIPConfig *s_ip6; NMIPRoute *ip_route; - connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", argv); + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); g_assert (connections); g_assert_cmpint (g_hash_table_size (connections), ==, 2); @@ -415,9 +409,9 @@ static void test_no_bootif (void) { gs_unref_hashtable GHashTable *connections = NULL; - gs_strfreev char **argv = g_strdupv ((char *[]){ "BOOTIF=01-00-53-AB-cd-02-03", "rd.bootif=0", NULL }); + const char *const*ARGV = NM_MAKE_STRV ("BOOTIF=01-00-53-AB-cd-02-03", "rd.bootif=0"); - connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", argv); + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); g_assert (connections); g_assert_cmpint (g_hash_table_size (connections), ==, 0); } @@ -426,10 +420,9 @@ static void test_bond (void) { gs_unref_hashtable GHashTable *connections = NULL; - gs_strfreev char **argv = g_strdupv ((char *[]){ "rd.route=192.0.2.53::bong0", - "bond=bong0:eth0,eth1:mode=balance-rr", - "nameserver=203.0.113.53", - NULL }); + const char *const*ARGV = NM_MAKE_STRV ("rd.route=192.0.2.53::bong0", + "bond=bong0:eth0,eth1:mode=balance-rr", + "nameserver=203.0.113.53"); NMConnection *connection; NMSettingConnection *s_con; NMSettingIPConfig *s_ip4; @@ -438,7 +431,7 @@ test_bond (void) NMIPRoute *ip_route; const char *master_uuid; - connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", argv); + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); g_assert (connections); g_assert_cmpint (g_hash_table_size (connections), ==, 3); @@ -509,7 +502,7 @@ static void test_bond_default (void) { gs_unref_hashtable GHashTable *connections = NULL; - gs_strfreev char **argv = g_strdupv ((char *[]){ "bond", NULL }); + const char *const*ARGV = NM_MAKE_STRV ("bond"); NMConnection *connection; NMSettingConnection *s_con; NMSettingIPConfig *s_ip4; @@ -517,7 +510,7 @@ test_bond_default (void) NMSettingBond *s_bond; const char *master_uuid; - connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", argv); + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); g_assert (connections); g_assert_cmpint (g_hash_table_size (connections), ==, 2); @@ -569,7 +562,7 @@ static void test_bridge (void) { gs_unref_hashtable GHashTable *connections = NULL; - gs_strfreev char **argv = g_strdupv ((char *[]){ "bridge=bridge0:eth0,eth1", "rd.route=192.0.2.53::bridge0", NULL }); + const char *const*ARGV = NM_MAKE_STRV ("bridge=bridge0:eth0,eth1", "rd.route=192.0.2.53::bridge0"); NMConnection *connection; NMSettingConnection *s_con; NMSettingIPConfig *s_ip4; @@ -578,7 +571,7 @@ test_bridge (void) NMIPRoute *ip_route; const char *master_uuid; - connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", argv); + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); g_assert (connections); g_assert_cmpint (g_hash_table_size (connections), ==, 3); @@ -646,7 +639,7 @@ static void test_bridge_default (void) { gs_unref_hashtable GHashTable *connections = NULL; - gs_strfreev char **argv = g_strdupv ((char *[]){ "bridge", NULL }); + const char *const*ARGV = NM_MAKE_STRV ("bridge"); NMConnection *connection; NMSettingConnection *s_con; NMSettingIPConfig *s_ip4; @@ -654,7 +647,7 @@ test_bridge_default (void) NMSettingBridge *s_bridge; const char *master_uuid; - connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", argv); + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); g_assert (connections); g_assert_cmpint (g_hash_table_size (connections), ==, 2); @@ -704,7 +697,7 @@ static void test_team (void) { gs_unref_hashtable GHashTable *connections = NULL; - gs_strfreev char **argv = g_strdupv ((char *[]){ "team=team0:eth0,eth1", "ip=team0:dhcp6", NULL }); + const char *const*ARGV = NM_MAKE_STRV ("team=team0:eth0,eth1", "ip=team0:dhcp6"); NMConnection *connection; NMSettingConnection *s_con; NMSettingIPConfig *s_ip4; @@ -712,7 +705,7 @@ test_team (void) NMSettingTeam *s_team; const char *master_uuid; - connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", argv); + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); g_assert (connections); g_assert_cmpint (g_hash_table_size (connections), ==, 3); @@ -774,10 +767,10 @@ static void test_ibft (void) { gs_unref_hashtable GHashTable *connections = NULL; - gs_strfreev char **argv = g_strdupv ((char *[]){ "ip=ibft", NULL }); + const char *const*ARGV = NM_MAKE_STRV ("ip=ibft"); NMConnection *connection; - connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", argv); + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); g_assert (connections); g_assert_cmpint (g_hash_table_size (connections), ==, 2); @@ -796,13 +789,72 @@ static void test_ignore_extra (void) { gs_unref_hashtable GHashTable *connections = NULL; - gs_strfreev char **argv = g_strdupv ((char *[]){ "blabla", "extra", "lalala", NULL }); + const char *const*ARGV = NM_MAKE_STRV ("blabla", "extra", "lalala"); - connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", argv); + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); g_assert (connections); g_assert_cmpint (g_hash_table_size (connections), ==, 0); } +static void +test_rd_znet (void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const*const ARGV = NM_MAKE_STRV ("ip=10.11.12.13::10.11.12.1:24:foo.example.com:enc800:none", + "rd.znet=ctc,0.0.0800,0.0.0801,layer2=0,portno=1"); + GHashTableIter h_iter; + NMConnection *connection; + NMSettingWired *s_wired; + const char *const*v_subchannels; + const NMUtilsNamedValue s390_options[] = { + { .name = "layer2", .value_str = "0" }, + { .name = "portno", .value_str = "1" }, + }; + int i_s390_options_keys; + + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); + g_assert (connections); + g_assert_cmpint (g_hash_table_size (connections), ==, 1); + + g_hash_table_iter_init (&h_iter, connections); + if (!g_hash_table_iter_next (&h_iter, NULL, (gpointer *) &connection)) + g_assert_not_reached (); + if (g_hash_table_iter_next (&h_iter, NULL, NULL)) + g_assert_not_reached (); + + g_assert (NM_IS_CONNECTION (connection)); + s_wired = nm_connection_get_setting_wired (connection); + g_assert (NM_IS_SETTING_WIRED (s_wired)); + + v_subchannels = nm_setting_wired_get_s390_subchannels (s_wired); + g_assert (v_subchannels); + g_assert_cmpstr (v_subchannels[0], ==, "0.0.0800"); + g_assert_cmpstr (v_subchannels[1], ==, "0.0.0801"); + g_assert_cmpstr (v_subchannels[2], ==, NULL); + + g_assert_cmpint (nm_setting_wired_get_num_s390_options (s_wired), ==, G_N_ELEMENTS (s390_options)); + for (i_s390_options_keys = 0; i_s390_options_keys < G_N_ELEMENTS (s390_options); i_s390_options_keys++) { + const NMUtilsNamedValue *s390_option = &s390_options[i_s390_options_keys]; + const char *k; + const char *v; + const char *v2; + + g_assert (s390_option->name); + g_assert (s390_option->value_str); + v = nm_setting_wired_get_s390_option_by_key (s_wired, s390_option->name); + g_assert (v); + g_assert_cmpstr (v, ==, s390_option->value_str); + + if (!nm_setting_wired_get_s390_option (s_wired, i_s390_options_keys, &k, &v2)) + g_assert_not_reached (); + g_assert_cmpstr (k, ==, s390_option->name); + g_assert (v == v2); + g_assert_cmpstr (v2, ==, s390_option->value_str); + } + + nmtst_assert_connection_verifies_without_normalization (connection); +} + NMTST_DEFINE (); int main (int argc, char **argv) @@ -825,6 +877,7 @@ int main (int argc, char **argv) g_test_add_func ("/initrd/cmdline/bridge/default", test_bridge_default); g_test_add_func ("/initrd/cmdline/ibft", test_ibft); g_test_add_func ("/initrd/cmdline/ignore_extra", test_ignore_extra); + g_test_add_func ("/initrd/cmdline/rd_zdnet", test_rd_znet); return g_test_run (); } diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index e2e1e581..d222527d 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -2879,19 +2879,11 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr && obj->_link.ext_data == NULL) { switch (obj->link.type) { case NM_LINK_TYPE_WIFI: + case NM_LINK_TYPE_OLPC_MESH: obj->_link.ext_data = (GObject *) nm_wifi_utils_new (ifi->ifi_index, _genl_sock (NM_LINUX_PLATFORM (platform)), TRUE); break; - case NM_LINK_TYPE_OLPC_MESH: -#if HAVE_WEXT - /* The kernel driver now uses nl80211, but we force use of WEXT because - * the cfg80211 interactions are not quite ready to support access to - * mesh control through nl80211 just yet. - */ - obj->_link.ext_data = (GObject *) nm_wifi_utils_wext_new (ifi->ifi_index, FALSE); -#endif - break; case NM_LINK_TYPE_WPAN: obj->_link.ext_data = (GObject *) nm_wpan_utils_new (ifi->ifi_index, _genl_sock (NM_LINUX_PLATFORM (platform)), diff --git a/src/platform/wifi/nm-wifi-utils-nl80211.c b/src/platform/wifi/nm-wifi-utils-nl80211.c index 84a93f4f..36901f83 100644 --- a/src/platform/wifi/nm-wifi-utils-nl80211.c +++ b/src/platform/wifi/nm-wifi-utils-nl80211.c @@ -706,6 +706,7 @@ struct nl80211_device_info { int phy; guint32 *freqs; int num_freqs; + guint32 freq; guint32 caps; gboolean can_scan; gboolean can_scan_ssid; @@ -767,6 +768,11 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg) info->phy = nla_get_u32 (tb[NL80211_ATTR_WIPHY]); + if (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]) { info->can_scan_ssid = nla_get_u8 (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]) > 0; @@ -912,6 +918,64 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg) return NL_SKIP; } +static guint32 +wifi_nl80211_get_mesh_channel (NMWifiUtils *data) +{ + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; + nm_auto_nlmsg struct nl_msg *msg = NULL; + struct nl80211_device_info device_info = { .self = self }; + int i; + + msg = nl80211_alloc_msg (self, NL80211_CMD_GET_WIPHY, 0); + + if (nl80211_send_and_recv (self, msg, nl80211_wiphy_info_handler, + &device_info) < 0) { + _LOGW ("NL80211_CMD_GET_WIPHY request failed"); + return 0; + } + + for (i = 0; i < self->num_freqs; i++) { + if (device_info.freq == self->freqs[i]) + return i + 1; + } + return 0; +} + +static gboolean +wifi_nl80211_set_mesh_channel (NMWifiUtils *data, guint32 channel) +{ + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; + nm_auto_nlmsg struct nl_msg *msg = NULL; + int err; + + if (channel > self->num_freqs) + return FALSE; + + msg = nl80211_alloc_msg (self, NL80211_CMD_SET_WIPHY, 0); + NLA_PUT_U32 (msg, NL80211_ATTR_WIPHY_FREQ, self->freqs[channel - 1]); + err = nl80211_send_and_recv (self, msg, NULL, NULL); + return err >= 0; + +nla_put_failure: + g_return_val_if_reached (FALSE); +} + +static gboolean +wifi_nl80211_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len) +{ + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; + nm_auto_nlmsg struct nl_msg *msg = NULL; + int err; + + msg = nl80211_alloc_msg (self, NL80211_CMD_SET_INTERFACE, 0); + NLA_PUT (msg, NL80211_ATTR_MESH_ID, len, ssid); + err = nl80211_send_and_recv (self, msg, NULL, NULL); + return err >= 0; + +nla_put_failure: + g_return_val_if_reached (FALSE); +} + static void nm_wifi_utils_nl80211_init (NMWifiUtilsNl80211 *self) { @@ -936,6 +1000,9 @@ nm_wifi_utils_nl80211_class_init (NMWifiUtilsNl80211Class *klass) wifi_utils_class->get_rate = wifi_nl80211_get_rate; wifi_utils_class->get_qual = wifi_nl80211_get_qual; wifi_utils_class->indicate_addressing_running = wifi_nl80211_indicate_addressing_running; + wifi_utils_class->get_mesh_channel = wifi_nl80211_get_mesh_channel; + wifi_utils_class->set_mesh_channel = wifi_nl80211_set_mesh_channel; + wifi_utils_class->set_mesh_ssid = wifi_nl80211_set_mesh_ssid; } NMWifiUtils * diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 4bdcb522..6529cc58 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -3379,26 +3379,13 @@ static gboolean have_connection_for_device (NMSettings *self, NMDevice *device) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - NMSettingWired *s_wired; - const char *setting_hwaddr; - const char *perm_hw_addr; NMSettingsConnection *sett_conn; g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); - perm_hw_addr = nm_device_get_permanent_hw_address (device); - - /* Find a wired connection locked to the given MAC address, if any */ + /* Find a wired connection matching for the device, if any */ c_list_for_each_entry (sett_conn, &priv->connections_lst_head, _connections_lst) { NMConnection *connection = nm_settings_connection_get_connection (sett_conn); - NMSettingConnection *s_con = nm_connection_get_setting_connection (connection); - const char *ctype; - const char *iface; - - ctype = nm_setting_connection_get_connection_type (s_con); - if (!NM_IN_STRSET (ctype, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_PPPOE_SETTING_NAME)) - continue; if (!nm_device_check_connection_compatible (device, connection, NULL)) continue; @@ -3410,27 +3397,7 @@ have_connection_for_device (NMSettings *self, NMDevice *device) NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE)) continue; - iface = nm_setting_connection_get_interface_name (s_con); - if (!nm_streq0 (iface, nm_device_get_iface (device))) - continue; - - s_wired = nm_connection_get_setting_wired (connection); - if ( !s_wired - && nm_streq (ctype, NM_SETTING_PPPOE_SETTING_NAME)) { - /* No wired setting; therefore the PPPoE connection applies to any device */ - return TRUE; - } - - setting_hwaddr = nm_setting_wired_get_mac_address (s_wired); - if (setting_hwaddr) { - /* A connection mac-locked to this device */ - if ( perm_hw_addr - && nm_utils_hwaddr_matches (setting_hwaddr, -1, perm_hw_addr, -1)) - return TRUE; - } else { - /* A connection that applies to any wired device */ - return TRUE; - } + return TRUE; } /* See if there's a known non-NetworkManager configuration for the device */ @@ -3486,7 +3453,8 @@ device_realized (NMDevice *device, GParamSpec *pspec, NMSettings *self) /* If the device isn't managed or it already has a default wired connection, * ignore it. */ - if ( !nm_device_get_managed (device, FALSE) + if ( !NM_DEVICE_GET_CLASS (device)->new_default_connection + || !nm_device_get_managed (device, FALSE) || g_object_get_qdata (G_OBJECT (device), _default_wired_connection_quark ()) || have_connection_for_device (self, device) || nm_config_get_no_auto_default_for_device (priv->config, device)) diff --git a/src/supplicant/nm-supplicant-settings-verify.c b/src/supplicant/nm-supplicant-settings-verify.c index b37fae9e..25cc0bc6 100644 --- a/src/supplicant/nm-supplicant-settings-verify.c +++ b/src/supplicant/nm-supplicant-settings-verify.c @@ -69,7 +69,7 @@ static const char *const proto_allowed[] = { "WPA", "RSN", NULL }; static const char *const key_mgmt_allowed[] = { "WPA-PSK", "WPA-PSK-SHA256", "FT-PSK", "WPA-EAP", "WPA-EAP-SHA256", "FT-EAP", "FT-EAP-SHA384", "FILS-SHA256", "FILS-SHA384", - "IEEE8021X", "WPA-NONE", "SAE", + "IEEE8021X", "WPA-NONE", "SAE", "FT-SAE", "NONE", NULL }; static const char *const auth_alg_allowed[] = { "OPEN", "SHARED", "LEAP", NULL }; static const char *const eap_allowed[] = { "LEAP", "MD5", "TLS", "PEAP", "TTLS", "SIM", |