summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2020-11-18 14:27:19 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2020-11-20 16:35:36 +0100
commitf2e51ace6815bd1bd264101694b8dc65226ddd90 (patch)
tree68b158cdb6baf7afd3143a69f8ff4d406e2bdcb9
parent4aa902ecf537fbf14fd483a336b83b2139025681 (diff)
downloadNetworkManager-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.c43
-rw-r--r--src/initrd/tests/test-cmdline-reader.c193
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);