diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2021-06-24 08:09:10 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2021-09-06 10:56:12 +0200 |
commit | 3565f155fb91cf5d5cff695a69925065a8a6c2c6 (patch) | |
tree | e4cba4f0d3ddedf1b9b85776c888b35715b15b79 | |
parent | 65868803e03c32fa0fe91664ca98818a17b37b40 (diff) | |
download | NetworkManager-bg/required-timeout-1-30.tar.gz |
initrd: set required-timeout for default IPv4 configurationbg/required-timeout-1-30
If the kernel command-line doesn't contain an explict ip=$method,
currently the generator creates connections with both IPv4 and IPv6
set to 'auto', and both allowed to fail.
Since NM is run in configure-and-quit mode in the initrd, NM can get
an IPv4 address or an IPv6 one (or both) depending on which address
family is quicker to complete. This unpredictable behavior is not
present in the legacy module, which always does IPv4 only by default.
Set a required-timeout of 20 seconds for IPv4, so that NM will
preferably get an IPv4, or will fall back to IPv6.
See also: https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/729
(cherry picked from commit 0a18e97345894a6ea76fd336a5b4e2ed7a1b537b)
(cherry picked from commit 1b9cf8c513767ecb41407224e5c4f0b7f6947db8)
-rw-r--r-- | src/core/initrd/nm-initrd-generator.h | 1 | ||||
-rw-r--r-- | src/core/initrd/nmi-cmdline-reader.c | 32 | ||||
-rw-r--r-- | src/core/initrd/tests/test-cmdline-reader.c | 44 |
3 files changed, 63 insertions, 14 deletions
diff --git a/src/core/initrd/nm-initrd-generator.h b/src/core/initrd/nm-initrd-generator.h index 534edcb783..2ec52a010a 100644 --- a/src/core/initrd/nm-initrd-generator.h +++ b/src/core/initrd/nm-initrd-generator.h @@ -10,6 +10,7 @@ #include "nm-utils.h" #define NMI_WAIT_DEVICE_TIMEOUT_MSEC 60000 +#define NMI_IP_REQUIRED_TIMEOUT_MSEC 20000 static inline int get_ip_address_family(const char *str, gboolean with_prefix) diff --git a/src/core/initrd/nmi-cmdline-reader.c b/src/core/initrd/nmi-cmdline-reader.c index befb59c317..fe36572776 100644 --- a/src/core/initrd/nmi-cmdline-reader.c +++ b/src/core/initrd/nmi-cmdline-reader.c @@ -117,6 +117,8 @@ reader_create_connection(Reader * reader, reader->dhcp_timeout, NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER, reader->dhcp4_vci, + NM_SETTING_IP_CONFIG_REQUIRED_TIMEOUT, + NMI_IP_REQUIRED_TIMEOUT_MSEC, NULL); setting = nm_setting_ip6_config_new(); @@ -399,18 +401,19 @@ reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument) 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; - const char * gateway_ip = NULL; - const char * netmask = NULL; - const char * client_hostname = NULL; - const char * iface_spec = NULL; - const char * mtu = NULL; - const char * macaddr = NULL; - int client_ip_family = AF_UNSPEC; - int client_ip_prefix = -1; - const char * dns[2] = { + const char * kind = NULL; + const char * client_ip = NULL; + const char * peer = NULL; + const char * gateway_ip = NULL; + const char * netmask = NULL; + const char * client_hostname = NULL; + const char * iface_spec = NULL; + const char * mtu = NULL; + const char * macaddr = NULL; + int client_ip_family = AF_UNSPEC; + int client_ip_prefix = -1; + gboolean clear_ip4_required_timeout = TRUE; + const char * dns[2] = { NULL, NULL, }; @@ -677,8 +680,13 @@ reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument) g_clear_error(&error); } } + } else { + clear_ip4_required_timeout = FALSE; } + if (clear_ip4_required_timeout) + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_REQUIRED_TIMEOUT, -1, NULL); + if (peer && *peer) _LOGW(LOGD_CORE, "Ignoring peer: %s (not implemented)\n", peer); diff --git a/src/core/initrd/tests/test-cmdline-reader.c b/src/core/initrd/tests/test-cmdline-reader.c index ed16cc6650..8a4cd73062 100644 --- a/src/core/initrd/tests/test-cmdline-reader.c +++ b/src/core/initrd/tests/test-cmdline-reader.c @@ -276,6 +276,7 @@ test_dhcp_timeout(void) ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); g_assert_cmpint(nm_setting_ip_config_get_dhcp_timeout(s_ip4), ==, data[i].timeout); + g_assert_cmpint(nm_setting_ip_config_get_required_timeout(s_ip4), ==, -1); s_ip6 = nm_connection_get_setting_ip6_config(connection); g_assert(s_ip6); @@ -283,6 +284,7 @@ test_dhcp_timeout(void) ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); g_assert_cmpint(nm_setting_ip_config_get_dhcp_timeout(s_ip6), ==, data[i].timeout); + g_assert_cmpint(nm_setting_ip_config_get_required_timeout(s_ip6), ==, -1); } } @@ -421,6 +423,7 @@ 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"); + g_assert_cmpint(nm_setting_ip_config_get_required_timeout(s_ip4), ==, -1); s_ip6 = nm_connection_get_setting_ip6_config(connection); g_assert(s_ip6); @@ -428,6 +431,7 @@ test_if_ip4_manual(void) ==, NM_SETTING_IP6_CONFIG_METHOD_DISABLED); g_assert(nm_setting_ip_config_get_may_fail(s_ip6)); + g_assert_cmpint(nm_setting_ip_config_get_required_timeout(s_ip6), ==, -1); connection = g_hash_table_lookup(connections, "eth4"); nmtst_assert_connection_verifies_without_normalization(connection); @@ -1154,6 +1158,9 @@ test_bridge(void) g_assert_cmpint(nm_ip_route_get_metric(ip_route), ==, -1); g_assert(!nm_ip_route_get_next_hop(ip_route)); g_assert_cmpint(nm_ip_route_get_prefix(ip_route), ==, 32); + g_assert_cmpint(nm_setting_ip_config_get_required_timeout(s_ip4), + ==, + NMI_IP_REQUIRED_TIMEOUT_MSEC); s_ip6 = nm_connection_get_setting_ip6_config(connection); g_assert(s_ip6); @@ -1163,6 +1170,7 @@ test_bridge(void) g_assert(!nm_setting_ip_config_get_gateway(s_ip6)); g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip6), ==, 0); g_assert_cmpint(nm_setting_ip_config_get_dhcp_timeout(s_ip6), ==, 10); + g_assert_cmpint(nm_setting_ip_config_get_required_timeout(s_ip6), ==, -1); s_bridge = nm_connection_get_setting_bridge(connection); g_assert(s_bridge); @@ -1903,7 +1911,38 @@ test_bootif_ip(void) } static void -test_neednet(void) +test_neednet_no_args(void) +{ + const char *const *ARGV = NM_MAKE_STRV("rd.neednet"); + gs_unref_object NMConnection *connection = NULL; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + + connection = _parse_con(ARGV, "default_connection"); + + g_assert_cmpstr(nm_connection_get_id(connection), ==, "Wired Connection"); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + + 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); + g_assert(nm_setting_ip_config_get_may_fail(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_required_timeout(s_ip4), + ==, + NMI_IP_REQUIRED_TIMEOUT_MSEC); + + 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); + g_assert(nm_setting_ip_config_get_may_fail(s_ip6)); + g_assert_cmpint(nm_setting_ip_config_get_required_timeout(s_ip6), ==, -1); +} + +static void +test_neednet_args(void) { gs_unref_hashtable GHashTable *connections = NULL; const char *const * ARGV = NM_MAKE_STRV("rd.neednet", @@ -2237,7 +2276,8 @@ main(int argc, char **argv) g_test_add_func("/initrd/cmdline/bootif/no_ip", test_bootif_no_ip); g_test_add_func("/initrd/cmdline/bootif/hwtype", test_bootif_hwtype); g_test_add_func("/initrd/cmdline/bootif/off", test_bootif_off); - g_test_add_func("/initrd/cmdline/neednet", test_neednet); + g_test_add_func("/initrd/cmdline/neednet/no_args", test_neednet_no_args); + g_test_add_func("/initrd/cmdline/neednet/args", test_neednet_args); g_test_add_func("/initrd/cmdline/dhcp/vendor_class_id", test_dhcp_vendor_class_id); g_test_add_func("/initrd/cmdline/infiniband/iface", test_infiniband_iface); g_test_add_func("/initrd/cmdline/infiniband/mac", test_infiniband_mac); |