diff options
Diffstat (limited to 'src/initrd/nmi-cmdline-reader.c')
| -rw-r--r-- | src/initrd/nmi-cmdline-reader.c | 121 |
1 files changed, 85 insertions, 36 deletions
diff --git a/src/initrd/nmi-cmdline-reader.c b/src/initrd/nmi-cmdline-reader.c index 5e610e15..1c1b43eb 100644 --- a/src/initrd/nmi-cmdline-reader.c +++ b/src/initrd/nmi-cmdline-reader.c @@ -24,6 +24,8 @@ typedef struct { GHashTable * hash; GPtrArray * array; + GPtrArray * vlan_parents; + GHashTable * explicit_ip_connections; NMConnection *bootdev_connection; /* connection for bootdev=$ifname */ NMConnection *default_connection; /* connection not bound to any ifname */ char * hostname; @@ -41,8 +43,11 @@ reader_new(void) reader = g_slice_new(Reader); *reader = (Reader){ - .hash = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_object_unref), - .array = g_ptr_array_new(), + .hash = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_object_unref), + .explicit_ip_connections = + g_hash_table_new_full(nm_direct_hash, NULL, g_object_unref, NULL), + .vlan_parents = g_ptr_array_new_with_free_func(g_free), + .array = g_ptr_array_new(), }; return reader; @@ -54,6 +59,8 @@ reader_destroy(Reader *reader, gboolean free_hash) gs_unref_hashtable GHashTable *hash = NULL; g_ptr_array_unref(reader->array); + g_ptr_array_unref(reader->vlan_parents); + g_hash_table_unref(reader->explicit_ip_connections); hash = g_steal_pointer(&reader->hash); nm_clear_g_free(&reader->hostname); nm_clear_g_free(&reader->dhcp4_vci); @@ -383,6 +390,7 @@ reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument) NMSettingIPConfig *s_ip4 = NULL, *s_ip6 = NULL; gs_unref_hashtable GHashTable *ibft = NULL; const char * tmp; + const char * tmp2; const char * kind = NULL; const char * client_ip = NULL; const char * peer = NULL; @@ -411,17 +419,37 @@ reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument) /* ip={dhcp|on|any|dhcp6|auto6|ibft} */ kind = tmp; } else { - client_ip_family = guess_ip_address_family(tmp); - if (client_ip_family != AF_UNSPEC) { - /* <client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>: */ - client_ip = tmp; - peer = get_word(&argument, ':'); + tmp2 = get_word(&argument, ':'); + if (NM_IN_STRSET(tmp2, + "none", + "off", + "dhcp", + "on" + "any", + "dhcp6", + "auto", + "auto6", + "ibft")) { + /* <ifname>:{none|off|dhcp|on|any|dhcp6|auto|auto6|ibft} */ + iface_spec = tmp; + kind = tmp2; + } else { + /* <client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<kind> */ + client_ip = tmp; + if (client_ip) { + client_ip_family = get_ip_address_family(client_ip, TRUE); + if (client_ip_family == AF_UNSPEC) { + _LOGW(LOGD_CORE, "Invalid IP address '%s'.", client_ip); + return; + } + } + + peer = tmp2; gateway_ip = get_word(&argument, ':'); netmask = get_word(&argument, ':'); client_hostname = get_word(&argument, ':'); iface_spec = get_word(&argument, ':'); - } else { - iface_spec = tmp; + kind = get_word(&argument, ':'); } if (client_hostname && !nm_sd_hostname_is_valid(client_hostname, FALSE)) @@ -432,16 +460,12 @@ reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument) reader->hostname = g_strdup(client_hostname); } - /* <ifname>:{none|off|dhcp|on|any|dhcp6|auto6|ibft} */ - - kind = get_word(&argument, ':'); - tmp = get_word(&argument, ':'); - dns_addr_family[0] = guess_ip_address_family(tmp); + dns_addr_family[0] = get_ip_address_family(tmp, FALSE); if (dns_addr_family[0] != AF_UNSPEC) { dns[0] = tmp; dns[1] = get_word(&argument, ':'); - dns_addr_family[1] = guess_ip_address_family(dns[1]); + dns_addr_family[1] = get_ip_address_family(dns[1], FALSE); if (*argument) _LOGW(LOGD_CORE, "Ignoring extra: '%s'.", argument); } else { @@ -461,6 +485,8 @@ reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument) else connection = reader_get_default_connection(reader); + g_hash_table_add(reader->explicit_ip_connections, g_object_ref(connection)); + s_ip4 = nm_connection_get_setting_ip4_config(connection); s_ip6 = nm_connection_get_setting_ip6_config(connection); @@ -506,9 +532,8 @@ reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument) _LOGW(LOGD_CORE, "Invalid address '%s': %s", client_ip, error->message); g_clear_error(&error); } - } else { - _LOGW(LOGD_CORE, "Unrecognized address: %s", client_ip); - } + } else + nm_assert_not_reached(); if (address) { switch (client_ip_family) { @@ -531,7 +556,7 @@ reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument) nm_setting_ip_config_add_address(s_ip6, address); break; default: - _LOGW(LOGD_CORE, "Unknown address family: %s", client_ip); + nm_assert_not_reached(); break; } nm_ip_address_unref(address); @@ -543,7 +568,7 @@ reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument) 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_AUTO, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED, NULL); } if (nm_setting_ip_config_get_num_addresses(s_ip4) == 0) { @@ -618,22 +643,16 @@ reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument) _LOGW(LOGD_CORE, "Ignoring peer: %s (not implemented)\n", peer); if (gateway_ip && *gateway_ip) { - int addr_family = guess_ip_address_family(gateway_ip); - - if (nm_utils_ipaddr_is_valid(addr_family, gateway_ip)) { - switch (addr_family) { - case AF_INET: - g_object_set(s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway_ip, NULL); - break; - case AF_INET6: - g_object_set(s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, gateway_ip, NULL); - break; - default: - _LOGW(LOGD_CORE, "Unknown address family: %s", gateway_ip); - break; - } - } else { + switch (get_ip_address_family(gateway_ip, FALSE)) { + case AF_INET: + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway_ip, NULL); + break; + case AF_INET6: + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, gateway_ip, NULL); + break; + default: _LOGW(LOGD_CORE, "Invalid gateway: %s", gateway_ip); + break; } } @@ -842,6 +861,9 @@ reader_parse_vlan(Reader *reader, char *argument) if (argument && *argument) _LOGW(LOGD_CORE, "Ignoring extra: '%s'.", argument); + + if (!nm_strv_ptrarray_contains(reader->vlan_parents, phy)) + g_ptr_array_add(reader->vlan_parents, g_strdup(phy)); } static void @@ -941,7 +963,7 @@ reader_add_nameservers(Reader *reader, GPtrArray *nameservers) for (i = 0; i < nameservers->len; i++) { ns = nameservers->pdata[i]; - addr_family = guess_ip_address_family(ns); + addr_family = get_ip_address_family(ns, FALSE); if (addr_family == AF_UNSPEC) { _LOGW(LOGD_CORE, "Unknown address family: %s", ns); continue; @@ -1085,6 +1107,33 @@ nmi_cmdline_reader_parse(const char *sysfs_dir, const char *const *argv, char ** } } + for (i = 0; i < reader->vlan_parents->len; i++) { + NMConnection * connection; + NMSettingIPConfig *s_ip; + + /* Disable IP configuration for parent connections of VLANs, + * unless those interfaces were explicitly configured otherwise. */ + + connection = reader_get_connection(reader, reader->vlan_parents->pdata[i], NULL, TRUE); + if (!g_hash_table_contains(reader->explicit_ip_connections, connection)) { + s_ip = nm_connection_get_setting_ip4_config(connection); + if (s_ip) { + g_object_set(s_ip, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NULL); + } + + s_ip = nm_connection_get_setting_ip6_config(connection); + if (s_ip) { + g_object_set(s_ip, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED, + NULL); + } + } + } + if (ignore_bootif) nm_clear_g_free(&bootif_val); if (bootif_val) { |