summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2020-03-26 22:12:33 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2020-03-26 22:12:33 +0100
commitc8b752c9735147d38832aa70027196c7458f6cc9 (patch)
tree84513db1ff6ec124dd9e365f6cdc470079369531
parent2da77547bafedd352d5c40f66ccd365c454c30d4 (diff)
parent99e01888864ddba4eda31c43809842afa2594a56 (diff)
downloadNetworkManager-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.c547
-rw-r--r--src/initrd/nmi-ibft-reader.c4
-rw-r--r--src/initrd/tests/test-cmdline-reader.c101
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);