diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2020-07-02 10:04:08 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2020-07-03 22:02:34 +0200 |
commit | 79f70bf5d62213e7e6ce2c5e15fdf6981dc19ef0 (patch) | |
tree | 75694cf5a2deb6910e8b7a89f9febff0a25ee1ca | |
parent | b2f03544a7947c3157f987f630e6c473cacbb53a (diff) | |
download | NetworkManager-79f70bf5d62213e7e6ce2c5e15fdf6981dc19ef0.tar.gz |
initrd: fix generation of MTU and cloned-mac-address for mastersbg/initrd-bond-cloned-mac
Setting a MTU or a cloned MAC for bonds/bridges/teams fails with:
# nm-initrd-generator -- bond=bond0:eno1,eno2:mode=802.3ad
ip=192.168.1.5::192.168.1.254:255.255.255.0:MyServer:bond0:none::01:02:03:04:05:06
bootdev=bond0 nameserver=192.168.1.1
<warn> cmdline-reader: 'bond' does not support setting cloned-mac-address
Fix this.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/460
-rw-r--r-- | src/initrd/nmi-cmdline-reader.c | 36 | ||||
-rw-r--r-- | src/initrd/tests/test-cmdline-reader.c | 155 |
2 files changed, 174 insertions, 17 deletions
diff --git a/src/initrd/nmi-cmdline-reader.c b/src/initrd/nmi-cmdline-reader.c index 69e5e56d07..e44841e683 100644 --- a/src/initrd/nmi-cmdline-reader.c +++ b/src/initrd/nmi-cmdline-reader.c @@ -237,20 +237,24 @@ get_word (char **argument, const char separator) } static void -_base_setting_set (NMConnection *connection, const char *property, const char *value) +connection_set (NMConnection *connection, const char *setting_name, const char *property, const char *value) { NMSetting *setting; - const char *type_name = nm_connection_get_connection_type (connection); - GObjectClass *object_class = g_type_class_ref (nm_setting_lookup_type (type_name)); - GParamSpec *spec = g_object_class_find_property (object_class, property); - - if (!spec) { - _LOGW (LOGD_CORE, "'%s' does not support setting %s", type_name, property); - return; + GType setting_type; + nm_auto_unref_gtypeclass GObjectClass *object_class = NULL; + GParamSpec *spec; + + setting_type = nm_setting_lookup_type (setting_name); + object_class = g_type_class_ref (setting_type); + spec = g_object_class_find_property (object_class, property); + nm_assert (spec); + + setting = nm_connection_get_setting_by_name (connection, setting_name); + if (!setting) { + setting = g_object_new (setting_type, NULL); + nm_connection_add_setting (connection, setting); } - setting = nm_connection_get_setting_by_name (connection, type_name); - if (G_IS_PARAM_SPEC_UINT (spec)) { guint v; @@ -259,14 +263,12 @@ _base_setting_set (NMConnection *connection, const char *property, const char *v || !nm_g_object_set_property_uint (G_OBJECT (setting), property, v, NULL)) { _LOGW (LOGD_CORE, "Could not set property '%s.%s' to '%s'", - type_name, property, value); + setting_name, property, value); } } else if (G_IS_PARAM_SPEC_STRING (spec)) g_object_set (setting, property, value, NULL); else - _LOGW (LOGD_CORE, "Don't know how to set '%s' of %s", property, type_name); - - g_type_class_unref (object_class); + _LOGW (LOGD_CORE, "Don't know how to set '%s' of %s", property, setting_name); } static void @@ -577,10 +579,10 @@ reader_parse_ip (Reader *reader, const char *sysfs_dir, char *argument) } if (mtu && *mtu) - _base_setting_set (connection, "mtu", mtu); + connection_set (connection, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MTU, mtu); if (macaddr && *macaddr) - _base_setting_set (connection, "cloned-mac-address", macaddr); + connection_set (connection, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, macaddr); } static void @@ -635,7 +637,7 @@ reader_parse_master (Reader *reader, NM_SETTING_CONNECTION_MASTER, master, NULL); if (mtu) - _base_setting_set (connection, "mtu", mtu); + connection_set (connection, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MTU, mtu); } while (slaves && *slaves != '\0'); if (argument && *argument) diff --git a/src/initrd/tests/test-cmdline-reader.c b/src/initrd/tests/test-cmdline-reader.c index 110770554c..bd2104c595 100644 --- a/src/initrd/tests/test-cmdline-reader.c +++ b/src/initrd/tests/test-cmdline-reader.c @@ -569,6 +569,94 @@ test_bond (void) } static void +test_bond_ip (void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const*ARGV = NM_MAKE_STRV ("bond=bond0:eth0,eth1", + "ip=192.168.1.1::192.168.1.254:24::bond0:none:1480:01:02:03:04:05:06", + "nameserver=4.8.15.16"); + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; + NMSettingWired *s_wired; + NMSettingBond *s_bond; + NMIPAddress *ip_addr; + const char *master_uuid; + 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), ==, 3); + g_assert_cmpstr (hostname, ==, NULL); + + connection = g_hash_table_lookup (connections, "bond0"); + 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), ==, "bond0"); + master_uuid = nm_connection_get_uuid (connection); + g_assert (master_uuid); + + s_wired = nm_connection_get_setting_wired (connection); + g_assert (s_wired); + g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 1480); + g_assert_cmpstr (nm_setting_wired_get_cloned_mac_address (s_wired), ==, "01:02:03:04:05:06"); + + 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); + g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 1); + ip_addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert (ip_addr); + g_assert_cmpstr (nm_ip_address_get_address (ip_addr), ==, "192.168.1.1"); + g_assert_cmpint (nm_ip_address_get_prefix (ip_addr), ==, 24); + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.254"); + g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 1); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 0), ==, "4.8.15.16"); + g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip4), ==, 0); + + 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_ignore_auto_dns (s_ip6)); + g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip6), ==, 0); + g_assert (!nm_setting_ip_config_get_gateway (s_ip6)); + g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip6), ==, 0); + + s_bond = nm_connection_get_setting_bond (connection); + g_assert (s_bond); + g_assert_cmpint (nm_setting_bond_get_num_options (s_bond), ==, 1); + g_assert_cmpstr (nm_setting_bond_get_option_by_name (s_bond, "mode"), ==, "balance-rr"); + + connection = g_hash_table_lookup (connections, "eth0"); + g_assert (connection); + nmtst_assert_connection_verifies_without_normalization (connection); + g_assert_cmpstr (nm_connection_get_id (connection), ==, "eth0"); + + 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), ==, "eth0"); + g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_BOND_SETTING_NAME); + g_assert_cmpstr (nm_setting_connection_get_master (s_con), ==, master_uuid); + g_assert_cmpint (nm_setting_connection_get_multi_connect (s_con), ==, NM_CONNECTION_MULTI_CONNECT_SINGLE); + + connection = g_hash_table_lookup (connections, "eth1"); + g_assert (connection); + nmtst_assert_connection_verifies_without_normalization (connection); + g_assert_cmpstr (nm_connection_get_id (connection), ==, "eth1"); + + 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), ==, "eth1"); + g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_BOND_SETTING_NAME); + g_assert_cmpstr (nm_setting_connection_get_master (s_con), ==, master_uuid); + g_assert_cmpint (nm_setting_connection_get_multi_connect (s_con), ==, NM_CONNECTION_MULTI_CONNECT_SINGLE); +} + +static void test_bond_default (void) { gs_unref_hashtable GHashTable *connections = NULL; @@ -775,6 +863,71 @@ test_bridge_default (void) } static void +test_bridge_ip (void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const*ARGV = NM_MAKE_STRV ("ip=bridge123:auto:1280:00:11:22:33:CA:fe", + "bridge=bridge123:eth0,eth1,eth2,eth3,eth4,eth5,eth6,eth7,eth8,eth9"); + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; + NMSettingWired *s_wired; + NMSettingBridge *s_bridge; + const char *master_uuid; + gs_free char *hostname = NULL; + guint i; + + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV, &hostname); + g_assert (connections); + g_assert_cmpint (g_hash_table_size (connections), ==, 11); + g_assert_cmpstr (hostname, ==, NULL); + + connection = g_hash_table_lookup (connections, "bridge123"); + g_assert (connection); + nmtst_assert_connection_verifies_without_normalization (connection); + g_assert_cmpstr (nm_connection_get_connection_type (connection), ==, NM_SETTING_BRIDGE_SETTING_NAME); + g_assert_cmpstr (nm_connection_get_id (connection), ==, "bridge123"); + master_uuid = nm_connection_get_uuid (connection); + g_assert (master_uuid); + + s_wired = nm_connection_get_setting_wired (connection); + g_assert (s_wired); + g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 1280); + g_assert_cmpstr (nm_setting_wired_get_cloned_mac_address (s_wired), ==, "00:11:22:33:CA:FE"); + + 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_bridge = nm_connection_get_setting_bridge (connection); + g_assert (s_bridge); + + for (i = 0; i < 10; i++) { + char ifname[16]; + + nm_sprintf_buf (ifname, "eth%u", i); + + connection = g_hash_table_lookup (connections, ifname); + g_assert (connection); + nmtst_assert_connection_verifies_without_normalization (connection); + g_assert_cmpstr (nm_connection_get_id (connection), ==, ifname); + + 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), ==, ifname); + g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_BRIDGE_SETTING_NAME); + g_assert_cmpstr (nm_setting_connection_get_master (s_con), ==, master_uuid); + g_assert_cmpint (nm_setting_connection_get_multi_connect (s_con), ==, NM_CONNECTION_MULTI_CONNECT_SINGLE); + } +} + +static void test_team (void) { gs_unref_hashtable GHashTable *connections = NULL; @@ -1244,10 +1397,12 @@ int main (int argc, char **argv) g_test_add_func ("/initrd/cmdline/some_more", test_some_more); g_test_add_func ("/initrd/cmdline/bootdev", test_bootdev); g_test_add_func ("/initrd/cmdline/bond", test_bond); + g_test_add_func ("/initrd/cmdline/bond/ip", test_bond_ip); 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/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); g_test_add_func ("/initrd/cmdline/ibft/ip_dev", test_ibft_ip_dev); g_test_add_func ("/initrd/cmdline/ibft/ip", test_ibft_ip); g_test_add_func ("/initrd/cmdline/ibft/rd_iscsi_ibft", test_ibft_rd_iscsi_ibft); |