diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2020-03-26 22:12:33 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2020-03-26 22:12:33 +0100 |
commit | c8b752c9735147d38832aa70027196c7458f6cc9 (patch) | |
tree | 84513db1ff6ec124dd9e365f6cdc470079369531 | |
parent | 2da77547bafedd352d5c40f66ccd365c454c30d4 (diff) | |
parent | 99e01888864ddba4eda31c43809842afa2594a56 (diff) | |
download | NetworkManager-c8b752c9735147d38832aa70027196c7458f6cc9.tar.gz |
initrd: branch 'bg/initrd-cmdline-fixes'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/447
-rw-r--r-- | src/initrd/nmi-cmdline-reader.c | 547 | ||||
-rw-r--r-- | src/initrd/nmi-ibft-reader.c | 4 | ||||
-rw-r--r-- | src/initrd/tests/test-cmdline-reader.c | 101 |
3 files changed, 426 insertions, 226 deletions
diff --git a/src/initrd/nmi-cmdline-reader.c b/src/initrd/nmi-cmdline-reader.c index bc870d65df..1c824dda6a 100644 --- a/src/initrd/nmi-cmdline-reader.c +++ b/src/initrd/nmi-cmdline-reader.c @@ -17,33 +17,67 @@ /*****************************************************************************/ -static gboolean -_connection_matches_type (gpointer key, gpointer value, gpointer user_data) +typedef struct { + GHashTable *hash; + GPtrArray *array; + NMConnection *bootdev_connection; /* connection for bootdev=$ifname */ + NMConnection *default_connection; /* connection not bound to any ifname */ +} Reader; + +static Reader * +reader_new (void) { - NMConnection *connection = value; - const char *type_name = user_data; - NMSettingConnection *s_con; + Reader *reader; - s_con = nm_connection_get_setting_connection (connection); - if (type_name == NULL) - return nm_setting_connection_get_master (s_con) == NULL; - else - return strcmp (nm_setting_connection_get_connection_type (s_con), type_name) == 0; + 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 (), + }; + + return reader; +} + +static GHashTable * +reader_destroy (Reader *reader, gboolean free_hash) +{ + gs_unref_hashtable GHashTable *hash = NULL; + + g_ptr_array_unref (reader->array); + hash = g_steal_pointer (&reader->hash); + nm_g_slice_free (reader); + if (!free_hash) + return g_steal_pointer (&hash); + return NULL; +} + +static NMConnection * +reader_add_connection (Reader *reader, const char *name, NMConnection *connection_take) +{ + char *name_dup; + + name_dup = g_strdup (name); + if (g_hash_table_insert (reader->hash, name_dup, connection_take)) + g_ptr_array_add (reader->array, name_dup); + + return connection_take; } +/* Returns a new connection owned by the reader */ static NMConnection * -add_conn (GHashTable *connections, - const char *basename, - const char *id, - const char *ifname, - const char *type_name, - NMConnectionMultiConnect multi_connect) +reader_create_connection (Reader *reader, + const char *basename, + const char *id, + const char *ifname, + const char *type_name, + NMConnectionMultiConnect multi_connect) { NMConnection *connection; NMSetting *setting; - connection = nm_simple_connection_new (); - g_hash_table_insert (connections, g_strdup (basename), connection); + connection = reader_add_connection (reader, + basename, + nm_simple_connection_new ()); /* Start off assuming dynamic IP configurations. */ @@ -76,44 +110,74 @@ add_conn (GHashTable *connections, } static NMConnection * -get_conn (GHashTable *connections, const char *ifname, const char *type_name) +reader_get_default_connection (Reader *reader) { - NMConnection *connection; + NMConnection *con; + + if (!reader->default_connection) { + con = reader_create_connection (reader, + "default_connection", + "Wired Connection", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + NM_CONNECTION_MULTI_CONNECT_MULTIPLE); + reader->default_connection = con; + } + return reader->default_connection; +} + +static NMConnection * +reader_get_connection (Reader *reader, + const char *ifname, + const char *type_name, + gboolean create_if_missing) +{ + NMConnection *connection = NULL; NMSetting *setting; - const char *basename; - NMConnectionMultiConnect multi_connect; - if (ifname) { - basename = ifname; - multi_connect = NM_CONNECTION_MULTI_CONNECT_SINGLE; - } else { - /* This is essentially for the "ip=dhcp" scenario. */ - basename = "default_connection"; - multi_connect = NM_CONNECTION_MULTI_CONNECT_MULTIPLE; - } + if (!ifname) { + NMConnection *candidate; + NMSettingConnection *s_con; + guint i; - connection = g_hash_table_lookup (connections, (gpointer) basename); - if (!connection && !ifname) { /* * If ifname was not given, we'll match the connection by type. * If the type was not given either, then we're happy with any connection but slaves. * This is so that things like "bond=bond0:eth1,eth2 nameserver=1.3.3.7 end up * slapping the nameserver to the most reasonable connection (bond0). */ - connection = g_hash_table_find (connections, - _connection_matches_type, - (gpointer) type_name); - } + for (i = 0; i < reader->array->len; i++) { + candidate = g_hash_table_lookup (reader->hash, reader->array->pdata[i]); + s_con = nm_connection_get_setting_connection (candidate); + + if ( type_name == NULL + && nm_setting_connection_get_master (s_con) == NULL) { + connection = candidate; + break; + } + + if ( type_name != NULL + && nm_streq (nm_setting_connection_get_connection_type (s_con), type_name)) { + connection = candidate; + break; + } + } + } else + connection = g_hash_table_lookup (reader->hash, (gpointer) ifname); if (!connection) { + if (!create_if_missing) + return NULL; + if (!type_name) type_name = NM_SETTING_WIRED_SETTING_NAME; - connection = add_conn (connections, basename, - ifname ?: "Wired Connection", - ifname, type_name, multi_connect); + connection = reader_create_connection (reader, ifname, + ifname ?: "Wired Connection", + ifname, type_name, + NM_CONNECTION_MULTI_CONNECT_SINGLE); } - setting = (NMSetting *)nm_connection_get_setting_connection (connection); + setting = (NMSetting *) nm_connection_get_setting_connection (connection); if (type_name) { g_object_set (setting, NM_SETTING_CONNECTION_TYPE, type_name, NULL); @@ -195,22 +259,27 @@ _base_setting_set (NMConnection *connection, const char *property, const char *v } static void -read_all_connections_from_fw (GHashTable *connections, const char *sysfs_dir) +reader_read_all_connections_from_fw (Reader *reader, const char *sysfs_dir) { gs_unref_hashtable GHashTable *ibft = NULL; - NMConnection *connection; - GHashTableIter iter; + NMConnection *dt_connection; const char *mac; GHashTable *nic; const char *index; GError *error = NULL; + guint i, length; + gs_free const char **keys = NULL; ibft = nmi_ibft_read (sysfs_dir); + keys = nm_utils_strdict_get_keys (ibft, TRUE, &length); - g_hash_table_iter_init (&iter, ibft); - while (g_hash_table_iter_next (&iter, (gpointer *) &mac, (gpointer *) &nic)) { - connection = nm_simple_connection_new (); + for (i = 0; i < length; i++) { + gs_unref_object NMConnection *connection = NULL; + gs_free char *name = NULL; + mac = keys[i]; + nic = g_hash_table_lookup (ibft, mac); + connection = nm_simple_connection_new (); index = g_hash_table_lookup (nic, "index"); if (!index) { _LOGW (LOGD_CORE, "Ignoring an iBFT entry without an index"); @@ -220,23 +289,20 @@ read_all_connections_from_fw (GHashTable *connections, const char *sysfs_dir) if (!nmi_ibft_update_connection_from_nic (connection, nic, &error)) { _LOGW (LOGD_CORE, "Unable to merge iBFT configuration: %s", error->message); g_error_free (error); + continue; } - g_hash_table_insert (connections, - g_strdup_printf ("ibft%s", index), - connection); + name = g_strdup_printf ("ibft%s", index); + reader_add_connection (reader, name, g_steal_pointer (&connection)); } - connection = nmi_dt_reader_parse (sysfs_dir); - if (connection) { - g_hash_table_insert (connections, - g_strdup ("ofw"), - connection); - } + dt_connection = nmi_dt_reader_parse (sysfs_dir); + if (dt_connection) + reader_add_connection (reader, "ofw", dt_connection); } static void -parse_ip (GHashTable *connections, const char *sysfs_dir, char *argument) +reader_parse_ip (Reader *reader, const char *sysfs_dir, char *argument) { NMConnection *connection; NMSettingIPConfig *s_ip4 = NULL, *s_ip6 = NULL; @@ -299,12 +365,16 @@ parse_ip (GHashTable *connections, const char *sysfs_dir, char *argument) if (ifname == NULL && ( g_strcmp0 (kind, "fw") == 0 || g_strcmp0 (kind, "ibft") == 0)) { - read_all_connections_from_fw (connections, sysfs_dir); + reader_read_all_connections_from_fw (reader, sysfs_dir); return; } /* Parsing done, construct the NMConnection. */ - connection = get_conn (connections, ifname, NULL); + if (ifname) + connection = reader_get_connection (reader, ifname, NULL, TRUE); + else + connection = reader_get_default_connection (reader); + s_ip4 = nm_connection_get_setting_ip4_config (connection); s_ip6 = nm_connection_get_setting_ip6_config (connection); @@ -390,7 +460,7 @@ parse_ip (GHashTable *connections, const char *sysfs_dir, char *argument) NULL); if (nm_setting_ip_config_get_num_addresses (s_ip6) == 0) { g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_DISABLED, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); } } else if (g_strcmp0 (kind, "dhcp6") == 0) { @@ -495,10 +565,10 @@ parse_ip (GHashTable *connections, const char *sysfs_dir, char *argument) } static void -parse_master (GHashTable *connections, - char *argument, - const char *type_name, - const char *default_name) +reader_parse_master (Reader *reader, + char *argument, + const char *type_name, + const char *default_name) { NMConnection *connection; NMSettingConnection *s_con; @@ -517,7 +587,7 @@ parse_master (GHashTable *connections, master = master_to_free = g_strdup_printf ("%s0", default_name ?: type_name); slaves = get_word (&argument, ':'); - connection = get_conn (connections, master, type_name); + connection = reader_get_connection (reader, master, type_name, TRUE); s_con = nm_connection_get_setting_connection (connection); master = nm_setting_connection_get_uuid (s_con); @@ -539,7 +609,7 @@ parse_master (GHashTable *connections, if (slave == NULL) slave = "eth0"; - connection = get_conn (connections, slave, NULL); + connection = reader_get_connection (reader, slave, NULL, TRUE); s_con = nm_connection_get_setting_connection (connection); g_object_set (s_con, NM_SETTING_CONNECTION_SLAVE_TYPE, type_name, @@ -554,69 +624,81 @@ parse_master (GHashTable *connections, } static void -parse_rd_route (GHashTable *connections, char *argument) +reader_add_routes (Reader *reader, GPtrArray *array) { - NMConnection *connection; - const char *net; - const char *gateway; - const char *interface; - int family = AF_UNSPEC; - NMIPAddr net_addr = { }; - NMIPAddr gateway_addr = { }; - int net_prefix = -1; - NMIPRoute *route; - NMSettingIPConfig *s_ip; - GError *error = NULL; - - net = get_word (&argument, ':'); - gateway = get_word (&argument, ':'); - interface = get_word (&argument, ':'); - - connection = get_conn (connections, interface, NULL); + guint i; + + for (i = 0; i < array->len; i++) { + NMConnection *connection = NULL; + const char *net; + const char *gateway; + const char *interface; + int family = AF_UNSPEC; + NMIPAddr net_addr = { }; + NMIPAddr gateway_addr = { }; + int net_prefix = -1; + NMIPRoute *route; + NMSettingIPConfig *s_ip; + char *argument; + gs_free_error GError *error = NULL; + + argument = array->pdata[i]; + net = get_word (&argument, ':'); + gateway = get_word (&argument, ':'); + interface = get_word (&argument, ':'); + + if (interface) + connection = reader_get_connection (reader, interface, NULL, TRUE); + if (!connection) + connection = reader->bootdev_connection; + if (!connection) + connection = reader_get_connection (reader, interface, NULL, FALSE); + if (!connection) + connection = reader_get_default_connection (reader); + + if (net && *net) { + if (!nm_utils_parse_inaddr_prefix_bin (family, net, &family, &net_addr, &net_prefix)) { + _LOGW (LOGD_CORE, "Unrecognized address: %s", net); + continue; + } + } - if (net && *net) { - if (!nm_utils_parse_inaddr_prefix_bin (family, net, &family, &net_addr, &net_prefix)) { - _LOGW (LOGD_CORE, "Unrecognized address: %s", net); - return; + if (gateway && *gateway) { + if (!nm_utils_parse_inaddr_bin (family, gateway, &family, &gateway_addr)) { + _LOGW (LOGD_CORE, "Unrecognized address: %s", gateway); + continue; + } } - } - if (gateway && *gateway) { - if (!nm_utils_parse_inaddr_bin (family, gateway, &family, &gateway_addr)) { - _LOGW (LOGD_CORE, "Unrecognized address: %s", gateway); - return; + switch (family) { + case AF_INET: + s_ip = nm_connection_get_setting_ip4_config (connection); + if (net_prefix == -1) + net_prefix = 32; + break; + case AF_INET6: + s_ip = nm_connection_get_setting_ip6_config (connection); + if (net_prefix == -1) + net_prefix = 128; + break; + default: + _LOGW (LOGD_CORE, "Unknown address family: %s", net); + continue; } - } - switch (family) { - case AF_INET: - s_ip = nm_connection_get_setting_ip4_config (connection); - if (net_prefix == -1) - net_prefix = 32; - break; - case AF_INET6: - s_ip = nm_connection_get_setting_ip6_config (connection); - if (net_prefix == -1) - net_prefix = 128; - break; - default: - _LOGW (LOGD_CORE, "Unknown address family: %s", net); - return; - } + route = nm_ip_route_new_binary (family, &net_addr.addr_ptr, net_prefix, &gateway_addr.addr_ptr, -1, &error); + if (!route) { + g_warning ("Invalid route '%s via %s': %s\n", net, gateway, error->message); + continue; + } - route = nm_ip_route_new_binary (family, &net_addr.addr_ptr, net_prefix, &gateway_addr.addr_ptr, -1, &error); - if (!route) { - g_warning ("Invalid route '%s via %s': %s\n", net, gateway, error->message); - g_clear_error (&error); - return; + nm_setting_ip_config_add_route (s_ip, route); + nm_ip_route_unref (route); } - - nm_setting_ip_config_add_route (s_ip, route); - nm_ip_route_unref (route); } static void -parse_vlan (GHashTable *connections, char *argument) +reader_parse_vlan (Reader *reader, char *argument) { NMConnection *connection; NMSettingVlan *s_vlan; @@ -632,7 +714,7 @@ parse_vlan (GHashTable *connections, char *argument) break; } - connection = get_conn (connections, vlan, NM_SETTING_VLAN_SETTING_NAME); + connection = reader_get_connection (reader, vlan, NM_SETTING_VLAN_SETTING_NAME, TRUE); s_vlan = nm_connection_get_setting_vlan (connection); g_object_set (s_vlan, @@ -645,77 +727,7 @@ parse_vlan (GHashTable *connections, char *argument) } static void -parse_bootdev (GHashTable *connections, char *argument) -{ - NMConnection *connection; - NMSettingConnection *s_con; - - connection = get_conn (connections, NULL, NULL); - - if ( nm_connection_get_interface_name (connection) - && strcmp (nm_connection_get_interface_name (connection), argument) != 0) { - /* If the default connection already has an interface name, - * we should not overwrite it. Create a new one instead. */ - connection = get_conn (connections, argument, NULL); - } - - s_con = nm_connection_get_setting_connection (connection); - g_object_set (s_con, - NM_SETTING_CONNECTION_INTERFACE_NAME, argument, - NULL); -} - -static void -parse_nameserver (GHashTable *connections, char *argument) -{ - NMConnection *connection; - NMSettingIPConfig *s_ip = NULL; - char *dns; - - connection = get_conn (connections, NULL, NULL); - - dns = get_word (&argument, '\0'); - - switch (guess_ip_address_family (dns)) { - case AF_INET: - s_ip = nm_connection_get_setting_ip4_config (connection); - break; - case AF_INET6: - s_ip = nm_connection_get_setting_ip6_config (connection); - break; - default: - _LOGW (LOGD_CORE, "Unknown address family: %s", dns); - break; - } - - nm_setting_ip_config_add_dns (s_ip, dns); - - if (argument && *argument) - _LOGW (LOGD_CORE, "Ignoring extra: '%s'.", argument); -} - -static void -parse_rd_peerdns (GHashTable *connections, char *argument) -{ - gboolean auto_dns = !_nm_utils_ascii_str_to_bool (argument, TRUE); - NMConnection *connection; - NMSettingIPConfig *s_ip = NULL; - - connection = get_conn (connections, NULL, NULL); - - s_ip = nm_connection_get_setting_ip4_config (connection); - g_object_set (s_ip, - NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, auto_dns, - NULL); - - s_ip = nm_connection_get_setting_ip6_config (connection); - g_object_set (s_ip, - NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, auto_dns, - NULL); -} - -static void -parse_rd_znet (GHashTable *connections, char *argument, gboolean net_ifnames) +reader_parse_rd_znet (Reader *reader, char *argument, gboolean net_ifnames) { const char *nettype; const char *subchannels[4] = { 0, 0, 0, 0 }; @@ -765,7 +777,7 @@ parse_rd_znet (GHashTable *connections, char *argument, gboolean net_ifnames) ifname = g_strdup_printf ("%s%d", prefix, index); } - connection = get_conn (connections, ifname, NM_SETTING_WIRED_SETTING_NAME); + connection = reader_get_connection (reader, ifname, NM_SETTING_WIRED_SETTING_NAME, TRUE); s_wired = nm_connection_get_setting_wired (connection); g_object_set (s_wired, NM_SETTING_WIRED_S390_NETTYPE, nettype, @@ -795,18 +807,88 @@ _normalize_conn (gpointer key, gpointer value, gpointer user_data) nm_connection_normalize (connection, NULL, NULL, NULL); } +static void +reader_set_ignore_auto_dns (Reader *reader) +{ + GHashTableIter iter; + NMConnection *connection; + NMSettingIPConfig *s_ip = NULL; + + g_hash_table_iter_init (&iter, reader->hash); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &connection)) { + s_ip = nm_connection_get_setting_ip4_config (connection); + g_object_set (s_ip, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, TRUE, + NULL); + + s_ip = nm_connection_get_setting_ip6_config (connection); + g_object_set (s_ip, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, TRUE, + NULL); + } +} + +static void +reader_add_nameservers (Reader *reader, GPtrArray *nameservers) +{ + NMConnection *connection; + NMSettingIPConfig *s_ip; + GHashTableIter iter; + int addr_family; + const char *ns; + guint i; + + for (i = 0; i < nameservers->len; i++) { + ns = nameservers->pdata[i]; + addr_family = guess_ip_address_family (ns); + if (addr_family == AF_UNSPEC) { + _LOGW (LOGD_CORE, "Unknown address family: %s", ns); + continue; + } + + g_hash_table_iter_init (&iter, reader->hash); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &connection)) { + switch (addr_family) { + case AF_INET: + s_ip = nm_connection_get_setting_ip4_config (connection); + if (!NM_IN_STRSET (nm_setting_ip_config_get_method (s_ip), + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) + continue; + break; + case AF_INET6: + s_ip = nm_connection_get_setting_ip6_config (connection); + if (!NM_IN_STRSET (nm_setting_ip_config_get_method (s_ip), + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP6_CONFIG_METHOD_DHCP, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) + continue; + break; + default: + nm_assert_not_reached (); + } + + nm_setting_ip_config_add_dns (s_ip, ns); + } + } +} + GHashTable * nmi_cmdline_reader_parse (const char *sysfs_dir, const char *const*argv) { - GHashTable *connections; + Reader *reader; const char *tag; gboolean ignore_bootif = FALSE; gboolean neednet = FALSE; gs_free char *bootif_val = NULL; + gs_free char *bootdev = NULL; gboolean net_ifnames = TRUE; + gs_unref_ptrarray GPtrArray *nameservers = NULL; + gs_unref_ptrarray GPtrArray *routes = NULL; + gboolean ignore_auto_dns = FALSE; int i; - connections = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_object_unref); + reader = reader_new (); for (i = 0; argv[i]; i++) { if (strcmp (argv[i], "net.ifnames=0") == 0) @@ -818,37 +900,48 @@ nmi_cmdline_reader_parse (const char *sysfs_dir, const char *const*argv) for (i = 0; argv[i]; i++) { gs_free char *argument_clone = NULL; char *argument; + char *word; argument_clone = g_strdup (argv[i]); argument = argument_clone; tag = get_word (&argument, '='); if (strcmp (tag, "ip") == 0) - parse_ip (connections, sysfs_dir, argument); - else if (strcmp (tag, "rd.route") == 0) - parse_rd_route (connections, argument); - else if (strcmp (tag, "bridge") == 0) - parse_master (connections, argument, NM_SETTING_BRIDGE_SETTING_NAME, "br"); + reader_parse_ip (reader, sysfs_dir, argument); + else if (strcmp (tag, "rd.route") == 0) { + if (!routes) + routes = g_ptr_array_new_with_free_func (g_free); + g_ptr_array_add (routes, g_strdup (argument)); + } else if (strcmp (tag, "bridge") == 0) + reader_parse_master (reader, argument, NM_SETTING_BRIDGE_SETTING_NAME, "br"); else if (strcmp (tag, "bond") == 0) - parse_master (connections, argument, NM_SETTING_BOND_SETTING_NAME, NULL); + reader_parse_master (reader, argument, NM_SETTING_BOND_SETTING_NAME, NULL); else if (strcmp (tag, "team") == 0) - parse_master (connections, argument, NM_SETTING_TEAM_SETTING_NAME, NULL); + reader_parse_master (reader, argument, NM_SETTING_TEAM_SETTING_NAME, NULL); else if (strcmp (tag, "vlan") == 0) - parse_vlan (connections, argument); - else if (strcmp (tag, "bootdev") == 0) - parse_bootdev (connections, argument); - else if (strcmp (tag, "nameserver") == 0) - parse_nameserver (connections, argument); - else if (strcmp (tag, "rd.peerdns") == 0) - parse_rd_peerdns (connections, argument); + reader_parse_vlan (reader, argument); + else if (strcmp (tag, "bootdev") == 0) { + g_free (bootdev); + bootdev = g_strdup (argument); + } else if (strcmp (tag, "nameserver") == 0) { + word = get_word (&argument, '\0'); + if (word) { + if (!nameservers) + nameservers = g_ptr_array_new_with_free_func (g_free); + g_ptr_array_add (nameservers, g_strdup (word)); + } + if (argument && *argument) + _LOGW (LOGD_CORE, "Ignoring extra: '%s'.", argument); + } else if (strcmp (tag, "rd.peerdns") == 0) + ignore_auto_dns = !_nm_utils_ascii_str_to_bool (argument, TRUE); else if (strcmp (tag, "rd.iscsi.ibft") == 0 && _nm_utils_ascii_str_to_bool (argument, TRUE)) - read_all_connections_from_fw (connections, sysfs_dir); + reader_read_all_connections_from_fw (reader, sysfs_dir); else if (strcmp (tag, "rd.bootif") == 0) ignore_bootif = !_nm_utils_ascii_str_to_bool (argument, TRUE); else if (strcmp (tag, "rd.neednet") == 0) neednet = _nm_utils_ascii_str_to_bool (argument, TRUE); else if (strcmp (tag, "rd.znet") == 0) - parse_rd_znet (connections, argument, net_ifnames); + reader_parse_rd_znet (reader, argument, net_ifnames); else if (g_ascii_strcasecmp (tag, "BOOTIF") == 0) { nm_clear_g_free (&bootif_val); bootif_val = g_strdup (argument); @@ -872,16 +965,22 @@ nmi_cmdline_reader_parse (const char *sysfs_dir, const char *const*argv) bootif += 3; } - connection = get_conn (connections, NULL, NM_SETTING_WIRED_SETTING_NAME); + connection = reader_get_connection (reader, NULL, NM_SETTING_WIRED_SETTING_NAME, FALSE); + if (!connection) + connection = reader_get_default_connection (reader); + s_wired = nm_connection_get_setting_wired (connection); if ( nm_connection_get_interface_name (connection) || ( nm_setting_wired_get_mac_address (s_wired) && !nm_utils_hwaddr_matches (nm_setting_wired_get_mac_address (s_wired), -1, bootif, -1))) { - connection = add_conn (connections, "bootif_connection", "BOOTIF Connection", - NULL, NM_SETTING_WIRED_SETTING_NAME, - NM_CONNECTION_MULTI_CONNECT_SINGLE); + connection = reader_create_connection (reader, + "bootif_connection", + "BOOTIF Connection", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + NM_CONNECTION_MULTI_CONNECT_SINGLE); s_wired = (NMSettingWired *) nm_setting_wired_new (); nm_connection_add_setting (connection, (NMSetting *) s_wired); } @@ -890,12 +989,28 @@ nmi_cmdline_reader_parse (const char *sysfs_dir, const char *const*argv) NM_SETTING_WIRED_MAC_ADDRESS, bootif, NULL); } - if (neednet && g_hash_table_size (connections) == 0) { + + if (bootdev) { + NMConnection *connection; + + connection = reader_get_connection (reader, bootdev, NULL, TRUE); + reader->bootdev_connection = connection; + } + + if (neednet && g_hash_table_size (reader->hash) == 0) { /* Make sure there's some connection. */ - get_conn (connections, NULL, NM_SETTING_WIRED_SETTING_NAME); + reader_get_default_connection (reader); } - g_hash_table_foreach (connections, _normalize_conn, NULL); + if (routes) + reader_add_routes (reader, routes); + + if (nameservers) + reader_add_nameservers (reader, nameservers); + + if (ignore_auto_dns) + reader_set_ignore_auto_dns (reader); - return connections; + g_hash_table_foreach (reader->hash, _normalize_conn, NULL); + return reader_destroy (reader, FALSE); } diff --git a/src/initrd/nmi-ibft-reader.c b/src/initrd/nmi-ibft-reader.c index ca44b399f0..477bc0bf5d 100644 --- a/src/initrd/nmi-ibft-reader.c +++ b/src/initrd/nmi-ibft-reader.c @@ -200,8 +200,8 @@ ip_setting_add_from_block (GHashTable *nic, g_return_val_if_reached (FALSE); } g_object_set (s_ip, - NM_SETTING_IP_CONFIG_METHOD, method, - NM_SETTING_IP_CONFIG_MAY_FAIL, FALSE, + NM_SETTING_IP_CONFIG_METHOD, method, + NM_SETTING_IP_CONFIG_MAY_FAIL, FALSE, NULL); if (s_gateway && !nm_utils_ipaddr_is_valid (family, s_gateway)) { diff --git a/src/initrd/tests/test-cmdline-reader.c b/src/initrd/tests/test-cmdline-reader.c index 8951e4913e..b2b06e27c3 100644 --- a/src/initrd/tests/test-cmdline-reader.c +++ b/src/initrd/tests/test-cmdline-reader.c @@ -264,7 +264,7 @@ test_if_ip6_manual (void) } static void -test_multiple (void) +test_multiple_merge (void) { gs_unref_hashtable GHashTable *connections = NULL; const char *const*ARGV = NM_MAKE_STRV ("ip=192.0.2.2:::::eth0", @@ -307,6 +307,37 @@ test_multiple (void) } static void +test_multiple_bootdev (void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const*ARGV = NM_MAKE_STRV ("nameserver=1.2.3.4", + "ip=eth3:auto6", + "ip=eth4:dhcp", + "bootdev=eth4"); + NMConnection *connection; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; + + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); + g_assert (connections); + g_assert_cmpint (g_hash_table_size (connections), ==, 2); + + connection = g_hash_table_lookup (connections, "eth3"); + g_assert (connection); + 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); + + connection = g_hash_table_lookup (connections, "eth4"); + g_assert (connection); + 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_cmpint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 1); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 0), ==, "1.2.3.4"); +} + +static void test_bootdev (void) { gs_unref_hashtable GHashTable *connections = NULL; @@ -358,16 +389,16 @@ test_some_more (void) g_assert (connections); g_assert_cmpint (g_hash_table_size (connections), ==, 2); - connection = g_hash_table_lookup (connections, "default_connection"); + connection = g_hash_table_lookup (connections, "eth1"); 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), ==, "Wired Connection"); + g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "eth1"); g_assert_cmpstr (nm_setting_connection_get_interface_name (s_con), ==, "eth1"); - g_assert_cmpint (nm_setting_connection_get_multi_connect (s_con), ==, NM_CONNECTION_MULTI_CONNECT_MULTIPLE); + g_assert_cmpint (nm_setting_connection_get_multi_connect (s_con), ==, NM_CONNECTION_MULTI_CONNECT_SINGLE); s_wired = nm_connection_get_setting_wired (connection); g_assert (s_wired); @@ -409,7 +440,8 @@ test_some_more (void) 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_cmpint (nm_setting_ip_config_get_num_dns (s_ip6), ==, 0); + g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip6), ==, 1); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip6, 0), ==, "2001:db8:3::53"); g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip6), ==, 1); g_assert (!nm_setting_ip_config_get_gateway (s_ip6)); ip_route = nm_setting_ip_config_get_route (s_ip6, 0); @@ -991,7 +1023,7 @@ test_bootif (void) 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); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_IGNORE); g_assert (!nm_setting_ip_config_get_ignore_auto_dns (s_ip6)); } @@ -1027,7 +1059,7 @@ test_bootif_hwtype (void) 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); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_IGNORE); g_assert (!nm_setting_ip_config_get_ignore_auto_dns (s_ip6)); connection = g_hash_table_lookup (connections, "bootif_connection"); @@ -1052,6 +1084,57 @@ test_bootif_hwtype (void) g_assert (nm_setting_ip_config_get_may_fail (s_ip6)); } +/* Check that nameservers are assigned to all existing + * connections that support the specific IPv4/IPv6 address + * family. + */ +static void +test_nameserver (void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const*ARGV = NM_MAKE_STRV ("nameserver=1.1.1.1", + "ip=eth0:dhcp", + "ip=eth1:auto6", + "ip=10.11.12.13::10.11.12.1:24:foo.example.com:eth2:none", + "nameserver=1.0.0.1", + "nameserver=[2606:4700:4700::1111]"); + NMConnection *connection; + NMSettingIPConfig *s_ip; + + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); + g_assert (connections); + g_assert_cmpint (g_hash_table_size (connections), ==, 3); + + connection = g_hash_table_lookup (connections, "eth0"); + g_assert (connection); + nmtst_assert_connection_verifies_without_normalization (connection); + + s_ip = nm_connection_get_setting_ip4_config (connection); + g_assert (s_ip); + g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip), ==, 2); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip, 0), ==, "1.1.1.1"); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip, 1), ==, "1.0.0.1"); + + connection = g_hash_table_lookup (connections, "eth1"); + g_assert (connection); + nmtst_assert_connection_verifies_without_normalization (connection); + + s_ip = nm_connection_get_setting_ip6_config (connection); + g_assert (s_ip); + g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip), ==, 1); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip, 0), ==, "2606:4700:4700::1111"); + + connection = g_hash_table_lookup (connections, "eth2"); + g_assert (connection); + nmtst_assert_connection_verifies_without_normalization (connection); + + s_ip = nm_connection_get_setting_ip4_config (connection); + g_assert (s_ip); + g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip), ==, 2); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip, 0), ==, "1.1.1.1"); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip, 1), ==, "1.0.0.1"); +} + static void test_bootif_off (void) { @@ -1075,7 +1158,9 @@ int main (int argc, char **argv) g_test_add_func ("/initrd/cmdline/if_auto_with_mtu_and_mac", test_if_auto_with_mtu_and_mac); g_test_add_func ("/initrd/cmdline/if_ip4_manual", test_if_ip4_manual); g_test_add_func ("/initrd/cmdline/if_ip6_manual", test_if_ip6_manual); - g_test_add_func ("/initrd/cmdline/multiple", test_multiple); + g_test_add_func ("/initrd/cmdline/multiple/merge", test_multiple_merge); + g_test_add_func ("/initrd/cmdline/multiple/bootdev", test_multiple_bootdev); + g_test_add_func ("/initrd/cmdline/nameserver", test_nameserver); 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); |