diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2020-11-18 14:27:19 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2020-11-20 16:35:36 +0100 |
commit | f2e51ace6815bd1bd264101694b8dc65226ddd90 (patch) | |
tree | 68b158cdb6baf7afd3143a69f8ff4d406e2bdcb9 | |
parent | 4aa902ecf537fbf14fd483a336b83b2139025681 (diff) | |
download | NetworkManager-bg/initrd-vlan.tar.gz |
initrd: disable ipv4 and ipv6 by default for vlan parent connectionbg/initrd-vlan
Change the generator to disable by default IP configuration for the
parent connection of a VLAN, because that is what a user would expect
and what the legacy module does. Of course if the user explicitly
configures DHCP or an address for the parent interface, that overrides
the default.
Note that now the generator always creates a connection for the parent
interface. Before this commit, it did only when there was an explicit
ip= argument for the parent interface.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/509
-rw-r--r-- | src/initrd/nmi-cmdline-reader.c | 43 | ||||
-rw-r--r-- | src/initrd/tests/test-cmdline-reader.c | 193 |
2 files changed, 232 insertions, 4 deletions
diff --git a/src/initrd/nmi-cmdline-reader.c b/src/initrd/nmi-cmdline-reader.c index 151555ce96..5d6afa74e4 100644 --- a/src/initrd/nmi-cmdline-reader.c +++ b/src/initrd/nmi-cmdline-reader.c @@ -24,6 +24,8 @@ typedef struct { GHashTable * hash; GPtrArray * array; + GPtrArray * vlan_parents; + GHashTable * explicit_ip_connections; NMConnection *bootdev_connection; /* connection for bootdev=$ifname */ NMConnection *default_connection; /* connection not bound to any ifname */ char * hostname; @@ -41,8 +43,11 @@ reader_new(void) reader = g_slice_new(Reader); *reader = (Reader){ - .hash = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_object_unref), - .array = g_ptr_array_new(), + .hash = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_object_unref), + .explicit_ip_connections = + g_hash_table_new_full(nm_direct_hash, NULL, g_object_unref, NULL), + .vlan_parents = g_ptr_array_new_with_free_func(g_free), + .array = g_ptr_array_new(), }; return reader; @@ -54,6 +59,8 @@ reader_destroy(Reader *reader, gboolean free_hash) gs_unref_hashtable GHashTable *hash = NULL; g_ptr_array_unref(reader->array); + g_ptr_array_unref(reader->vlan_parents); + g_hash_table_unref(reader->explicit_ip_connections); hash = g_steal_pointer(&reader->hash); nm_clear_g_free(&reader->hostname); nm_clear_g_free(&reader->dhcp4_vci); @@ -461,6 +468,8 @@ reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument) else connection = reader_get_default_connection(reader); + g_hash_table_add(reader->explicit_ip_connections, g_object_ref(connection)); + s_ip4 = nm_connection_get_setting_ip4_config(connection); s_ip6 = nm_connection_get_setting_ip6_config(connection); @@ -846,6 +855,9 @@ reader_parse_vlan(Reader *reader, char *argument) if (argument && *argument) _LOGW(LOGD_CORE, "Ignoring extra: '%s'.", argument); + + if (!nm_strv_ptrarray_contains(reader->vlan_parents, phy)) + g_ptr_array_add(reader->vlan_parents, g_strdup(phy)); } static void @@ -1089,6 +1101,33 @@ nmi_cmdline_reader_parse(const char *sysfs_dir, const char *const *argv, char ** } } + for (i = 0; i < reader->vlan_parents->len; i++) { + NMConnection * connection; + NMSettingIPConfig *s_ip; + + /* Disable IP configuration for parent connections of VLANs, + * unless those interfaces were explicitly configured otherwise. */ + + connection = reader_get_connection(reader, reader->vlan_parents->pdata[i], NULL, TRUE); + if (!g_hash_table_contains(reader->explicit_ip_connections, connection)) { + s_ip = nm_connection_get_setting_ip4_config(connection); + if (s_ip) { + g_object_set(s_ip, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NULL); + } + + s_ip = nm_connection_get_setting_ip6_config(connection); + if (s_ip) { + g_object_set(s_ip, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED, + NULL); + } + } + } + if (ignore_bootif) nm_clear_g_free(&bootif_val); if (bootif_val) { diff --git a/src/initrd/tests/test-cmdline-reader.c b/src/initrd/tests/test-cmdline-reader.c index 281d690dcd..ef664b7035 100644 --- a/src/initrd/tests/test-cmdline-reader.c +++ b/src/initrd/tests/test-cmdline-reader.c @@ -504,7 +504,7 @@ test_bootdev(void) connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", ARGV, &hostname); g_assert(connections); - g_assert_cmpint(g_hash_table_size(connections), ==, 2); + g_assert_cmpint(g_hash_table_size(connections), ==, 3); g_assert_cmpstr(hostname, ==, NULL); connection = g_hash_table_lookup(connections, "ens3"); @@ -533,6 +533,18 @@ test_bootdev(void) NM_SETTING_VLAN_SETTING_NAME); g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "vlan2"); g_assert_cmpstr(nm_setting_connection_get_interface_name(s_con), ==, "vlan2"); + + connection = g_hash_table_lookup(connections, "ens5"); + 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), ==, "ens5"); + g_assert_cmpstr(nm_setting_connection_get_interface_name(s_con), ==, "ens5"); } static void @@ -1237,9 +1249,80 @@ test_vlan(void) 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_cmpint(g_hash_table_size(connections), ==, 2); + g_assert_cmpstr(hostname, ==, NULL); + + /* VLAN eth0.100 */ + connection = g_hash_table_lookup(connections, "eth0.100"); + g_assert(connection); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_VLAN_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth0.100"); + + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); + g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, "eth0"); + g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 100); + + 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); + + /* Ethernet eth0 */ + connection = g_hash_table_lookup(connections, "eth0"); + g_assert(connection); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth0"); + + 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_DISABLED); + + 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_DISABLED); + } +} + +static void +test_vlan_with_dhcp_on_parent(void) +{ + const char *const *ARGV0 = NM_MAKE_STRV("vlan=eth0.100:eth0", "ip=eth0:dhcp"); + const char *const *ARGV1 = NM_MAKE_STRV("ip=eth0:dhcp", "vlan=eth0.100:eth0"); + 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; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMSettingVlan * s_vlan; + 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), ==, 2); g_assert_cmpstr(hostname, ==, NULL); + /* VLAN eth0.100 */ connection = g_hash_table_lookup(connections, "eth0.100"); g_assert(connection); nmtst_assert_connection_verifies_without_normalization(connection); @@ -1248,11 +1331,32 @@ test_vlan(void) NM_SETTING_VLAN_SETTING_NAME); g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth0.100"); + 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); + s_vlan = nm_connection_get_setting_vlan(connection); g_assert(s_vlan); g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, "eth0"); g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 100); + /* Ethernet eth0 */ + connection = g_hash_table_lookup(connections, "eth0"); + g_assert(connection); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth0"); + s_ip4 = nm_connection_get_setting_ip4_config(connection); g_assert(s_ip4); g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), @@ -1268,6 +1372,89 @@ test_vlan(void) } static void +test_vlan_over_bond(void) +{ + const char *const *ARGV0 = NM_MAKE_STRV("ip=1.2.3.4:::24::vlan1:none", + "bond=bond2:ens3,ens4:mode=active-backup", + "vlan=vlan1:bond2"); + const char *const *ARGV1 = NM_MAKE_STRV("vlan=vlan1:bond2", + "ip=1.2.3.4:::24::vlan1:none", + "bond=bond2:ens3,ens4:mode=active-backup"); + const char *const *ARGV2 = NM_MAKE_STRV("bond=bond2:ens3,ens4:mode=active-backup", + "ip=1.2.3.4:::24::vlan1:none", + "vlan=vlan1:bond2"); + const char *const *ARGV[] = {ARGV0, ARGV1, ARGV2}; + guint i; + + for (i = 0; i < G_N_ELEMENTS(ARGV); i++) { + gs_unref_hashtable GHashTable *connections = NULL; + NMConnection * connection; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMSettingVlan * s_vlan; + 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), ==, 4); + g_assert_cmpstr(hostname, ==, NULL); + + /* VLAN vlan1 */ + connection = g_hash_table_lookup(connections, "vlan1"); + g_assert(connection); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_VLAN_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "vlan1"); + + 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); + + 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_DISABLED); + + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); + g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, "bond2"); + g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 1); + + /* Bond bond2 */ + connection = g_hash_table_lookup(connections, "bond2"); + g_assert(connection); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_BOND_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "bond2"); + + 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_DISABLED); + + 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_DISABLED); + + /* Ethernet ens3 and ens4 */ + connection = g_hash_table_lookup(connections, "ens3"); + g_assert(connection); + connection = g_hash_table_lookup(connections, "ens4"); + g_assert(connection); + } +} + +static void test_ibft_ip_dev(void) { const char *const *ARGV = NM_MAKE_STRV("ip=eth0:ibft"); @@ -1901,6 +2088,8 @@ main(int argc, char **argv) g_test_add_func("/initrd/cmdline/bond/default", test_bond_default); g_test_add_func("/initrd/cmdline/team", test_team); g_test_add_func("/initrd/cmdline/vlan", test_vlan); + g_test_add_func("/initrd/cmdline/vlan/dhcp-on-parent", test_vlan_with_dhcp_on_parent); + g_test_add_func("/initrd/cmdline/vlan/over-bond", test_vlan_over_bond); g_test_add_func("/initrd/cmdline/bridge", test_bridge); g_test_add_func("/initrd/cmdline/bridge/default", test_bridge_default); g_test_add_func("/initrd/cmdline/bridge/ip", test_bridge_ip); |