From 4b097e314e3186a6d5327c194907e5bf4737125e Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 2 Jul 2019 09:31:46 +0200 Subject: [PATCH 1/6] initrd: fix error reporting on bad netmask It says the address is bad, but what is wrong is the mask. --- src/initrd/nmi-cmdline-reader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/initrd/nmi-cmdline-reader.c b/src/initrd/nmi-cmdline-reader.c index d8b32f8623..1c53d4147f 100644 --- a/src/initrd/nmi-cmdline-reader.c +++ b/src/initrd/nmi-cmdline-reader.c @@ -273,7 +273,7 @@ parse_ip (GHashTable *connections, const char *sysfs_dir, char *argument) if (nm_utils_parse_inaddr_bin (AF_INET, netmask, NULL, &addr)) { client_ip_prefix = nm_utils_ip4_netmask_to_prefix (addr.addr4); } else { - _LOGW (LOGD_CORE, "Unrecognized address: %s", client_ip); + _LOGW (LOGD_CORE, "Invalid IP mask: %s", netmask); } } From 920e59016f8827ee006b168a7e189730116ea784 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 2 Jul 2019 09:33:20 +0200 Subject: [PATCH 2/6] initrd: remove an accidental backspace --- src/initrd/nm-initrd-generator.c | 2 +- src/initrd/nmi-cmdline-reader.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/initrd/nm-initrd-generator.c b/src/initrd/nm-initrd-generator.c index 4c1c4037b1..c916459d5c 100644 --- a/src/initrd/nm-initrd-generator.c +++ b/src/initrd/nm-initrd-generator.c @@ -66,7 +66,7 @@ output_conn (gpointer key, gpointer value, gpointer user_data) if (!nm_utils_file_set_contents (full_filename, data, len, 0600, &error)) goto err_out; } else - g_print ("\n*** Connection '%s' ***\n\n%s\n", basename, data); + g_print ("\n*** Connection '%s' ***\n\n%s", basename, data); return; err_out: diff --git a/src/initrd/nmi-cmdline-reader.c b/src/initrd/nmi-cmdline-reader.c index 1c53d4147f..5bc1f4bdef 100644 --- a/src/initrd/nmi-cmdline-reader.c +++ b/src/initrd/nmi-cmdline-reader.c @@ -398,7 +398,7 @@ parse_ip (GHashTable *connections, const char *sysfs_dir, char *argument) } if (peer && *peer) - _LOGW (LOGD_CORE, "Ignoring peer: %s (not implemented)\b", peer); + _LOGW (LOGD_CORE, "Ignoring peer: %s (not implemented)\n", peer); if (gateway_ip && *gateway_ip) { int addr_family = guess_ip_address_family (gateway_ip); From 390d79079eeabe6879f19ee9afee7ca8e1c6b778 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 2 Jul 2019 09:45:22 +0200 Subject: [PATCH 3/6] initrd: allow specifying the net mask in form of a prefix This is not documented in dracut.cmdline(7), however it seems to have worked and has users and Red Hat even seems to recommend this (thanks to Dan Horak for the pointers): https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/installation_guide/chap-installer-booting-ipl-s390 https://bugzilla.redhat.com/show_bug.cgi?id=1725872 --- src/initrd/nmi-cmdline-reader.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/initrd/nmi-cmdline-reader.c b/src/initrd/nmi-cmdline-reader.c index 5bc1f4bdef..a7fffd19b3 100644 --- a/src/initrd/nmi-cmdline-reader.c +++ b/src/initrd/nmi-cmdline-reader.c @@ -270,11 +270,13 @@ parse_ip (GHashTable *connections, const char *sysfs_dir, char *argument) if (netmask && *netmask) { NMIPAddr addr; - if (nm_utils_parse_inaddr_bin (AF_INET, netmask, NULL, &addr)) { + if (nm_utils_parse_inaddr_bin (AF_INET, netmask, NULL, &addr)) client_ip_prefix = nm_utils_ip4_netmask_to_prefix (addr.addr4); - } else { + else + client_ip_prefix = _nm_utils_ascii_str_to_int64 (netmask, 10, 0, 32, -1); + + if (client_ip_prefix == -1) _LOGW (LOGD_CORE, "Invalid IP mask: %s", netmask); - } } /* Static IP configuration might be present. */ From 77540b2a7cf1a73fa944ccabd73aa8881d898f04 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 2 Jul 2019 10:28:19 +0200 Subject: [PATCH 4/6] initrd/tests: ensure we accept a prefix in place of an IPv4 mask --- src/initrd/tests/test-cmdline-reader.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/initrd/tests/test-cmdline-reader.c b/src/initrd/tests/test-cmdline-reader.c index 1a87505aec..d135aebaa4 100644 --- a/src/initrd/tests/test-cmdline-reader.c +++ b/src/initrd/tests/test-cmdline-reader.c @@ -193,14 +193,16 @@ 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", NULL }); + "hostname0.example.com:eth3::192.0.2.53", + "ip=203.0.113.2::203.0.113.1:26:" + "hostname1.example.com:eth4", NULL }); NMConnection *connection; NMSettingIPConfig *s_ip4; NMIPAddress *ip_addr; connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", argv); g_assert (connections); - g_assert_cmpint (g_hash_table_size (connections), ==, 1); + g_assert_cmpint (g_hash_table_size (connections), ==, 2); connection = g_hash_table_lookup (connections, "eth3"); g_assert (connection); @@ -221,8 +223,26 @@ test_if_ip4_manual (void) g_assert_cmpint (nm_ip_address_get_prefix (ip_addr), ==, 24); g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.0.2.1"); g_assert_cmpstr (nm_setting_ip_config_get_dhcp_hostname (s_ip4), ==, "hostname0.example.com"); -} + connection = g_hash_table_lookup (connections, "eth4"); + g_assert (connection); + nmtst_assert_connection_verifies_without_normalization (connection); + g_assert_cmpstr (nm_connection_get_id (connection), ==, "eth4"); + + s_ip4 = nm_connection_get_setting_ip4_config (connection); + g_assert (s_ip4); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + g_assert (!nm_setting_ip_config_get_ignore_auto_dns (s_ip4)); + g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 0); + g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip4), ==, 0); + g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 1); + ip_addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert (ip_addr); + g_assert_cmpstr (nm_ip_address_get_address (ip_addr), ==, "203.0.113.2"); + g_assert_cmpint (nm_ip_address_get_prefix (ip_addr), ==, 26); + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "203.0.113.1"); + g_assert_cmpstr (nm_setting_ip_config_get_dhcp_hostname (s_ip4), ==, "hostname1.example.com"); +} static void test_if_ip6_manual (void) From 6da2058237a40e26fd2e636abe5b74e55204a7b6 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 2 Jul 2019 10:03:00 +0200 Subject: [PATCH 5/6] initrd: don't create a default connection if there's already one Certain arguments (such as "nameserver") don't specify a connection they apply to and using them would generate a default ethernet connection. This is probably not the right thing to do. --- src/initrd/nmi-cmdline-reader.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/initrd/nmi-cmdline-reader.c b/src/initrd/nmi-cmdline-reader.c index a7fffd19b3..b79b43fe42 100644 --- a/src/initrd/nmi-cmdline-reader.c +++ b/src/initrd/nmi-cmdline-reader.c @@ -32,6 +32,20 @@ /*****************************************************************************/ +static gboolean +_connection_matches_type (gpointer key, gpointer value, gpointer user_data) +{ + NMConnection *connection = value; + const char *type_name = user_data; + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection (connection); + if (type_name == NULL) + return nm_setting_connection_get_master (s_con) == NULL; + else + return strcmp (nm_setting_connection_get_connection_type (s_con), type_name) == 0; +} + static NMConnection * get_conn (GHashTable *connections, const char *ifname, const char *type_name) { @@ -49,7 +63,18 @@ get_conn (GHashTable *connections, const char *ifname, const char *type_name) multi_connect = NM_CONNECTION_MULTI_CONNECT_MULTIPLE; } - connection = g_hash_table_lookup (connections, (gpointer)basename); + connection = g_hash_table_lookup (connections, (gpointer) basename); + if (!connection && !ifname) { + /* + * If ifname was not given, we'll match the connection by type. + * If the type was not given either, then we're happy with any connection but slaves. + * This is so that things like "bond=bond0:eth1,eth2 nameserver=1.3.3.7 end up + * slapping the nameserver to the most reasonable connection (bond0). + */ + connection = g_hash_table_find (connections, + _connection_matches_type, + (gpointer) type_name); + } if (connection) { setting = (NMSetting *)nm_connection_get_setting_connection (connection); @@ -658,7 +683,6 @@ parse_rd_peerdns (GHashTable *connections, char *argument) NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, auto_dns, NULL); - s_ip = nm_connection_get_setting_ip6_config (connection); g_object_set (s_ip, NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, auto_dns, From 39d5c8c12f0d4bf4aa5d16c564e4b11487ed4ec3 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 2 Jul 2019 10:20:10 +0200 Subject: [PATCH 6/6] initrd/tests: ensure that nameserver= setting affects the correct connection --- src/initrd/tests/test-cmdline-reader.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/initrd/tests/test-cmdline-reader.c b/src/initrd/tests/test-cmdline-reader.c index d135aebaa4..798efbfa6a 100644 --- a/src/initrd/tests/test-cmdline-reader.c +++ b/src/initrd/tests/test-cmdline-reader.c @@ -418,7 +418,10 @@ 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", 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 }); NMConnection *connection; NMSettingConnection *s_con; NMSettingIPConfig *s_ip4; @@ -443,7 +446,8 @@ test_bond (void) g_assert (s_ip4); g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); g_assert (!nm_setting_ip_config_get_ignore_auto_dns (s_ip4)); - g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 0); + g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 1); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 0), ==, "203.0.113.53"); g_assert (!nm_setting_ip_config_get_gateway (s_ip4)); g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip4), ==, 1); ip_route = nm_setting_ip_config_get_route (s_ip4, 0);