initrd: disable ipv4 and ipv6 by default for vlan parent connection

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
(cherry picked from commit f2e51ace68)
This commit is contained in:
Beniamino Galvani 2020-11-18 14:27:19 +01:00
parent f766b3cbae
commit 4b0007b037
2 changed files with 232 additions and 4 deletions

View file

@ -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);
@ -835,6 +844,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
@ -1078,6 +1090,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) {

View file

@ -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,10 @@ 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);
@ -1264,6 +1277,180 @@ test_vlan(void)
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);
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_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),
==,
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_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);
}
}
@ -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);