initrd: rework command line parsing
The 'default_connection' created by the command line parser has multiple purposes. It's the connection created for 'ip=' arguments without command line, but is also created when there is a 'bootdev=' or for 'nameserver=' and no other connection exists at the moment the argument is parsed. This is confusing and leads to a result that depends on the order of parameters. For example: $ /usr/libexec/nm-initrd-generator -c connections -- bootdev=eth1 ip=eth0:dhcp $ ls connections/ default_connection.nmconnection eth0.nmconnection $ /usr/libexec/nm-initrd-generator -c connections -- ip=eth0:dhcp bootdev=eth1 $ ls connections/ eth0.nmconnection eth1.nmconnection Make this more explicit by tracking 'bootdev_connection' and 'default_connection' individually. Also fix handling of 'nameserver', 'rd.peerdns' and 'rd.route' arguments. First process all connections, and then set those properties. In particular, now nameservers are applied to all connections. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/391
This commit is contained in:
@@ -20,6 +20,8 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
GHashTable *hash;
|
GHashTable *hash;
|
||||||
GPtrArray *array;
|
GPtrArray *array;
|
||||||
|
NMConnection *bootdev_connection; /* connection for bootdev=$ifname */
|
||||||
|
NMConnection *default_connection; /* connection not bound to any ifname */
|
||||||
} Reader;
|
} Reader;
|
||||||
|
|
||||||
static Reader *
|
static Reader *
|
||||||
@@ -108,24 +110,32 @@ create_connection (Reader *reader,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static NMConnection *
|
static NMConnection *
|
||||||
get_connection (Reader *reader, const char *ifname, const char *type_name)
|
get_default_connection (Reader *reader)
|
||||||
{
|
{
|
||||||
NMConnection *connection;
|
NMConnection *con;
|
||||||
NMSetting *setting;
|
|
||||||
const char *basename;
|
|
||||||
NMConnectionMultiConnect multi_connect;
|
|
||||||
|
|
||||||
if (ifname) {
|
if (!reader->default_connection) {
|
||||||
basename = ifname;
|
con = create_connection (reader,
|
||||||
multi_connect = NM_CONNECTION_MULTI_CONNECT_SINGLE;
|
"default_connection",
|
||||||
} else {
|
"Wired Connection",
|
||||||
/* This is essentially for the "ip=dhcp" scenario. */
|
NULL,
|
||||||
basename = "default_connection";
|
NM_SETTING_WIRED_SETTING_NAME,
|
||||||
multi_connect = NM_CONNECTION_MULTI_CONNECT_MULTIPLE;
|
NM_CONNECTION_MULTI_CONNECT_MULTIPLE);
|
||||||
|
reader->default_connection = con;
|
||||||
}
|
}
|
||||||
|
return reader->default_connection;
|
||||||
|
}
|
||||||
|
|
||||||
connection = g_hash_table_lookup (reader->hash, (gpointer) basename);
|
static NMConnection *
|
||||||
if (!connection && !ifname) {
|
get_connection (Reader *reader,
|
||||||
|
const char *ifname,
|
||||||
|
const char *type_name,
|
||||||
|
gboolean create_if_missing)
|
||||||
|
{
|
||||||
|
NMConnection *connection = NULL;
|
||||||
|
NMSetting *setting;
|
||||||
|
|
||||||
|
if (!ifname) {
|
||||||
NMConnection *candidate;
|
NMConnection *candidate;
|
||||||
NMSettingConnection *s_con;
|
NMSettingConnection *s_con;
|
||||||
guint i;
|
guint i;
|
||||||
@@ -136,7 +146,6 @@ get_connection (Reader *reader, const char *ifname, const char *type_name)
|
|||||||
* This is so that things like "bond=bond0:eth1,eth2 nameserver=1.3.3.7 end up
|
* 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).
|
* slapping the nameserver to the most reasonable connection (bond0).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (i = 0; i < reader->array->len; i++) {
|
for (i = 0; i < reader->array->len; i++) {
|
||||||
candidate = g_hash_table_lookup (reader->hash, reader->array->pdata[i]);
|
candidate = g_hash_table_lookup (reader->hash, reader->array->pdata[i]);
|
||||||
s_con = nm_connection_get_setting_connection (candidate);
|
s_con = nm_connection_get_setting_connection (candidate);
|
||||||
@@ -153,17 +162,22 @@ get_connection (Reader *reader, const char *ifname, const char *type_name)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
|
connection = g_hash_table_lookup (reader->hash, (gpointer) ifname);
|
||||||
|
|
||||||
if (!connection) {
|
if (!connection) {
|
||||||
|
if (!create_if_missing)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (!type_name)
|
if (!type_name)
|
||||||
type_name = NM_SETTING_WIRED_SETTING_NAME;
|
type_name = NM_SETTING_WIRED_SETTING_NAME;
|
||||||
|
|
||||||
connection = create_connection (reader, basename,
|
connection = create_connection (reader, ifname,
|
||||||
ifname ?: "Wired Connection",
|
ifname ?: "Wired Connection",
|
||||||
ifname, type_name, multi_connect);
|
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) {
|
if (type_name) {
|
||||||
g_object_set (setting, NM_SETTING_CONNECTION_TYPE, type_name, NULL);
|
g_object_set (setting, NM_SETTING_CONNECTION_TYPE, type_name, NULL);
|
||||||
@@ -356,7 +370,11 @@ parse_ip (Reader *reader, const char *sysfs_dir, char *argument)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Parsing done, construct the NMConnection. */
|
/* Parsing done, construct the NMConnection. */
|
||||||
connection = get_connection (reader, ifname, NULL);
|
if (ifname)
|
||||||
|
connection = get_connection (reader, ifname, NULL, TRUE);
|
||||||
|
else
|
||||||
|
connection = get_default_connection (reader);
|
||||||
|
|
||||||
s_ip4 = nm_connection_get_setting_ip4_config (connection);
|
s_ip4 = nm_connection_get_setting_ip4_config (connection);
|
||||||
s_ip6 = nm_connection_get_setting_ip6_config (connection);
|
s_ip6 = nm_connection_get_setting_ip6_config (connection);
|
||||||
|
|
||||||
@@ -569,7 +587,7 @@ parse_master (Reader *reader,
|
|||||||
master = master_to_free = g_strdup_printf ("%s0", default_name ?: type_name);
|
master = master_to_free = g_strdup_printf ("%s0", default_name ?: type_name);
|
||||||
slaves = get_word (&argument, ':');
|
slaves = get_word (&argument, ':');
|
||||||
|
|
||||||
connection = get_connection (reader, master, type_name);
|
connection = get_connection (reader, master, type_name, TRUE);
|
||||||
s_con = nm_connection_get_setting_connection (connection);
|
s_con = nm_connection_get_setting_connection (connection);
|
||||||
master = nm_setting_connection_get_uuid (s_con);
|
master = nm_setting_connection_get_uuid (s_con);
|
||||||
|
|
||||||
@@ -591,7 +609,7 @@ parse_master (Reader *reader,
|
|||||||
if (slave == NULL)
|
if (slave == NULL)
|
||||||
slave = "eth0";
|
slave = "eth0";
|
||||||
|
|
||||||
connection = get_connection (reader, slave, NULL);
|
connection = get_connection (reader, slave, NULL, TRUE);
|
||||||
s_con = nm_connection_get_setting_connection (connection);
|
s_con = nm_connection_get_setting_connection (connection);
|
||||||
g_object_set (s_con,
|
g_object_set (s_con,
|
||||||
NM_SETTING_CONNECTION_SLAVE_TYPE, type_name,
|
NM_SETTING_CONNECTION_SLAVE_TYPE, type_name,
|
||||||
@@ -606,65 +624,77 @@ parse_master (Reader *reader,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_rd_route (Reader *reader, char *argument)
|
add_routes (Reader *reader, GPtrArray *array)
|
||||||
{
|
{
|
||||||
NMConnection *connection;
|
guint i;
|
||||||
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, ':');
|
for (i = 0; i < array->len; i++) {
|
||||||
gateway = get_word (&argument, ':');
|
NMConnection *connection = NULL;
|
||||||
interface = get_word (&argument, ':');
|
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;
|
||||||
|
|
||||||
connection = get_connection (reader, interface, NULL);
|
argument = array->pdata[i];
|
||||||
|
net = get_word (&argument, ':');
|
||||||
|
gateway = get_word (&argument, ':');
|
||||||
|
interface = get_word (&argument, ':');
|
||||||
|
|
||||||
if (net && *net) {
|
if (interface)
|
||||||
if (!nm_utils_parse_inaddr_prefix_bin (family, net, &family, &net_addr, &net_prefix)) {
|
connection = get_connection (reader, interface, NULL, TRUE);
|
||||||
_LOGW (LOGD_CORE, "Unrecognized address: %s", net);
|
if (!connection)
|
||||||
return;
|
connection = reader->bootdev_connection;
|
||||||
|
if (!connection)
|
||||||
|
connection = get_connection (reader, interface, NULL, FALSE);
|
||||||
|
if (!connection)
|
||||||
|
connection = 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 (gateway && *gateway) {
|
if (gateway && *gateway) {
|
||||||
if (!nm_utils_parse_inaddr_bin (family, gateway, &family, &gateway_addr)) {
|
if (!nm_utils_parse_inaddr_bin (family, gateway, &family, &gateway_addr)) {
|
||||||
_LOGW (LOGD_CORE, "Unrecognized address: %s", gateway);
|
_LOGW (LOGD_CORE, "Unrecognized address: %s", gateway);
|
||||||
return;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
switch (family) {
|
switch (family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
s_ip = nm_connection_get_setting_ip4_config (connection);
|
s_ip = nm_connection_get_setting_ip4_config (connection);
|
||||||
if (net_prefix == -1)
|
if (net_prefix == -1)
|
||||||
net_prefix = 32;
|
net_prefix = 32;
|
||||||
break;
|
break;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
s_ip = nm_connection_get_setting_ip6_config (connection);
|
s_ip = nm_connection_get_setting_ip6_config (connection);
|
||||||
if (net_prefix == -1)
|
if (net_prefix == -1)
|
||||||
net_prefix = 128;
|
net_prefix = 128;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
_LOGW (LOGD_CORE, "Unknown address family: %s", net);
|
_LOGW (LOGD_CORE, "Unknown address family: %s", net);
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
route = nm_ip_route_new_binary (family, &net_addr.addr_ptr, net_prefix, &gateway_addr.addr_ptr, -1, &error);
|
route = nm_ip_route_new_binary (family, &net_addr.addr_ptr, net_prefix, &gateway_addr.addr_ptr, -1, &error);
|
||||||
if (!route) {
|
if (!route) {
|
||||||
g_warning ("Invalid route '%s via %s': %s\n", net, gateway, error->message);
|
g_warning ("Invalid route '%s via %s': %s\n", net, gateway, error->message);
|
||||||
g_clear_error (&error);
|
continue;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
nm_setting_ip_config_add_route (s_ip, route);
|
nm_setting_ip_config_add_route (s_ip, route);
|
||||||
nm_ip_route_unref (route);
|
nm_ip_route_unref (route);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -684,7 +714,7 @@ parse_vlan (Reader *reader, char *argument)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
connection = get_connection (reader, vlan, NM_SETTING_VLAN_SETTING_NAME);
|
connection = get_connection (reader, vlan, NM_SETTING_VLAN_SETTING_NAME, TRUE);
|
||||||
|
|
||||||
s_vlan = nm_connection_get_setting_vlan (connection);
|
s_vlan = nm_connection_get_setting_vlan (connection);
|
||||||
g_object_set (s_vlan,
|
g_object_set (s_vlan,
|
||||||
@@ -696,76 +726,6 @@ parse_vlan (Reader *reader, char *argument)
|
|||||||
_LOGW (LOGD_CORE, "Ignoring extra: '%s'.", argument);
|
_LOGW (LOGD_CORE, "Ignoring extra: '%s'.", argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
parse_bootdev (Reader *reader, char *argument)
|
|
||||||
{
|
|
||||||
NMConnection *connection;
|
|
||||||
NMSettingConnection *s_con;
|
|
||||||
|
|
||||||
connection = get_connection (reader, 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_connection (reader, 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 (Reader *reader, char *argument)
|
|
||||||
{
|
|
||||||
NMConnection *connection;
|
|
||||||
NMSettingIPConfig *s_ip = NULL;
|
|
||||||
char *dns;
|
|
||||||
|
|
||||||
connection = get_connection (reader, 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 (Reader *reader, char *argument)
|
|
||||||
{
|
|
||||||
gboolean auto_dns = !_nm_utils_ascii_str_to_bool (argument, TRUE);
|
|
||||||
NMConnection *connection;
|
|
||||||
NMSettingIPConfig *s_ip = NULL;
|
|
||||||
|
|
||||||
connection = get_connection (reader, 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
|
static void
|
||||||
parse_rd_znet (Reader *reader, char *argument, gboolean net_ifnames)
|
parse_rd_znet (Reader *reader, char *argument, gboolean net_ifnames)
|
||||||
{
|
{
|
||||||
@@ -817,7 +777,7 @@ parse_rd_znet (Reader *reader, char *argument, gboolean net_ifnames)
|
|||||||
ifname = g_strdup_printf ("%s%d", prefix, index);
|
ifname = g_strdup_printf ("%s%d", prefix, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
connection = get_connection (reader, ifname, NM_SETTING_WIRED_SETTING_NAME);
|
connection = get_connection (reader, ifname, NM_SETTING_WIRED_SETTING_NAME, TRUE);
|
||||||
s_wired = nm_connection_get_setting_wired (connection);
|
s_wired = nm_connection_get_setting_wired (connection);
|
||||||
g_object_set (s_wired,
|
g_object_set (s_wired,
|
||||||
NM_SETTING_WIRED_S390_NETTYPE, nettype,
|
NM_SETTING_WIRED_S390_NETTYPE, nettype,
|
||||||
@@ -847,6 +807,72 @@ _normalize_conn (gpointer key, gpointer value, gpointer user_data)
|
|||||||
nm_connection_normalize (connection, NULL, NULL, NULL);
|
nm_connection_normalize (connection, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
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
|
||||||
|
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 *
|
GHashTable *
|
||||||
nmi_cmdline_reader_parse (const char *sysfs_dir, const char *const*argv)
|
nmi_cmdline_reader_parse (const char *sysfs_dir, const char *const*argv)
|
||||||
{
|
{
|
||||||
@@ -855,7 +881,11 @@ nmi_cmdline_reader_parse (const char *sysfs_dir, const char *const*argv)
|
|||||||
gboolean ignore_bootif = FALSE;
|
gboolean ignore_bootif = FALSE;
|
||||||
gboolean neednet = FALSE;
|
gboolean neednet = FALSE;
|
||||||
gs_free char *bootif_val = NULL;
|
gs_free char *bootif_val = NULL;
|
||||||
|
gs_free char *bootdev = NULL;
|
||||||
gboolean net_ifnames = TRUE;
|
gboolean net_ifnames = TRUE;
|
||||||
|
gs_unref_ptrarray GPtrArray *nameservers = NULL;
|
||||||
|
gs_unref_ptrarray GPtrArray *routes = NULL;
|
||||||
|
gboolean ignore_auto_dns = FALSE;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
reader = reader_new ();
|
reader = reader_new ();
|
||||||
@@ -870,6 +900,7 @@ nmi_cmdline_reader_parse (const char *sysfs_dir, const char *const*argv)
|
|||||||
for (i = 0; argv[i]; i++) {
|
for (i = 0; argv[i]; i++) {
|
||||||
gs_free char *argument_clone = NULL;
|
gs_free char *argument_clone = NULL;
|
||||||
char *argument;
|
char *argument;
|
||||||
|
char *word;
|
||||||
|
|
||||||
argument_clone = g_strdup (argv[i]);
|
argument_clone = g_strdup (argv[i]);
|
||||||
argument = argument_clone;
|
argument = argument_clone;
|
||||||
@@ -877,9 +908,11 @@ nmi_cmdline_reader_parse (const char *sysfs_dir, const char *const*argv)
|
|||||||
tag = get_word (&argument, '=');
|
tag = get_word (&argument, '=');
|
||||||
if (strcmp (tag, "ip") == 0)
|
if (strcmp (tag, "ip") == 0)
|
||||||
parse_ip (reader, sysfs_dir, argument);
|
parse_ip (reader, sysfs_dir, argument);
|
||||||
else if (strcmp (tag, "rd.route") == 0)
|
else if (strcmp (tag, "rd.route") == 0) {
|
||||||
parse_rd_route (reader, argument);
|
if (!routes)
|
||||||
else if (strcmp (tag, "bridge") == 0)
|
routes = g_ptr_array_new_with_free_func (g_free);
|
||||||
|
g_ptr_array_add (routes, g_strdup (argument));
|
||||||
|
} else if (strcmp (tag, "bridge") == 0)
|
||||||
parse_master (reader, argument, NM_SETTING_BRIDGE_SETTING_NAME, "br");
|
parse_master (reader, argument, NM_SETTING_BRIDGE_SETTING_NAME, "br");
|
||||||
else if (strcmp (tag, "bond") == 0)
|
else if (strcmp (tag, "bond") == 0)
|
||||||
parse_master (reader, argument, NM_SETTING_BOND_SETTING_NAME, NULL);
|
parse_master (reader, argument, NM_SETTING_BOND_SETTING_NAME, NULL);
|
||||||
@@ -887,12 +920,20 @@ nmi_cmdline_reader_parse (const char *sysfs_dir, const char *const*argv)
|
|||||||
parse_master (reader, argument, NM_SETTING_TEAM_SETTING_NAME, NULL);
|
parse_master (reader, argument, NM_SETTING_TEAM_SETTING_NAME, NULL);
|
||||||
else if (strcmp (tag, "vlan") == 0)
|
else if (strcmp (tag, "vlan") == 0)
|
||||||
parse_vlan (reader, argument);
|
parse_vlan (reader, argument);
|
||||||
else if (strcmp (tag, "bootdev") == 0)
|
else if (strcmp (tag, "bootdev") == 0) {
|
||||||
parse_bootdev (reader, argument);
|
g_free (bootdev);
|
||||||
else if (strcmp (tag, "nameserver") == 0)
|
bootdev = g_strdup (argument);
|
||||||
parse_nameserver (reader, argument);
|
} else if (strcmp (tag, "nameserver") == 0) {
|
||||||
else if (strcmp (tag, "rd.peerdns") == 0)
|
word = get_word (&argument, '\0');
|
||||||
parse_rd_peerdns (reader, argument);
|
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))
|
else if (strcmp (tag, "rd.iscsi.ibft") == 0 && _nm_utils_ascii_str_to_bool (argument, TRUE))
|
||||||
read_all_connections_from_fw (reader, sysfs_dir);
|
read_all_connections_from_fw (reader, sysfs_dir);
|
||||||
else if (strcmp (tag, "rd.bootif") == 0)
|
else if (strcmp (tag, "rd.bootif") == 0)
|
||||||
@@ -924,7 +965,10 @@ nmi_cmdline_reader_parse (const char *sysfs_dir, const char *const*argv)
|
|||||||
bootif += 3;
|
bootif += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
connection = get_connection (reader, NULL, NM_SETTING_WIRED_SETTING_NAME);
|
connection = get_connection (reader, NULL, NM_SETTING_WIRED_SETTING_NAME, FALSE);
|
||||||
|
if (!connection)
|
||||||
|
connection = get_default_connection (reader);
|
||||||
|
|
||||||
s_wired = nm_connection_get_setting_wired (connection);
|
s_wired = nm_connection_get_setting_wired (connection);
|
||||||
|
|
||||||
if ( nm_connection_get_interface_name (connection)
|
if ( nm_connection_get_interface_name (connection)
|
||||||
@@ -942,11 +986,28 @@ nmi_cmdline_reader_parse (const char *sysfs_dir, const char *const*argv)
|
|||||||
NM_SETTING_WIRED_MAC_ADDRESS, bootif,
|
NM_SETTING_WIRED_MAC_ADDRESS, bootif,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bootdev) {
|
||||||
|
NMConnection *connection;
|
||||||
|
|
||||||
|
connection = get_connection (reader, bootdev, NULL, TRUE);
|
||||||
|
reader->bootdev_connection = connection;
|
||||||
|
}
|
||||||
|
|
||||||
if (neednet && g_hash_table_size (reader->hash) == 0) {
|
if (neednet && g_hash_table_size (reader->hash) == 0) {
|
||||||
/* Make sure there's some connection. */
|
/* Make sure there's some connection. */
|
||||||
get_connection (reader, NULL, NM_SETTING_WIRED_SETTING_NAME);
|
get_default_connection (reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (routes)
|
||||||
|
add_routes (reader, routes);
|
||||||
|
|
||||||
|
if (nameservers)
|
||||||
|
add_nameservers (reader, nameservers);
|
||||||
|
|
||||||
|
if (ignore_auto_dns)
|
||||||
|
set_ignore_auto_dns (reader);
|
||||||
|
|
||||||
g_hash_table_foreach (reader->hash, _normalize_conn, NULL);
|
g_hash_table_foreach (reader->hash, _normalize_conn, NULL);
|
||||||
return reader_destroy (reader, FALSE);
|
return reader_destroy (reader, FALSE);
|
||||||
}
|
}
|
||||||
|
@@ -264,7 +264,7 @@ test_if_ip6_manual (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_multiple (void)
|
test_multiple_merge (void)
|
||||||
{
|
{
|
||||||
gs_unref_hashtable GHashTable *connections = NULL;
|
gs_unref_hashtable GHashTable *connections = NULL;
|
||||||
const char *const*ARGV = NM_MAKE_STRV ("ip=192.0.2.2:::::eth0",
|
const char *const*ARGV = NM_MAKE_STRV ("ip=192.0.2.2:::::eth0",
|
||||||
@@ -306,6 +306,37 @@ test_multiple (void)
|
|||||||
g_assert_cmpstr (nm_ip_address_get_address (ip_addr), ==, "2001:db8::2");
|
g_assert_cmpstr (nm_ip_address_get_address (ip_addr), ==, "2001:db8::2");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static void
|
||||||
test_bootdev (void)
|
test_bootdev (void)
|
||||||
{
|
{
|
||||||
@@ -358,16 +389,16 @@ test_some_more (void)
|
|||||||
g_assert (connections);
|
g_assert (connections);
|
||||||
g_assert_cmpint (g_hash_table_size (connections), ==, 2);
|
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);
|
g_assert (connection);
|
||||||
nmtst_assert_connection_verifies_without_normalization (connection);
|
nmtst_assert_connection_verifies_without_normalization (connection);
|
||||||
|
|
||||||
s_con = nm_connection_get_setting_connection (connection);
|
s_con = nm_connection_get_setting_connection (connection);
|
||||||
g_assert (s_con);
|
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_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_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);
|
s_wired = nm_connection_get_setting_wired (connection);
|
||||||
g_assert (s_wired);
|
g_assert (s_wired);
|
||||||
@@ -409,7 +440,8 @@ test_some_more (void)
|
|||||||
s_ip6 = nm_connection_get_setting_ip6_config (connection);
|
s_ip6 = nm_connection_get_setting_ip6_config (connection);
|
||||||
g_assert (s_ip6);
|
g_assert (s_ip6);
|
||||||
g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO);
|
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_cmpint (nm_setting_ip_config_get_num_routes (s_ip6), ==, 1);
|
||||||
g_assert (!nm_setting_ip_config_get_gateway (s_ip6));
|
g_assert (!nm_setting_ip_config_get_gateway (s_ip6));
|
||||||
ip_route = nm_setting_ip_config_get_route (s_ip6, 0);
|
ip_route = nm_setting_ip_config_get_route (s_ip6, 0);
|
||||||
@@ -1052,6 +1084,57 @@ test_bootif_hwtype (void)
|
|||||||
g_assert (nm_setting_ip_config_get_may_fail (s_ip6));
|
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
|
static void
|
||||||
test_bootif_off (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_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_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/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/some_more", test_some_more);
|
||||||
g_test_add_func ("/initrd/cmdline/bootdev", test_bootdev);
|
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", test_bond);
|
||||||
|
Reference in New Issue
Block a user