233 lines
8.9 KiB
Diff
233 lines
8.9 KiB
Diff
From aaf22cfa2ac38f786faab16d027c29616c9f9385 Mon Sep 17 00:00:00 2001
|
|
From: Beniamino Galvani <bgalvani@redhat.com>
|
|
Date: Wed, 25 Nov 2020 17:39:48 +0100
|
|
Subject: [PATCH 1/1] initrd: fix parsing of ip= arguments with empty first
|
|
token
|
|
|
|
The parser checks if the first token of an ip= argument is an IP
|
|
address to determine which of the two possible syntaxes is used:
|
|
|
|
ip=<interface>:{dhcp|on|any|dhcp6|auto6}[:[<mtu>][:<macaddr>]]
|
|
ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<interface>:{none|off|dhcp|on|any|dhcp6|auto6|ibft}[:[<mtu>][:<macaddr>]]
|
|
|
|
This works as long as the first token is not empty, which - according
|
|
to the dracut.cmdline man page - seems to be guaranteed.
|
|
|
|
However, the network-legacy dracut plugin accepts an empty interface
|
|
or client IP. Also, if a user needs DHCP and wants to specify a
|
|
hostname, the only possible syntax is:
|
|
|
|
ip=::::<hostname>::dhcp
|
|
|
|
Change the parser to check the second token instead, similarly to what
|
|
the network-legacy module does [1].
|
|
|
|
[1] https://github.com/dracutdevs/dracut/blob/050/modules.d/40network/net-lib.sh#L490
|
|
|
|
https://bugzilla.redhat.com/show_bug.cgi?id=1900260
|
|
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/693
|
|
(cherry picked from commit b0c018830e7884e7457b8ea44553946ff680eb89)
|
|
(cherry picked from commit 435d662669cf487abe91c31b94ac71239073ce98)
|
|
(cherry picked from commit d67d0a34950fb44d66aea9e45c1d09b82fcaa18b)
|
|
Signed-off-by: Antonio Cardace <acardace@redhat.com>
|
|
---
|
|
src/initrd/nmi-cmdline-reader.c | 37 ++++++---
|
|
src/initrd/tests/test-cmdline-reader.c | 100 ++++++++++++++++++++++++-
|
|
2 files changed, 126 insertions(+), 11 deletions(-)
|
|
|
|
diff --git a/src/initrd/nmi-cmdline-reader.c b/src/initrd/nmi-cmdline-reader.c
|
|
index f94cc7db8..17e0ce5d4 100644
|
|
--- a/src/initrd/nmi-cmdline-reader.c
|
|
+++ b/src/initrd/nmi-cmdline-reader.c
|
|
@@ -367,6 +367,7 @@ reader_parse_ip (Reader *reader, const char *sysfs_dir, char *argument)
|
|
NMSettingIPConfig *s_ip4 = NULL, *s_ip6 = NULL;
|
|
gs_unref_hashtable GHashTable *ibft = NULL;
|
|
const char *tmp;
|
|
+ const char *tmp2;
|
|
const char *kind = NULL;
|
|
const char *client_ip = NULL;
|
|
const char *peer = NULL;
|
|
@@ -391,17 +392,37 @@ reader_parse_ip (Reader *reader, const char *sysfs_dir, char *argument)
|
|
/* ip={dhcp|on|any|dhcp6|auto6|ibft} */
|
|
kind = tmp;
|
|
} else {
|
|
- client_ip_family = get_ip_address_family (tmp, TRUE);
|
|
- if (client_ip_family != AF_UNSPEC) {
|
|
- /* <client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>: */
|
|
+ tmp2 = get_word (&argument, ':');
|
|
+ if (NM_IN_STRSET (tmp2,
|
|
+ "none",
|
|
+ "off",
|
|
+ "dhcp",
|
|
+ "on"
|
|
+ "any",
|
|
+ "dhcp6",
|
|
+ "auto",
|
|
+ "auto6",
|
|
+ "ibft")) {
|
|
+ /* <ifname>:{none|off|dhcp|on|any|dhcp6|auto|auto6|ibft} */
|
|
+ iface_spec = tmp;
|
|
+ kind = tmp2;
|
|
+ } else {
|
|
+ /* <client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<kind> */
|
|
client_ip = tmp;
|
|
- peer = get_word (&argument, ':');
|
|
+ if (client_ip) {
|
|
+ client_ip_family = get_ip_address_family (client_ip, TRUE);
|
|
+ if (client_ip_family == AF_UNSPEC) {
|
|
+ _LOGW (LOGD_CORE, "Invalid IP address '%s'.", client_ip);
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ peer = tmp2;
|
|
gateway_ip = get_word (&argument, ':');
|
|
netmask = get_word (&argument, ':');
|
|
client_hostname = get_word (&argument, ':');
|
|
iface_spec = get_word (&argument, ':');
|
|
- } else {
|
|
- iface_spec = tmp;
|
|
+ kind = get_word (&argument, ':');
|
|
}
|
|
|
|
if (client_hostname && !nm_sd_hostname_is_valid (client_hostname, FALSE))
|
|
@@ -412,10 +433,6 @@ reader_parse_ip (Reader *reader, const char *sysfs_dir, char *argument)
|
|
reader->hostname = g_strdup (client_hostname);
|
|
}
|
|
|
|
- /* <ifname>:{none|off|dhcp|on|any|dhcp6|auto6|ibft} */
|
|
-
|
|
- kind = get_word (&argument, ':');
|
|
-
|
|
tmp = get_word (&argument, ':');
|
|
dns_addr_family[0] = get_ip_address_family (tmp, FALSE);
|
|
if (dns_addr_family[0] != AF_UNSPEC) {
|
|
diff --git a/src/initrd/tests/test-cmdline-reader.c b/src/initrd/tests/test-cmdline-reader.c
|
|
index b9d2acf41..f5c1a1422 100644
|
|
--- a/src/initrd/tests/test-cmdline-reader.c
|
|
+++ b/src/initrd/tests/test-cmdline-reader.c
|
|
@@ -75,6 +75,103 @@ test_auto (void)
|
|
g_assert (!nm_setting_ip_config_get_gateway (s_ip6));
|
|
}
|
|
|
|
+static void
|
|
+test_dhcp_with_hostname (void)
|
|
+{
|
|
+ gs_unref_hashtable GHashTable *connections = NULL;
|
|
+ const char *const *ARGV = NM_MAKE_STRV ("ip=::::host1::dhcp");
|
|
+ NMConnection *connection;
|
|
+ NMSettingConnection *s_con;
|
|
+ NMSettingWired *s_wired;
|
|
+ NMSettingIPConfig *s_ip4;
|
|
+ NMSettingIPConfig *s_ip6;
|
|
+ gs_free char *hostname = NULL;
|
|
+
|
|
+ connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV, &hostname);
|
|
+ g_assert (connections);
|
|
+ g_assert_cmpint (g_hash_table_size (connections), ==, 1);
|
|
+ g_assert_cmpstr (hostname, ==, "host1");
|
|
+
|
|
+ connection = g_hash_table_lookup (connections, "default_connection");
|
|
+ g_assert (connection);
|
|
+ nmtst_assert_connection_verifies_without_normalization (connection);
|
|
+
|
|
+ g_assert (!nm_connection_get_setting_vlan (connection));
|
|
+
|
|
+ s_con = nm_connection_get_setting_connection (connection);
|
|
+ g_assert (s_con);
|
|
+ g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRED_SETTING_NAME);
|
|
+ g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "Wired Connection");
|
|
+ g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, 0);
|
|
+ g_assert_cmpint (nm_setting_connection_get_multi_connect (s_con), ==, NM_CONNECTION_MULTI_CONNECT_MULTIPLE);
|
|
+ g_assert_cmpint (nm_setting_connection_get_wait_device_timeout (s_con), ==, -1);
|
|
+
|
|
+ g_assert (nm_setting_connection_get_autoconnect (s_con));
|
|
+
|
|
+ s_wired = nm_connection_get_setting_wired (connection);
|
|
+ g_assert (s_wired);
|
|
+ g_assert (!nm_setting_wired_get_mac_address (s_wired));
|
|
+ g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 0);
|
|
+
|
|
+ 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_AUTO);
|
|
+
|
|
+ s_ip6 = nm_connection_get_setting_ip6_config (connection);
|
|
+ g_assert (s_ip6);
|
|
+ g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO);
|
|
+}
|
|
+
|
|
+static void
|
|
+test_dhcp_with_mtu (void)
|
|
+{
|
|
+ const char *const *ARGV0 = NM_MAKE_STRV ("ip=:dhcp:1499");
|
|
+ const char *const *ARGV1 = NM_MAKE_STRV ("ip=::::::dhcp:1499");
|
|
+ const char *const *ARGV[] = {ARGV0, ARGV1};
|
|
+ guint i;
|
|
+
|
|
+ for (i = 0; i < G_N_ELEMENTS (ARGV); i++) {
|
|
+ gs_unref_hashtable GHashTable *connections = NULL;
|
|
+ NMConnection *connection;
|
|
+ NMSettingConnection *s_con;
|
|
+ NMSettingWired *s_wired;
|
|
+ NMSettingIPConfig *s_ip4;
|
|
+ NMSettingIPConfig *s_ip6;
|
|
+ gs_free char *hostname = NULL;
|
|
+
|
|
+ connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV[i], &hostname);
|
|
+ g_assert (connections);
|
|
+ g_assert_cmpint (g_hash_table_size (connections), ==, 1);
|
|
+ g_assert_cmpstr (hostname, ==, NULL);
|
|
+
|
|
+ connection = g_hash_table_lookup (connections, "default_connection");
|
|
+ g_assert (connection);
|
|
+ nmtst_assert_connection_verifies_without_normalization (connection);
|
|
+
|
|
+ s_con = nm_connection_get_setting_connection (connection);
|
|
+ g_assert (s_con);
|
|
+ g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRED_SETTING_NAME);
|
|
+ g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "Wired Connection");
|
|
+ g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, 0);
|
|
+ g_assert_cmpint (nm_setting_connection_get_multi_connect (s_con), ==, NM_CONNECTION_MULTI_CONNECT_MULTIPLE);
|
|
+ g_assert_cmpint (nm_setting_connection_get_wait_device_timeout (s_con), ==, -1);
|
|
+
|
|
+ g_assert (nm_setting_connection_get_autoconnect (s_con));
|
|
+
|
|
+ s_wired = nm_connection_get_setting_wired (connection);
|
|
+ g_assert (s_wired);
|
|
+ g_assert (!nm_setting_wired_get_mac_address (s_wired));
|
|
+ g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 1499);
|
|
+
|
|
+ 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_AUTO);
|
|
+ s_ip6 = nm_connection_get_setting_ip6_config (connection);
|
|
+ g_assert (s_ip6);
|
|
+ g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO);
|
|
+ }
|
|
+}
|
|
+
|
|
static void
|
|
test_if_auto_with_mtu (void)
|
|
{
|
|
@@ -111,7 +208,6 @@ test_if_auto_with_mtu (void)
|
|
g_assert (!nm_setting_ip_config_get_ignore_auto_dns (s_ip6));
|
|
}
|
|
|
|
-
|
|
static void
|
|
test_if_dhcp6 (void)
|
|
{
|
|
@@ -1894,6 +1990,8 @@ int main (int argc, char **argv)
|
|
nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT");
|
|
|
|
g_test_add_func ("/initrd/cmdline/auto", test_auto);
|
|
+ g_test_add_func ("/initrd/cmdline/dhcp_with_hostname", test_dhcp_with_hostname);
|
|
+ g_test_add_func ("/initrd/cmdline/dhcp_with_mtu", test_dhcp_with_mtu);
|
|
g_test_add_func ("/initrd/cmdline/if_auto_with_mtu", test_if_auto_with_mtu);
|
|
g_test_add_func ("/initrd/cmdline/if_dhcp6", test_if_dhcp6);
|
|
g_test_add_func ("/initrd/cmdline/if_auto_with_mtu_and_mac", test_if_auto_with_mtu_and_mac);
|
|
--
|
|
2.28.0
|
|
|